mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-01-19 05:52:11 +01:00
Revert "[dxbc] Bound-check dynamically indexed constant buffer reads"
This reverts commit 621aed5fdbaf92764944be7b3a27cbb3df63ba94. Breaks Dishonored 2. Apparently, out-of-bounds access to constant buffers is allowed as long as it doesn't exceed the range of bound constants.
This commit is contained in:
parent
34477933ef
commit
217399926d
@ -4210,6 +4210,35 @@ namespace dxvk {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
DxbcRegisterPointer DxbcCompiler::emitGetConstBufPtr(
|
||||||
|
const DxbcRegister& operand) {
|
||||||
|
// Constant buffers take a two-dimensional index:
|
||||||
|
// (0) register index (immediate)
|
||||||
|
// (1) constant offset (relative)
|
||||||
|
DxbcRegisterInfo info;
|
||||||
|
info.type.ctype = DxbcScalarType::Float32;
|
||||||
|
info.type.ccount = 4;
|
||||||
|
info.type.alength = 0;
|
||||||
|
info.sclass = spv::StorageClassUniform;
|
||||||
|
|
||||||
|
const uint32_t regId = operand.idx[0].offset;
|
||||||
|
const DxbcRegisterValue constId = emitIndexLoad(operand.idx[1]);
|
||||||
|
|
||||||
|
const uint32_t ptrTypeId = getPointerTypeId(info);
|
||||||
|
|
||||||
|
const std::array<uint32_t, 2> indices =
|
||||||
|
{{ m_module.consti32(0), constId.id }};
|
||||||
|
|
||||||
|
DxbcRegisterPointer result;
|
||||||
|
result.type.ctype = info.type.ctype;
|
||||||
|
result.type.ccount = info.type.ccount;
|
||||||
|
result.id = m_module.opAccessChain(ptrTypeId,
|
||||||
|
m_constantBuffers.at(regId).varId,
|
||||||
|
indices.size(), indices.data());
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
DxbcRegisterPointer DxbcCompiler::emitGetImmConstBufPtr(
|
DxbcRegisterPointer DxbcCompiler::emitGetImmConstBufPtr(
|
||||||
const DxbcRegister& operand) {
|
const DxbcRegister& operand) {
|
||||||
if (m_immConstBuf == 0)
|
if (m_immConstBuf == 0)
|
||||||
@ -4252,6 +4281,9 @@ namespace dxvk {
|
|||||||
case DxbcOperandType::Output:
|
case DxbcOperandType::Output:
|
||||||
return emitGetOutputPtr(operand);
|
return emitGetOutputPtr(operand);
|
||||||
|
|
||||||
|
case DxbcOperandType::ConstantBuffer:
|
||||||
|
return emitGetConstBufPtr(operand);
|
||||||
|
|
||||||
case DxbcOperandType::ImmediateConstantBuffer:
|
case DxbcOperandType::ImmediateConstantBuffer:
|
||||||
return emitGetImmConstBufPtr(operand);
|
return emitGetImmConstBufPtr(operand);
|
||||||
|
|
||||||
@ -4708,22 +4740,6 @@ namespace dxvk {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
DxbcRegisterValue DxbcCompiler::emitIndexBoundCheck(
|
|
||||||
DxbcRegisterValue index,
|
|
||||||
DxbcRegisterValue count) {
|
|
||||||
index = emitRegisterBitcast(index, DxbcScalarType::Uint32);
|
|
||||||
count = emitRegisterBitcast(count, DxbcScalarType::Uint32);
|
|
||||||
|
|
||||||
DxbcRegisterValue result;
|
|
||||||
result.type.ctype = DxbcScalarType::Bool;
|
|
||||||
result.type.ccount = index.type.ccount;
|
|
||||||
result.id = m_module.opULessThan(
|
|
||||||
getVectorTypeId(result.type),
|
|
||||||
index.id, count.id);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
DxbcRegisterValue DxbcCompiler::emitIndexLoad(
|
DxbcRegisterValue DxbcCompiler::emitIndexLoad(
|
||||||
DxbcRegIndex index) {
|
DxbcRegIndex index) {
|
||||||
if (index.relReg != nullptr) {
|
if (index.relReg != nullptr) {
|
||||||
@ -4786,56 +4802,9 @@ namespace dxvk {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
DxbcRegisterValue DxbcCompiler::emitConstBufLoadRaw(
|
|
||||||
const DxbcRegister& operand) {
|
|
||||||
// Constant buffers take a two-dimensional index:
|
|
||||||
// (0) register index (immediate)
|
|
||||||
// (1) constant offset (relative)
|
|
||||||
DxbcRegisterInfo info;
|
|
||||||
info.type.ctype = DxbcScalarType::Float32;
|
|
||||||
info.type.ccount = 4;
|
|
||||||
info.type.alength = 0;
|
|
||||||
info.sclass = spv::StorageClassUniform;
|
|
||||||
|
|
||||||
const uint32_t regId = operand.idx[0].offset;
|
|
||||||
const DxbcRegisterValue constId = emitIndexLoad(operand.idx[1]);
|
|
||||||
|
|
||||||
const uint32_t ptrTypeId = getPointerTypeId(info);
|
|
||||||
|
|
||||||
const std::array<uint32_t, 2> indices =
|
|
||||||
{{ m_module.consti32(0), constId.id }};
|
|
||||||
|
|
||||||
DxbcRegisterPointer pointer;
|
|
||||||
pointer.type.ctype = info.type.ctype;
|
|
||||||
pointer.type.ccount = info.type.ccount;
|
|
||||||
pointer.id = m_module.opAccessChain(ptrTypeId,
|
|
||||||
m_constantBuffers.at(regId).varId,
|
|
||||||
indices.size(), indices.data());
|
|
||||||
|
|
||||||
DxbcRegisterValue value = emitValueLoad(pointer);
|
|
||||||
|
|
||||||
// For dynamically indexed constant buffers, we should
|
|
||||||
// return a vec4(ß.0f) if the index is out of bounds
|
|
||||||
if (operand.idx[1].relReg != nullptr) {
|
|
||||||
DxbcRegisterValue cbSize;
|
|
||||||
cbSize.type = { DxbcScalarType::Uint32, 1 };
|
|
||||||
cbSize.id = m_module.constu32(m_constantBuffers.at(regId).size);
|
|
||||||
DxbcRegisterValue inBounds = emitRegisterExtend(emitIndexBoundCheck(constId, cbSize), 4);
|
|
||||||
|
|
||||||
value.id = m_module.opSelect(
|
|
||||||
getVectorTypeId(value.type), inBounds.id, value.id,
|
|
||||||
m_module.constvec4f32(0.0f, 0.0f, 0.0f, 0.0f));
|
|
||||||
}
|
|
||||||
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
DxbcRegisterValue DxbcCompiler::emitRegisterLoadRaw(
|
DxbcRegisterValue DxbcCompiler::emitRegisterLoadRaw(
|
||||||
const DxbcRegister& reg) {
|
const DxbcRegister& reg) {
|
||||||
return reg.type == DxbcOperandType::ConstantBuffer
|
return emitValueLoad(emitGetOperandPtr(reg));
|
||||||
? emitConstBufLoadRaw(reg)
|
|
||||||
: emitValueLoad(emitGetOperandPtr(reg));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -819,6 +819,9 @@ namespace dxvk {
|
|||||||
DxbcRegisterPointer emitGetOutputPtr(
|
DxbcRegisterPointer emitGetOutputPtr(
|
||||||
const DxbcRegister& operand);
|
const DxbcRegister& operand);
|
||||||
|
|
||||||
|
DxbcRegisterPointer emitGetConstBufPtr(
|
||||||
|
const DxbcRegister& operand);
|
||||||
|
|
||||||
DxbcRegisterPointer emitGetImmConstBufPtr(
|
DxbcRegisterPointer emitGetImmConstBufPtr(
|
||||||
const DxbcRegister& operand);
|
const DxbcRegister& operand);
|
||||||
|
|
||||||
@ -876,10 +879,6 @@ namespace dxvk {
|
|||||||
|
|
||||||
//////////////////////////////
|
//////////////////////////////
|
||||||
// Operand load/store methods
|
// Operand load/store methods
|
||||||
DxbcRegisterValue emitIndexBoundCheck(
|
|
||||||
DxbcRegisterValue index,
|
|
||||||
DxbcRegisterValue count);
|
|
||||||
|
|
||||||
DxbcRegisterValue emitIndexLoad(
|
DxbcRegisterValue emitIndexLoad(
|
||||||
DxbcRegIndex index);
|
DxbcRegIndex index);
|
||||||
|
|
||||||
@ -891,9 +890,6 @@ namespace dxvk {
|
|||||||
DxbcRegisterValue value,
|
DxbcRegisterValue value,
|
||||||
DxbcRegMask writeMask);
|
DxbcRegMask writeMask);
|
||||||
|
|
||||||
DxbcRegisterValue emitConstBufLoadRaw(
|
|
||||||
const DxbcRegister& operand);
|
|
||||||
|
|
||||||
DxbcRegisterValue emitRegisterLoadRaw(
|
DxbcRegisterValue emitRegisterLoadRaw(
|
||||||
const DxbcRegister& reg);
|
const DxbcRegister& reg);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user