1
0
mirror of https://github.com/doitsujin/dxvk.git synced 2025-02-05 11:52:10 +01:00
dxvk/src/d3d11/d3d11_context_common.cpp

118 lines
4.1 KiB
C++
Raw Normal View History

2022-08-03 16:33:54 +02:00
#include "d3d11_context_common.h"
#include "d3d11_context_def.h"
#include "d3d11_context_imm.h"
namespace dxvk {
template<typename ContextType>
D3D11CommonContext<ContextType>::D3D11CommonContext(
D3D11Device* pParent,
const Rc<DxvkDevice>& Device,
DxvkCsChunkFlags CsFlags)
: D3D11DeviceContext(pParent, Device, CsFlags) {
}
template<typename ContextType>
D3D11CommonContext<ContextType>::~D3D11CommonContext() {
}
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);
}
}
2022-08-03 16:33:54 +02:00
// Explicitly instantiate here
template class D3D11CommonContext<D3D11DeferredContext>;
template class D3D11CommonContext<D3D11ImmediateContext>;
}