retrieve ps input table without using global variable

This commit is contained in:
Samuliak 2024-10-19 15:32:45 +02:00
parent 295a6ed9fd
commit 1750715791
No known key found for this signature in database
4 changed files with 52 additions and 54 deletions

View File

@ -209,11 +209,9 @@ void LatteShader_free(LatteDecompilerShader* shader)
delete shader; delete shader;
} }
// both vertex and geometry/pixel shader depend on PS inputs void LatteShader_CreatePSInputTable(LatteShaderPSInputTable* psInputTable, uint32* contextRegisters)
// we prepare the PS import info in advance
void LatteShader_UpdatePSInputs(uint32* contextRegisters)
{ {
// PS control // PS control
uint32 psControl0 = contextRegisters[mmSPI_PS_IN_CONTROL_0]; uint32 psControl0 = contextRegisters[mmSPI_PS_IN_CONTROL_0];
uint32 spi0_positionEnable = (psControl0 >> 8) & 1; uint32 spi0_positionEnable = (psControl0 >> 8) & 1;
uint32 spi0_positionCentroid = (psControl0 >> 9) & 1; uint32 spi0_positionCentroid = (psControl0 >> 9) & 1;
@ -242,12 +240,12 @@ void LatteShader_UpdatePSInputs(uint32* contextRegisters)
{ {
key += std::rotr<uint64>(spi0_paramGen, 7); key += std::rotr<uint64>(spi0_paramGen, 7);
key += std::rotr<uint64>(spi0_paramGenAddr, 3); key += std::rotr<uint64>(spi0_paramGenAddr, 3);
_activePSImportTable.paramGen = spi0_paramGen; psInputTable->paramGen = spi0_paramGen;
_activePSImportTable.paramGenGPR = spi0_paramGenAddr; psInputTable->paramGenGPR = spi0_paramGenAddr;
} }
else else
{ {
_activePSImportTable.paramGen = 0; psInputTable->paramGen = 0;
} }
// semantic imports from vertex shader // semantic imports from vertex shader
@ -281,9 +279,9 @@ void LatteShader_UpdatePSInputs(uint32* contextRegisters)
key = std::rotl<uint64>(key, 7); key = std::rotl<uint64>(key, 7);
if (spi0_positionEnable && f == spi0_positionAddr) if (spi0_positionEnable && f == spi0_positionAddr)
{ {
_activePSImportTable.import[f].semanticId = LATTE_ANALYZER_IMPORT_INDEX_SPIPOSITION; psInputTable->import[f].semanticId = LATTE_ANALYZER_IMPORT_INDEX_SPIPOSITION;
_activePSImportTable.import[f].isFlat = false; psInputTable->import[f].isFlat = false;
_activePSImportTable.import[f].isNoPerspective = false; psInputTable->import[f].isNoPerspective = false;
key += (uint64)0x33; key += (uint64)0x33;
} }
else else
@ -296,13 +294,20 @@ void LatteShader_UpdatePSInputs(uint32* contextRegisters)
semanticMask[psSemanticId >> 3] |= (1 << (psSemanticId & 7)); semanticMask[psSemanticId >> 3] |= (1 << (psSemanticId & 7));
#endif #endif
_activePSImportTable.import[f].semanticId = psSemanticId; psInputTable->import[f].semanticId = psSemanticId;
_activePSImportTable.import[f].isFlat = (psInputControl&(1 << 10)) != 0; psInputTable->import[f].isFlat = (psInputControl&(1 << 10)) != 0;
_activePSImportTable.import[f].isNoPerspective = (psInputControl&(1 << 12)) != 0; psInputTable->import[f].isNoPerspective = (psInputControl&(1 << 12)) != 0;
} }
} }
_activePSImportTable.key = key; psInputTable->key = key;
_activePSImportTable.count = numPSInputs; psInputTable->count = numPSInputs;
}
// both vertex and geometry/pixel shader depend on PS inputs
// we prepare the PS import info in advance
void LatteShader_UpdatePSInputs(uint32* contextRegisters)
{
LatteShader_CreatePSInputTable(&_activePSImportTable, contextRegisters);
} }
void LatteShader_CreateRendererShader(LatteDecompilerShader* shader, bool compileAsync) void LatteShader_CreateRendererShader(LatteDecompilerShader* shader, bool compileAsync)

