[d3d11] Move UpdateSubresource code to D3D11CommonContext

This commit is contained in:
Philip Rebohle 2022-08-03 16:41:50 +02:00
parent e4204f76e6
commit 3ead348b82
No known key found for this signature in database
GPG Key ID: C8CC613427A31C99
7 changed files with 117 additions and 146 deletions

View File

@ -806,68 +806,6 @@ namespace dxvk {
ID3D11Resource* pResource,
UINT Subresource);
template<typename ContextType>
static void UpdateResource(
ContextType* pContext,
ID3D11Resource* pDstResource,
UINT DstSubresource,
const D3D11_BOX* pDstBox,
const void* pSrcData,
UINT SrcRowPitch,
UINT SrcDepthPitch,
UINT CopyFlags) {
D3D10DeviceLock lock = pContext->LockContext();
if (!pDstResource)
return;
// We need a different code path for buffers
D3D11_RESOURCE_DIMENSION resourceType;
pDstResource->GetType(&resourceType);
if (likely(resourceType == D3D11_RESOURCE_DIMENSION_BUFFER)) {
const auto bufferResource = static_cast<D3D11Buffer*>(pDstResource);
uint64_t bufferSize = bufferResource->Desc()->ByteWidth;
// Provide a fast path for mapped buffer updates since some
// games use UpdateSubresource to update constant buffers.
if (likely(bufferResource->GetMapMode() == D3D11_COMMON_BUFFER_MAP_MODE_DIRECT) && likely(!pDstBox)) {
pContext->UpdateMappedBuffer(bufferResource, 0, bufferSize, pSrcData, 0);
return;
}
// Validate buffer range to update
uint64_t offset = 0;
uint64_t length = bufferSize;
if (pDstBox) {
offset = pDstBox->left;
length = pDstBox->right - offset;
}
if (unlikely(offset + length > bufferSize))
return;
// Still try to be fast if a box is provided but we update the full buffer
if (likely(bufferResource->GetMapMode() == D3D11_COMMON_BUFFER_MAP_MODE_DIRECT)) {
CopyFlags &= D3D11_COPY_DISCARD | D3D11_COPY_NO_OVERWRITE;
if (likely(length == bufferSize) || unlikely(CopyFlags != 0)) {
pContext->UpdateMappedBuffer(bufferResource, offset, length, pSrcData, CopyFlags);
return;
}
}
// Otherwise we can't really do anything fancy, so just do a GPU copy
pContext->UpdateBuffer(bufferResource, offset, length, pSrcData);
} else {
D3D11CommonTexture* textureResource = GetCommonTexture(pDstResource);
pContext->UpdateTexture(textureResource,
DstSubresource, pDstBox, pSrcData, SrcRowPitch, SrcDepthPitch);
}
}
void UpdateBuffer(
D3D11Buffer* pDstBuffer,
UINT Offset,

View File

@ -19,6 +19,97 @@ namespace dxvk {
}
template<typename ContextType>
void STDMETHODCALLTYPE D3D11CommonContext<ContextType>::UpdateSubresource(
ID3D11Resource* pDstResource,
UINT DstSubresource,
const D3D11_BOX* pDstBox,
const void* pSrcData,
UINT SrcRowPitch,
UINT SrcDepthPitch) {
UpdateResource(pDstResource, DstSubresource, pDstBox,
pSrcData, SrcRowPitch, SrcDepthPitch, 0);
}
template<typename ContextType>
void STDMETHODCALLTYPE D3D11CommonContext<ContextType>::UpdateSubresource1(
ID3D11Resource* pDstResource,
UINT DstSubresource,
const D3D11_BOX* pDstBox,
const void* pSrcData,
UINT SrcRowPitch,
UINT SrcDepthPitch,
UINT CopyFlags) {
UpdateResource(pDstResource, DstSubresource, pDstBox,
pSrcData, SrcRowPitch, SrcDepthPitch, CopyFlags);
}
template<typename ContextType>
void D3D11CommonContext<ContextType>::UpdateResource(
ID3D11Resource* pDstResource,
UINT DstSubresource,
const D3D11_BOX* pDstBox,
const void* pSrcData,
UINT SrcRowPitch,
UINT SrcDepthPitch,
UINT CopyFlags) {
auto context = static_cast<ContextType*>(this);
D3D10DeviceLock lock = context->LockContext();
if (!pDstResource)
return;
// We need a different code path for buffers
D3D11_RESOURCE_DIMENSION resourceType;
pDstResource->GetType(&resourceType);
if (likely(resourceType == D3D11_RESOURCE_DIMENSION_BUFFER)) {
const auto bufferResource = static_cast<D3D11Buffer*>(pDstResource);
uint64_t bufferSize = bufferResource->Desc()->ByteWidth;
// Provide a fast path for mapped buffer updates since some
// games use UpdateSubresource to update constant buffers.
if (likely(bufferResource->GetMapMode() == D3D11_COMMON_BUFFER_MAP_MODE_DIRECT) && likely(!pDstBox)) {
context->UpdateMappedBuffer(bufferResource, 0, bufferSize, pSrcData, 0);
return;
}
// Validate buffer range to update
uint64_t offset = 0;
uint64_t length = bufferSize;
if (pDstBox) {
offset = pDstBox->left;
length = pDstBox->right - offset;
}
if (unlikely(offset + length > bufferSize))
return;
// Still try to be fast if a box is provided but we update the full buffer
if (likely(bufferResource->GetMapMode() == D3D11_COMMON_BUFFER_MAP_MODE_DIRECT)) {
CopyFlags &= D3D11_COPY_DISCARD | D3D11_COPY_NO_OVERWRITE;
if (likely(length == bufferSize) || unlikely(CopyFlags != 0)) {
context->UpdateMappedBuffer(bufferResource, offset, length, pSrcData, CopyFlags);
return;
}
}
// Otherwise we can't really do anything fancy, so just do a GPU copy
context->UpdateBuffer(bufferResource, offset, length, pSrcData);
} else {
D3D11CommonTexture* textureResource = GetCommonTexture(pDstResource);
context->UpdateTexture(textureResource,
DstSubresource, pDstBox, pSrcData, SrcRowPitch, SrcDepthPitch);
}
}
// Explicitly instantiate here
template class D3D11CommonContext<D3D11DeferredContext>;
template class D3D11CommonContext<D3D11ImmediateContext>;

View File

@ -64,7 +64,33 @@ namespace dxvk {
~D3D11CommonContext();
void STDMETHODCALLTYPE UpdateSubresource(
ID3D11Resource* pDstResource,
UINT DstSubresource,
const D3D11_BOX* pDstBox,
const void* pSrcData,
UINT SrcRowPitch,
UINT SrcDepthPitch);
void STDMETHODCALLTYPE UpdateSubresource1(
ID3D11Resource* pDstResource,
UINT DstSubresource,
const D3D11_BOX* pDstBox,
const void* pSrcData,
UINT SrcRowPitch,
UINT SrcDepthPitch,
UINT CopyFlags);
protected:
void UpdateResource(
ID3D11Resource* pDstResource,
UINT DstSubresource,
const D3D11_BOX* pDstBox,
const void* pSrcData,
UINT SrcRowPitch,
UINT SrcDepthPitch,
UINT CopyFlags);
};

View File

@ -236,31 +236,6 @@ namespace dxvk {
}
void STDMETHODCALLTYPE D3D11DeferredContext::UpdateSubresource(
ID3D11Resource* pDstResource,
UINT DstSubresource,
const D3D11_BOX* pDstBox,
const void* pSrcData,
UINT SrcRowPitch,
UINT SrcDepthPitch) {
UpdateResource<D3D11DeferredContext>(this, pDstResource,
DstSubresource, pDstBox, pSrcData, SrcRowPitch, SrcDepthPitch, 0);
}
void STDMETHODCALLTYPE D3D11DeferredContext::UpdateSubresource1(
ID3D11Resource* pDstResource,
UINT DstSubresource,
const D3D11_BOX* pDstBox,
const void* pSrcData,
UINT SrcRowPitch,
UINT SrcDepthPitch,
UINT CopyFlags) {
UpdateResource<D3D11DeferredContext>(this, pDstResource,
DstSubresource, pDstBox, pSrcData, SrcRowPitch, SrcDepthPitch, CopyFlags);
}
void STDMETHODCALLTYPE D3D11DeferredContext::SwapDeviceContextState(
ID3DDeviceContextState* pState,
ID3DDeviceContextState** ppPreviousState) {

View File

@ -80,23 +80,6 @@ namespace dxvk {
ID3D11Resource* pResource,
UINT Subresource);
void STDMETHODCALLTYPE UpdateSubresource(
ID3D11Resource* pDstResource,
UINT DstSubresource,
const D3D11_BOX* pDstBox,
const void* pSrcData,
UINT SrcRowPitch,
UINT SrcDepthPitch);
void STDMETHODCALLTYPE UpdateSubresource1(
ID3D11Resource* pDstResource,
UINT DstSubresource,
const D3D11_BOX* pDstBox,
const void* pSrcData,
UINT SrcRowPitch,
UINT SrcDepthPitch,
UINT CopyFlags);
void STDMETHODCALLTYPE SwapDeviceContextState(
ID3DDeviceContextState* pState,
ID3DDeviceContextState** ppPreviousState);

View File

@ -321,31 +321,6 @@ namespace dxvk {
}
}
void STDMETHODCALLTYPE D3D11ImmediateContext::UpdateSubresource(
ID3D11Resource* pDstResource,
UINT DstSubresource,
const D3D11_BOX* pDstBox,
const void* pSrcData,
UINT SrcRowPitch,
UINT SrcDepthPitch) {
UpdateResource<D3D11ImmediateContext>(this, pDstResource,
DstSubresource, pDstBox, pSrcData, SrcRowPitch, SrcDepthPitch, 0);
}
void STDMETHODCALLTYPE D3D11ImmediateContext::UpdateSubresource1(
ID3D11Resource* pDstResource,
UINT DstSubresource,
const D3D11_BOX* pDstBox,
const void* pSrcData,
UINT SrcRowPitch,
UINT SrcDepthPitch,
UINT CopyFlags) {
UpdateResource<D3D11ImmediateContext>(this, pDstResource,
DstSubresource, pDstBox, pSrcData, SrcRowPitch, SrcDepthPitch, CopyFlags);
}
void STDMETHODCALLTYPE D3D11ImmediateContext::OMSetRenderTargets(
UINT NumViews,
ID3D11RenderTargetView* const* ppRenderTargetViews,

View File

@ -78,23 +78,6 @@ namespace dxvk {
ID3D11Resource* pResource,
UINT Subresource);
void STDMETHODCALLTYPE UpdateSubresource(
ID3D11Resource* pDstResource,
UINT DstSubresource,
const D3D11_BOX* pDstBox,
const void* pSrcData,
UINT SrcRowPitch,
UINT SrcDepthPitch);
void STDMETHODCALLTYPE UpdateSubresource1(
ID3D11Resource* pDstResource,
UINT DstSubresource,
const D3D11_BOX* pDstBox,
const void* pSrcData,
UINT SrcRowPitch,
UINT SrcDepthPitch,
UINT CopyFlags);
void STDMETHODCALLTYPE OMSetRenderTargets(
UINT NumViews,
ID3D11RenderTargetView* const* ppRenderTargetViews,