mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-03-06 20:58:37 +01:00
[d3d11] Correctly handle out-of-bounds constant buffer ranges
Otherwise we pass an invalid offset and length to the backend, which leads to invalid descriptor set updates in Vulkan. The D3D11 runtime does not report corrected constant offset and count parameters to the applicaion in *GetConstantBuffers1. Reported-by: Danylo Piliaiev <danylo.piliaiev@globallogic.com>
This commit is contained in:
parent
09d60f42bc
commit
8f580efa25
2 changed files with 26 additions and 10 deletions
|
@ -3262,10 +3262,10 @@ namespace dxvk {
|
|||
const D3D11ConstantBufferBinding* pBufferBinding) {
|
||||
EmitCs([
|
||||
cSlotId = Slot,
|
||||
cBufferSlice = pBufferBinding->buffer != nullptr
|
||||
cBufferSlice = pBufferBinding->constantBound
|
||||
? pBufferBinding->buffer->GetBufferSlice(
|
||||
pBufferBinding->constantOffset * 16,
|
||||
pBufferBinding->constantCount * 16)
|
||||
pBufferBinding->constantBound * 16)
|
||||
: DxvkBufferSlice()
|
||||
] (DxvkContext* ctx) {
|
||||
ctx->bindResourceBuffer(cSlotId, cBufferSlice);
|
||||
|
@ -3371,14 +3371,28 @@ namespace dxvk {
|
|||
for (uint32_t i = 0; i < NumBuffers; i++) {
|
||||
auto newBuffer = static_cast<D3D11Buffer*>(ppConstantBuffers[i]);
|
||||
|
||||
UINT constantOffset = 0;
|
||||
UINT constantCount = newBuffer != nullptr
|
||||
? newBuffer->Desc()->ByteWidth / 16
|
||||
: 0;
|
||||
|
||||
if (newBuffer != nullptr && pFirstConstant != nullptr && pNumConstants != nullptr) {
|
||||
constantOffset = pFirstConstant[i];
|
||||
constantCount = pNumConstants [i];
|
||||
UINT constantOffset;
|
||||
UINT constantCount;
|
||||
UINT constantBound;
|
||||
|
||||
if (likely(newBuffer != nullptr)) {
|
||||
constantBound = newBuffer->Desc()->ByteWidth / 16;
|
||||
|
||||
if (pFirstConstant && pNumConstants) {
|
||||
constantOffset = pFirstConstant[i];
|
||||
constantCount = pNumConstants [i];
|
||||
|
||||
constantBound = (constantOffset + constantCount > constantBound)
|
||||
? constantBound - std::min(constantOffset, constantBound)
|
||||
: constantCount;
|
||||
} else {
|
||||
constantOffset = 0;
|
||||
constantCount = constantBound;
|
||||
}
|
||||
} else {
|
||||
constantOffset = 0;
|
||||
constantCount = 0;
|
||||
constantBound = 0;
|
||||
}
|
||||
|
||||
if (Bindings[StartSlot + i].buffer != newBuffer
|
||||
|
@ -3387,6 +3401,7 @@ namespace dxvk {
|
|||
Bindings[StartSlot + i].buffer = newBuffer;
|
||||
Bindings[StartSlot + i].constantOffset = constantOffset;
|
||||
Bindings[StartSlot + i].constantCount = constantCount;
|
||||
Bindings[StartSlot + i].constantBound = constantBound;
|
||||
|
||||
BindConstantBuffer(slotId + i, &Bindings[StartSlot + i]);
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@ namespace dxvk {
|
|||
Com<D3D11Buffer> buffer = nullptr;
|
||||
UINT constantOffset = 0;
|
||||
UINT constantCount = 0;
|
||||
UINT constantBound = 0;
|
||||
};
|
||||
|
||||
using D3D11ConstantBufferBindings = std::array<
|
||||
|
|
Loading…
Add table
Reference in a new issue