From 320534cb342d74897e5457f23dd26119432dba79 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Fri, 15 Jul 2022 14:42:55 +0200 Subject: [PATCH] [spirv] Automatically track interface variables --- src/d3d9/d3d9_fixed_function.cpp | 13 +++---------- src/d3d9/d3d9_fixed_function.h | 2 +- src/d3d9/d3d9_swvp_emu.cpp | 8 +------- src/dxbc/dxbc_compiler.cpp | 21 ++------------------- src/dxbc/dxbc_compiler.h | 1 - src/dxso/dxso_compiler.cpp | 16 ++-------------- src/dxso/dxso_compiler.h | 1 - src/spirv/spirv_module.cpp | 30 +++++++++++++++++++++++------- src/spirv/spirv_module.h | 13 ++++++++----- 9 files changed, 40 insertions(+), 65 deletions(-) diff --git a/src/d3d9/d3d9_fixed_function.cpp b/src/d3d9/d3d9_fixed_function.cpp index 62073c6a8..69198eace 100644 --- a/src/d3d9/d3d9_fixed_function.cpp +++ b/src/d3d9/d3d9_fixed_function.cpp @@ -343,7 +343,7 @@ namespace dxvk { } - uint32_t GetPointCoord(SpirvModule& spvModule, std::vector& 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 m_bindings; - std::vector 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++) { diff --git a/src/d3d9/d3d9_fixed_function.h b/src/d3d9/d3d9_fixed_function.h index 8e312aa2d..3c0158c75 100644 --- a/src/d3d9/d3d9_fixed_function.h +++ b/src/d3d9/d3d9_fixed_function.h @@ -64,7 +64,7 @@ namespace dxvk { D3D9PointSizeInfoPS GetPointSizeInfoPS(SpirvModule& spvModule, uint32_t rsBlock); - uint32_t GetPointCoord(SpirvModule& spvModule, std::vector& entryPointInterfaces); + uint32_t GetPointCoord(SpirvModule& spvModule); uint32_t GetSharedConstants(SpirvModule& spvModule); diff --git a/src/d3d9/d3d9_swvp_emu.cpp b/src/d3d9/d3d9_swvp_emu.cpp index f02d4a20e..4c5eeaddb 100644 --- a/src/d3d9/d3d9_swvp_emu.cpp +++ b/src/d3d9/d3d9_swvp_emu.cpp @@ -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 m_entryPointInterfaces; uint32_t m_entryPointId = 0; uint32_t m_inputMask = 0u; DxvkBindingInfo m_bufferBinding; diff --git a/src/dxbc/dxbc_compiler.cpp b/src/dxbc/dxbc_compiler.cpp index 8e9d49cf8..045da8d97 100644 --- a/src/dxbc/dxbc_compiler.cpp +++ b/src/dxbc/dxbc_compiler.cpp @@ -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; } diff --git a/src/dxbc/dxbc_compiler.h b/src/dxbc/dxbc_compiler.h index af2d00e8e..65c331f16 100644 --- a/src/dxbc/dxbc_compiler.h +++ b/src/dxbc/dxbc_compiler.h @@ -517,7 +517,6 @@ namespace dxvk { /////////////////////////////////////////////////// // Entry point description - we'll need to declare // the function ID and all input/output variables. - std::vector m_entryPointInterfaces; uint32_t m_entryPointId = 0; //////////////////////////////////////////// diff --git a/src/dxso/dxso_compiler.cpp b/src/dxso/dxso_compiler.cpp index 1b2413fc5..b17c4c556 100644 --- a/src/dxso/dxso_compiler.cpp +++ b/src/dxso/dxso_compiler.cpp @@ -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); diff --git a/src/dxso/dxso_compiler.h b/src/dxso/dxso_compiler.h index 1d1699d60..93ee78fc5 100644 --- a/src/dxso/dxso_compiler.h +++ b/src/dxso/dxso_compiler.h @@ -348,7 +348,6 @@ namespace dxvk { /////////////////////////////////////////////////// // Entry point description - we'll need to declare // the function ID and all input/output variables. - std::vector m_entryPointInterfaces; uint32_t m_entryPointId = 0; //////////////////////////////////////////// diff --git a/src/spirv/spirv_module.cpp b/src/spirv/spirv_module.cpp index 7811bae9a..f107f7f27 100644 --- a/src/spirv/spirv_module.cpp +++ b/src/spirv/spirv_module.cpp @@ -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; + } + } + } \ No newline at end of file diff --git a/src/spirv/spirv_module.h b/src/spirv/spirv_module.h index 7ce5b8f15..e9be24d6f 100644 --- a/src/spirv/spirv_module.h +++ b/src/spirv/spirv_module.h @@ -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 m_lateConsts; - + + std::vector 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; + }; } \ No newline at end of file