From 5f97031df5eb3347101f897938a4be6aae6392c5 Mon Sep 17 00:00:00 2001 From: jute-ado <304153664+jute-ado@users.noreply.github.com> Date: Wed, 22 Jul 2026 13:46:15 +0200 Subject: [PATCH] shader: allow larger bounded Gen5 programs (#514) --- .../Gen5ShaderTranslator.cs | 2 +- .../Agc/Gen5ShaderDecoderBoundaryTests.cs | 20 ++++++++++++++++++- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/src/SharpEmu.ShaderCompiler/Gen5ShaderTranslator.cs b/src/SharpEmu.ShaderCompiler/Gen5ShaderTranslator.cs index 7c33629..137a8b1 100644 --- a/src/SharpEmu.ShaderCompiler/Gen5ShaderTranslator.cs +++ b/src/SharpEmu.ShaderCompiler/Gen5ShaderTranslator.cs @@ -80,7 +80,7 @@ public static class Gen5ShaderTranslator public static bool IsScalarConsumed(ulong[] mask, uint register) => register < 256 && (mask[register >> 6] & (1UL << (int)(register & 63))) != 0; - private const int MaxInstructions = 4096; + private const int MaxInstructions = 16384; private const uint PsUserDataRegister = 0x0C; private const uint VsUserDataRegister = 0x4C; private const uint GsUserDataRegister = 0x8C; diff --git a/tests/SharpEmu.Libs.Tests/Agc/Gen5ShaderDecoderBoundaryTests.cs b/tests/SharpEmu.Libs.Tests/Agc/Gen5ShaderDecoderBoundaryTests.cs index 6ad5c98..1c316bc 100644 --- a/tests/SharpEmu.Libs.Tests/Agc/Gen5ShaderDecoderBoundaryTests.cs +++ b/tests/SharpEmu.Libs.Tests/Agc/Gen5ShaderDecoderBoundaryTests.cs @@ -13,7 +13,8 @@ public sealed class Gen5ShaderDecoderBoundaryTests private const ulong ShaderAddress = 0x1_0000_0000; private const uint Export = 0xF8000000; private const uint Nop = 0xBF800000; - private const int MaximumInstructionCount = 4096; + private const uint EndPgm = 0xBF810000; + private const int MaximumInstructionCount = 16384; [Fact] public void MissingAddress_IsRejectedWithoutReadingGuestMemory() @@ -99,6 +100,23 @@ public sealed class Gen5ShaderDecoderBoundaryTests memory.Reads[^1]); } + [Fact] + public void ProgramMayEndAfterPreviousDecoderLimit() + { + const int previousDecoderLimit = 4096; + var words = new uint[previousDecoderLimit + 1]; + Array.Fill(words, Nop); + words[^1] = EndPgm; + var memory = RecordingCpuMemory.FromWords(ShaderAddress, words); + + var decoded = Decode(memory, ShaderAddress, out var program, out var error); + + Assert.True(decoded, error); + Assert.Equal(words.Length, program.Instructions.Count); + Assert.Equal("SEndpgm", program.Instructions[^1].Opcode); + Assert.Equal(words.Length, memory.Reads.Count); + } + private static bool Decode( RecordingCpuMemory memory, ulong address,