diff --git a/src/graphics/shader/recompiler/Tessellation.cpp b/src/graphics/shader/recompiler/Tessellation.cpp index 863c2f859..2400ae031 100644 --- a/src/graphics/shader/recompiler/Tessellation.cpp +++ b/src/graphics/shader/recompiler/Tessellation.cpp @@ -156,11 +156,14 @@ void ReflectTessellationLayout(const Decoder::Program& program, bool local, if (rhs.constant == 0u && third.constant == 8u) value = constant(0u); } break; - case Opcode::V_AND_B32: - if ((lhs.kind == Kind::PackedControlPoint && rhs == constant(0xffu)) || - (rhs.kind == Kind::PackedControlPoint && lhs == constant(0xffu))) - value = constant(0u); + case Opcode::V_AND_B32: { + const auto mask = lhs.kind == Kind::PackedControlPoint ? rhs + : rhs.kind == Kind::PackedControlPoint ? lhs + : Address {}; + if (mask == constant(0xffu)) value = constant(0u); + if (mask == constant(0x1f00u)) value = {Kind::Affine, 256u, 0u}; break; + } case Opcode::V_ADD_NC_U32: value = add(lhs, rhs); break; case Opcode::V_MUL_LO_U32: value = multiply(lhs, rhs); break; case Opcode::V_MUL_U32_U24: value = multiply(low24(lhs), low24(rhs)); break; diff --git a/tests/ShaderRecompilerComputeTests.cpp b/tests/ShaderRecompilerComputeTests.cpp index f73329078..d66a79569 100644 --- a/tests/ShaderRecompilerComputeTests.cpp +++ b/tests/ShaderRecompilerComputeTests.cpp @@ -47230,8 +47230,15 @@ void CheckTessellationProgram(const char *name, u32 ls_stride, u32 hs_stride, u3 control.push_back(EncodeSopk(0x00, 106, control_points * hs_stride)); control.push_back(EncodeVop2(0x0b, 2, 249u, 1)); control.push_back(EncodeVop2Sdwa(106, 6, 0, 6, 0, 0, 0, 0, 0, 0, 0, 1)); - AppendVop3(&control, 0x346, output_address, Vgpr(control_point), InlineU32(7), - Vgpr(2)); + if (hs_stride == 256) { + // Keep the packed control-point field in place: bits 12:8 give a 256-byte stride. + control.push_back(EncodeVop2(0x1b, output_address, 255u, 1)); + control.push_back(0x1f00u); + control.push_back(EncodeVop2(0x25, output_address, Vgpr(output_address), 2)); + } else { + AppendVop3(&control, 0x346, output_address, Vgpr(control_point), InlineU32(7), + Vgpr(2)); + } control.push_back(EncodeVop2(0x0b, input_address, 255u, control_point)); control.push_back(ls_stride); } @@ -47513,6 +47520,7 @@ void CheckTessellationPrograms() { CheckTessellationProgram("TessellationShiftedStride", 124, 128); CheckTessellationProgram("TessellationMultipliedStride", 108, 112); CheckTessellationProgram("TessellationQuadFactors", 36, 128, 2); + CheckTessellationProgram("TessellationMaskedControlPoint", 32, 256, 2); CheckTessellationPatchConstants(); }