[PATCH vkd3d 5/8] vkd3d-shader: Support patch constant inputs in tessellation control shader join phases.

Henri Verbeet hverbeet at codeweavers.com
Mon Mar 22 07:20:06 CDT 2021


Signed-off-by: Henri Verbeet <hverbeet at codeweavers.com>
---
 libs/vkd3d-shader/spirv.c | 38 +++++++++++++++++++++++++++++++++-----
 tests/d3d12.c             |  2 +-
 2 files changed, 34 insertions(+), 6 deletions(-)

diff --git a/libs/vkd3d-shader/spirv.c b/libs/vkd3d-shader/spirv.c
index a639f7e8..a6e5e223 100644
--- a/libs/vkd3d-shader/spirv.c
+++ b/libs/vkd3d-shader/spirv.c
@@ -4252,7 +4252,9 @@ static uint32_t vkd3d_dxbc_compiler_emit_input(struct vkd3d_dxbc_compiler *compi
     }
 
     if (!(use_private_var = builtin && builtin->fixup_pfn)
-            && needs_private_io_variable(shader_signature, reg_idx, builtin, &input_component_count, &write_mask))
+            && needs_private_io_variable(shader_signature, reg_idx, builtin, &input_component_count, &write_mask)
+            && (compiler->shader_type != VKD3D_SHADER_TYPE_HULL
+            || (reg->type != VKD3DSPR_INCONTROLPOINT && reg->type != VKD3DSPR_PATCHCONST)))
         use_private_var = true;
     else
         component_idx = vkd3d_write_mask_get_component_idx(write_mask);
@@ -4266,20 +4268,45 @@ static uint32_t vkd3d_dxbc_compiler_emit_input(struct vkd3d_dxbc_compiler *compi
         symbol = RB_ENTRY_VALUE(entry, struct vkd3d_symbol, entry);
         input_id = symbol->id;
     }
-    else if (compiler->shader_type == VKD3D_SHADER_TYPE_HULL && reg->type == VKD3DSPR_INCONTROLPOINT)
-    {
+    else if (compiler->shader_type == VKD3D_SHADER_TYPE_HULL
+            && (reg->type == VKD3DSPR_INCONTROLPOINT || reg->type == VKD3DSPR_PATCHCONST))
+    {
+        /* Input/output registers from one phase can be used as inputs in
+         * subsequent phases. Specifically:
+         *
+         *   - Control phase inputs are available as "vicp" in fork and join
+         *     phases.
+         *   - Control phase outputs are available as "vocp" in fork and join
+         *     phases.
+         *   - Fork phase patch constants are available as "vpc" in join
+         *     phases.
+         *
+         * We handle "vicp" and "vpc" here by creating aliases to the shader's
+         * global inputs and outputs. We handle "vocp" in
+         * vkd3d_dxbc_compiler_leave_shader_phase(). */
+
         tmp_symbol = reg_symbol;
-        tmp_symbol.key.reg.type = VKD3DSPR_INPUT;
+        if (reg->type == VKD3DSPR_PATCHCONST)
+            tmp_symbol.key.reg.type = VKD3DSPR_OUTPUT;
+        else
+            tmp_symbol.key.reg.type = VKD3DSPR_INPUT;
 
         if ((entry = rb_get(&compiler->symbol_table, &tmp_symbol)))
         {
             symbol = RB_ENTRY_VALUE(entry, struct vkd3d_symbol, entry);
             tmp_symbol = *symbol;
-            tmp_symbol.key.reg.type = VKD3DSPR_INCONTROLPOINT;
+            tmp_symbol.key.reg.type = reg->type;
             vkd3d_dxbc_compiler_put_symbol(compiler, &tmp_symbol);
 
             input_id = symbol->id;
         }
+        else
+        {
+            if (reg->type == VKD3DSPR_PATCHCONST)
+                ERR("Patch constant register %u was not declared in a previous phase.\n", reg_idx);
+            else
+                ERR("Input control point register %u was not declared in a previous phase.\n", reg_idx);
+        }
     }
 
     if (!symbol || ~symbol->info.reg.dcl_mask & write_mask)
@@ -4418,6 +4445,7 @@ static void vkd3d_dxbc_compiler_emit_shader_phase_input(struct vkd3d_dxbc_compil
     {
         case VKD3DSPR_INPUT:
         case VKD3DSPR_INCONTROLPOINT:
+        case VKD3DSPR_PATCHCONST:
             vkd3d_dxbc_compiler_emit_input(compiler, dst, VKD3D_SIV_NONE, VKD3DSIM_NONE);
             return;
         case VKD3DSPR_PRIMID:
diff --git a/tests/d3d12.c b/tests/d3d12.c
index dfdbefa5..f289a10d 100644
--- a/tests/d3d12.c
+++ b/tests/d3d12.c
@@ -33809,7 +33809,7 @@ static void test_hull_shader_patch_constant_inputs(void)
     transition_resource_state(command_list, so_buffer,
             D3D12_RESOURCE_STATE_STREAM_OUT, D3D12_RESOURCE_STATE_COPY_SOURCE);
     get_buffer_readback_with_command_list(so_buffer, DXGI_FORMAT_UNKNOWN, &rb, queue, command_list);
-    todo check_triangles(&rb, &expected_triangle, 1);
+    check_triangles(&rb, &expected_triangle, 1);
     release_resource_readback(&rb);
 
     ID3D12Resource_Release(so_buffer);
-- 
2.20.1




More information about the wine-devel mailing list