mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-03-13 19:29:14 +01:00
[d3d11] Update mapped buffers of staging textures immediately
Improves performance in Lords of the Fallen and The Surge. Closes #1049. Co-authored-by: Robin <robin.kertels@outlook.com>
This commit is contained in:
parent
905f3fe520
commit
8e9e7963a2
@ -554,6 +554,9 @@ namespace dxvk {
|
||||
cExtent);
|
||||
}
|
||||
});
|
||||
|
||||
if (dstTextureInfo->CanUpdateMappedBufferEarly())
|
||||
UpdateMappedBuffer(dstTextureInfo, dstSubresource);
|
||||
}
|
||||
}
|
||||
|
||||
@ -604,8 +607,11 @@ namespace dxvk {
|
||||
cSrcBuffer.length());
|
||||
});
|
||||
} else {
|
||||
const Rc<DxvkImage> dstImage = GetCommonTexture(pDstResource)->GetImage();
|
||||
const Rc<DxvkImage> srcImage = GetCommonTexture(pSrcResource)->GetImage();
|
||||
auto dstTexture = GetCommonTexture(pDstResource);
|
||||
auto srcTexture = GetCommonTexture(pSrcResource);
|
||||
|
||||
const Rc<DxvkImage> dstImage = dstTexture->GetImage();
|
||||
const Rc<DxvkImage> srcImage = srcTexture->GetImage();
|
||||
|
||||
const DxvkFormatInfo* dstFormatInfo = imageFormatInfo(dstImage->info().format);
|
||||
const DxvkFormatInfo* srcFormatInfo = imageFormatInfo(srcImage->info().format);
|
||||
@ -652,6 +658,11 @@ namespace dxvk {
|
||||
cSrcImage, cSrcLayers, VkOffset3D { 0, 0, 0 },
|
||||
cExtent);
|
||||
});
|
||||
|
||||
if (dstTexture->CanUpdateMappedBufferEarly()) {
|
||||
for (uint32_t j = 0; j < dstImage->info().numLayers; j++)
|
||||
UpdateMappedBuffer(dstTexture, { dstLayers.aspectMask, i, j });
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1229,6 +1240,9 @@ namespace dxvk {
|
||||
cPackedFormat);
|
||||
}
|
||||
});
|
||||
|
||||
if (textureInfo->CanUpdateMappedBufferEarly())
|
||||
UpdateMappedBuffer(textureInfo, subresource);
|
||||
}
|
||||
}
|
||||
|
||||
@ -3667,6 +3681,40 @@ namespace dxvk {
|
||||
ctrSlotId + i, ~0u);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void D3D11DeviceContext::UpdateMappedBuffer(
|
||||
const D3D11CommonTexture* pTexture,
|
||||
VkImageSubresource Subresource) {
|
||||
Rc<DxvkImage> mappedImage = pTexture->GetImage();
|
||||
Rc<DxvkBuffer> mappedBuffer = pTexture->GetMappedBuffer();
|
||||
|
||||
VkFormat packedFormat = m_parent->LookupPackedFormat(
|
||||
pTexture->Desc()->Format, pTexture->GetFormatMode()).Format;
|
||||
|
||||
VkExtent3D levelExtent = mappedImage->mipLevelExtent(Subresource.mipLevel);
|
||||
|
||||
EmitCs([
|
||||
cImageBuffer = std::move(mappedBuffer),
|
||||
cImage = std::move(mappedImage),
|
||||
cSubresources = vk::makeSubresourceLayers(Subresource),
|
||||
cLevelExtent = levelExtent,
|
||||
cPackedFormat = packedFormat
|
||||
] (DxvkContext* ctx) {
|
||||
if (cSubresources.aspectMask != (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) {
|
||||
ctx->copyImageToBuffer(
|
||||
cImageBuffer, 0, VkExtent2D { 0u, 0u },
|
||||
cImage, cSubresources, VkOffset3D { 0, 0, 0 },
|
||||
cLevelExtent);
|
||||
} else {
|
||||
ctx->copyDepthStencilImageToPackedBuffer(
|
||||
cImageBuffer, 0, cImage, cSubresources,
|
||||
VkOffset2D { 0, 0 },
|
||||
VkExtent2D { cLevelExtent.width, cLevelExtent.height },
|
||||
cPackedFormat);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
bool D3D11DeviceContext::ValidateRenderTargets(
|
||||
|
@ -803,6 +803,10 @@ namespace dxvk {
|
||||
DxbcProgramType Stage,
|
||||
D3D11UnorderedAccessBindings& Bindings);
|
||||
|
||||
void UpdateMappedBuffer(
|
||||
const D3D11CommonTexture* pTexture,
|
||||
VkImageSubresource Subresource);
|
||||
|
||||
bool ValidateRenderTargets(
|
||||
UINT NumViews,
|
||||
ID3D11RenderTargetView* const* ppRenderTargetViews,
|
||||
|
@ -383,32 +383,16 @@ namespace dxvk {
|
||||
// When using any map mode which requires the image contents
|
||||
// to be preserved, and if the GPU has write access to the
|
||||
// image, copy the current image contents into the buffer.
|
||||
if (pResource->Desc()->Usage == D3D11_USAGE_STAGING) {
|
||||
auto subresourceLayers = vk::makeSubresourceLayers(subresource);
|
||||
|
||||
EmitCs([
|
||||
cImageBuffer = mappedBuffer,
|
||||
cImage = mappedImage,
|
||||
cSubresources = subresourceLayers,
|
||||
cLevelExtent = levelExtent,
|
||||
cPackedFormat = packedFormat
|
||||
] (DxvkContext* ctx) {
|
||||
if (cSubresources.aspectMask != (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) {
|
||||
ctx->copyImageToBuffer(
|
||||
cImageBuffer, 0, VkExtent2D { 0u, 0u },
|
||||
cImage, cSubresources, VkOffset3D { 0, 0, 0 },
|
||||
cLevelExtent);
|
||||
} else {
|
||||
ctx->copyDepthStencilImageToPackedBuffer(
|
||||
cImageBuffer, 0, cImage, cSubresources,
|
||||
VkOffset2D { 0, 0 },
|
||||
VkExtent2D { cLevelExtent.width, cLevelExtent.height },
|
||||
cPackedFormat);
|
||||
}
|
||||
});
|
||||
if (pResource->Desc()->Usage == D3D11_USAGE_STAGING
|
||||
&& !pResource->CanUpdateMappedBufferEarly()) {
|
||||
UpdateMappedBuffer(pResource, subresource);
|
||||
MapFlags &= ~D3D11_MAP_FLAG_DO_NOT_WAIT;
|
||||
}
|
||||
|
||||
WaitForResource(mappedBuffer, 0);
|
||||
// Wait for mapped buffer to become available
|
||||
if (!WaitForResource(mappedBuffer, MapFlags))
|
||||
return DXGI_ERROR_WAS_STILL_DRAWING;
|
||||
|
||||
physSlice = mappedBuffer->getSliceHandle();
|
||||
}
|
||||
|
||||
|
@ -130,6 +130,22 @@ namespace dxvk {
|
||||
void ClearMappedSubresource() {
|
||||
m_mappedSubresource = VkImageSubresource { };
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Checks whether we can update the mapped buffer early
|
||||
*
|
||||
* For images which are mapped through a buffer and that are
|
||||
* only used for transfer operations, we can update the mapped
|
||||
* buffer right after performing those transfers to avoid stalls.
|
||||
* \returns \c true if the mapped buffer can be updated early
|
||||
*/
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Computes subresource from the subresource index
|
||||
|
Loading…
x
Reference in New Issue
Block a user