1
0
mirror of https://github.com/doitsujin/dxvk.git synced 2025-02-25 16:54:15 +01:00

[d3d11] Support mapping multiple image subresources at the same time

Fixes #1066.
This commit is contained in:
Philip Rebohle 2019-05-20 15:56:31 +02:00
parent a82dbf6200
commit 3168626f4b
No known key found for this signature in database
GPG Key ID: C8CC613427A31C99
4 changed files with 74 additions and 63 deletions

View File

@ -3686,8 +3686,12 @@ namespace dxvk {
void D3D11DeviceContext::UpdateMappedBuffer( void D3D11DeviceContext::UpdateMappedBuffer(
const D3D11CommonTexture* pTexture, const D3D11CommonTexture* pTexture,
VkImageSubresource Subresource) { VkImageSubresource Subresource) {
UINT SubresourceIndex = D3D11CalcSubresource(
Subresource.mipLevel, Subresource.arrayLayer,
pTexture->Desc()->MipLevels);
Rc<DxvkImage> mappedImage = pTexture->GetImage(); Rc<DxvkImage> mappedImage = pTexture->GetImage();
Rc<DxvkBuffer> mappedBuffer = pTexture->GetMappedBuffer(); Rc<DxvkBuffer> mappedBuffer = pTexture->GetMappedBuffer(SubresourceIndex);
VkFormat packedFormat = m_parent->LookupPackedFormat( VkFormat packedFormat = m_parent->LookupPackedFormat(
pTexture->Desc()->Format, pTexture->GetFormatMode()).Format; pTexture->Desc()->Format, pTexture->GetFormatMode()).Format;

View File

@ -332,21 +332,21 @@ namespace dxvk {
UINT MapFlags, UINT MapFlags,
D3D11_MAPPED_SUBRESOURCE* pMappedResource) { D3D11_MAPPED_SUBRESOURCE* pMappedResource) {
const Rc<DxvkImage> mappedImage = pResource->GetImage(); const Rc<DxvkImage> mappedImage = pResource->GetImage();
const Rc<DxvkBuffer> mappedBuffer = pResource->GetMappedBuffer(); const Rc<DxvkBuffer> mappedBuffer = pResource->GetMappedBuffer(Subresource);
if (unlikely(pResource->GetMapMode() == D3D11_COMMON_TEXTURE_MAP_MODE_NONE)) { if (unlikely(pResource->GetMapMode() == D3D11_COMMON_TEXTURE_MAP_MODE_NONE)) {
Logger::err("D3D11: Cannot map a device-local image"); Logger::err("D3D11: Cannot map a device-local image");
return E_INVALIDARG; return E_INVALIDARG;
} }
pResource->SetMapType(Subresource, MapType);
VkFormat packedFormat = m_parent->LookupPackedFormat( VkFormat packedFormat = m_parent->LookupPackedFormat(
pResource->Desc()->Format, pResource->GetFormatMode()).Format; pResource->Desc()->Format, pResource->GetFormatMode()).Format;
auto formatInfo = imageFormatInfo(packedFormat); auto formatInfo = imageFormatInfo(packedFormat);
auto subresource = pResource->GetSubresourceFromIndex( auto subresource = pResource->GetSubresourceFromIndex(
formatInfo->aspectMask, Subresource); formatInfo->aspectMask, Subresource);
pResource->SetMappedSubresource(subresource, MapType);
if (pResource->GetMapMode() == D3D11_COMMON_TEXTURE_MAP_MODE_DIRECT) { if (pResource->GetMapMode() == D3D11_COMMON_TEXTURE_MAP_MODE_DIRECT) {
const VkImageType imageType = mappedImage->info().type; const VkImageType imageType = mappedImage->info().type;
@ -408,16 +408,25 @@ namespace dxvk {
void D3D11ImmediateContext::UnmapImage( void D3D11ImmediateContext::UnmapImage(
D3D11CommonTexture* pResource, D3D11CommonTexture* pResource,
UINT Subresource) { UINT Subresource) {
if (pResource->GetMapType() == D3D11_MAP_READ) D3D11_MAP mapType = pResource->GetMapType(Subresource);
pResource->SetMapType(Subresource, D3D11_MAP(~0u));
if (mapType == D3D11_MAP(~0u)
|| mapType == D3D11_MAP_READ)
return; return;
if (pResource->GetMapMode() == D3D11_COMMON_TEXTURE_MAP_MODE_BUFFER) { if (pResource->GetMapMode() == D3D11_COMMON_TEXTURE_MAP_MODE_BUFFER) {
// Now that data has been written into the buffer, // Now that data has been written into the buffer,
// we need to copy its contents into the image // we need to copy its contents into the image
const Rc<DxvkImage> mappedImage = pResource->GetImage(); const Rc<DxvkImage> mappedImage = pResource->GetImage();
const Rc<DxvkBuffer> mappedBuffer = pResource->GetMappedBuffer(); const Rc<DxvkBuffer> mappedBuffer = pResource->GetMappedBuffer(Subresource);
VkImageSubresource subresource = pResource->GetMappedSubresource(); VkFormat packedFormat = m_parent->LookupPackedFormat(
pResource->Desc()->Format, pResource->GetFormatMode()).Format;
auto formatInfo = imageFormatInfo(packedFormat);
auto subresource = pResource->GetSubresourceFromIndex(
formatInfo->aspectMask, Subresource);
VkExtent3D levelExtent = mappedImage VkExtent3D levelExtent = mappedImage
->mipLevelExtent(subresource.mipLevel); ->mipLevelExtent(subresource.mipLevel);
@ -447,8 +456,6 @@ namespace dxvk {
} }
}); });
} }
pResource->ClearMappedSubresource();
} }

View File

@ -164,8 +164,14 @@ namespace dxvk {
} }
// If necessary, create the mapped linear buffer // If necessary, create the mapped linear buffer
if (m_mapMode == D3D11_COMMON_TEXTURE_MAP_MODE_BUFFER) for (uint32_t i = 0; i < m_desc.ArraySize; i++) {
m_buffer = CreateMappedBuffer(); for (uint32_t j = 0; j < m_desc.MipLevels; j++) {
if (m_mapMode == D3D11_COMMON_TEXTURE_MAP_MODE_BUFFER)
m_buffers.push_back(CreateMappedBuffer(j));
if (m_mapMode != D3D11_COMMON_TEXTURE_MAP_MODE_NONE)
m_mapTypes.push_back(D3D11_MAP(~0u));
}
}
// Create the image on a host-visible memory type // Create the image on a host-visible memory type
// in case it is going to be mapped directly. // in case it is going to be mapped directly.
@ -404,13 +410,16 @@ namespace dxvk {
} }
Rc<DxvkBuffer> D3D11CommonTexture::CreateMappedBuffer() const { Rc<DxvkBuffer> D3D11CommonTexture::CreateMappedBuffer(UINT MipLevel) const {
const DxvkFormatInfo* formatInfo = imageFormatInfo( const DxvkFormatInfo* formatInfo = imageFormatInfo(
m_device->LookupPackedFormat(m_desc.Format, GetFormatMode()).Format); m_device->LookupPackedFormat(m_desc.Format, GetFormatMode()).Format);
const VkExtent3D blockCount = util::computeBlockCount( const VkExtent3D mipExtent = util::computeMipLevelExtent(
VkExtent3D { m_desc.Width, m_desc.Height, m_desc.Depth }, VkExtent3D { m_desc.Width, m_desc.Height, m_desc.Depth },
formatInfo->blockSize); MipLevel);
const VkExtent3D blockCount = util::computeBlockCount(
mipExtent, formatInfo->blockSize);
DxvkBufferCreateInfo info; DxvkBufferCreateInfo info;
info.size = formatInfo->elementSize info.size = formatInfo->elementSize

View File

@ -83,6 +83,29 @@ namespace dxvk {
return m_mapMode; return m_mapMode;
} }
/**
* \brief Map type of a given subresource
*
* \param [in] Subresource Subresource index
* \returns Current map mode of that subresource
*/
D3D11_MAP GetMapType(UINT Subresource) const {
return Subresource < m_mapTypes.size()
? D3D11_MAP(m_mapTypes[Subresource])
: D3D11_MAP(~0u);
}
/**
* \brief Sets map type for a given subresource
*
* \param [in] Subresource The subresource
* \param [in] MapType The map type
*/
void SetMapType(UINT Subresource, D3D11_MAP MapType) {
if (Subresource < m_mapTypes.size())
m_mapTypes[Subresource] = MapType;
}
/** /**
* \brief The DXVK image * \brief The DXVK image
* \returns The DXVK image * \returns The DXVK image
@ -92,43 +115,15 @@ namespace dxvk {
} }
/** /**
* \brief The DXVK buffer * \brief Mapped subresource buffer
* \returns The DXVK buffer *
* \param [in] Subresource Subresource index
* \returns Mapped subresource buffer
*/ */
Rc<DxvkBuffer> GetMappedBuffer() const { Rc<DxvkBuffer> GetMappedBuffer(UINT Subresource) const {
return m_buffer; return Subresource < m_buffers.size()
} ? m_buffers[Subresource]
: Rc<DxvkBuffer>();
/**
* \brief Currently mapped subresource
* \returns Mapped subresource
*/
VkImageSubresource GetMappedSubresource() const {
return m_mappedSubresource;
}
/**
* \brief Current map type
*/
D3D11_MAP GetMapType() const {
return m_mapType;
}
/**
* \brief Sets mapped subresource
* \param [in] subresource THe subresource
*/
void SetMappedSubresource(VkImageSubresource Subresource, D3D11_MAP MapType) {
m_mappedSubresource = Subresource;
m_mapType = MapType;
}
/**
* \brief Resets mapped subresource
* Marks the texture as not mapped.
*/
void ClearMappedSubresource() {
m_mappedSubresource = VkImageSubresource { };
} }
/** /**
@ -142,9 +137,7 @@ namespace dxvk {
bool CanUpdateMappedBufferEarly() const { bool CanUpdateMappedBufferEarly() const {
return m_mapMode == D3D11_COMMON_TEXTURE_MAP_MODE_BUFFER return m_mapMode == D3D11_COMMON_TEXTURE_MAP_MODE_BUFFER
&& (m_desc.BindFlags & ~D3D11_BIND_SHADER_RESOURCE) == 0 && (m_desc.BindFlags & ~D3D11_BIND_SHADER_RESOURCE) == 0
&& m_desc.Usage == D3D11_USAGE_STAGING && (m_desc.Usage == D3D11_USAGE_STAGING);
&& m_desc.MipLevels == 1
&& m_desc.ArraySize == 1;
} }
/** /**
@ -208,14 +201,12 @@ namespace dxvk {
D3D11_COMMON_TEXTURE_DESC m_desc; D3D11_COMMON_TEXTURE_DESC m_desc;
D3D11_COMMON_TEXTURE_MAP_MODE m_mapMode; D3D11_COMMON_TEXTURE_MAP_MODE m_mapMode;
Rc<DxvkImage> m_image; Rc<DxvkImage> m_image;
Rc<DxvkBuffer> m_buffer; std::vector<Rc<DxvkBuffer>> m_buffers;
std::vector<D3D11_MAP> m_mapTypes;
VkImageSubresource m_mappedSubresource Rc<DxvkBuffer> CreateMappedBuffer(
= { VK_IMAGE_ASPECT_COLOR_BIT, 0, 0 }; UINT MipLevel) const;
D3D11_MAP m_mapType = D3D11_MAP_READ;
Rc<DxvkBuffer> CreateMappedBuffer() const;
BOOL CheckImageSupport( BOOL CheckImageSupport(
const DxvkImageCreateInfo* pImageInfo, const DxvkImageCreateInfo* pImageInfo,