From 7d7267cc5699e3207d97d99f62af4d24c0d7f623 Mon Sep 17 00:00:00 2001 From: nmzik Date: Wed, 23 Sep 2026 20:39:46 +0400 Subject: [PATCH] Translate NGG mesh prolog with guest wave32 width --- .../recompiler/frontend/translate/Translate.cpp | 17 ++++++++++------- tests/shaderCfgTests.cpp | 6 +++++- 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/src/graphics/shader/recompiler/frontend/translate/Translate.cpp b/src/graphics/shader/recompiler/frontend/translate/Translate.cpp index 58622cc79..b180094a3 100644 --- a/src/graphics/shader/recompiler/frontend/translate/Translate.cpp +++ b/src/graphics/shader/recompiler/frontend/translate/Translate.cpp @@ -1063,8 +1063,8 @@ IR::Program TranslateProgram(const Decoder::Program& decoded, const CFG::Graph& } } else if (options.stage == ShaderType::Mesh) { const auto& mesh = options.input_info.vertex->mesh; - EXIT_NOT_IMPLEMENTED(options.wave_size != 64u || mesh.primitives_per_group == 0u || - mesh.vertices_per_group > 64u || total_threads > 15u * 64u); + EXIT_NOT_IMPLEMENTED(mesh.primitives_per_group == 0u || mesh.vertices_per_group > 64u || + total_threads > 15u * options.wave_size); const auto u32 = [](uint32_t value) { return IR::U32(IR::Value(value)); }; const auto draw = [&](uint32_t index) { return IR::U32( @@ -1089,12 +1089,15 @@ IR::Program TranslateProgram(const Decoder::Program& decoded, const CFG::Graph& entry_ir.IAdd(IR::U32(entry_ir.Emit(IR::ValueOpcode::UDiv32, {subtract_saturate(vertices, size), step})), u32(1))); - const auto wave = entry_ir.ShiftRightLogical(local, u32(6)); - const auto wave_base = entry_ir.BitwiseAnd(local, u32(~63u)); - const auto vertex_count = minimum(subtract_saturate(vertices, wave_base), u32(64)); - const auto primitive_count = minimum(subtract_saturate(primitives, wave_base), u32(64)); + const auto wave = entry_ir.ShiftRightLogical(local, u32(options.wave_size == 32u ? 5u : 6u)); + const auto wave_base = entry_ir.BitwiseAnd(local, u32(~(options.wave_size - 1u))); + const auto vertex_count = + minimum(subtract_saturate(vertices, wave_base), u32(options.wave_size)); + const auto primitive_count = + minimum(subtract_saturate(primitives, wave_base), u32(options.wave_size)); const auto wave_info = entry_ir.BitwiseOr(entry_ir.ShiftLeftLogical(wave, u32(24)), - u32(((total_threads + 63u) / 64u) << 28u)); + u32(((total_threads + options.wave_size - 1u) / + options.wave_size) << 28u)); entry_ir.SetScalarReg( static_cast(3), entry_ir.BitwiseOr(wave_info, entry_ir.BitwiseOr(entry_ir.ShiftLeftLogical( diff --git a/tests/shaderCfgTests.cpp b/tests/shaderCfgTests.cpp index d80e2c191..b71499546 100644 --- a/tests/shaderCfgTests.cpp +++ b/tests/shaderCfgTests.cpp @@ -9885,6 +9885,7 @@ void TestMeshInputAssembly() { uint32_t capacity, count, group, lane, width, address_low, base_vertex; uint32_t wave_info, first, second, third, byte_offset, vertex_id; bool fetch; + uint32_t wave_size = 64; }; const Case cases[] = { {Prospero::PrimitiveType::kTriList, 14, 177, 14, 2, 2, 0x1002, UINT32_MAX, @@ -9931,11 +9932,14 @@ void TestMeshInputAssembly() { 0x40000c0c, 1, 0, 0, 52, 0xabcd0128, true}, {Prospero::PrimitiveType::kPointList, 12, 265, 1, 64, 4, 0x1000, 0, 0x41000000, 64, 0, 0, 304, 0, false}, + {Prospero::PrimitiveType::kTriStrip, 40, 40, 0, 32, 0, 0, 11, + 0x81000608, 32, 33, 34, 0, 43, false, 32}, }; for (const auto &test : cases) { ShaderVertexInputInfo input{}; auto &mesh = input.mesh; mesh.input_primitive = static_cast(test.topology); + mesh.wave_size = test.wave_size; mesh.primitives_per_group = mesh.InputPrimitiveCount(test.capacity); mesh.vertices_per_group = mesh.InputVertexCount(mesh.primitives_per_group); mesh.threads_num[0] = 256; @@ -9949,7 +9953,7 @@ void TestMeshInputAssembly() { graph.entry_block = 0; Frontend::TranslateOptions options{}; options.stage = ShaderType::Mesh; - options.wave_size = 64; + options.wave_size = test.wave_size; options.user_data_count = 0; options.input_info.vertex = &input; auto program = Frontend::TranslateProgram(decoded, graph, options);