1
0
mirror of https://github.com/doitsujin/dxvk.git synced 2025-02-20 19:54:19 +01:00

[dxbc] Implement Xfb output declarations and setup

This commit is contained in:
Philip Rebohle 2018-06-24 01:07:48 +02:00
parent bb780bbe10
commit 017699df15
No known key found for this signature in database
GPG Key ID: C8CC613427A31C99
2 changed files with 108 additions and 3 deletions

View File

@ -673,12 +673,19 @@ namespace dxvk {
info.type.ccount = regType.ccount;
info.type.alength = regDim;
info.sclass = spv::StorageClassOutput;
// In xfb mode, we set up the actual
// output vars when emitting a vertex
if (m_moduleInfo.xfb != nullptr)
info.sclass = spv::StorageClassPrivate;
const uint32_t varId = this->emitNewVariable(info);
m_module.decorateLocation(varId, regIdx);
m_module.setDebugName(varId, str::format("o", regIdx).c_str());
m_entryPointInterfaces.push_back(varId);
if (info.sclass == spv::StorageClassOutput) {
m_module.decorateLocation(varId, regIdx);
m_entryPointInterfaces.push_back(varId);
}
m_oRegs.at(regIdx) = { regType, varId };
@ -2071,6 +2078,7 @@ namespace dxvk {
emitOutputSetup();
emitClipCullStore(DxbcSystemValue::ClipDistance, m_clipDistances);
emitClipCullStore(DxbcSystemValue::CullDistance, m_cullDistances);
emitXfbOutputSetup(streamId);
m_module.opEmitVertex(streamVar);
}
@ -6050,6 +6058,10 @@ namespace dxvk {
spv::BuiltInCullDistance,
spv::StorageClassOutput);
// Emit Xfb variables if necessary
if (m_moduleInfo.xfb != nullptr)
emitXfbOutputDeclarations();
// Main function of the vertex shader
m_gs.functionId = m_module.allocateId();
m_module.setDebugName(m_gs.functionId, "gs_main");
@ -6226,6 +6238,77 @@ namespace dxvk {
}
void DxbcCompiler::emitXfbOutputDeclarations() {
for (uint32_t i = 0; i < m_moduleInfo.xfb->entryCount; i++) {
const DxbcXfbEntry* xfbEntry = m_moduleInfo.xfb->entries + i;
const DxbcSgnEntry* sigEntry = m_osgn->find(
xfbEntry->semanticName,
xfbEntry->semanticIndex,
xfbEntry->streamId);
if (sigEntry == nullptr)
continue;
DxbcRegisterInfo varInfo;
varInfo.type.ctype = DxbcScalarType::Float32;
varInfo.type.ccount = xfbEntry->componentCount;
varInfo.type.alength = 0;
varInfo.sclass = spv::StorageClassOutput;
uint32_t dstComponentMask = (1 << xfbEntry->componentCount) - 1;
uint32_t srcComponentMask = dstComponentMask
<< sigEntry->componentMask.firstSet()
<< xfbEntry->componentIndex;
DxbcXfbVar xfbVar;
xfbVar.varId = emitNewVariable(varInfo);
xfbVar.streamId = xfbEntry->streamId;
xfbVar.outputId = sigEntry->registerId;
xfbVar.srcMask = DxbcRegMask(srcComponentMask);
xfbVar.dstMask = DxbcRegMask(dstComponentMask);
m_xfbVars.push_back(xfbVar);
m_entryPointInterfaces.push_back(xfbVar.varId);
m_module.setDebugName(xfbVar.varId,
str::format("xfb", i).c_str());
m_module.decorateXfb(xfbVar.varId,
xfbEntry->streamId, xfbEntry->bufferId, xfbEntry->offset,
m_moduleInfo.xfb->strides[xfbEntry->bufferId]);
}
// TODO Compact location/component assignment
for (uint32_t i = 0; i < m_xfbVars.size(); i++) {
m_xfbVars[i].location = i;
m_xfbVars[i].component = 0;
}
for (uint32_t i = 0; i < m_xfbVars.size(); i++) {
const DxbcXfbVar* var = &m_xfbVars[i];
m_module.decorateLocation (var->varId, var->location);
m_module.decorateComponent(var->varId, var->component);
}
}
void DxbcCompiler::emitXfbOutputSetup(uint32_t streamId) {
for (size_t i = 0; i < m_xfbVars.size(); i++) {
if (m_xfbVars[i].streamId == streamId) {
DxbcRegisterPointer srcPtr = m_oRegs[m_xfbVars[i].outputId];
DxbcRegisterPointer dstPtr;
dstPtr.type.ctype = DxbcScalarType::Float32;
dstPtr.type.ccount = m_xfbVars[i].dstMask.popCount();
dstPtr.id = m_xfbVars[i].varId;
DxbcRegisterValue value = emitRegisterExtract(
emitValueLoad(srcPtr), m_xfbVars[i].srcMask);
emitValueStore(dstPtr, value, m_xfbVars[i].dstMask);
}
}
}
void DxbcCompiler::emitHsControlPointPhase(
const DxbcCompilerHsControlPointPhase& phase) {
m_module.opFunctionCall(

View File

@ -122,6 +122,17 @@ namespace dxvk {
uint32_t labelElse = 0;
uint32_t labelEnd = 0;
};
struct DxbcXfbVar {
uint32_t varId = 0;
uint32_t streamId = 0;
uint32_t outputId = 0;
DxbcRegMask srcMask = 0;
DxbcRegMask dstMask = 0;
uint32_t location = 0;
uint32_t component = 0;
};
/**
@ -419,6 +430,10 @@ namespace dxvk {
DxbcRegisterPointer,
DxbcMaxInterfaceRegs> m_oRegs;
std::vector<DxbcSvMapping> m_oMappings;
/////////////////////////////////////////////
// xfb output registers for geometry shaders
std::vector<DxbcXfbVar> m_xfbVars;
//////////////////////////////////////////////////////
// Shader resource variables. These provide access to
@ -1044,6 +1059,13 @@ namespace dxvk {
void emitGsFinalize();
void emitPsFinalize();
void emitCsFinalize();
///////////////////////
// Xfb related methods
void emitXfbOutputDeclarations();
void emitXfbOutputSetup(
uint32_t streamId);
///////////////////////////////
// Hull shader phase methods