Skip to content

Commit

Permalink
[dxbc] Only load requested components from constant buffers
Browse files Browse the repository at this point in the history
Results in better performance compared to loading the entire vector
on RADV. Suggested by Samuel Pitoiset.
  • Loading branch information
doitsujin committed Jan 30, 2019
1 parent c360a19 commit e5a06d3
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 2 deletions.
57 changes: 55 additions & 2 deletions src/dxbc/dxbc_compiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5187,14 +5187,65 @@ namespace dxvk {
m_module.opStore(ptr.id, tmp.id);
}
}


DxbcRegisterValue DxbcCompiler::emitRegisterLoadRaw(
const DxbcRegister& reg) {
return emitValueLoad(emitGetOperandPtr(reg));
}


DxbcRegisterValue DxbcCompiler::emitConstantBufferLoad(
const DxbcRegister& reg,
DxbcRegMask writeMask) {
DxbcRegisterPointer ptr = emitGetOperandPtr(reg);

std::array<uint32_t, 4> ccomps = { 0, 0, 0, 0 };
std::array<uint32_t, 4> scomps = { 0, 0, 0, 0 };
uint32_t scount = 0;

for (uint32_t i = 0; i < 4; i++) {
uint32_t sindex = reg.swizzle[i];

if (!writeMask[i] || ccomps[sindex])
continue;

uint32_t componentId = m_module.constu32(sindex);
uint32_t componentPtr = m_module.opAccessChain(
m_module.defPointerType(
getScalarTypeId(DxbcScalarType::Float32),
spv::StorageClassUniformConstant),
ptr.id, 1, &componentId);

ccomps[sindex] = m_module.opLoad(
getScalarTypeId(DxbcScalarType::Float32),
componentPtr);
}

for (uint32_t i = 0; i < 4; i++) {
uint32_t sindex = reg.swizzle[i];

if (writeMask[i])
scomps[scount++] = ccomps[sindex];
}

DxbcRegisterValue result;
result.type.ctype = DxbcScalarType::Float32;
result.type.ccount = scount;
result.id = scomps[0];

if (scount > 1) {
result.id = m_module.opCompositeConstruct(
getVectorTypeId(result.type),
scount, scomps.data());
}

result = emitRegisterBitcast(result, reg.dataType);
result = emitSrcOperandModifiers(result, reg.modifiers);
return result;
}


DxbcRegisterValue DxbcCompiler::emitRegisterLoad(
const DxbcRegister& reg,
DxbcRegMask writeMask) {
Expand Down Expand Up @@ -5236,6 +5287,8 @@ namespace dxvk {

// Cast constants to the requested type
return emitRegisterBitcast(result, reg.dataType);
} else if (reg.type == DxbcOperandType::ConstantBuffer) {
return emitConstantBufferLoad(reg, writeMask);
} else {
// Load operand from the operand pointer
DxbcRegisterValue result = emitRegisterLoadRaw(reg);
Expand Down
4 changes: 4 additions & 0 deletions src/dxbc/dxbc_compiler.h
Original file line number Diff line number Diff line change
Expand Up @@ -972,6 +972,10 @@ namespace dxvk {
DxbcRegisterValue emitRegisterLoadRaw(
const DxbcRegister& reg);

DxbcRegisterValue emitConstantBufferLoad(
const DxbcRegister& reg,
DxbcRegMask writeMask);

DxbcRegisterValue emitRegisterLoad(
const DxbcRegister& reg,
DxbcRegMask writeMask);
Expand Down

0 comments on commit e5a06d3

Please sign in to comment.