diff --git a/src/d3d11/d3d11_context.cpp b/src/d3d11/d3d11_context.cpp index 4c8e2506..dc6ced40 100644 --- a/src/d3d11/d3d11_context.cpp +++ b/src/d3d11/d3d11_context.cpp @@ -15,6 +15,7 @@ namespace dxvk { DxvkCsChunkFlags CsFlags) : m_parent (pParent), m_annotation(this), + m_multithread(this, false), m_device (Device), m_csFlags (CsFlags), m_csChunk (AllocCsChunk()) { @@ -57,6 +58,11 @@ namespace dxvk { *ppvObject = ref(&m_annotation); return S_OK; } + + if (riid == __uuidof(ID3D10Multithread)) { + *ppvObject = ref(&m_multithread); + return S_OK; + } Logger::warn("D3D11DeviceContext::QueryInterface: Unknown interface query"); Logger::warn(str::format(riid)); @@ -65,6 +71,8 @@ namespace dxvk { void STDMETHODCALLTYPE D3D11DeviceContext::DiscardResource(ID3D11Resource* pResource) { + D3D10DeviceLock lock = LockContext(); + if (!pResource) return; @@ -80,6 +88,8 @@ namespace dxvk { void STDMETHODCALLTYPE D3D11DeviceContext::DiscardView(ID3D11View* pResourceView) { + D3D10DeviceLock lock = LockContext(); + // ID3D11View has no methods to query the exact type of // the view, so we'll have to check each possible class auto dsv = dynamic_cast(pResourceView); @@ -112,18 +122,22 @@ namespace dxvk { Logger::err("D3D11DeviceContext::DiscardView1: Not implemented"); } + void STDMETHODCALLTYPE D3D11DeviceContext::SwapDeviceContextState( ID3DDeviceContextState* pState, ID3DDeviceContextState** ppPreviousState) { Logger::err("D3D11DeviceContext::SwapDeviceContextState: Not implemented"); } + void STDMETHODCALLTYPE D3D11DeviceContext::GetDevice(ID3D11Device **ppDevice) { *ppDevice = ref(m_parent); } void STDMETHODCALLTYPE D3D11DeviceContext::ClearState() { + D3D10DeviceLock lock = LockContext(); + // Default shaders m_state.vs.shader = nullptr; m_state.hs.shader = nullptr; @@ -225,6 +239,8 @@ namespace dxvk { void STDMETHODCALLTYPE D3D11DeviceContext::Begin(ID3D11Asynchronous *pAsync) { + D3D10DeviceLock lock = LockContext(); + if (!pAsync) return; @@ -240,6 +256,8 @@ namespace dxvk { void STDMETHODCALLTYPE D3D11DeviceContext::End(ID3D11Asynchronous *pAsync) { + D3D10DeviceLock lock = LockContext(); + if (!pAsync) return; @@ -266,6 +284,8 @@ namespace dxvk { if (pPredicate && !std::exchange(s_errorShown, true)) Logger::err("D3D11DeviceContext::SetPredication: Stub"); + D3D10DeviceLock lock = LockContext(); + m_state.pr.predicateObject = static_cast(pPredicate); m_state.pr.predicateValue = PredicateValue; } @@ -274,6 +294,8 @@ namespace dxvk { void STDMETHODCALLTYPE D3D11DeviceContext::GetPredication( ID3D11Predicate** ppPredicate, BOOL* pPredicateValue) { + D3D10DeviceLock lock = LockContext(); + if (ppPredicate != nullptr) *ppPredicate = m_state.pr.predicateObject.ref(); @@ -307,6 +329,8 @@ namespace dxvk { UINT SrcSubresource, const D3D11_BOX* pSrcBox, UINT CopyFlags) { + D3D10DeviceLock lock = LockContext(); + D3D11_RESOURCE_DIMENSION dstResourceDim = D3D11_RESOURCE_DIMENSION_UNKNOWN; D3D11_RESOURCE_DIMENSION srcResourceDim = D3D11_RESOURCE_DIMENSION_UNKNOWN; @@ -526,6 +550,8 @@ namespace dxvk { void STDMETHODCALLTYPE D3D11DeviceContext::CopyResource( ID3D11Resource* pDstResource, ID3D11Resource* pSrcResource) { + D3D10DeviceLock lock = LockContext(); + if (!pDstResource || !pSrcResource || (pDstResource == pSrcResource)) return; @@ -624,6 +650,8 @@ namespace dxvk { ID3D11Buffer* pDstBuffer, UINT DstAlignedByteOffset, ID3D11UnorderedAccessView* pSrcView) { + D3D10DeviceLock lock = LockContext(); + auto buf = static_cast(pDstBuffer); auto uav = static_cast(pSrcView); @@ -647,6 +675,8 @@ namespace dxvk { void STDMETHODCALLTYPE D3D11DeviceContext::ClearRenderTargetView( ID3D11RenderTargetView* pRenderTargetView, const FLOAT ColorRGBA[4]) { + D3D10DeviceLock lock = LockContext(); + auto rtv = static_cast(pRenderTargetView); if (!rtv) @@ -675,6 +705,8 @@ namespace dxvk { void STDMETHODCALLTYPE D3D11DeviceContext::ClearUnorderedAccessViewUint( ID3D11UnorderedAccessView* pUnorderedAccessView, const UINT Values[4]) { + D3D10DeviceLock lock = LockContext(); + auto uav = static_cast(pUnorderedAccessView); if (!uav) @@ -774,6 +806,8 @@ namespace dxvk { void STDMETHODCALLTYPE D3D11DeviceContext::ClearUnorderedAccessViewFloat( ID3D11UnorderedAccessView* pUnorderedAccessView, const FLOAT Values[4]) { + D3D10DeviceLock lock = LockContext(); + auto uav = static_cast(pUnorderedAccessView); if (!uav) @@ -814,6 +848,8 @@ namespace dxvk { UINT ClearFlags, FLOAT Depth, UINT8 Stencil) { + D3D10DeviceLock lock = LockContext(); + auto dsv = static_cast(pDepthStencilView); if (!dsv) @@ -855,6 +891,8 @@ namespace dxvk { const FLOAT Color[4], const D3D11_RECT* pRect, UINT NumRects) { + D3D10DeviceLock lock = LockContext(); + // ID3D11View has no methods to query the exact type of // the view, so we'll have to check each possible class auto dsv = dynamic_cast(pView); @@ -995,6 +1033,8 @@ namespace dxvk { void STDMETHODCALLTYPE D3D11DeviceContext::GenerateMips(ID3D11ShaderResourceView* pShaderResourceView) { + D3D10DeviceLock lock = LockContext(); + auto view = static_cast(pShaderResourceView); if (!view || view->GetResourceType() == D3D11_RESOURCE_DIMENSION_BUFFER) @@ -1028,6 +1068,8 @@ namespace dxvk { UINT SrcRowPitch, UINT SrcDepthPitch, UINT CopyFlags) { + D3D10DeviceLock lock = LockContext(); + if (!pDstResource) return; @@ -1167,6 +1209,8 @@ namespace dxvk { ID3D11Resource* pSrcResource, UINT SrcSubresource, DXGI_FORMAT Format) { + D3D10DeviceLock lock = LockContext(); + bool isSameSubresource = pDstResource == pSrcResource && DstSubresource == SrcSubresource; @@ -1265,6 +1309,8 @@ namespace dxvk { void STDMETHODCALLTYPE D3D11DeviceContext::DrawAuto() { + D3D10DeviceLock lock = LockContext(); + D3D11Buffer* buffer = m_state.ia.vertexBuffers[0].buffer.ptr(); if (buffer == nullptr) @@ -1287,6 +1333,8 @@ namespace dxvk { void STDMETHODCALLTYPE D3D11DeviceContext::Draw( UINT VertexCount, UINT StartVertexLocation) { + D3D10DeviceLock lock = LockContext(); + EmitCs([=] (DxvkContext* ctx) { ctx->draw( VertexCount, 1, @@ -1299,6 +1347,8 @@ namespace dxvk { UINT IndexCount, UINT StartIndexLocation, INT BaseVertexLocation) { + D3D10DeviceLock lock = LockContext(); + EmitCs([=] (DxvkContext* ctx) { ctx->drawIndexed( IndexCount, 1, @@ -1313,6 +1363,8 @@ namespace dxvk { UINT InstanceCount, UINT StartVertexLocation, UINT StartInstanceLocation) { + D3D10DeviceLock lock = LockContext(); + EmitCs([=] (DxvkContext* ctx) { ctx->draw( VertexCountPerInstance, @@ -1329,6 +1381,8 @@ namespace dxvk { UINT StartIndexLocation, INT BaseVertexLocation, UINT StartInstanceLocation) { + D3D10DeviceLock lock = LockContext(); + EmitCs([=] (DxvkContext* ctx) { ctx->drawIndexed( IndexCountPerInstance, @@ -1343,6 +1397,8 @@ namespace dxvk { void STDMETHODCALLTYPE D3D11DeviceContext::DrawIndexedInstancedIndirect( ID3D11Buffer* pBufferForArgs, UINT AlignedByteOffsetForArgs) { + D3D10DeviceLock lock = LockContext(); + SetDrawBuffer(pBufferForArgs); EmitCs([cOffset = AlignedByteOffsetForArgs] @@ -1355,6 +1411,8 @@ namespace dxvk { void STDMETHODCALLTYPE D3D11DeviceContext::DrawInstancedIndirect( ID3D11Buffer* pBufferForArgs, UINT AlignedByteOffsetForArgs) { + D3D10DeviceLock lock = LockContext(); + SetDrawBuffer(pBufferForArgs); EmitCs([cOffset = AlignedByteOffsetForArgs] @@ -1368,6 +1426,8 @@ namespace dxvk { UINT ThreadGroupCountX, UINT ThreadGroupCountY, UINT ThreadGroupCountZ) { + D3D10DeviceLock lock = LockContext(); + EmitCs([=] (DxvkContext* ctx) { ctx->dispatch( ThreadGroupCountX, @@ -1380,6 +1440,8 @@ namespace dxvk { void STDMETHODCALLTYPE D3D11DeviceContext::DispatchIndirect( ID3D11Buffer* pBufferForArgs, UINT AlignedByteOffsetForArgs) { + D3D10DeviceLock lock = LockContext(); + SetDrawBuffer(pBufferForArgs); EmitCs([cOffset = AlignedByteOffsetForArgs] @@ -1390,6 +1452,8 @@ namespace dxvk { void STDMETHODCALLTYPE D3D11DeviceContext::IASetInputLayout(ID3D11InputLayout* pInputLayout) { + D3D10DeviceLock lock = LockContext(); + auto inputLayout = static_cast(pInputLayout); if (m_state.ia.inputLayout != inputLayout) { @@ -1410,6 +1474,8 @@ namespace dxvk { void STDMETHODCALLTYPE D3D11DeviceContext::IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY Topology) { + D3D10DeviceLock lock = LockContext(); + if (m_state.ia.primitiveTopology != Topology) { m_state.ia.primitiveTopology = Topology; ApplyPrimitiveTopology(); @@ -1423,6 +1489,8 @@ namespace dxvk { ID3D11Buffer* const* ppVertexBuffers, const UINT* pStrides, const UINT* pOffsets) { + D3D10DeviceLock lock = LockContext(); + for (uint32_t i = 0; i < NumBuffers; i++) { auto newBuffer = static_cast(ppVertexBuffers[i]); @@ -1439,6 +1507,8 @@ namespace dxvk { ID3D11Buffer* pIndexBuffer, DXGI_FORMAT Format, UINT Offset) { + D3D10DeviceLock lock = LockContext(); + auto newBuffer = static_cast(pIndexBuffer); m_state.ia.indexBuffer.buffer = newBuffer; @@ -1450,11 +1520,15 @@ namespace dxvk { void STDMETHODCALLTYPE D3D11DeviceContext::IAGetInputLayout(ID3D11InputLayout** ppInputLayout) { + D3D10DeviceLock lock = LockContext(); + *ppInputLayout = m_state.ia.inputLayout.ref(); } void STDMETHODCALLTYPE D3D11DeviceContext::IAGetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY* pTopology) { + D3D10DeviceLock lock = LockContext(); + *pTopology = m_state.ia.primitiveTopology; } @@ -1465,6 +1539,8 @@ namespace dxvk { ID3D11Buffer** ppVertexBuffers, UINT* pStrides, UINT* pOffsets) { + D3D10DeviceLock lock = LockContext(); + for (uint32_t i = 0; i < NumBuffers; i++) { if (ppVertexBuffers != nullptr) ppVertexBuffers[i] = m_state.ia.vertexBuffers[StartSlot + i].buffer.ref(); @@ -1482,6 +1558,8 @@ namespace dxvk { ID3D11Buffer** ppIndexBuffer, DXGI_FORMAT* pFormat, UINT* pOffset) { + D3D10DeviceLock lock = LockContext(); + if (ppIndexBuffer != nullptr) *ppIndexBuffer = m_state.ia.indexBuffer.buffer.ref(); @@ -1497,6 +1575,8 @@ namespace dxvk { ID3D11VertexShader* pVertexShader, ID3D11ClassInstance* const* ppClassInstances, UINT NumClassInstances) { + D3D10DeviceLock lock = LockContext(); + auto shader = static_cast(pVertexShader); if (NumClassInstances != 0) @@ -1516,6 +1596,8 @@ namespace dxvk { UINT StartSlot, UINT NumBuffers, ID3D11Buffer* const* ppConstantBuffers) { + D3D10DeviceLock lock = LockContext(); + SetConstantBuffers( DxbcProgramType::VertexShader, m_state.vs.constantBuffers, @@ -1531,6 +1613,8 @@ namespace dxvk { ID3D11Buffer* const* ppConstantBuffers, const UINT* pFirstConstant, const UINT* pNumConstants) { + D3D10DeviceLock lock = LockContext(); + SetConstantBuffers( DxbcProgramType::VertexShader, m_state.vs.constantBuffers, @@ -1545,6 +1629,8 @@ namespace dxvk { UINT StartSlot, UINT NumViews, ID3D11ShaderResourceView* const* ppShaderResourceViews) { + D3D10DeviceLock lock = LockContext(); + SetShaderResources( DxbcProgramType::VertexShader, m_state.vs.shaderResources, @@ -1557,6 +1643,8 @@ namespace dxvk { UINT StartSlot, UINT NumSamplers, ID3D11SamplerState* const* ppSamplers) { + D3D10DeviceLock lock = LockContext(); + SetSamplers( DxbcProgramType::VertexShader, m_state.vs.samplers, @@ -1569,6 +1657,8 @@ namespace dxvk { ID3D11VertexShader** ppVertexShader, ID3D11ClassInstance** ppClassInstances, UINT* pNumClassInstances) { + D3D10DeviceLock lock = LockContext(); + if (ppVertexShader != nullptr) *ppVertexShader = m_state.vs.shader.ref(); @@ -1581,6 +1671,8 @@ namespace dxvk { UINT StartSlot, UINT NumBuffers, ID3D11Buffer** ppConstantBuffers) { + D3D10DeviceLock lock = LockContext(); + GetConstantBuffers( m_state.vs.constantBuffers, StartSlot, NumBuffers, @@ -1595,6 +1687,8 @@ namespace dxvk { ID3D11Buffer** ppConstantBuffers, UINT* pFirstConstant, UINT* pNumConstants) { + D3D10DeviceLock lock = LockContext(); + GetConstantBuffers( m_state.vs.constantBuffers, StartSlot, NumBuffers, @@ -1608,6 +1702,8 @@ namespace dxvk { UINT StartSlot, UINT NumViews, ID3D11ShaderResourceView** ppShaderResourceViews) { + D3D10DeviceLock lock = LockContext(); + for (uint32_t i = 0; i < NumViews; i++) ppShaderResourceViews[i] = m_state.vs.shaderResources.at(StartSlot + i).ref(); } @@ -1617,6 +1713,8 @@ namespace dxvk { UINT StartSlot, UINT NumSamplers, ID3D11SamplerState** ppSamplers) { + D3D10DeviceLock lock = LockContext(); + for (uint32_t i = 0; i < NumSamplers; i++) ppSamplers[i] = m_state.vs.samplers.at(StartSlot + i).ref(); } @@ -1626,6 +1724,8 @@ namespace dxvk { ID3D11HullShader* pHullShader, ID3D11ClassInstance* const* ppClassInstances, UINT NumClassInstances) { + D3D10DeviceLock lock = LockContext(); + auto shader = static_cast(pHullShader); if (NumClassInstances != 0) @@ -1645,6 +1745,8 @@ namespace dxvk { UINT StartSlot, UINT NumViews, ID3D11ShaderResourceView* const* ppShaderResourceViews) { + D3D10DeviceLock lock = LockContext(); + SetShaderResources( DxbcProgramType::HullShader, m_state.hs.shaderResources, @@ -1657,6 +1759,8 @@ namespace dxvk { UINT StartSlot, UINT NumBuffers, ID3D11Buffer* const* ppConstantBuffers) { + D3D10DeviceLock lock = LockContext(); + SetConstantBuffers( DxbcProgramType::HullShader, m_state.hs.constantBuffers, @@ -1672,6 +1776,8 @@ namespace dxvk { ID3D11Buffer* const* ppConstantBuffers, const UINT* pFirstConstant, const UINT* pNumConstants) { + D3D10DeviceLock lock = LockContext(); + SetConstantBuffers( DxbcProgramType::HullShader, m_state.hs.constantBuffers, @@ -1686,6 +1792,8 @@ namespace dxvk { UINT StartSlot, UINT NumSamplers, ID3D11SamplerState* const* ppSamplers) { + D3D10DeviceLock lock = LockContext(); + SetSamplers( DxbcProgramType::HullShader, m_state.hs.samplers, @@ -1698,6 +1806,8 @@ namespace dxvk { ID3D11HullShader** ppHullShader, ID3D11ClassInstance** ppClassInstances, UINT* pNumClassInstances) { + D3D10DeviceLock lock = LockContext(); + if (ppHullShader != nullptr) *ppHullShader = m_state.hs.shader.ref(); @@ -1710,6 +1820,8 @@ namespace dxvk { UINT StartSlot, UINT NumBuffers, ID3D11Buffer** ppConstantBuffers) { + D3D10DeviceLock lock = LockContext(); + GetConstantBuffers( m_state.hs.constantBuffers, StartSlot, NumBuffers, @@ -1724,6 +1836,8 @@ namespace dxvk { ID3D11Buffer** ppConstantBuffers, UINT* pFirstConstant, UINT* pNumConstants) { + D3D10DeviceLock lock = LockContext(); + GetConstantBuffers( m_state.hs.constantBuffers, StartSlot, NumBuffers, @@ -1737,6 +1851,8 @@ namespace dxvk { UINT StartSlot, UINT NumViews, ID3D11ShaderResourceView** ppShaderResourceViews) { + D3D10DeviceLock lock = LockContext(); + for (uint32_t i = 0; i < NumViews; i++) ppShaderResourceViews[i] = m_state.hs.shaderResources.at(StartSlot + i).ref(); } @@ -1746,6 +1862,8 @@ namespace dxvk { UINT StartSlot, UINT NumSamplers, ID3D11SamplerState** ppSamplers) { + D3D10DeviceLock lock = LockContext(); + for (uint32_t i = 0; i < NumSamplers; i++) ppSamplers[i] = m_state.hs.samplers.at(StartSlot + i).ref(); } @@ -1755,6 +1873,8 @@ namespace dxvk { ID3D11DomainShader* pDomainShader, ID3D11ClassInstance* const* ppClassInstances, UINT NumClassInstances) { + D3D10DeviceLock lock = LockContext(); + auto shader = static_cast(pDomainShader); if (NumClassInstances != 0) @@ -1774,6 +1894,8 @@ namespace dxvk { UINT StartSlot, UINT NumViews, ID3D11ShaderResourceView* const* ppShaderResourceViews) { + D3D10DeviceLock lock = LockContext(); + SetShaderResources( DxbcProgramType::DomainShader, m_state.ds.shaderResources, @@ -1786,6 +1908,8 @@ namespace dxvk { UINT StartSlot, UINT NumBuffers, ID3D11Buffer* const* ppConstantBuffers) { + D3D10DeviceLock lock = LockContext(); + SetConstantBuffers( DxbcProgramType::DomainShader, m_state.ds.constantBuffers, @@ -1801,6 +1925,8 @@ namespace dxvk { ID3D11Buffer* const* ppConstantBuffers, const UINT* pFirstConstant, const UINT* pNumConstants) { + D3D10DeviceLock lock = LockContext(); + SetConstantBuffers( DxbcProgramType::DomainShader, m_state.ds.constantBuffers, @@ -1815,6 +1941,8 @@ namespace dxvk { UINT StartSlot, UINT NumSamplers, ID3D11SamplerState* const* ppSamplers) { + D3D10DeviceLock lock = LockContext(); + SetSamplers( DxbcProgramType::DomainShader, m_state.ds.samplers, @@ -1827,6 +1955,8 @@ namespace dxvk { ID3D11DomainShader** ppDomainShader, ID3D11ClassInstance** ppClassInstances, UINT* pNumClassInstances) { + D3D10DeviceLock lock = LockContext(); + if (ppDomainShader != nullptr) *ppDomainShader = m_state.ds.shader.ref(); @@ -1839,6 +1969,8 @@ namespace dxvk { UINT StartSlot, UINT NumBuffers, ID3D11Buffer** ppConstantBuffers) { + D3D10DeviceLock lock = LockContext(); + GetConstantBuffers( m_state.ds.constantBuffers, StartSlot, NumBuffers, @@ -1853,6 +1985,8 @@ namespace dxvk { ID3D11Buffer** ppConstantBuffers, UINT* pFirstConstant, UINT* pNumConstants) { + D3D10DeviceLock lock = LockContext(); + GetConstantBuffers( m_state.ds.constantBuffers, StartSlot, NumBuffers, @@ -1866,6 +2000,8 @@ namespace dxvk { UINT StartSlot, UINT NumViews, ID3D11ShaderResourceView** ppShaderResourceViews) { + D3D10DeviceLock lock = LockContext(); + for (uint32_t i = 0; i < NumViews; i++) ppShaderResourceViews[i] = m_state.ds.shaderResources.at(StartSlot + i).ref(); } @@ -1875,6 +2011,8 @@ namespace dxvk { UINT StartSlot, UINT NumSamplers, ID3D11SamplerState** ppSamplers) { + D3D10DeviceLock lock = LockContext(); + for (uint32_t i = 0; i < NumSamplers; i++) ppSamplers[i] = m_state.ds.samplers.at(StartSlot + i).ref(); } @@ -1884,6 +2022,8 @@ namespace dxvk { ID3D11GeometryShader* pShader, ID3D11ClassInstance* const* ppClassInstances, UINT NumClassInstances) { + D3D10DeviceLock lock = LockContext(); + auto shader = static_cast(pShader); if (NumClassInstances != 0) @@ -1903,6 +2043,8 @@ namespace dxvk { UINT StartSlot, UINT NumBuffers, ID3D11Buffer* const* ppConstantBuffers) { + D3D10DeviceLock lock = LockContext(); + SetConstantBuffers( DxbcProgramType::GeometryShader, m_state.gs.constantBuffers, @@ -1918,6 +2060,8 @@ namespace dxvk { ID3D11Buffer* const* ppConstantBuffers, const UINT* pFirstConstant, const UINT* pNumConstants) { + D3D10DeviceLock lock = LockContext(); + SetConstantBuffers( DxbcProgramType::GeometryShader, m_state.gs.constantBuffers, @@ -1932,6 +2076,8 @@ namespace dxvk { UINT StartSlot, UINT NumViews, ID3D11ShaderResourceView* const* ppShaderResourceViews) { + D3D10DeviceLock lock = LockContext(); + SetShaderResources( DxbcProgramType::GeometryShader, m_state.gs.shaderResources, @@ -1944,6 +2090,8 @@ namespace dxvk { UINT StartSlot, UINT NumSamplers, ID3D11SamplerState* const* ppSamplers) { + D3D10DeviceLock lock = LockContext(); + SetSamplers( DxbcProgramType::GeometryShader, m_state.gs.samplers, @@ -1956,6 +2104,8 @@ namespace dxvk { ID3D11GeometryShader** ppGeometryShader, ID3D11ClassInstance** ppClassInstances, UINT* pNumClassInstances) { + D3D10DeviceLock lock = LockContext(); + if (ppGeometryShader != nullptr) *ppGeometryShader = m_state.gs.shader.ref(); @@ -1968,6 +2118,8 @@ namespace dxvk { UINT StartSlot, UINT NumBuffers, ID3D11Buffer** ppConstantBuffers) { + D3D10DeviceLock lock = LockContext(); + GetConstantBuffers( m_state.gs.constantBuffers, StartSlot, NumBuffers, @@ -1982,6 +2134,8 @@ namespace dxvk { ID3D11Buffer** ppConstantBuffers, UINT* pFirstConstant, UINT* pNumConstants) { + D3D10DeviceLock lock = LockContext(); + GetConstantBuffers( m_state.gs.constantBuffers, StartSlot, NumBuffers, @@ -1995,6 +2149,8 @@ namespace dxvk { UINT StartSlot, UINT NumViews, ID3D11ShaderResourceView** ppShaderResourceViews) { + D3D10DeviceLock lock = LockContext(); + for (uint32_t i = 0; i < NumViews; i++) ppShaderResourceViews[i] = m_state.gs.shaderResources.at(StartSlot + i).ref(); } @@ -2004,6 +2160,8 @@ namespace dxvk { UINT StartSlot, UINT NumSamplers, ID3D11SamplerState** ppSamplers) { + D3D10DeviceLock lock = LockContext(); + for (uint32_t i = 0; i < NumSamplers; i++) ppSamplers[i] = m_state.gs.samplers.at(StartSlot + i).ref(); } @@ -2013,6 +2171,8 @@ namespace dxvk { ID3D11PixelShader* pPixelShader, ID3D11ClassInstance* const* ppClassInstances, UINT NumClassInstances) { + D3D10DeviceLock lock = LockContext(); + auto shader = static_cast(pPixelShader); if (NumClassInstances != 0) @@ -2032,6 +2192,8 @@ namespace dxvk { UINT StartSlot, UINT NumBuffers, ID3D11Buffer* const* ppConstantBuffers) { + D3D10DeviceLock lock = LockContext(); + SetConstantBuffers( DxbcProgramType::PixelShader, m_state.ps.constantBuffers, @@ -2047,6 +2209,8 @@ namespace dxvk { ID3D11Buffer* const* ppConstantBuffers, const UINT* pFirstConstant, const UINT* pNumConstants) { + D3D10DeviceLock lock = LockContext(); + SetConstantBuffers( DxbcProgramType::PixelShader, m_state.ps.constantBuffers, @@ -2061,6 +2225,8 @@ namespace dxvk { UINT StartSlot, UINT NumViews, ID3D11ShaderResourceView* const* ppShaderResourceViews) { + D3D10DeviceLock lock = LockContext(); + SetShaderResources( DxbcProgramType::PixelShader, m_state.ps.shaderResources, @@ -2073,6 +2239,8 @@ namespace dxvk { UINT StartSlot, UINT NumSamplers, ID3D11SamplerState* const* ppSamplers) { + D3D10DeviceLock lock = LockContext(); + SetSamplers( DxbcProgramType::PixelShader, m_state.ps.samplers, @@ -2085,6 +2253,8 @@ namespace dxvk { ID3D11PixelShader** ppPixelShader, ID3D11ClassInstance** ppClassInstances, UINT* pNumClassInstances) { + D3D10DeviceLock lock = LockContext(); + if (ppPixelShader != nullptr) *ppPixelShader = m_state.ps.shader.ref(); @@ -2097,6 +2267,8 @@ namespace dxvk { UINT StartSlot, UINT NumBuffers, ID3D11Buffer** ppConstantBuffers) { + D3D10DeviceLock lock = LockContext(); + GetConstantBuffers( m_state.ps.constantBuffers, StartSlot, NumBuffers, @@ -2111,6 +2283,8 @@ namespace dxvk { ID3D11Buffer** ppConstantBuffers, UINT* pFirstConstant, UINT* pNumConstants) { + D3D10DeviceLock lock = LockContext(); + GetConstantBuffers( m_state.ps.constantBuffers, StartSlot, NumBuffers, @@ -2124,6 +2298,8 @@ namespace dxvk { UINT StartSlot, UINT NumViews, ID3D11ShaderResourceView** ppShaderResourceViews) { + D3D10DeviceLock lock = LockContext(); + for (uint32_t i = 0; i < NumViews; i++) ppShaderResourceViews[i] = m_state.ps.shaderResources.at(StartSlot + i).ref(); } @@ -2133,6 +2309,8 @@ namespace dxvk { UINT StartSlot, UINT NumSamplers, ID3D11SamplerState** ppSamplers) { + D3D10DeviceLock lock = LockContext(); + for (uint32_t i = 0; i < NumSamplers; i++) ppSamplers[i] = m_state.ps.samplers.at(StartSlot + i).ref(); } @@ -2142,6 +2320,8 @@ namespace dxvk { ID3D11ComputeShader* pComputeShader, ID3D11ClassInstance* const* ppClassInstances, UINT NumClassInstances) { + D3D10DeviceLock lock = LockContext(); + auto shader = static_cast(pComputeShader); if (NumClassInstances != 0) @@ -2161,6 +2341,8 @@ namespace dxvk { UINT StartSlot, UINT NumBuffers, ID3D11Buffer* const* ppConstantBuffers) { + D3D10DeviceLock lock = LockContext(); + SetConstantBuffers( DxbcProgramType::ComputeShader, m_state.cs.constantBuffers, @@ -2176,6 +2358,8 @@ namespace dxvk { ID3D11Buffer* const* ppConstantBuffers, const UINT* pFirstConstant, const UINT* pNumConstants) { + D3D10DeviceLock lock = LockContext(); + SetConstantBuffers( DxbcProgramType::ComputeShader, m_state.cs.constantBuffers, @@ -2190,6 +2374,8 @@ namespace dxvk { UINT StartSlot, UINT NumViews, ID3D11ShaderResourceView* const* ppShaderResourceViews) { + D3D10DeviceLock lock = LockContext(); + SetShaderResources( DxbcProgramType::ComputeShader, m_state.cs.shaderResources, @@ -2202,6 +2388,8 @@ namespace dxvk { UINT StartSlot, UINT NumSamplers, ID3D11SamplerState* const* ppSamplers) { + D3D10DeviceLock lock = LockContext(); + SetSamplers( DxbcProgramType::ComputeShader, m_state.cs.samplers, @@ -2215,6 +2403,8 @@ namespace dxvk { UINT NumUAVs, ID3D11UnorderedAccessView* const* ppUnorderedAccessViews, const UINT* pUAVInitialCounts) { + D3D10DeviceLock lock = LockContext(); + SetUnorderedAccessViews( DxbcProgramType::ComputeShader, m_state.cs.unorderedAccessViews, @@ -2228,6 +2418,8 @@ namespace dxvk { ID3D11ComputeShader** ppComputeShader, ID3D11ClassInstance** ppClassInstances, UINT* pNumClassInstances) { + D3D10DeviceLock lock = LockContext(); + if (ppComputeShader != nullptr) *ppComputeShader = m_state.cs.shader.ref(); @@ -2240,6 +2432,8 @@ namespace dxvk { UINT StartSlot, UINT NumBuffers, ID3D11Buffer** ppConstantBuffers) { + D3D10DeviceLock lock = LockContext(); + GetConstantBuffers( m_state.cs.constantBuffers, StartSlot, NumBuffers, @@ -2254,6 +2448,8 @@ namespace dxvk { ID3D11Buffer** ppConstantBuffers, UINT* pFirstConstant, UINT* pNumConstants) { + D3D10DeviceLock lock = LockContext(); + GetConstantBuffers( m_state.cs.constantBuffers, StartSlot, NumBuffers, @@ -2267,6 +2463,8 @@ namespace dxvk { UINT StartSlot, UINT NumViews, ID3D11ShaderResourceView** ppShaderResourceViews) { + D3D10DeviceLock lock = LockContext(); + for (uint32_t i = 0; i < NumViews; i++) ppShaderResourceViews[i] = m_state.cs.shaderResources.at(StartSlot + i).ref(); } @@ -2276,6 +2474,8 @@ namespace dxvk { UINT StartSlot, UINT NumSamplers, ID3D11SamplerState** ppSamplers) { + D3D10DeviceLock lock = LockContext(); + for (uint32_t i = 0; i < NumSamplers; i++) ppSamplers[i] = m_state.cs.samplers.at(StartSlot + i).ref(); } @@ -2285,6 +2485,8 @@ namespace dxvk { UINT StartSlot, UINT NumUAVs, ID3D11UnorderedAccessView** ppUnorderedAccessViews) { + D3D10DeviceLock lock = LockContext(); + for (uint32_t i = 0; i < NumUAVs; i++) ppUnorderedAccessViews[i] = m_state.cs.unorderedAccessViews.at(StartSlot + i).ref(); } @@ -2294,6 +2496,8 @@ namespace dxvk { UINT NumViews, ID3D11RenderTargetView* const* ppRenderTargetViews, ID3D11DepthStencilView* pDepthStencilView) { + D3D10DeviceLock lock = LockContext(); + SetRenderTargets(NumViews, ppRenderTargetViews, pDepthStencilView); BindFramebuffer(false); } @@ -2307,6 +2511,8 @@ namespace dxvk { UINT NumUAVs, ID3D11UnorderedAccessView* const* ppUnorderedAccessViews, const UINT* pUAVInitialCounts) { + D3D10DeviceLock lock = LockContext(); + bool isUavRendering = false; if (NumRTVs != D3D11_KEEP_RENDER_TARGETS_AND_DEPTH_STENCIL) @@ -2336,6 +2542,8 @@ namespace dxvk { ID3D11BlendState* pBlendState, const FLOAT BlendFactor[4], UINT SampleMask) { + D3D10DeviceLock lock = LockContext(); + auto blendState = static_cast(pBlendState); if (m_state.om.cbState != blendState @@ -2358,6 +2566,8 @@ namespace dxvk { void STDMETHODCALLTYPE D3D11DeviceContext::OMSetDepthStencilState( ID3D11DepthStencilState* pDepthStencilState, UINT StencilRef) { + D3D10DeviceLock lock = LockContext(); + auto depthStencilState = static_cast(pDepthStencilState); if (m_state.om.dsState != depthStencilState) { @@ -2376,6 +2586,8 @@ namespace dxvk { UINT NumViews, ID3D11RenderTargetView** ppRenderTargetViews, ID3D11DepthStencilView** ppDepthStencilView) { + D3D10DeviceLock lock = LockContext(); + if (ppRenderTargetViews != nullptr) { for (UINT i = 0; i < NumViews; i++) ppRenderTargetViews[i] = m_state.om.renderTargetViews[i].ref(); @@ -2395,6 +2607,8 @@ namespace dxvk { ID3D11UnorderedAccessView** ppUnorderedAccessViews) { OMGetRenderTargets(NumRTVs, ppRenderTargetViews, ppDepthStencilView); + D3D10DeviceLock lock = LockContext(); + if (ppUnorderedAccessViews != nullptr) { for (UINT i = 0; i < NumUAVs; i++) ppUnorderedAccessViews[i] = m_state.ps.unorderedAccessViews[UAVStartSlot + i].ref(); @@ -2406,6 +2620,8 @@ namespace dxvk { ID3D11BlendState** ppBlendState, FLOAT BlendFactor[4], UINT* pSampleMask) { + D3D10DeviceLock lock = LockContext(); + if (ppBlendState != nullptr) *ppBlendState = m_state.om.cbState.ref(); @@ -2420,6 +2636,8 @@ namespace dxvk { void STDMETHODCALLTYPE D3D11DeviceContext::OMGetDepthStencilState( ID3D11DepthStencilState** ppDepthStencilState, UINT* pStencilRef) { + D3D10DeviceLock lock = LockContext(); + if (ppDepthStencilState != nullptr) *ppDepthStencilState = m_state.om.dsState.ref(); @@ -2429,6 +2647,8 @@ namespace dxvk { void STDMETHODCALLTYPE D3D11DeviceContext::RSSetState(ID3D11RasterizerState* pRasterizerState) { + D3D10DeviceLock lock = LockContext(); + auto rasterizerState = static_cast(pRasterizerState); if (m_state.rs.state != rasterizerState) { @@ -2446,6 +2666,8 @@ namespace dxvk { void STDMETHODCALLTYPE D3D11DeviceContext::RSSetViewports( UINT NumViewports, const D3D11_VIEWPORT* pViewports) { + D3D10DeviceLock lock = LockContext(); + m_state.rs.numViewports = NumViewports; for (uint32_t i = 0; i < NumViewports; i++) @@ -2458,6 +2680,8 @@ namespace dxvk { void STDMETHODCALLTYPE D3D11DeviceContext::RSSetScissorRects( UINT NumRects, const D3D11_RECT* pRects) { + D3D10DeviceLock lock = LockContext(); + m_state.rs.numScissors = NumRects; for (uint32_t i = 0; i < NumRects; i++) { @@ -2477,6 +2701,8 @@ namespace dxvk { void STDMETHODCALLTYPE D3D11DeviceContext::RSGetState(ID3D11RasterizerState** ppRasterizerState) { + D3D10DeviceLock lock = LockContext(); + if (ppRasterizerState != nullptr) *ppRasterizerState = m_state.rs.state.ref(); } @@ -2485,6 +2711,8 @@ namespace dxvk { void STDMETHODCALLTYPE D3D11DeviceContext::RSGetViewports( UINT* pNumViewports, D3D11_VIEWPORT* pViewports) { + D3D10DeviceLock lock = LockContext(); + if (pViewports != nullptr) { for (uint32_t i = 0; i < *pNumViewports; i++) { if (i < m_state.rs.numViewports) { @@ -2507,6 +2735,8 @@ namespace dxvk { void STDMETHODCALLTYPE D3D11DeviceContext::RSGetScissorRects( UINT* pNumRects, D3D11_RECT* pRects) { + D3D10DeviceLock lock = LockContext(); + if (pRects != nullptr) { for (uint32_t i = 0; i < *pNumRects; i++) { if (i < m_state.rs.numScissors) { @@ -2528,6 +2758,8 @@ namespace dxvk { UINT NumBuffers, ID3D11Buffer* const* ppSOTargets, const UINT* pOffsets) { + D3D10DeviceLock lock = LockContext(); + for (uint32_t i = 0; i < NumBuffers; i++) { D3D11Buffer* buffer = static_cast(ppSOTargets[i]); UINT offset = pOffsets != nullptr ? pOffsets[i] : 0; @@ -2552,6 +2784,8 @@ namespace dxvk { void STDMETHODCALLTYPE D3D11DeviceContext::SOGetTargets( UINT NumBuffers, ID3D11Buffer** ppSOTargets) { + D3D10DeviceLock lock = LockContext(); + for (uint32_t i = 0; i < NumBuffers; i++) ppSOTargets[i] = m_state.so.targets[i].buffer.ref(); } @@ -2561,6 +2795,8 @@ namespace dxvk { UINT NumBuffers, ID3D11Buffer** ppSOTargets, UINT* pOffsets) { + D3D10DeviceLock lock = LockContext(); + for (uint32_t i = 0; i < NumBuffers; i++) { if (ppSOTargets != nullptr) ppSOTargets[i] = m_state.so.targets[i].buffer.ref(); @@ -2576,6 +2812,8 @@ namespace dxvk { const VkImageSubresourceRange* pSubresources, VkImageLayout OldLayout, VkImageLayout NewLayout) { + D3D10DeviceLock lock = LockContext(); + // Get the underlying D3D11 resource Com resource; diff --git a/src/d3d11/d3d11_context.h b/src/d3d11/d3d11_context.h index 7ce4375d..c55a79e7 100644 --- a/src/d3d11/d3d11_context.h +++ b/src/d3d11/d3d11_context.h @@ -4,6 +4,8 @@ #include "../dxvk/dxvk_cs.h" #include "../dxvk/dxvk_device.h" +#include "../d3d10/d3d10_multithread.h" + #include "d3d11_annotation.h" #include "d3d11_context_state.h" #include "d3d11_device_child.h" @@ -647,6 +649,7 @@ namespace dxvk { D3D11Device* const m_parent; D3D11UserDefinedAnnotation m_annotation; + D3D10Multithread m_multithread; Rc m_device; Rc m_updateBuffer; @@ -805,6 +808,10 @@ namespace dxvk { return pShader != nullptr ? pShader->GetCommonShader() : nullptr; } + D3D10DeviceLock LockContext() { + return m_multithread.AcquireLock(); + } + template void EmitCs(Cmd&& command) { if (!m_csChunk->push(command)) { diff --git a/src/d3d11/d3d11_context_def.cpp b/src/d3d11/d3d11_context_def.cpp index e77b1ec4..f633b5a8 100644 --- a/src/d3d11/d3d11_context_def.cpp +++ b/src/d3d11/d3d11_context_def.cpp @@ -42,6 +42,8 @@ namespace dxvk { void STDMETHODCALLTYPE D3D11DeferredContext::ExecuteCommandList( ID3D11CommandList* pCommandList, BOOL RestoreContextState) { + D3D10DeviceLock lock = LockContext(); + FlushCsChunk(); static_cast(pCommandList)->EmitToCommandList(m_commandList.ptr()); @@ -56,6 +58,8 @@ namespace dxvk { HRESULT STDMETHODCALLTYPE D3D11DeferredContext::FinishCommandList( BOOL RestoreDeferredContextState, ID3D11CommandList **ppCommandList) { + D3D10DeviceLock lock = LockContext(); + FlushCsChunk(); if (ppCommandList != nullptr) @@ -78,6 +82,8 @@ namespace dxvk { D3D11_MAP MapType, UINT MapFlags, D3D11_MAPPED_SUBRESOURCE* pMappedResource) { + D3D10DeviceLock lock = LockContext(); + D3D11_RESOURCE_DIMENSION resourceDim = D3D11_RESOURCE_DIMENSION_UNKNOWN; pResource->GetType(&resourceDim); @@ -132,6 +138,8 @@ namespace dxvk { void STDMETHODCALLTYPE D3D11DeferredContext::Unmap( ID3D11Resource* pResource, UINT Subresource) { + D3D10DeviceLock lock = LockContext(); + D3D11_RESOURCE_DIMENSION resourceDim = D3D11_RESOURCE_DIMENSION_UNKNOWN; pResource->GetType(&resourceDim); diff --git a/src/d3d11/d3d11_context_imm.cpp b/src/d3d11/d3d11_context_imm.cpp index d332290c..6898e81a 100644 --- a/src/d3d11/d3d11_context_imm.cpp +++ b/src/d3d11/d3d11_context_imm.cpp @@ -98,6 +98,8 @@ namespace dxvk { void STDMETHODCALLTYPE D3D11ImmediateContext::Flush() { m_parent->FlushInitContext(); + D3D10DeviceLock lock = LockContext(); + if (m_csIsBusy || m_csChunk->commandCount() != 0) { // Add commands to flush the threaded // context, then flush the command list @@ -117,6 +119,8 @@ namespace dxvk { void STDMETHODCALLTYPE D3D11ImmediateContext::ExecuteCommandList( ID3D11CommandList* pCommandList, BOOL RestoreContextState) { + D3D10DeviceLock lock = LockContext(); + auto commandList = static_cast(pCommandList); // Flush any outstanding commands so that @@ -158,6 +162,8 @@ namespace dxvk { D3D11_MAP MapType, UINT MapFlags, D3D11_MAPPED_SUBRESOURCE* pMappedResource) { + D3D10DeviceLock lock = LockContext(); + if (!pResource || !pMappedResource) return E_INVALIDARG; @@ -190,6 +196,8 @@ namespace dxvk { void STDMETHODCALLTYPE D3D11ImmediateContext::Unmap( ID3D11Resource* pResource, UINT Subresource) { + D3D10DeviceLock lock = LockContext(); + D3D11_RESOURCE_DIMENSION resourceDim = D3D11_RESOURCE_DIMENSION_UNKNOWN; pResource->GetType(&resourceDim);