From 4b0e26a5768ae05ee0ff34057c2642930dbb0942 Mon Sep 17 00:00:00 2001 From: Samuliak Date: Thu, 26 Jun 2025 10:42:49 +0200 Subject: [PATCH] msl: fix shader output when rasterization is disabled --- .../LatteDecompilerEmitMSL.cpp | 29 ++++++++++++++----- .../LatteDecompilerEmitMSLHeader.hpp | 16 +++++----- 2 files changed, 29 insertions(+), 16 deletions(-) diff --git a/src/Cafe/HW/Latte/LegacyShaderDecompiler/LatteDecompilerEmitMSL.cpp b/src/Cafe/HW/Latte/LegacyShaderDecompiler/LatteDecompilerEmitMSL.cpp index 93377478..cb512308 100644 --- a/src/Cafe/HW/Latte/LegacyShaderDecompiler/LatteDecompilerEmitMSL.cpp +++ b/src/Cafe/HW/Latte/LegacyShaderDecompiler/LatteDecompilerEmitMSL.cpp @@ -3184,6 +3184,12 @@ static void _emitExportCode(LatteDecompilerShaderContext* shaderContext, LatteDe src->add("// export" _CRLF); if(shaderContext->shaderType == LatteConst::ShaderType::Vertex ) { + if (!shaderContext->contextRegistersNew->IsRasterizationEnabled()) + { + src->add("// Rasterization disabled" _CRLF); + return; + } + if( cfInstruction->exportBurstCount != 0 ) debugBreakpoint(); if (cfInstruction->exportType == 1 && cfInstruction->exportArrayBase == GPU7_DECOMPILER_CF_EXPORT_BASE_POSITION) @@ -3409,6 +3415,12 @@ static void _emitCFRingWriteCode(LatteDecompilerShaderContext* shaderContext, La if (shaderContext->shaderType == LatteConst::ShaderType::Vertex) { + if (!shaderContext->contextRegistersNew->IsRasterizationEnabled()) + { + src->add("// Rasterization disabled" _CRLF); + return; + } + if (cfInstruction->memWriteElemSize != 3) cemu_assert_unimplemented(); if ((cfInstruction->exportArrayBase & 3) != 0) @@ -4104,7 +4116,7 @@ void LatteDecompiler_emitMSLShader(LatteDecompilerShaderContext* shaderContext, { functionType = "vertex"; if (shaderContext->contextRegistersNew->IsRasterizationEnabled()) - outputTypeName = "Out"; + outputTypeName = "VertexOut"; else outputTypeName = "void"; } @@ -4115,7 +4127,7 @@ void LatteDecompiler_emitMSLShader(LatteDecompilerShaderContext* shaderContext, break; case LatteConst::ShaderType::Pixel: functionType = "fragment"; - outputTypeName = "Out"; + outputTypeName = "FragmentOut"; break; } // start of main @@ -4141,26 +4153,27 @@ void LatteDecompiler_emitMSLShader(LatteDecompilerShaderContext* shaderContext, src->add("VertexIn in = fetchVertex(vid, iid, indexBuffer, indexType VERTEX_BUFFERS);" _CRLF); // Output is defined as object payload - src->add("object_data Out& out = objectPayload.vertexOut[tid];" _CRLF); + src->add("object_data VertexOut& out = objectPayload.vertexOut[tid];" _CRLF); } else { // Fetch the input src->add("VertexIn in = fetchVertex(vid, iid VERTEX_BUFFERS);" _CRLF); - src->add("Out out;" _CRLF); } } else if (shader->shaderType == LatteConst::ShaderType::Geometry) { - src->add("Out out;" _CRLF); + src->add("GeometryOut out;" _CRLF); // The index of the current vertex that is being emitted src->add("uint vertexIndex = 0;" _CRLF); } } - else + + if (shader->shaderType == LatteConst::ShaderType::Pixel || (shaderContext->contextRegistersNew->IsRasterizationEnabled() && !usesGeometryShader)) { - src->addFmt("Out out;" _CRLF); + src->addFmt("{} out;" _CRLF, outputTypeName); } + // variable definition if (shaderContext->typeTracker.useArrayGPRs == false) { @@ -4383,7 +4396,7 @@ void LatteDecompiler_emitMSLShader(LatteDecompilerShaderContext* shaderContext, // vertex shader should write renderstate point size at the end if required but not modified by shader if (shaderContext->analyzer.outputPointSize && !shaderContext->analyzer.writesPointSize) { - if (shader->shaderType == LatteConst::ShaderType::Vertex && !shaderContext->options->usesGeometryShader) + if (shader->shaderType == LatteConst::ShaderType::Vertex && !shaderContext->options->usesGeometryShader && shaderContext->contextRegistersNew->IsRasterizationEnabled()) src->add("out.pointSize = supportBuffer.pointSize;" _CRLF); } diff --git a/src/Cafe/HW/Latte/LegacyShaderDecompiler/LatteDecompilerEmitMSLHeader.hpp b/src/Cafe/HW/Latte/LegacyShaderDecompiler/LatteDecompilerEmitMSLHeader.hpp index 8cab7dc1..f61abcb1 100644 --- a/src/Cafe/HW/Latte/LegacyShaderDecompiler/LatteDecompilerEmitMSLHeader.hpp +++ b/src/Cafe/HW/Latte/LegacyShaderDecompiler/LatteDecompilerEmitMSLHeader.hpp @@ -179,7 +179,7 @@ namespace LatteDecompiler { auto* src = shaderContext->shaderSource; - src->add("struct Out {" _CRLF); + src->add("struct VertexOut {" _CRLF); src->add("float4 position [[position]] [[invariant]];" _CRLF); if (shaderContext->analyzer.outputPointSize) src->add("float pointSize [[point_size]];" _CRLF); @@ -239,7 +239,7 @@ namespace LatteDecompiler if (isRectVertexShader) { src->add("struct ObjectPayload {" _CRLF); - src->add("Out vertexOut[VERTICES_PER_VERTEX_PRIMITIVE];" _CRLF); + src->add("VertexOut vertexOut[VERTICES_PER_VERTEX_PRIMITIVE];" _CRLF); src->add("};" _CRLF _CRLF); } } @@ -282,7 +282,7 @@ namespace LatteDecompiler { _emitPSInputs(decompilerContext); - src->add("struct Out {" _CRLF); + src->add("struct FragmentOut {" _CRLF); // generate pixel outputs for pixel shader for (uint32 i = 0; i < LATTE_NUM_COLOR_TARGET; i++) @@ -306,14 +306,14 @@ namespace LatteDecompiler if (!usesGeometryShader || isRectVertexShader) { - if (decompilerContext->shaderType == LatteConst::ShaderType::Vertex) + if (decompilerContext->shaderType == LatteConst::ShaderType::Vertex && decompilerContext->contextRegistersNew->IsRasterizationEnabled()) _emitVSOutputs(decompilerContext, isRectVertexShader); } else { if (decompilerContext->shaderType == LatteConst::ShaderType::Vertex || decompilerContext->shaderType == LatteConst::ShaderType::Geometry) { - src->add("struct Out {" _CRLF); + src->add("struct VertexOut {" _CRLF); uint32 ringParameterCountVS2GS = 0; if (decompilerContext->shaderType == LatteConst::ShaderType::Vertex) { @@ -327,7 +327,7 @@ namespace LatteDecompiler src->addFmt("int4 passParameterSem{};" _CRLF, f); src->add("};" _CRLF _CRLF); src->add("struct ObjectPayload {" _CRLF); - src->add("Out vertexOut[VERTICES_PER_VERTEX_PRIMITIVE];" _CRLF); + src->add("VertexOut vertexOut[VERTICES_PER_VERTEX_PRIMITIVE];" _CRLF); src->add("};" _CRLF _CRLF); } if (decompilerContext->shaderType == LatteConst::ShaderType::Geometry) @@ -339,7 +339,7 @@ namespace LatteDecompiler if (((decompilerContext->contextRegisters[mmSQ_GSVS_RING_ITEMSIZE] & 0x7FFF) & 0xF) != 0) debugBreakpoint(); - src->add("struct Out {" _CRLF); + src->add("struct GeometryOut {" _CRLF); src->add("float4 position [[position]];" _CRLF); for (sint32 p = 0; p < decompilerContext->parsedGSCopyShader->numParam; p++) { @@ -352,7 +352,7 @@ namespace LatteDecompiler const uint32 MAX_VERTEX_COUNT = 32; // Define the mesh shader output type - src->addFmt("using MeshType = mesh;" _CRLF, MAX_VERTEX_COUNT, MAX_VERTEX_COUNT); + src->addFmt("using MeshType = mesh;" _CRLF, MAX_VERTEX_COUNT, MAX_VERTEX_COUNT); } } }