mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-01-18 20:52:10 +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(
|
||||
const DxbcRegister& operand) {
|
||||
if (m_immConstBuf == 0)
|
||||
@ -4252,6 +4281,9 @@ namespace dxvk {
|
||||
case DxbcOperandType::Output:
|
||||
return emitGetOutputPtr(operand);
|
||||
|
||||
case DxbcOperandType::ConstantBuffer:
|
||||
return emitGetConstBufPtr(operand);
|
||||
|
||||
case DxbcOperandType::ImmediateConstantBuffer:
|
||||
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(
|
||||
DxbcRegIndex index) {
|
||||
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(
|
||||
const DxbcRegister& reg) {
|
||||
return reg.type == DxbcOperandType::ConstantBuffer
|
||||
? emitConstBufLoadRaw(reg)
|
||||
: emitValueLoad(emitGetOperandPtr(reg));
|
||||
return emitValueLoad(emitGetOperandPtr(reg));
|
||||
}
|
||||
|
||||
|
||||
|
@ -819,6 +819,9 @@ namespace dxvk {
|
||||
DxbcRegisterPointer emitGetOutputPtr(
|
||||
const DxbcRegister& operand);
|
||||
|
||||
DxbcRegisterPointer emitGetConstBufPtr(
|
||||
const DxbcRegister& operand);
|
||||
|
||||
DxbcRegisterPointer emitGetImmConstBufPtr(
|
||||
const DxbcRegister& operand);
|
||||
|
||||
@ -876,10 +879,6 @@ namespace dxvk {
|
||||
|
||||
//////////////////////////////
|
||||
// Operand load/store methods
|
||||
DxbcRegisterValue emitIndexBoundCheck(
|
||||
DxbcRegisterValue index,
|
||||
DxbcRegisterValue count);
|
||||
|
||||
DxbcRegisterValue emitIndexLoad(
|
||||
DxbcRegIndex index);
|
||||
|
||||
@ -891,9 +890,6 @@ namespace dxvk {
|
||||
DxbcRegisterValue value,
|
||||
DxbcRegMask writeMask);
|
||||
|
||||
DxbcRegisterValue emitConstBufLoadRaw(
|
||||
const DxbcRegister& operand);
|
||||
|
||||
DxbcRegisterValue emitRegisterLoadRaw(
|
||||
const DxbcRegister& reg);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user