[spirv] Automatically track interface variables

This commit is contained in:
Philip Rebohle 2022-07-15 14:42:55 +02:00
parent 10c5c17bc1
commit 320534cb34
No known key found for this signature in database
GPG Key ID: C8CC613427A31C99
9 changed files with 40 additions and 65 deletions

View File

@ -343,7 +343,7 @@ namespace dxvk {
}
uint32_t GetPointCoord(SpirvModule& spvModule, std::vector<uint32_t>& entryPointInterfaces) {
uint32_t GetPointCoord(SpirvModule& spvModule) {
uint32_t floatType = spvModule.defFloatType(32);
uint32_t vec2Type = spvModule.defVectorType(floatType, 2);
uint32_t vec4Type = spvModule.defVectorType(floatType, 4);
@ -352,7 +352,6 @@ namespace dxvk {
uint32_t pointCoordPtr = spvModule.newVar(vec2Ptr, spv::StorageClassInput);
spvModule.decorateBuiltIn(pointCoordPtr, spv::BuiltInPointCoord);
entryPointInterfaces.push_back(pointCoordPtr);
uint32_t pointCoord = spvModule.opLoad(vec2Type, pointCoordPtr);
@ -603,7 +602,6 @@ namespace dxvk {
SpirvModule m_module;
std::vector
<DxvkBindingInfo> m_bindings;
std::vector<uint32_t> m_entryPointInterfaces;
uint32_t m_inputMask = 0u;
uint32_t m_outputMask = 0u;
@ -705,9 +703,7 @@ namespace dxvk {
// Declare the entry point, we now have all the
// information we need, including the interfaces
m_module.addEntryPoint(m_entryPointId,
isVS() ? spv::ExecutionModelVertex : spv::ExecutionModelFragment, "main",
m_entryPointInterfaces.size(),
m_entryPointInterfaces.data());
isVS() ? spv::ExecutionModelVertex : spv::ExecutionModelFragment, "main");
// Create the shader module object
DxvkShaderCreateInfo info;
@ -773,8 +769,6 @@ namespace dxvk {
std::string name = str::format(input ? "in_" : "out_", semantic.usage, semantic.usageIndex);
m_module.setDebugName(ptr, name.c_str());
m_entryPointInterfaces.push_back(ptr);
if (input)
return m_module.opLoad(type, ptr);
@ -1974,7 +1968,7 @@ namespace dxvk {
m_module.setExecutionMode(m_entryPointId,
spv::ExecutionModeOriginUpperLeft);
uint32_t pointCoord = GetPointCoord(m_module, m_entryPointInterfaces);
uint32_t pointCoord = GetPointCoord(m_module);
auto pointInfo = GetPointSizeInfoPS(m_module, m_rsBlock);
// We need to replace TEXCOORD inputs with gl_PointCoord
@ -2164,7 +2158,6 @@ namespace dxvk {
spv::StorageClassOutput);
m_module.decorateBuiltIn(clipDistArray, spv::BuiltInClipDistance);
m_entryPointInterfaces.push_back(clipDistArray);
// Compute clip distances
for (uint32_t i = 0; i < caps::MaxClipPlanes; i++) {

View File

@ -64,7 +64,7 @@ namespace dxvk {
D3D9PointSizeInfoPS GetPointSizeInfoPS(SpirvModule& spvModule, uint32_t rsBlock);
uint32_t GetPointCoord(SpirvModule& spvModule, std::vector<uint32_t>& entryPointInterfaces);
uint32_t GetPointCoord(SpirvModule& spvModule);
uint32_t GetSharedConstants(SpirvModule& spvModule);

View File

@ -139,7 +139,6 @@ namespace dxvk {
// Load our builtins
uint32_t primitiveIdPtr = m_module.newVar(m_module.defPointerType(uint_t, spv::StorageClassInput), spv::StorageClassInput);
m_module.decorateBuiltIn(primitiveIdPtr, spv::BuiltInPrimitiveId);
m_entryPointInterfaces.push_back(primitiveIdPtr);
uint32_t primitiveId = m_module.opLoad(uint_t, primitiveIdPtr);
@ -174,8 +173,6 @@ namespace dxvk {
elementVar = m_module.opAccessChain(m_module.defPointerType(vec4_t, spv::StorageClassInput), elementPtr, 1, &zero);
elementVar = m_module.opLoad(vec4_t, elementVar);
m_entryPointInterfaces.push_back(elementPtr);
// The offset of this element from the beginning of any given vertex
uint32_t perVertexElementOffset = m_module.constu32(element.Offset / sizeof(uint32_t));
@ -277,9 +274,7 @@ namespace dxvk {
m_module.functionEnd();
m_module.addEntryPoint(m_entryPointId,
spv::ExecutionModelGeometry, "main",
m_entryPointInterfaces.size(),
m_entryPointInterfaces.data());
spv::ExecutionModelGeometry, "main");
m_module.setDebugName(m_entryPointId, "main");
DxvkShaderCreateInfo info;
@ -295,7 +290,6 @@ namespace dxvk {
SpirvModule m_module;
std::vector<uint32_t> m_entryPointInterfaces;
uint32_t m_entryPointId = 0;
uint32_t m_inputMask = 0u;
DxvkBindingInfo m_bufferBinding;

View File

@ -243,9 +243,7 @@ namespace dxvk {
// Declare the entry point, we now have all the
// information we need, including the interfaces
m_module.addEntryPoint(m_entryPointId,
m_programInfo.executionModel(), "main",
m_entryPointInterfaces.size(),
m_entryPointInterfaces.data());
m_programInfo.executionModel(), "main");
m_module.setDebugName(m_entryPointId, "main");
// Create the shader object
@ -665,7 +663,6 @@ namespace dxvk {
m_module.decorateLocation(varId, regIdx);
m_module.setDebugName(varId, str::format("v", regIdx).c_str());
m_entryPointInterfaces.push_back(varId);
m_vRegs.at(regIdx) = { regType, varId };
@ -747,7 +744,6 @@ namespace dxvk {
if (info.sclass == spv::StorageClassOutput) {
m_module.decorateLocation(varId, regIdx);
m_entryPointInterfaces.push_back(varId);
// Add index decoration for potential dual-source blending
if (m_programInfo.type() == DxbcProgramType::PixelShader)
@ -6631,7 +6627,6 @@ namespace dxvk {
m_perVertexOut = m_module.newVar(
perVertexPointer, spv::StorageClassOutput);
m_entryPointInterfaces.push_back(m_perVertexOut);
m_module.setDebugName(m_perVertexOut, "vs_vertex_out");
// Standard input array
@ -6704,7 +6699,6 @@ namespace dxvk {
m_perVertexOut = m_module.newVar(
perVertexPointer, spv::StorageClassOutput);
m_entryPointInterfaces.push_back(m_perVertexOut);
m_module.setDebugName(m_perVertexOut, "ds_vertex_out");
// Main function of the domain shader
@ -6743,7 +6737,6 @@ namespace dxvk {
m_perVertexOut = m_module.newVar(
perVertexPointer, spv::StorageClassOutput);
m_entryPointInterfaces.push_back(m_perVertexOut);
m_module.setDebugName(m_perVertexOut, "gs_vertex_out");
}
@ -6996,7 +6989,6 @@ namespace dxvk {
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());
@ -7118,8 +7110,6 @@ namespace dxvk {
m_perVertexIn = m_module.newVar(
ptrTypeId, spv::StorageClassInput);
m_module.setDebugName(m_perVertexIn, varName);
m_entryPointInterfaces.push_back(m_perVertexIn);
}
@ -7141,7 +7131,6 @@ namespace dxvk {
? "clip_distances"
: "cull_distances");
m_entryPointInterfaces.push_back(varId);
return varId;
}
@ -7332,8 +7321,6 @@ namespace dxvk {
if (storageClass != spv::StorageClassPrivate) {
m_module.decorate (varId, spv::DecorationPatch);
m_module.decorateLocation (varId, 0);
m_entryPointInterfaces.push_back(varId);
}
return varId;
@ -7362,9 +7349,6 @@ namespace dxvk {
m_module.setDebugName (varId, isInput ? "vVertex" : "oVertex");
m_module.decorateLocation (varId, locIdx);
if (storageClass != spv::StorageClassPrivate)
m_entryPointInterfaces.push_back(varId);
return varId;
}
@ -7484,8 +7468,7 @@ namespace dxvk {
&& info.type.ctype != DxbcScalarType::Bool
&& info.sclass == spv::StorageClassInput)
m_module.decorate(varId, spv::DecorationFlat);
m_entryPointInterfaces.push_back(varId);
return varId;
}

View File

@ -517,7 +517,6 @@ namespace dxvk {
///////////////////////////////////////////////////
// Entry point description - we'll need to declare
// the function ID and all input/output variables.
std::vector<uint32_t> m_entryPointInterfaces;
uint32_t m_entryPointId = 0;
////////////////////////////////////////////

View File

@ -216,9 +216,7 @@ namespace dxvk {
// Declare the entry point, we now have all the
// information we need, including the interfaces
m_module.addEntryPoint(m_entryPointId,
m_programInfo.executionModel(), "main",
m_entryPointInterfaces.size(),
m_entryPointInterfaces.data());
m_programInfo.executionModel(), "main");
m_module.setDebugName(m_entryPointId, "main");
}
@ -664,7 +662,6 @@ namespace dxvk {
&& info.sclass == spv::StorageClassInput)
m_module.decorate(varId, spv::DecorationFlat);
m_entryPointInterfaces.push_back(varId);
return varId;
}
@ -1208,8 +1205,6 @@ namespace dxvk {
input ? 0 : m_module.constf32(1.0f),
input ? spv::StorageClassInput : spv::StorageClassOutput);
m_entryPointInterfaces.push_back(m_fog.id);
m_module.decorateLocation(m_fog.id, slot);
}
return m_fog;
@ -1244,7 +1239,6 @@ namespace dxvk {
m_module.decorateLocation(m_ps.oColor[idx].id, idx);
m_module.decorateIndex(m_ps.oColor[idx].id, 0);
m_entryPointInterfaces.push_back(m_ps.oColor[idx].id);
m_usedRTs |= (1u << idx);
}
return m_ps.oColor[idx];
@ -3371,7 +3365,7 @@ void DxsoCompiler::emitControlFlowGenericLoop(
D3D9PointSizeInfoPS pointInfo;
if (m_programInfo.type() == DxsoProgramType::PixelShader) {
pointCoord = GetPointCoord(m_module, m_entryPointInterfaces);
pointCoord = GetPointCoord(m_module);
pointInfo = GetPointSizeInfoPS(m_module, m_rsBlock);
}
@ -3399,8 +3393,6 @@ void DxsoCompiler::emitControlFlowGenericLoop(
if (elem.centroid)
m_module.decorate(inputPtr.id, spv::DecorationCentroid);
m_entryPointInterfaces.push_back(inputPtr.id);
uint32_t typeId = this->getVectorTypeId({ DxsoScalarType::Float32, 4 });
uint32_t ptrTypeId = m_module.defPointerType(typeId, spv::StorageClassPrivate);
@ -3520,8 +3512,6 @@ void DxsoCompiler::emitControlFlowGenericLoop(
}
}
m_entryPointInterfaces.push_back(outputPtr.id);
uint32_t typeId = this->getVectorTypeId({ DxsoScalarType::Float32, 4 });
uint32_t ptrTypeId = m_module.defPointerType(typeId, spv::StorageClassPrivate);
@ -3598,7 +3588,6 @@ void DxsoCompiler::emitControlFlowGenericLoop(
m_module.setDebugName(outputPtr, name.c_str());
m_outputMask |= 1u << slot;
m_entryPointInterfaces.push_back(outputPtr);
};
if (!outputtedColor0)
@ -3668,7 +3657,6 @@ void DxsoCompiler::emitControlFlowGenericLoop(
spv::StorageClassOutput);
m_module.decorateBuiltIn(clipDistArray, spv::BuiltInClipDistance);
m_entryPointInterfaces.push_back(clipDistArray);
if (m_moduleInfo.options.invariantPosition)
m_module.decorate(m_vs.oPos.id, spv::DecorationInvariant);

View File

@ -348,7 +348,6 @@ namespace dxvk {
///////////////////////////////////////////////////
// Entry point description - we'll need to declare
// the function ID and all input/output variables.
std::vector<uint32_t> m_entryPointInterfaces;
uint32_t m_entryPointId = 0;
////////////////////////////////////////////

View File

@ -69,16 +69,14 @@ namespace dxvk {
void SpirvModule::addEntryPoint(
uint32_t entryPointId,
spv::ExecutionModel executionModel,
const char* name,
uint32_t interfaceCount,
const uint32_t* interfaceIds) {
m_entryPoints.putIns (spv::OpEntryPoint, 3 + m_entryPoints.strLen(name) + interfaceCount);
const char* name) {
m_entryPoints.putIns (spv::OpEntryPoint, 3 + m_entryPoints.strLen(name) + m_interfaceVars.size());
m_entryPoints.putWord (executionModel);
m_entryPoints.putWord (entryPointId);
m_entryPoints.putStr (name);
for (uint32_t i = 0; i < interfaceCount; i++)
m_entryPoints.putWord(interfaceIds[i]);
for (uint32_t varId : m_interfaceVars)
m_entryPoints.putWord(varId);
}
@ -884,9 +882,12 @@ namespace dxvk {
spv::StorageClass storageClass) {
uint32_t resultId = this->allocateId();
if (isInterfaceVar(storageClass))
m_interfaceVars.push_back(resultId);
auto& code = storageClass != spv::StorageClassFunction
? m_variables : m_code;
code.putIns (spv::OpVariable, 4);
code.putWord (pointerType);
code.putWord (resultId);
@ -901,6 +902,9 @@ namespace dxvk {
uint32_t initialValue) {
uint32_t resultId = this->allocateId();
if (isInterfaceVar(storageClass))
m_interfaceVars.push_back(resultId);
auto& code = storageClass != spv::StorageClassFunction
? m_variables : m_code;
@ -3738,4 +3742,16 @@ namespace dxvk {
}
}
bool SpirvModule::isInterfaceVar(
spv::StorageClass sclass) const {
if (m_version < spvVersion(1, 4)) {
return sclass == spv::StorageClassInput
|| sclass == spv::StorageClassOutput;
} else {
// All global variables need to be declared
return sclass != spv::StorageClassFunction;
}
}
}

View File

@ -77,9 +77,7 @@ namespace dxvk {
void addEntryPoint(
uint32_t entryPointId,
spv::ExecutionModel executionModel,
const char* name,
uint32_t interfaceCount,
const uint32_t* interfaceIds);
const char* name);
void setMemoryModel(
spv::AddressingModel addressModel,
@ -1255,7 +1253,9 @@ namespace dxvk {
SpirvCodeBuffer m_code;
std::unordered_set<uint32_t> m_lateConsts;
std::vector<uint32_t> m_interfaceVars;
uint32_t defType(
spv::Op op,
uint32_t argCount,
@ -1274,7 +1274,10 @@ namespace dxvk {
void putImageOperands(
const SpirvImageOperands& op);
bool isInterfaceVar(
spv::StorageClass sclass) const;
};
}