=?UTF-8?Q?J=C3=B3zef=20Kucia=20?=: vkd3d-shader: Add support for instanced fork phases.

Alexandre Julliard julliard at winehq.org
Thu Feb 7 16:08:54 CST 2019


Module: vkd3d
Branch: master
Commit: ea4dd223090f53865bb62086902606160b5e5877
URL:    https://source.winehq.org/git/vkd3d.git/?a=commit;h=ea4dd223090f53865bb62086902606160b5e5877

Author: Józef Kucia <jkucia at codeweavers.com>
Date:   Thu Feb  7 09:59:15 2019 +0100

vkd3d-shader: Add support for instanced fork phases.

Signed-off-by: Józef Kucia <jkucia at codeweavers.com>
Signed-off-by: Henri Verbeet <hverbeet at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 libs/vkd3d-shader/spirv.c | 62 ++++++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 58 insertions(+), 4 deletions(-)

diff --git a/libs/vkd3d-shader/spirv.c b/libs/vkd3d-shader/spirv.c
index e1ea236..f14306e 100644
--- a/libs/vkd3d-shader/spirv.c
+++ b/libs/vkd3d-shader/spirv.c
@@ -1910,6 +1910,7 @@ struct vkd3d_shader_phase
     unsigned int idx;
     unsigned int instance_count;
     uint32_t function_id;
+    uint32_t instance_id;
     size_t function_location;
 };
 
@@ -3836,16 +3837,31 @@ static void vkd3d_dxbc_compiler_begin_shader_phase(struct vkd3d_dxbc_compiler *c
 {
     struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
     uint32_t void_id, function_type_id;
+    unsigned int param_count;
+    uint32_t param_type_id;
     const char *name;
 
+    if (phase->instance_count)
+    {
+        param_type_id = vkd3d_spirv_get_type_id(builder, VKD3D_TYPE_UINT, 1);
+        param_count = 1;
+    }
+    else
+    {
+        param_count = 0;
+    }
+
     phase->function_id = vkd3d_spirv_alloc_id(builder);
 
     void_id = vkd3d_spirv_get_op_type_void(builder);
-    function_type_id = vkd3d_spirv_get_op_type_function(builder, void_id, NULL, 0);
+    function_type_id = vkd3d_spirv_get_op_type_function(builder, void_id, &param_type_id, param_count);
     vkd3d_spirv_build_op_function(builder, void_id, phase->function_id,
             SpvFunctionControlMaskNone, function_type_id);
-    vkd3d_spirv_build_op_label(builder, vkd3d_spirv_alloc_id(builder));
 
+    if (phase->instance_count)
+        phase->instance_id = vkd3d_spirv_build_op_function_parameter(builder, param_type_id);
+
+    vkd3d_spirv_build_op_label(builder, vkd3d_spirv_alloc_id(builder));
     phase->function_location = vkd3d_spirv_stream_current_location(&builder->function_stream);
 
     switch (phase->type)
@@ -4765,15 +4781,37 @@ static void vkd3d_dxbc_compiler_enter_shader_phase(struct vkd3d_dxbc_compiler *c
     phase->idx = idx;
     phase->instance_count = 0;
     phase->function_id = 0;
+    phase->instance_id = 0;
     phase->function_location = 0;
 }
 
+static int vkd3d_dxbc_compiler_emit_hs_fork_phase_instance_count(struct vkd3d_dxbc_compiler *compiler,
+        const struct vkd3d_shader_instruction *instruction)
+{
+    struct vkd3d_shader_phase *phase = &compiler->shader_phases[compiler->shader_phase_count - 1];
+
+    if (!compiler->shader_phase_count
+            || phase->type != VKD3DSIH_HS_FORK_PHASE
+            || phase->function_id)
+    {
+        WARN("Unexpected dcl_hs_fork_phase_instance_count instruction.\n");
+        return VKD3D_ERROR_INVALID_SHADER;
+    }
+
+    phase->instance_count = instruction->declaration.count;
+
+    vkd3d_dxbc_compiler_begin_shader_phase(compiler, phase);
+
+    return VKD3D_OK;
+}
+
 static void vkd3d_dxbc_compiler_emit_hull_shader_main(struct vkd3d_dxbc_compiler *compiler)
 {
     struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
     const struct vkd3d_shader_phase *phase;
+    uint32_t phase_instance_id;
+    unsigned int i, j;
     uint32_t void_id;
-    unsigned int i;
 
     vkd3d_spirv_builder_begin_main_function(builder);
 
@@ -4781,7 +4819,20 @@ static void vkd3d_dxbc_compiler_emit_hull_shader_main(struct vkd3d_dxbc_compiler
     for (i = 0; i < compiler->shader_phase_count; ++i)
     {
         phase = &compiler->shader_phases[i];
-        vkd3d_spirv_build_op_function_call(builder, void_id, phase->function_id, NULL, 0);
+
+        if (phase->instance_count)
+        {
+            for (j = 0; j < phase->instance_count; ++j)
+            {
+                phase_instance_id = vkd3d_dxbc_compiler_get_constant_uint(compiler, j);
+                vkd3d_spirv_build_op_function_call(builder,
+                        void_id, phase->function_id, &phase_instance_id, 1);
+            }
+        }
+        else
+        {
+            vkd3d_spirv_build_op_function_call(builder, void_id, phase->function_id, NULL, 0);
+        }
     }
 
     vkd3d_spirv_build_op_return(builder);
@@ -7074,6 +7125,9 @@ int vkd3d_dxbc_compiler_handle_instruction(struct vkd3d_dxbc_compiler *compiler,
         case VKD3DSIH_DCL_THREAD_GROUP:
             vkd3d_dxbc_compiler_emit_dcl_thread_group(compiler, instruction);
             break;
+        case VKD3DSIH_DCL_HS_FORK_PHASE_INSTANCE_COUNT:
+            ret = vkd3d_dxbc_compiler_emit_hs_fork_phase_instance_count(compiler, instruction);
+            break;
         case VKD3DSIH_HS_CONTROL_POINT_PHASE:
         case VKD3DSIH_HS_FORK_PHASE:
         case VKD3DSIH_HS_JOIN_PHASE:




More information about the wine-cvs mailing list