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:
parent
09d60f42bc
commit
8f580efa25
@ -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…
x
Reference in New Issue
Block a user