diff --git a/src/graphics/shader/recompiler/ir/passes/ResourceTracking.cpp b/src/graphics/shader/recompiler/ir/passes/ResourceTracking.cpp index b21361b22..677e9a5ca 100644 --- a/src/graphics/shader/recompiler/ir/passes/ResourceTracking.cpp +++ b/src/graphics/shader/recompiler/ir/passes/ResourceTracking.cpp @@ -4047,18 +4047,18 @@ UniformFillPlan RecognizePatternFill(Program& program, const Decoder::Program& d struct Pattern { size_t code_words; uint64_t hash; - uint32_t wave_size; + uint32_t wave_size_mask; bool bounded; }; constexpr std::array patterns { // Bounded 64-lane variant. - Pattern {.code_words = 69, .hash = 0x0704b9818e3cba06ull, .wave_size = 64, .bounded = true}, + Pattern {.code_words = 69, .hash = 0x0704b9818e3cba06ull, .wave_size_mask = 64, .bounded = true}, // Dispatch thread dimensions, 64-lane variants. - Pattern {.code_words = 42, .hash = 0x92ce57f21310ef02ull, .wave_size = 64, .bounded = false}, - Pattern {.code_words = 40, .hash = 0x374161027f58bee7ull, .wave_size = 64, .bounded = false}, - Pattern {.code_words = 40, .hash = 0x7d7172c56c2e296dull, .wave_size = 64, .bounded = false}, - // Dispatch thread dimensions, 32-lane variant. - Pattern {.code_words = 38, .hash = 0xacbda1a1ccdd4198ull, .wave_size = 32, .bounded = false}, + Pattern {.code_words = 42, .hash = 0x92ce57f21310ef02ull, .wave_size_mask = 64, .bounded = false}, + Pattern {.code_words = 40, .hash = 0x374161027f58bee7ull, .wave_size_mask = 64, .bounded = false}, + Pattern {.code_words = 40, .hash = 0x7d7172c56c2e296dull, .wave_size_mask = 64, .bounded = false}, + // Dispatch thread dimensions, valid in both wave sizes. + Pattern {.code_words = 38, .hash = 0xacbda1a1ccdd4198ull, .wave_size_mask = 32 | 64, .bounded = false}, }; if (program.stage != ShaderType::Compute || input.compute == nullptr || decoded.instructions.empty() || program.user_data_base != 0 || program.user_data_count < 10 || @@ -4078,7 +4078,7 @@ UniformFillPlan RecognizePatternFill(Program& program, const Decoder::Program& d const auto pattern = std::ranges::find_if(patterns, [&](const Pattern& candidate) { return candidate.code_words == words && candidate.hash == hash; }); - if (pattern == patterns.end() || program.wave_size != pattern->wave_size || + if (pattern == patterns.end() || (program.wave_size & pattern->wave_size_mask) == 0 || cs.dispatch_thread_dimensions != !pattern->bounded) return {}; std::array userdata; for (auto* block: program.blocks) { diff --git a/tests/shaderCfgTests.cpp b/tests/shaderCfgTests.cpp index 53810c31f..8f351f584 100644 --- a/tests/shaderCfgTests.cpp +++ b/tests/shaderCfgTests.cpp @@ -14508,6 +14508,7 @@ void TestPatternFill() { const PatternCase cases[] = { {bounded_shader, 64, true, 10}, {thread_dimension_shader, 32, false, 8}, + {thread_dimension_shader, 64, false, 8}, {thread_dimension_wave64_shader, 64, false, 9}, {thread_dimension_wave64_scalar_shader, 64, false, 8}, {thread_dimension_wave64_vector_shader, 64, false, 8}, @@ -14584,6 +14585,8 @@ void TestPatternFill() { Check(Build(changed).uniform_fill.fill.kind == UniformFillKind::None, "pattern recognition accepted modified executable instructions"); for (const uint32_t invalid_input : {0u, 1u, 2u, 3u}) { + // Both wave sizes are covered above for this executable. + if (invalid_input == 1 && shader.data() == thread_dimension_shader) continue; const auto saved_compute = compute; const auto saved_wave = options.wave_size; if (invalid_input == 0) compute.workgroup_register = 11;