[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(
const D3D11CommonTexture* pTexture,
VkImageSubresource Subresource) {
UINT SubresourceIndex = D3D11CalcSubresource(
Subresource.mipLevel, Subresource.arrayLayer,
pTexture->Desc()->MipLevels);
Rc<DxvkImage> mappedImage = pTexture->GetImage();
Rc<DxvkBuffer> mappedBuffer = pTexture->GetMappedBuffer();
Rc<DxvkBuffer> mappedBuffer = pTexture->GetMappedBuffer(SubresourceIndex);
VkFormat packedFormat = m_parent->LookupPackedFormat(
pTexture->Desc()->Format, pTexture->GetFormatMode()).Format;

View File

@ -332,21 +332,21 @@ namespace dxvk {
UINT MapFlags,
D3D11_MAPPED_SUBRESOURCE* pMappedResource) {
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)) {
Logger::err("D3D11: Cannot map a device-local image");
return E_INVALIDARG;
}
pResource->SetMapType(Subresource, MapType);
VkFormat packedFormat = m_parent->LookupPackedFormat(
pResource->Desc()->Format, pResource->GetFormatMode()).Format;
auto formatInfo = imageFormatInfo(packedFormat);
auto subresource = pResource->GetSubresourceFromIndex(
formatInfo->aspectMask, Subresource);
pResource->SetMappedSubresource(subresource, MapType);
formatInfo->aspectMask, Subresource);
if (pResource->GetMapMode() == D3D11_COMMON_TEXTURE_MAP_MODE_DIRECT) {
const VkImageType imageType = mappedImage->info().type;
@ -408,17 +408,26 @@ namespace dxvk {
void D3D11ImmediateContext::UnmapImage(
D3D11CommonTexture* pResource,
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;
if (pResource->GetMapMode() == D3D11_COMMON_TEXTURE_MAP_MODE_BUFFER) {
// Now that data has been written into the buffer,
// we need to copy its contents into the image
const Rc<DxvkImage> mappedImage = pResource->GetImage();
const Rc<DxvkBuffer> mappedBuffer = pResource->GetMappedBuffer();
VkImageSubresource subresource = pResource->GetMappedSubresource();
const Rc<DxvkBuffer> mappedBuffer = pResource->GetMappedBuffer(Subresource);
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
->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 (m_mapMode == D3D11_COMMON_TEXTURE_MAP_MODE_BUFFER)
m_buffer = CreateMappedBuffer();
for (uint32_t i = 0; i < m_desc.ArraySize; i++) {
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
// 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(
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 },
formatInfo->blockSize);
MipLevel);
const VkExtent3D blockCount = util::computeBlockCount(
mipExtent, formatInfo->blockSize);
DxvkBufferCreateInfo info;
info.size = formatInfo->elementSize

View File

@ -82,6 +82,29 @@ namespace dxvk {
D3D11_COMMON_TEXTURE_MAP_MODE GetMapMode() const {
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
@ -92,45 +115,17 @@ namespace dxvk {
}
/**
* \brief The DXVK buffer
* \returns The DXVK buffer
* \brief Mapped subresource buffer
*
* \param [in] Subresource Subresource index
* \returns Mapped subresource buffer
*/
Rc<DxvkBuffer> GetMappedBuffer() const {
return m_buffer;
Rc<DxvkBuffer> GetMappedBuffer(UINT Subresource) const {
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 { };
}
/**
* \brief Checks whether we can update the mapped buffer early
*
@ -142,9 +137,7 @@ namespace dxvk {
bool CanUpdateMappedBufferEarly() const {
return m_mapMode == D3D11_COMMON_TEXTURE_MAP_MODE_BUFFER
&& (m_desc.BindFlags & ~D3D11_BIND_SHADER_RESOURCE) == 0
&& m_desc.Usage == D3D11_USAGE_STAGING
&& m_desc.MipLevels == 1
&& m_desc.ArraySize == 1;
&& (m_desc.Usage == D3D11_USAGE_STAGING);
}
/**
@ -208,14 +201,12 @@ namespace dxvk {
D3D11_COMMON_TEXTURE_DESC m_desc;
D3D11_COMMON_TEXTURE_MAP_MODE m_mapMode;
Rc<DxvkImage> m_image;
Rc<DxvkBuffer> m_buffer;
Rc<DxvkImage> m_image;
std::vector<Rc<DxvkBuffer>> m_buffers;
std::vector<D3D11_MAP> m_mapTypes;
VkImageSubresource m_mappedSubresource
= { VK_IMAGE_ASPECT_COLOR_BIT, 0, 0 };
D3D11_MAP m_mapType = D3D11_MAP_READ;
Rc<DxvkBuffer> CreateMappedBuffer() const;
Rc<DxvkBuffer> CreateMappedBuffer(
UINT MipLevel) const;
BOOL CheckImageSupport(
const DxvkImageCreateInfo* pImageInfo,