1
0
mirror of https://github.com/doitsujin/dxvk.git synced 2025-01-31 14:52:11 +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:
Philip Rebohle 2019-03-28 13:45:41 +01:00
parent 09d60f42bc
commit 8f580efa25
No known key found for this signature in database
GPG Key ID: C8CC613427A31C99
2 changed files with 26 additions and 10 deletions

View File

@ -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]);
}

View File

@ -19,6 +19,7 @@ namespace dxvk {
Com<D3D11Buffer> buffer = nullptr;
UINT constantOffset = 0;
UINT constantCount = 0;
UINT constantBound = 0;
};
using D3D11ConstantBufferBindings = std::array<