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

View File

@ -84,6 +84,7 @@ struct LatteShaderPSInputTable
}
};
void LatteShader_CreatePSInputTable(LatteShaderPSInputTable* psInputTable, uint32* contextRegisters);
void LatteShader_UpdatePSInputs(uint32* contextRegisters);
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);
// 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);
// If FBOs don't match, it wouldn't be possible to reconstruct the pipeline from the cache
if (fbosMatch)
if (pipeline && fbosMatch)
AddCurrentStateToCache(hash);
// 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);
// TODO: this shouldn't probably be called directly
LatteShader_UpdatePSInputs(lcr->GetRawView());
MTL::RenderPipelineState* pipeline = nullptr;
// 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_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;
for (uint32 i = 0; i < 32; i++)
{
if ((parameterMask & (1 << i)) == 0)
continue;
sint32 vsSemanticId = psInputTable->getVertexShaderOutParamSemanticId(latteRegister.GetRawView(), i);
sint32 vsSemanticId = psInputTable.getVertexShaderOutParamSemanticId(latteRegister.GetRawView(), i);
if (vsSemanticId < 0)
continue;
// make sure PS has matching input
if (!psInputTable->hasPSImportForSemanticId(vsSemanticId))
if (!psInputTable.hasPSImportForSemanticId(vsSemanticId))
continue;
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));
}
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;
for (uint32 i = 0; i < 32; i++)
{
if ((parameterMask & (1 << i)) == 0)
continue;
sint32 vsSemanticId = psInputTable->getVertexShaderOutParamSemanticId(latteRegister.GetRawView(), i);
sint32 vsSemanticId = psInputTable.getVertexShaderOutParamSemanticId(latteRegister.GetRawView(), i);
if (vsSemanticId < 0)
continue;
// make sure PS has matching input
if (!psInputTable->hasPSImportForSemanticId(vsSemanticId))
if (!psInputTable.hasPSImportForSemanticId(vsSemanticId))
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));
}
@ -55,7 +55,7 @@ static void rectsEmulationGS_outputGeneratedVertex(std::string& gsSrc, const Lat
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 };
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("using namespace metal;\r\n");
LatteShaderPSInputTable* psInputTable = LatteSHRC_GetPSInputTable();
LatteShaderPSInputTable psInputTable;
LatteShader_CreatePSInputTable(&psInputTable, latteRegister.GetRawView());
// inputs & outputs
std::string vertexOutDefinition = "struct VertexOut {\r\n";
@ -87,35 +88,29 @@ static RendererShaderMtl* rectsEmulationGS_generate(MetalRenderer* metalRenderer
std::string geometryOutDefinition = "struct GeometryOut {\r\n";
geometryOutDefinition += "float4 position [[position]];\r\n";
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;
sint32 vsSemanticId = psInputTable->getVertexShaderOutParamSemanticId(latteRegister.GetRawView(), i);
if (vsSemanticId < 0)
continue;
auto psImport = psInputTable->getPSImportBySemanticId(vsSemanticId);
if (psImport == nullptr)
continue;
if ((parameterMask & (1 << i)) == 0)
continue;
sint32 vsSemanticId = psInputTable.getVertexShaderOutParamSemanticId(latteRegister.GetRawView(), i);
if (vsSemanticId < 0)
continue;
auto psImport = psInputTable.getPSImportBySemanticId(vsSemanticId);
if (psImport == nullptr)
continue;
if (f == 0)
{
vertexOutDefinition += fmt::format("float4 passParameterSem{};\r\n", vsSemanticId);
}
else
{
geometryOutDefinition += fmt::format("float4 passParameterSem{}", vsSemanticId);
// VertexOut
vertexOutDefinition += fmt::format("float4 passParameterSem{};\r\n", vsSemanticId);
geometryOutDefinition += fmt::format(" [[user(locn{})]]", psInputTable->getPSImportLocationBySemanticId(vsSemanticId));
if (psImport->isFlat)
geometryOutDefinition += " [[flat]]";
if (psImport->isNoPerspective)
geometryOutDefinition += " [[center_no_perspective]]";
geometryOutDefinition += ";\r\n";
}
}
// GeometryOut
geometryOutDefinition += fmt::format("float4 passParameterSem{}", vsSemanticId);
geometryOutDefinition += fmt::format(" [[user(locn{})]]", psInputTable.getPSImportLocationBySemanticId(vsSemanticId));
if (psImport->isFlat)
geometryOutDefinition += " [[flat]]";
if (psImport->isNoPerspective)
geometryOutDefinition += " [[center_no_perspective]]";
geometryOutDefinition += ";\r\n";
}
vertexOutDefinition += "};\r\n";
geometryOutDefinition += "};\r\n";