View File

@ -84,6 +84,7 @@ struct LatteShaderPSInputTable
} }
}; };
void LatteShader_CreatePSInputTable(LatteShaderPSInputTable* psInputTable, uint32* contextRegisters);
void LatteShader_UpdatePSInputs(uint32* contextRegisters); void LatteShader_UpdatePSInputs(uint32* contextRegisters);
LatteShaderPSInputTable* LatteSHRC_GetPSInputTable(); LatteShaderPSInputTable* LatteSHRC_GetPSInputTable();
@ -126,4 +127,4 @@ void LatteShaderCache_writeSeparableGeometryShader(uint64 shaderBaseHash, uint64
void LatteShaderCache_writeSeparablePixelShader(uint64 shaderBaseHash, uint64 shaderAuxHash, uint8* pixelShader, uint32 pixelShaderSize, uint32* contextRegisters, bool usesGeometryShader); void LatteShaderCache_writeSeparablePixelShader(uint64 shaderBaseHash, uint64 shaderAuxHash, uint8* pixelShader, uint32 pixelShaderSize, uint32* contextRegisters, bool usesGeometryShader);
// todo - refactor this // todo - refactor this
sint32 LatteDecompiler_getTextureSamplerBaseIndex(LatteConst::ShaderType shaderType); sint32 LatteDecompiler_getTextureSamplerBaseIndex(LatteConst::ShaderType shaderType);

View File

@ -54,7 +54,7 @@ MTL::RenderPipelineState* MetalPipelineCache::GetRenderPipelineState(const Latte
MTL::RenderPipelineState* pipeline = compiler.Compile(false, true, true, attemptedCompilation); MTL::RenderPipelineState* pipeline = compiler.Compile(false, true, true, attemptedCompilation);
// If FBOs don't match, it wouldn't be possible to reconstruct the pipeline from the cache // If FBOs don't match, it wouldn't be possible to reconstruct the pipeline from the cache
if (fbosMatch) if (pipeline && fbosMatch)
AddCurrentStateToCache(hash); AddCurrentStateToCache(hash);
// Place the pipeline to the cache if the compilation was at least attempted // Place the pipeline to the cache if the compilation was at least attempted
@ -360,9 +360,6 @@ void MetalPipelineCache::LoadPipelineFromCache(std::span<uint8> fileData)
MetalAttachmentsInfo attachmentsInfo(*lcr, pixelShader); MetalAttachmentsInfo attachmentsInfo(*lcr, pixelShader);
// TODO: this shouldn't probably be called directly
LatteShader_UpdatePSInputs(lcr->GetRawView());
MTL::RenderPipelineState* pipeline = nullptr; MTL::RenderPipelineState* pipeline = nullptr;
// compile // compile
{ {

View File

@ -17,18 +17,18 @@ extern std::atomic_int g_compiling_pipelines;
extern std::atomic_int g_compiling_pipelines_async; extern std::atomic_int g_compiling_pipelines_async;
extern std::atomic_uint64_t g_compiling_pipelines_syncTimeSum; extern std::atomic_uint64_t g_compiling_pipelines_syncTimeSum;
static void rectsEmulationGS_outputSingleVertex(std::string& gsSrc, const LatteDecompilerShader* vertexShader, LatteShaderPSInputTable* psInputTable, sint32 vIdx, const LatteContextRegister& latteRegister) static void rectsEmulationGS_outputSingleVertex(std::string& gsSrc, const LatteDecompilerShader* vertexShader, LatteShaderPSInputTable& psInputTable, sint32 vIdx, const LatteContextRegister& latteRegister)
{ {
auto parameterMask = vertexShader->outputParameterMask; auto parameterMask = vertexShader->outputParameterMask;
for (uint32 i = 0; i < 32; i++) for (uint32 i = 0; i < 32; i++)
{ {
if ((parameterMask & (1 << i)) == 0) if ((parameterMask & (1 << i)) == 0)
continue; continue;
sint32 vsSemanticId = psInputTable->getVertexShaderOutParamSemanticId(latteRegister.GetRawView(), i); sint32 vsSemanticId = psInputTable.getVertexShaderOutParamSemanticId(latteRegister.GetRawView(), i);
if (vsSemanticId < 0) if (vsSemanticId < 0)
continue; continue;
// make sure PS has matching input // make sure PS has matching input
if (!psInputTable->hasPSImportForSemanticId(vsSemanticId)) if (!psInputTable.hasPSImportForSemanticId(vsSemanticId))
continue; continue;
gsSrc.append(fmt::format("out.passParameterSem{} = objectPayload.vertexOut[{}].passParameterSem{};\r\n", vsSemanticId, vIdx, vsSemanticId)); gsSrc.append(fmt::format("out.passParameterSem{} = objectPayload.vertexOut[{}].passParameterSem{};\r\n", vsSemanticId, vIdx, vsSemanticId));
} }
@ -36,18 +36,18 @@ static void rectsEmulationGS_outputSingleVertex(std::string& gsSrc, const LatteD
gsSrc.append(fmt::format("mesh.set_vertex({}, out);\r\n", vIdx)); gsSrc.append(fmt::format("mesh.set_vertex({}, out);\r\n", vIdx));
} }
static void rectsEmulationGS_outputGeneratedVertex(std::string& gsSrc, const LatteDecompilerShader* vertexShader, LatteShaderPSInputTable* psInputTable, const char* variant, const LatteContextRegister& latteRegister) static void rectsEmulationGS_outputGeneratedVertex(std::string& gsSrc, const LatteDecompilerShader* vertexShader, LatteShaderPSInputTable& psInputTable, const char* variant, const LatteContextRegister& latteRegister)
{ {
auto parameterMask = vertexShader->outputParameterMask; auto parameterMask = vertexShader->outputParameterMask;
for (uint32 i = 0; i < 32; i++) for (uint32 i = 0; i < 32; i++)
{ {
if ((parameterMask & (1 << i)) == 0) if ((parameterMask & (1 << i)) == 0)
continue; continue;
sint32 vsSemanticId = psInputTable->getVertexShaderOutParamSemanticId(latteRegister.GetRawView(), i); sint32 vsSemanticId = psInputTable.getVertexShaderOutParamSemanticId(latteRegister.GetRawView(), i);
if (vsSemanticId < 0) if (vsSemanticId < 0)
continue; continue;
// make sure PS has matching input // make sure PS has matching input
if (!psInputTable->hasPSImportForSemanticId(vsSemanticId)) if (!psInputTable.hasPSImportForSemanticId(vsSemanticId))
continue; continue;
gsSrc.append(fmt::format("out.passParameterSem{} = gen4thVertex{}(objectPayload.vertexOut[0].passParameterSem{}, objectPayload.vertexOut[1].passParameterSem{}, objectPayload.vertexOut[2].passParameterSem{});\r\n", vsSemanticId, variant, vsSemanticId, vsSemanticId, vsSemanticId)); gsSrc.append(fmt::format("out.passParameterSem{} = gen4thVertex{}(objectPayload.vertexOut[0].passParameterSem{}, objectPayload.vertexOut[1].passParameterSem{}, objectPayload.vertexOut[2].passParameterSem{});\r\n", vsSemanticId, variant, vsSemanticId, vsSemanticId, vsSemanticId));
} }
@ -55,7 +55,7 @@ static void rectsEmulationGS_outputGeneratedVertex(std::string& gsSrc, const Lat
gsSrc.append(fmt::format("mesh.set_vertex(3, out);\r\n")); gsSrc.append(fmt::format("mesh.set_vertex(3, out);\r\n"));
} }
static void rectsEmulationGS_outputVerticesCode(std::string& gsSrc, const LatteDecompilerShader* vertexShader, LatteShaderPSInputTable* psInputTable, sint32 p0, sint32 p1, sint32 p2, sint32 p3, const char* variant, const LatteContextRegister& latteRegister) static void rectsEmulationGS_outputVerticesCode(std::string& gsSrc, const LatteDecompilerShader* vertexShader, LatteShaderPSInputTable& psInputTable, sint32 p0, sint32 p1, sint32 p2, sint32 p3, const char* variant, const LatteContextRegister& latteRegister)
{ {
sint32 pList[4] = { p0, p1, p2, p3 }; sint32 pList[4] = { p0, p1, p2, p3 };
for (sint32 i = 0; i < 4; i++) for (sint32 i = 0; i < 4; i++)
@ -79,7 +79,8 @@ static RendererShaderMtl* rectsEmulationGS_generate(MetalRenderer* metalRenderer
gsSrc.append("#include <metal_stdlib>\r\n"); gsSrc.append("#include <metal_stdlib>\r\n");
gsSrc.append("using namespace metal;\r\n"); gsSrc.append("using namespace metal;\r\n");
LatteShaderPSInputTable* psInputTable = LatteSHRC_GetPSInputTable(); LatteShaderPSInputTable psInputTable;
LatteShader_CreatePSInputTable(&psInputTable, latteRegister.GetRawView());
// inputs & outputs // inputs & outputs
std::string vertexOutDefinition = "struct VertexOut {\r\n"; std::string vertexOutDefinition = "struct VertexOut {\r\n";
@ -87,35 +88,29 @@ static RendererShaderMtl* rectsEmulationGS_generate(MetalRenderer* metalRenderer
std::string geometryOutDefinition = "struct GeometryOut {\r\n"; std::string geometryOutDefinition = "struct GeometryOut {\r\n";
geometryOutDefinition += "float4 position [[position]];\r\n"; geometryOutDefinition += "float4 position [[position]];\r\n";
auto parameterMask = vertexShader->outputParameterMask; auto parameterMask = vertexShader->outputParameterMask;
for (sint32 f = 0; f < 2; f++) for (uint32 i = 0; i < 32; i++)
{ {
for (uint32 i = 0; i < 32; i++) if ((parameterMask & (1 << i)) == 0)
{ continue;
if ((parameterMask & (1 << i)) == 0) sint32 vsSemanticId = psInputTable.getVertexShaderOutParamSemanticId(latteRegister.GetRawView(), i);
continue; if (vsSemanticId < 0)
sint32 vsSemanticId = psInputTable->getVertexShaderOutParamSemanticId(latteRegister.GetRawView(), i); continue;
if (vsSemanticId < 0) auto psImport = psInputTable.getPSImportBySemanticId(vsSemanticId);
continue; if (psImport == nullptr)
auto psImport = psInputTable->getPSImportBySemanticId(vsSemanticId); continue;
if (psImport == nullptr)
continue;
if (f == 0) // VertexOut
{ vertexOutDefinition += fmt::format("float4 passParameterSem{};\r\n", vsSemanticId);
vertexOutDefinition += fmt::format("float4 passParameterSem{};\r\n", vsSemanticId);
}
else
{
geometryOutDefinition += fmt::format("float4 passParameterSem{}", vsSemanticId);
geometryOutDefinition += fmt::format(" [[user(locn{})]]", psInputTable->getPSImportLocationBySemanticId(vsSemanticId)); // GeometryOut
if (psImport->isFlat) geometryOutDefinition += fmt::format("float4 passParameterSem{}", vsSemanticId);
geometryOutDefinition += " [[flat]]";
if (psImport->isNoPerspective) geometryOutDefinition += fmt::format(" [[user(locn{})]]", psInputTable.getPSImportLocationBySemanticId(vsSemanticId));
geometryOutDefinition += " [[center_no_perspective]]"; if (psImport->isFlat)
geometryOutDefinition += ";\r\n"; geometryOutDefinition += " [[flat]]";
} if (psImport->isNoPerspective)
} geometryOutDefinition += " [[center_no_perspective]]";
geometryOutDefinition += ";\r\n";
} }
vertexOutDefinition += "};\r\n"; vertexOutDefinition += "};\r\n";
geometryOutDefinition += "};\r\n"; geometryOutDefinition += "};\r\n";