From 1d923fdd2bb3dbd26b5a2e515f981d27fd267cde Mon Sep 17 00:00:00 2001 From: Virgile Bello Date: Fri, 17 Apr 2026 17:50:56 +0900 Subject: [PATCH] microsoft/compiler, d3d12: flip tess winding at caller, not in nir_to_dxil MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit get_tessellator_output_primitive used to unconditionally invert CW<->CCW on the assumption the input was GL-origin (lower-left). That was wrong for any upper-left caller — including spirv_to_dxil, whose SPIR-V sources (DXC, glslang) already align with D3D winding. Make nir_to_dxil copy info.tess.ccw through and expect upper-left. The d3d12 gallium driver (GL) flips before the conversion to preserve its output. spirv_to_dxil and dozen (Vulkan, UPPER_LEFT default) are unchanged. Assisted-by: Claude Opus 4.7 Part-of: --- src/gallium/drivers/d3d12/d3d12_compiler.cpp | 4 +++- src/microsoft/compiler/nir_to_dxil.c | 7 ++----- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/gallium/drivers/d3d12/d3d12_compiler.cpp b/src/gallium/drivers/d3d12/d3d12_compiler.cpp index 0f4247b094b..cdefd9b6c14 100644 --- a/src/gallium/drivers/d3d12/d3d12_compiler.cpp +++ b/src/gallium/drivers/d3d12/d3d12_compiler.cpp @@ -1144,7 +1144,9 @@ select_shader_variant(struct d3d12_selection_context *sel_ctx, d3d12_shader_sele if (new_nir_variant->info.stage == MESA_SHADER_TESS_CTRL) { new_nir_variant->info.tess._primitive_mode = (tess_primitive_mode)key.hs.primitive_mode; - new_nir_variant->info.tess.ccw = key.hs.ccw; + /* GL tess domain is lower-left origin, D3D is upper-left. + * Since we invert origin, we also need to invert triangle winding. */ + new_nir_variant->info.tess.ccw = !key.hs.ccw; new_nir_variant->info.tess.point_mode = key.hs.point_mode; new_nir_variant->info.tess.spacing = key.hs.spacing; diff --git a/src/microsoft/compiler/nir_to_dxil.c b/src/microsoft/compiler/nir_to_dxil.c index 9f11158abe8..a20c7c0b878 100644 --- a/src/microsoft/compiler/nir_to_dxil.c +++ b/src/microsoft/compiler/nir_to_dxil.c @@ -1746,12 +1746,9 @@ get_tessellator_output_primitive(const struct shader_info *info) return DXIL_TESSELLATOR_OUTPUT_PRIMITIVE_POINT; if (info->tess._primitive_mode == TESS_PRIMITIVE_ISOLINES) return DXIL_TESSELLATOR_OUTPUT_PRIMITIVE_LINE; - /* Note: GL tessellation domain is inverted from D3D, which means triangle - * winding needs to be inverted. - */ if (info->tess.ccw) - return DXIL_TESSELLATOR_OUTPUT_PRIMITIVE_TRIANGLE_CW; - return DXIL_TESSELLATOR_OUTPUT_PRIMITIVE_TRIANGLE_CCW; + return DXIL_TESSELLATOR_OUTPUT_PRIMITIVE_TRIANGLE_CCW; + return DXIL_TESSELLATOR_OUTPUT_PRIMITIVE_TRIANGLE_CW; } static const struct dxil_mdnode *