=?UTF-8?Q?J=C3=B3zef=20Kucia=20?=: wined3d: Recognize hull shader phases.

Alexandre Julliard julliard at winehq.org
Fri May 19 15:59:53 CDT 2017


Module: wine
Branch: master
Commit: 2b85e49e1b5dabdd169b15a834a623a3d9c7e505
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=2b85e49e1b5dabdd169b15a834a623a3d9c7e505

Author: Józef Kucia <jkucia at codeweavers.com>
Date:   Thu May 18 15:19:58 2017 +0200

wined3d: Recognize hull shader 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>

---

 dlls/wined3d/glsl_shader.c     |  6 +--
 dlls/wined3d/shader.c          | 89 ++++++++++++++++++++++++++++++++++++++++--
 dlls/wined3d/wined3d_private.h | 20 ++++++++--
 3 files changed, 106 insertions(+), 9 deletions(-)

diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c
index 522a30d..5d08a48 100644
--- a/dlls/wined3d/glsl_shader.c
+++ b/dlls/wined3d/glsl_shader.c
@@ -10346,10 +10346,10 @@ static const SHADER_HANDLER shader_glsl_instruction_handler_table[WINED3DSIH_TAB
     /* WINED3DSIH_GATHER4_C                        */ shader_glsl_gather4,
     /* WINED3DSIH_GATHER4_PO                       */ shader_glsl_gather4,
     /* WINED3DSIH_GE                               */ shader_glsl_relop,
-    /* WINED3DSIH_HS_CONTROL_POINT_PHASE           */ NULL,
+    /* WINED3DSIH_HS_CONTROL_POINT_PHASE           */ shader_glsl_nop,
     /* WINED3DSIH_HS_DECLS                         */ shader_glsl_nop,
-    /* WINED3DSIH_HS_FORK_PHASE                    */ NULL,
-    /* WINED3DSIH_HS_JOIN_PHASE                    */ NULL,
+    /* WINED3DSIH_HS_FORK_PHASE                    */ shader_glsl_nop,
+    /* WINED3DSIH_HS_JOIN_PHASE                    */ shader_glsl_nop,
     /* WINED3DSIH_IADD                             */ shader_glsl_binop,
     /* WINED3DSIH_IBFE                             */ shader_glsl_bitwise_op,
     /* WINED3DSIH_IEQ                              */ shader_glsl_relop,
diff --git a/dlls/wined3d/shader.c b/dlls/wined3d/shader.c
index 0f12b69..146ad63 100644
--- a/dlls/wined3d/shader.c
+++ b/dlls/wined3d/shader.c
@@ -900,6 +900,62 @@ static HRESULT shader_reg_maps_add_tgsm(struct wined3d_shader_reg_maps *reg_maps
     return S_OK;
 }
 
+static HRESULT shader_record_shader_phase(struct wined3d_shader *shader,
+        struct wined3d_shader_phase **current_phase, const struct wined3d_shader_instruction *ins,
+        const DWORD *current_instruction_ptr, const DWORD *previous_instruction_ptr)
+{
+    struct wined3d_shader_phase *phase;
+
+    if ((phase = *current_phase))
+    {
+        phase->end = previous_instruction_ptr;
+        *current_phase = NULL;
+    }
+
+    if (shader->reg_maps.shader_version.type != WINED3D_SHADER_TYPE_HULL)
+    {
+        ERR("Unexpected shader type %#x.\n", shader->reg_maps.shader_version.type);
+        return E_FAIL;
+    }
+
+    switch (ins->handler_idx)
+    {
+        case WINED3DSIH_HS_CONTROL_POINT_PHASE:
+            if (shader->u.hs.phases.control_point)
+            {
+                FIXME("Multiple control point phases.\n");
+                HeapFree(GetProcessHeap(), 0, shader->u.hs.phases.control_point);
+            }
+            if (!(shader->u.hs.phases.control_point = HeapAlloc(GetProcessHeap(),
+                    HEAP_ZERO_MEMORY, sizeof(*shader->u.hs.phases.control_point))))
+                return E_OUTOFMEMORY;
+            phase = shader->u.hs.phases.control_point;
+            break;
+        case WINED3DSIH_HS_FORK_PHASE:
+            if (!wined3d_array_reserve((void **)&shader->u.hs.phases.fork,
+                    &shader->u.hs.phases.fork_size, shader->u.hs.phases.fork_count + 1,
+                    sizeof(*shader->u.hs.phases.fork)))
+                return E_OUTOFMEMORY;
+            phase = &shader->u.hs.phases.fork[shader->u.hs.phases.fork_count++];
+            break;
+        case WINED3DSIH_HS_JOIN_PHASE:
+            if (!wined3d_array_reserve((void **)&shader->u.hs.phases.join,
+                    &shader->u.hs.phases.join_size, shader->u.hs.phases.join_count + 1,
+                    sizeof(*shader->u.hs.phases.join)))
+                return E_OUTOFMEMORY;
+            phase = &shader->u.hs.phases.join[shader->u.hs.phases.join_count++];
+            break;
+        default:
+            ERR("Unexpected opcode %s.\n", debug_d3dshaderinstructionhandler(ins->handler_idx));
+            return E_FAIL;
+    }
+
+    phase->start = current_instruction_ptr;
+    *current_phase = phase;
+
+    return WINED3D_OK;
+}
+
 /* Note that this does not count the loop register as an address register. */
 static HRESULT shader_get_registers_used(struct wined3d_shader *shader, const struct wined3d_shader_frontend *fe,
         struct wined3d_shader_reg_maps *reg_maps, struct wined3d_shader_signature *input_signature,
@@ -908,9 +964,10 @@ static HRESULT shader_get_registers_used(struct wined3d_shader *shader, const st
     struct wined3d_shader_signature_element input_signature_elements[max(MAX_ATTRIBS, MAX_REG_INPUT)];
     struct wined3d_shader_signature_element output_signature_elements[MAX_REG_OUTPUT];
     unsigned int cur_loop_depth = 0, max_loop_depth = 0;
-    void *fe_data = shader->frontend_data;
     struct wined3d_shader_version shader_version;
-    const DWORD *ptr;
+    struct wined3d_shader_phase *phase = NULL;
+    const DWORD *ptr, *prev_ins, *current_ins;
+    void *fe_data = shader->frontend_data;
     unsigned int i;
     HRESULT hr;
 
@@ -921,6 +978,7 @@ static HRESULT shader_get_registers_used(struct wined3d_shader *shader, const st
     list_init(&reg_maps->indexable_temps);
 
     fe->shader_read_header(fe_data, &ptr, &shader_version);
+    prev_ins = current_ins = ptr;
     reg_maps->shader_version = shader_version;
 
     shader_set_limits(shader);
@@ -936,6 +994,7 @@ static HRESULT shader_get_registers_used(struct wined3d_shader *shader, const st
     {
         struct wined3d_shader_instruction ins;
 
+        current_ins = ptr;
         /* Fetch opcode. */
         fe->shader_read_instruction(fe_data, &ptr, &ins);
 
@@ -1239,6 +1298,14 @@ static HRESULT shader_get_registers_used(struct wined3d_shader *shader, const st
             list_add_head(&shader->constantsB, &lconst->entry);
             reg_maps->local_bool_consts |= (1u << lconst->idx);
         }
+        /* Handle shader phases. */
+        else if (ins.handler_idx == WINED3DSIH_HS_CONTROL_POINT_PHASE
+                || ins.handler_idx == WINED3DSIH_HS_FORK_PHASE
+                || ins.handler_idx == WINED3DSIH_HS_JOIN_PHASE)
+        {
+            if (FAILED(hr = shader_record_shader_phase(shader, &phase, &ins, current_ins, prev_ins)))
+                return hr;
+        }
         /* For subroutine prototypes. */
         else if (ins.handler_idx == WINED3DSIH_LABEL)
         {
@@ -1557,9 +1624,17 @@ static HRESULT shader_get_registers_used(struct wined3d_shader *shader, const st
                 }
             }
         }
+
+        prev_ins = current_ins;
     }
     reg_maps->loop_depth = max_loop_depth;
 
+    if (phase)
+    {
+        phase->end = prev_ins;
+        phase = NULL;
+    }
+
     /* PS before 2.0 don't have explicit color outputs. Instead the value of
      * R0 is written to the render target. */
     if (shader_version.major < 2 && shader_version.type == WINED3D_SHADER_TYPE_PIXEL)
@@ -2873,8 +2948,16 @@ static void shader_trace_init(const struct wined3d_shader_frontend *fe, void *fe
 
 static void shader_cleanup(struct wined3d_shader *shader)
 {
-    if (shader->reg_maps.shader_version.type == WINED3D_SHADER_TYPE_GEOMETRY)
+    if (shader->reg_maps.shader_version.type == WINED3D_SHADER_TYPE_HULL)
+    {
+        HeapFree(GetProcessHeap(), 0, shader->u.hs.phases.control_point);
+        HeapFree(GetProcessHeap(), 0, shader->u.hs.phases.fork);
+        HeapFree(GetProcessHeap(), 0, shader->u.hs.phases.join);
+    }
+    else if (shader->reg_maps.shader_version.type == WINED3D_SHADER_TYPE_GEOMETRY)
+    {
         HeapFree(GetProcessHeap(), 0, shader->u.gs.so_desc.elements);
+    }
 
     HeapFree(GetProcessHeap(), 0, shader->patch_constant_signature.elements);
     HeapFree(GetProcessHeap(), 0, shader->output_signature.elements);
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 70dd8ed..34548a3 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -3699,9 +3699,11 @@ int shader_addline(struct wined3d_string_buffer *buffer, const char *fmt, ...) P
 BOOL string_buffer_resize(struct wined3d_string_buffer *buffer, int rc) DECLSPEC_HIDDEN;
 int shader_vaddline(struct wined3d_string_buffer *buffer, const char *fmt, va_list args) DECLSPEC_HIDDEN;
 
-/* Vertex shader utility functions */
-BOOL vshader_get_input(const struct wined3d_shader *shader,
-        BYTE usage_req, BYTE usage_idx_req, unsigned int *regnum) DECLSPEC_HIDDEN;
+struct wined3d_shader_phase
+{
+    const DWORD *start;
+    const DWORD *end;
+};
 
 struct wined3d_vertex_shader
 {
@@ -3710,6 +3712,16 @@ struct wined3d_vertex_shader
 
 struct wined3d_hull_shader
 {
+    struct
+    {
+        struct wined3d_shader_phase *control_point;
+        unsigned int fork_count;
+        unsigned int join_count;
+        struct wined3d_shader_phase *fork;
+        SIZE_T fork_size;
+        struct wined3d_shader_phase *join;
+        SIZE_T join_size;
+    } phases;
     unsigned int output_vertex_count;
     enum wined3d_tessellator_output_primitive tessellator_output_primitive;
     enum wined3d_tessellator_partitioning tessellator_partitioning;
@@ -3796,6 +3808,8 @@ void find_ps_compile_args(const struct wined3d_state *state, const struct wined3
         BOOL position_transformed, struct ps_compile_args *args,
         const struct wined3d_context *context) DECLSPEC_HIDDEN;
 
+BOOL vshader_get_input(const struct wined3d_shader *shader,
+        BYTE usage_req, BYTE usage_idx_req, unsigned int *regnum) DECLSPEC_HIDDEN;
 void find_vs_compile_args(const struct wined3d_state *state, const struct wined3d_shader *shader,
         WORD swizzle_map, struct vs_compile_args *args,
         const struct wined3d_d3d_info *d3d_info) DECLSPEC_HIDDEN;




More information about the wine-cvs mailing list