From 4801fbe0980bb7e062b3223a10e57d56ed5c0aab Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Mon, 14 Sep 2020 16:47:07 +0200 Subject: [PATCH] [d3d11] Clamp and validate bound constant buffer range SetConstantBuffers will only bind the first 65536 bytes of any buffer passed to it if it is larger. This can be seen even when querying the bound range via GetConstantBuffers1. SetConstantBuffers1 does not have any effect if the bound range is invalid. --- src/d3d11/d3d11_context.cpp | 33 ++++++++++++--------------------- src/d3d11/d3d11_context.h | 4 ---- 2 files changed, 12 insertions(+), 25 deletions(-) diff --git a/src/d3d11/d3d11_context.cpp b/src/d3d11/d3d11_context.cpp index fbd9dd61..b7f0aef4 100644 --- a/src/d3d11/d3d11_context.cpp +++ b/src/d3d11/d3d11_context.cpp @@ -3497,18 +3497,6 @@ namespace dxvk { void D3D11DeviceContext::BindConstantBuffer( - UINT Slot, - D3D11Buffer* pBuffer) { - EmitCs([ - cSlotId = Slot, - cBufferSlice = pBuffer ? pBuffer->GetBufferSlice() : DxvkBufferSlice() - ] (DxvkContext* ctx) { - ctx->bindResourceBuffer(cSlotId, cBufferSlice); - }); - } - - - void D3D11DeviceContext::BindConstantBuffer1( UINT Slot, D3D11Buffer* pBuffer, UINT Offset, @@ -3628,19 +3616,19 @@ namespace dxvk { for (uint32_t i = 0; i < NumBuffers; i++) { auto newBuffer = static_cast(ppConstantBuffers[i]); - UINT constantBound = 0; + UINT constantCount = 0; if (likely(newBuffer != nullptr)) - constantBound = newBuffer->Desc()->ByteWidth / 16; + constantCount = std::min(newBuffer->Desc()->ByteWidth / 16, UINT(D3D11_REQ_CONSTANT_BUFFER_ELEMENT_COUNT)); if (Bindings[StartSlot + i].buffer != newBuffer - || Bindings[StartSlot + i].constantBound != constantBound) { + || Bindings[StartSlot + i].constantCount != constantCount) { Bindings[StartSlot + i].buffer = newBuffer; Bindings[StartSlot + i].constantOffset = 0; - Bindings[StartSlot + i].constantCount = constantBound; - Bindings[StartSlot + i].constantBound = constantBound; + Bindings[StartSlot + i].constantCount = constantCount; + Bindings[StartSlot + i].constantBound = constantCount; - BindConstantBuffer(slotId + i, newBuffer); + BindConstantBuffer(slotId + i, newBuffer, 0, constantCount); } } } @@ -3664,12 +3652,15 @@ namespace dxvk { UINT constantBound; if (likely(newBuffer != nullptr)) { - constantBound = newBuffer->Desc()->ByteWidth / 16; + constantBound = std::min(newBuffer->Desc()->ByteWidth / 16, UINT(D3D11_REQ_CONSTANT_BUFFER_ELEMENT_COUNT)); if (likely(pFirstConstant && pNumConstants)) { constantOffset = pFirstConstant[i]; constantCount = pNumConstants [i]; + if (unlikely(constantCount > D3D11_REQ_CONSTANT_BUFFER_ELEMENT_COUNT)) + continue; + constantBound = (constantOffset + constantCount > constantBound) ? constantBound - std::min(constantOffset, constantBound) : constantCount; @@ -3696,7 +3687,7 @@ namespace dxvk { Bindings[StartSlot + i].constantCount = constantCount; Bindings[StartSlot + i].constantBound = constantBound; - BindConstantBuffer1(slotId + i, newBuffer, constantOffset, constantBound); + BindConstantBuffer(slotId + i, newBuffer, constantOffset, constantBound); } } } @@ -3937,7 +3928,7 @@ namespace dxvk { uint32_t slotId = computeConstantBufferBinding(Stage, 0); for (uint32_t i = 0; i < Bindings.size(); i++) { - BindConstantBuffer1(slotId + i, Bindings[i].buffer.ptr(), + BindConstantBuffer(slotId + i, Bindings[i].buffer.ptr(), Bindings[i].constantOffset, Bindings[i].constantBound); } } diff --git a/src/d3d11/d3d11_context.h b/src/d3d11/d3d11_context.h index 3776ae61..baf0e627 100644 --- a/src/d3d11/d3d11_context.h +++ b/src/d3d11/d3d11_context.h @@ -763,10 +763,6 @@ namespace dxvk { UINT Offset); void BindConstantBuffer( - UINT Slot, - D3D11Buffer* pBuffer); - - void BindConstantBuffer1( UINT Slot, D3D11Buffer* pBuffer, UINT Offset,