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

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

View File

@ -64,7 +64,7 @@ namespace dxvk {
D3D9PointSizeInfoPS GetPointSizeInfoPS(SpirvModule& spvModule, uint32_t rsBlock); 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); uint32_t GetSharedConstants(SpirvModule& spvModule);

View File

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

View File

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

View File

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

View File

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

View File

@ -69,16 +69,14 @@ namespace dxvk {
void SpirvModule::addEntryPoint( void SpirvModule::addEntryPoint(
uint32_t entryPointId, uint32_t entryPointId,
spv::ExecutionModel executionModel, spv::ExecutionModel executionModel,
const char* name, const char* name) {
uint32_t interfaceCount, m_entryPoints.putIns (spv::OpEntryPoint, 3 + m_entryPoints.strLen(name) + m_interfaceVars.size());
const uint32_t* interfaceIds) {
m_entryPoints.putIns (spv::OpEntryPoint, 3 + m_entryPoints.strLen(name) + interfaceCount);
m_entryPoints.putWord (executionModel); m_entryPoints.putWord (executionModel);
m_entryPoints.putWord (entryPointId); m_entryPoints.putWord (entryPointId);
m_entryPoints.putStr (name); m_entryPoints.putStr (name);
for (uint32_t i = 0; i < interfaceCount; i++) for (uint32_t varId : m_interfaceVars)
m_entryPoints.putWord(interfaceIds[i]); m_entryPoints.putWord(varId);
} }
@ -884,9 +882,12 @@ namespace dxvk {
spv::StorageClass storageClass) { spv::StorageClass storageClass) {
uint32_t resultId = this->allocateId(); uint32_t resultId = this->allocateId();
if (isInterfaceVar(storageClass))
m_interfaceVars.push_back(resultId);
auto& code = storageClass != spv::StorageClassFunction auto& code = storageClass != spv::StorageClassFunction
? m_variables : m_code; ? m_variables : m_code;
code.putIns (spv::OpVariable, 4); code.putIns (spv::OpVariable, 4);
code.putWord (pointerType); code.putWord (pointerType);
code.putWord (resultId); code.putWord (resultId);
@ -901,6 +902,9 @@ namespace dxvk {
uint32_t initialValue) { uint32_t initialValue) {
uint32_t resultId = this->allocateId(); uint32_t resultId = this->allocateId();
if (isInterfaceVar(storageClass))
m_interfaceVars.push_back(resultId);
auto& code = storageClass != spv::StorageClassFunction auto& code = storageClass != spv::StorageClassFunction
? m_variables : m_code; ? 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( void addEntryPoint(
uint32_t entryPointId, uint32_t entryPointId,
spv::ExecutionModel executionModel, spv::ExecutionModel executionModel,
const char* name, const char* name);
uint32_t interfaceCount,
const uint32_t* interfaceIds);
void setMemoryModel( void setMemoryModel(
spv::AddressingModel addressModel, spv::AddressingModel addressModel,
@ -1255,7 +1253,9 @@ namespace dxvk {
SpirvCodeBuffer m_code; SpirvCodeBuffer m_code;
std::unordered_set<uint32_t> m_lateConsts; std::unordered_set<uint32_t> m_lateConsts;
std::vector<uint32_t> m_interfaceVars;
uint32_t defType( uint32_t defType(
spv::Op op, spv::Op op,
uint32_t argCount, uint32_t argCount,
@ -1274,7 +1274,10 @@ namespace dxvk {
void putImageOperands( void putImageOperands(
const SpirvImageOperands& op); const SpirvImageOperands& op);
bool isInterfaceVar(
spv::StorageClass sclass) const;
}; };
} }