1
0
mirror of https://github.com/doitsujin/dxvk.git synced 2025-03-15 07:29:17 +01:00

[dxbc] Refactor immediate constant buffer loads

This commit is contained in:
Philip Rebohle 2025-02-27 16:26:05 +01:00
parent fcbdff3b72
commit ad095deaa8
2 changed files with 42 additions and 43 deletions

View File

@ -5326,50 +5326,66 @@ namespace dxvk {
} }
DxbcRegisterPointer DxbcCompiler::emitGetImmConstBufPtr( DxbcRegisterValue DxbcCompiler::emitImmediateConstantBufferLoadRaw(
const DxbcRegister& operand) { const DxbcRegister& operand) {
DxbcRegisterValue constId = emitIndexLoad(operand.idx[0]); DxbcRegisterValue constId = emitIndexLoad(operand.idx[0]);
DxbcRegisterValue value = { };
if (m_icbArray) { if (m_icbArray) {
// We pad the icb array with an extra zero vector, so we can // We pad the icb array with an extra zero vector, so we can
// clamp the index and get correct robustness behaviour. // clamp the index and get correct robustness behaviour.
constId.id = m_module.opUMin(getVectorTypeId(constId.type), constId.id = m_module.opUMin(getVectorTypeId(constId.type),
constId.id, m_module.constu32(m_icbSize)); constId.id, m_module.constu32(m_icbSize));
DxbcRegisterInfo ptrInfo; DxbcRegisterInfo ptrInfo = { };
ptrInfo.type.ctype = DxbcScalarType::Uint32; ptrInfo.type.ctype = DxbcScalarType::Uint32;
ptrInfo.type.ccount = m_icbComponents; ptrInfo.type.ccount = m_icbComponents;
ptrInfo.type.alength = 0;
ptrInfo.sclass = spv::StorageClassPrivate; ptrInfo.sclass = spv::StorageClassPrivate;
DxbcRegisterPointer result; uint32_t ptrId = m_module.opAccessChain(
result.type.ctype = ptrInfo.type.ctype; getPointerTypeId(ptrInfo), m_icbArray, 1, &constId.id);
result.type.ccount = ptrInfo.type.ccount;
result.id = m_module.opAccessChain( value.type.ctype = ptrInfo.type.ctype;
getPointerTypeId(ptrInfo), value.type.ccount = ptrInfo.type.ccount;
m_icbArray, 1, &constId.id); value.id = m_module.opLoad(getVectorTypeId(value.type), ptrId);
return result;
} else if (m_constantBuffers.at(Icb_BindingSlotId).varId != 0) { } else if (m_constantBuffers.at(Icb_BindingSlotId).varId != 0) {
const std::array<uint32_t, 2> indices = const std::array<uint32_t, 2> indices =
{{ m_module.consti32(0), constId.id }}; {{ m_module.consti32(0), constId.id }};
DxbcRegisterInfo ptrInfo; DxbcRegisterInfo ptrInfo = { };
ptrInfo.type.ctype = DxbcScalarType::Float32; ptrInfo.type.ctype = DxbcScalarType::Float32;
ptrInfo.type.ccount = m_icbComponents; ptrInfo.type.ccount = m_icbComponents;
ptrInfo.type.alength = 0;
ptrInfo.sclass = spv::StorageClassUniform; ptrInfo.sclass = spv::StorageClassUniform;
DxbcRegisterPointer result; uint32_t ptrId = m_module.opAccessChain(getPointerTypeId(ptrInfo),
result.type.ctype = ptrInfo.type.ctype;
result.type.ccount = ptrInfo.type.ccount;
result.id = m_module.opAccessChain(
getPointerTypeId(ptrInfo),
m_constantBuffers.at(Icb_BindingSlotId).varId, m_constantBuffers.at(Icb_BindingSlotId).varId,
indices.size(), indices.data()); indices.size(), indices.data());
return result;
value.type.ctype = ptrInfo.type.ctype;
value.type.ccount = ptrInfo.type.ccount;
value.id = m_module.opLoad(getVectorTypeId(value.type), ptrId);
} else { } else {
throw DxvkError("DxbcCompiler: Immediate constant buffer not defined"); throw DxvkError("DxbcCompiler: Immediate constant buffer not defined");
} }
// Pad to vec4 since apps may want to access
// components that we optimized away
if (value.type.ccount < 4u) {
DxbcVectorType zeroType;
zeroType.ctype = value.type.ctype;
zeroType.ccount = 4u - value.type.ccount;
uint32_t zeroVector = emitBuildZeroVector(zeroType).id;
std::array<uint32_t, 2> constituents = { value.id, zeroVector };
value.type.ccount = 4u;
value.id = m_module.opCompositeConstruct(getVectorTypeId(value.type),
constituents.size(), constituents.data());
}
return value;
} }
@ -5391,9 +5407,6 @@ namespace dxvk {
case DxbcOperandType::Output: case DxbcOperandType::Output:
return emitGetOutputPtr(operand); return emitGetOutputPtr(operand);
case DxbcOperandType::ImmediateConstantBuffer:
return emitGetImmConstBufPtr(operand);
case DxbcOperandType::InputThreadId: case DxbcOperandType::InputThreadId:
return DxbcRegisterPointer { return DxbcRegisterPointer {
{ DxbcScalarType::Uint32, 3 }, { DxbcScalarType::Uint32, 3 },
@ -5796,6 +5809,9 @@ namespace dxvk {
DxbcRegisterValue DxbcCompiler::emitRegisterLoadRaw( DxbcRegisterValue DxbcCompiler::emitRegisterLoadRaw(
const DxbcRegister& reg) { const DxbcRegister& reg) {
if (reg.type == DxbcOperandType::ImmediateConstantBuffer)
return emitImmediateConstantBufferLoadRaw(reg);
// Try to find index range for the given register // Try to find index range for the given register
const DxbcIndexRange* indexRange = nullptr; const DxbcIndexRange* indexRange = nullptr;
@ -5862,24 +5878,7 @@ namespace dxvk {
} }
} }
DxbcRegisterValue value = emitValueLoad(emitGetOperandPtr(reg)); return emitValueLoad(emitGetOperandPtr(reg));
// Pad icb values to a vec4 since the app may access components that are always 0
if (reg.type == DxbcOperandType::ImmediateConstantBuffer && value.type.ccount < 4u) {
DxbcVectorType zeroType;
zeroType.ctype = value.type.ctype;
zeroType.ccount = 4u - value.type.ccount;
uint32_t zeroVector = emitBuildZeroVector(zeroType).id;
std::array<uint32_t, 2> constituents = { value.id, zeroVector };
value.type.ccount = 4u;
value.id = m_module.opCompositeConstruct(getVectorTypeId(value.type),
constituents.size(), constituents.data());
}
return value;
} }

View File

@ -968,9 +968,6 @@ namespace dxvk {
DxbcRegisterPointer emitGetConstBufPtr( DxbcRegisterPointer emitGetConstBufPtr(
const DxbcRegister& operand); const DxbcRegister& operand);
DxbcRegisterPointer emitGetImmConstBufPtr(
const DxbcRegister& operand);
DxbcRegisterPointer emitGetOperandPtr( DxbcRegisterPointer emitGetOperandPtr(
const DxbcRegister& operand); const DxbcRegister& operand);
@ -1027,6 +1024,9 @@ namespace dxvk {
DxbcRegisterValue value, DxbcRegisterValue value,
DxbcRegMask writeMask); DxbcRegMask writeMask);
DxbcRegisterValue emitImmediateConstantBufferLoadRaw(
const DxbcRegister& reg);
DxbcRegisterValue emitRegisterLoadRaw( DxbcRegisterValue emitRegisterLoadRaw(
const DxbcRegister& reg); const DxbcRegister& reg);