[PATCH vkd3d 3/9] vkd3d-shader: Emit epilogue functions while leaving shader phases.

Józef Kucia joseph.kucia at gmail.com
Mon Feb 25 04:59:11 CST 2019


From: Józef Kucia <jkucia at codeweavers.com>

Signed-off-by: Józef Kucia <jkucia at codeweavers.com>
---
 libs/vkd3d-shader/spirv.c | 291 ++++++++++++++++++++------------------
 1 file changed, 156 insertions(+), 135 deletions(-)

diff --git a/libs/vkd3d-shader/spirv.c b/libs/vkd3d-shader/spirv.c
index ce6201603afa..16dc90c13e6b 100644
--- a/libs/vkd3d-shader/spirv.c
+++ b/libs/vkd3d-shader/spirv.c
@@ -3365,6 +3365,33 @@ static unsigned int vkd3d_count_signature_elements_for_reg(
     return count;
 }
 
+static void vkd3d_dxbc_compiler_emit_shader_phase_name(struct vkd3d_dxbc_compiler *compiler,
+        uint32_t id, const struct vkd3d_shader_phase *phase, const char *suffix)
+{
+    struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
+    const char *name;
+
+    if (!suffix)
+        suffix = "";
+
+    switch (phase->type)
+    {
+        case VKD3DSIH_HS_CONTROL_POINT_PHASE:
+            name = "control";
+            break;
+        case VKD3DSIH_HS_FORK_PHASE:
+            name = "fork";
+            break;
+        case VKD3DSIH_HS_JOIN_PHASE:
+            name = "join";
+            break;
+        default:
+            ERR("Invalid phase type %#x.\n", phase->type);
+            return;
+    }
+    vkd3d_spirv_build_op_name(builder, id, "%s%u%s", name, phase->idx, suffix);
+}
+
 static void vkd3d_dxbc_compiler_begin_shader_phase(struct vkd3d_dxbc_compiler *compiler,
         struct vkd3d_shader_phase *phase)
 {
@@ -3372,7 +3399,6 @@ static void vkd3d_dxbc_compiler_begin_shader_phase(struct vkd3d_dxbc_compiler *c
     uint32_t void_id, function_type_id;
     unsigned int param_count;
     uint32_t param_type_id;
-    const char *name;
 
     if (phase->instance_count)
     {
@@ -3397,22 +3423,7 @@ static void vkd3d_dxbc_compiler_begin_shader_phase(struct vkd3d_dxbc_compiler *c
     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)
-    {
-        case VKD3DSIH_HS_CONTROL_POINT_PHASE:
-            name = "control";
-            break;
-        case VKD3DSIH_HS_FORK_PHASE:
-            name = "fork";
-            break;
-        case VKD3DSIH_HS_JOIN_PHASE:
-            name = "join";
-            break;
-        default:
-            ERR("Invalid phase type %#x.\n", phase->type);
-            return;
-    }
-    vkd3d_spirv_build_op_name(builder, phase->function_id, "%s%u", name, phase->idx);
+    vkd3d_dxbc_compiler_emit_shader_phase_name(compiler, phase->function_id, phase, NULL);
 }
 
 static const struct vkd3d_shader_phase *vkd3d_dxbc_compiler_get_current_shader_phase(
@@ -4022,6 +4033,128 @@ static void vkd3d_dxbc_compiler_emit_shader_phase_output(struct vkd3d_dxbc_compi
     vkd3d_dxbc_compiler_put_symbol(compiler, &reg_symbol);
 }
 
+static void vkd3d_dxbc_compiler_emit_store_shader_output(struct vkd3d_dxbc_compiler *compiler,
+        const struct vkd3d_shader_signature_element *output,
+        const struct vkd3d_shader_output_info *output_info, uint32_t val_id)
+{
+    struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
+    uint32_t type_id, zero_id, ptr_type_id, chain_id, object_id;
+    uint32_t write_mask, use_mask, uninit_mask, swizzle, mask;
+    uint32_t output_id, indexes[1];
+    unsigned int component_count;
+    unsigned int i, index;
+
+    write_mask = output->mask & 0xff;
+    use_mask = (output->mask >> 8) & 0xff;
+    swizzle = get_shader_output_swizzle(compiler, output->register_index);
+    val_id = vkd3d_dxbc_compiler_emit_swizzle(compiler,
+            val_id, VKD3D_TYPE_FLOAT, swizzle, write_mask);
+
+    component_count = vkd3d_write_mask_component_count(write_mask);
+
+    if (output_info->component_type != VKD3D_TYPE_FLOAT)
+    {
+        type_id = vkd3d_spirv_get_type_id(builder, output_info->component_type, component_count);
+        val_id = vkd3d_spirv_build_op_bitcast(builder, type_id, val_id);
+    }
+
+    uninit_mask = write_mask & use_mask;
+    if (uninit_mask)
+    {
+        /* Set values to 0 for not initialized shader output components. */
+        zero_id = vkd3d_dxbc_compiler_get_constant_vector(compiler,
+                output_info->component_type, VKD3D_VEC4_SIZE, 0);
+        val_id = vkd3d_dxbc_compiler_emit_vector_shuffle(compiler,
+                val_id, zero_id, uninit_mask, output_info->component_type, component_count);
+    }
+
+    output_id = output_info->id;
+
+    if (!output_info->array_element_mask)
+    {
+        vkd3d_spirv_build_op_store(builder, output_id, val_id, SpvMemoryAccessMaskNone);
+        return;
+    }
+
+    type_id = vkd3d_spirv_get_type_id(builder, VKD3D_TYPE_FLOAT, 1);
+    ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, SpvStorageClassOutput, type_id);
+    mask = output_info->array_element_mask;
+    mask &= (1u << (output->semantic_index * VKD3D_VEC4_SIZE)) - 1;
+    for (i = 0, index = vkd3d_popcount(mask); i < VKD3D_VEC4_SIZE; ++i)
+    {
+        if (!(write_mask & (VKD3DSP_WRITEMASK_0 << i)))
+            continue;
+
+        indexes[0] = vkd3d_dxbc_compiler_get_constant_uint(compiler, index++);
+        chain_id = vkd3d_spirv_build_op_access_chain(builder, ptr_type_id,
+                output_id, indexes, ARRAY_SIZE(indexes));
+        object_id = vkd3d_dxbc_compiler_emit_swizzle_ext(compiler, val_id,
+                write_mask, output_info->component_type, VKD3D_NO_SWIZZLE, VKD3DSP_WRITEMASK_0 << i);
+        vkd3d_spirv_build_op_store(builder, chain_id, object_id, SpvMemoryAccessMaskNone);
+    }
+}
+
+static void vkd3d_dxbc_compiler_emit_shader_epilogue_function(struct vkd3d_dxbc_compiler *compiler)
+{
+    uint32_t param_type_id[MAX_REG_OUTPUT + 1], param_id[MAX_REG_OUTPUT + 1] = {};
+    const struct vkd3d_shader_signature *signature = compiler->output_signature;
+    uint32_t void_id, type_id, ptr_type_id, function_type_id, function_id;
+    struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
+    unsigned int i, count;
+    DWORD variable_idx;
+
+    STATIC_ASSERT(ARRAY_SIZE(compiler->private_output_variable) == ARRAY_SIZE(param_id));
+    STATIC_ASSERT(ARRAY_SIZE(compiler->private_output_variable) == ARRAY_SIZE(param_type_id));
+
+    function_id = compiler->epilogue_function_id;
+
+    void_id = vkd3d_spirv_get_op_type_void(builder);
+    type_id = vkd3d_spirv_get_type_id(builder, VKD3D_TYPE_FLOAT, 4);
+    ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, SpvStorageClassPrivate, type_id);
+    for (i = 0, count = 0; i < ARRAY_SIZE(compiler->private_output_variable); ++i)
+    {
+        if (compiler->private_output_variable[i])
+            param_type_id[count++] = ptr_type_id;
+    }
+    function_type_id = vkd3d_spirv_get_op_type_function(builder, void_id, param_type_id, count);
+
+    vkd3d_spirv_build_op_function(builder, void_id, function_id,
+            SpvFunctionControlMaskNone, function_type_id);
+
+    for (i = 0; i < ARRAY_SIZE(compiler->private_output_variable); ++i)
+    {
+        if (compiler->private_output_variable[i])
+            param_id[i] = vkd3d_spirv_build_op_function_parameter(builder, ptr_type_id);
+    }
+
+    vkd3d_spirv_build_op_label(builder, vkd3d_spirv_alloc_id(builder));
+
+    for (i = 0; i < ARRAY_SIZE(compiler->private_output_variable); ++i)
+    {
+        if (compiler->private_output_variable[i])
+            param_id[i] = vkd3d_spirv_build_op_load(builder, type_id, param_id[i], SpvMemoryAccessMaskNone);
+    }
+
+    for (i = 0; i < signature->element_count; ++i)
+    {
+        variable_idx = vkd3d_dxbc_compiler_get_output_variable_index(compiler,
+                signature->elements[i].register_index);
+
+        if (!param_id[variable_idx])
+            continue;
+
+        vkd3d_dxbc_compiler_emit_store_shader_output(compiler,
+                &signature->elements[i], &compiler->output_info[i], param_id[variable_idx]);
+    }
+
+    vkd3d_spirv_build_op_return(&compiler->spirv_builder);
+    vkd3d_spirv_build_op_function_end(builder);
+
+    memset(compiler->output_info, 0, signature->element_count * sizeof(*compiler->output_info));
+    memset(compiler->private_output_variable, 0, sizeof(compiler->private_output_variable));
+    compiler->epilogue_function_id = 0;
+}
+
 static void vkd3d_dxbc_compiler_emit_initial_declarations(struct vkd3d_dxbc_compiler *compiler)
 {
     const struct vkd3d_shader_transform_feedback_info *xfb_info = compiler->xfb_info;
@@ -4999,6 +5132,12 @@ static void vkd3d_dxbc_compiler_leave_shader_phase(struct vkd3d_dxbc_compiler *c
 
     vkd3d_spirv_build_op_function_end(builder);
 
+    if (compiler->epilogue_function_id)
+    {
+        vkd3d_dxbc_compiler_emit_shader_phase_name(compiler, compiler->epilogue_function_id, phase, "_epilogue");
+        vkd3d_dxbc_compiler_emit_shader_epilogue_function(compiler);
+    }
+
     compiler->temp_id = 0;
     compiler->temp_count = 0;
 
@@ -7721,124 +7860,6 @@ int vkd3d_dxbc_compiler_handle_instruction(struct vkd3d_dxbc_compiler *compiler,
     return ret;
 }
 
-static void vkd3d_dxbc_compiler_emit_store_shader_output(struct vkd3d_dxbc_compiler *compiler,
-        const struct vkd3d_shader_signature_element *output,
-        const struct vkd3d_shader_output_info *output_info, uint32_t val_id)
-{
-    struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
-    uint32_t type_id, zero_id, ptr_type_id, chain_id, object_id;
-    uint32_t write_mask, use_mask, uninit_mask, swizzle, mask;
-    uint32_t output_id, indexes[1];
-    unsigned int component_count;
-    unsigned int i, index;
-
-    write_mask = output->mask & 0xff;
-    use_mask = (output->mask >> 8) & 0xff;
-    swizzle = get_shader_output_swizzle(compiler, output->register_index);
-    val_id = vkd3d_dxbc_compiler_emit_swizzle(compiler,
-            val_id, VKD3D_TYPE_FLOAT, swizzle, write_mask);
-
-    component_count = vkd3d_write_mask_component_count(write_mask);
-
-    if (output_info->component_type != VKD3D_TYPE_FLOAT)
-    {
-        type_id = vkd3d_spirv_get_type_id(builder, output_info->component_type, component_count);
-        val_id = vkd3d_spirv_build_op_bitcast(builder, type_id, val_id);
-    }
-
-    uninit_mask = write_mask & use_mask;
-    if (uninit_mask)
-    {
-        /* Set values to 0 for not initialized shader output components. */
-        zero_id = vkd3d_dxbc_compiler_get_constant_vector(compiler,
-                output_info->component_type, VKD3D_VEC4_SIZE, 0);
-        val_id = vkd3d_dxbc_compiler_emit_vector_shuffle(compiler,
-                val_id, zero_id, uninit_mask, output_info->component_type, component_count);
-    }
-
-    output_id = output_info->id;
-
-    if (!output_info->array_element_mask)
-    {
-        vkd3d_spirv_build_op_store(builder, output_id, val_id, SpvMemoryAccessMaskNone);
-        return;
-    }
-
-    type_id = vkd3d_spirv_get_type_id(builder, VKD3D_TYPE_FLOAT, 1);
-    ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, SpvStorageClassOutput, type_id);
-    mask = output_info->array_element_mask;
-    mask &= (1u << (output->semantic_index * VKD3D_VEC4_SIZE)) - 1;
-    for (i = 0, index = vkd3d_popcount(mask); i < VKD3D_VEC4_SIZE; ++i)
-    {
-        if (!(write_mask & (VKD3DSP_WRITEMASK_0 << i)))
-            continue;
-
-        indexes[0] = vkd3d_dxbc_compiler_get_constant_uint(compiler, index++);
-        chain_id = vkd3d_spirv_build_op_access_chain(builder, ptr_type_id,
-                output_id, indexes, ARRAY_SIZE(indexes));
-        object_id = vkd3d_dxbc_compiler_emit_swizzle_ext(compiler, val_id,
-                write_mask, output_info->component_type, VKD3D_NO_SWIZZLE, VKD3DSP_WRITEMASK_0 << i);
-        vkd3d_spirv_build_op_store(builder, chain_id, object_id, SpvMemoryAccessMaskNone);
-    }
-}
-
-static void vkd3d_dxbc_compiler_emit_shader_epilogue_function(struct vkd3d_dxbc_compiler *compiler)
-{
-    uint32_t param_type_id[MAX_REG_OUTPUT + 1], param_id[MAX_REG_OUTPUT + 1] = {};
-    const struct vkd3d_shader_signature *signature = compiler->output_signature;
-    uint32_t void_id, type_id, ptr_type_id, function_type_id, function_id;
-    struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
-    unsigned int i, count;
-    DWORD variable_idx;
-
-    STATIC_ASSERT(ARRAY_SIZE(compiler->private_output_variable) == ARRAY_SIZE(param_id));
-    STATIC_ASSERT(ARRAY_SIZE(compiler->private_output_variable) == ARRAY_SIZE(param_type_id));
-
-    function_id = compiler->epilogue_function_id;
-
-    void_id = vkd3d_spirv_get_op_type_void(builder);
-    type_id = vkd3d_spirv_get_type_id(builder, VKD3D_TYPE_FLOAT, 4);
-    ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, SpvStorageClassPrivate, type_id);
-    for (i = 0, count = 0; i < ARRAY_SIZE(compiler->private_output_variable); ++i)
-    {
-        if (compiler->private_output_variable[i])
-            param_type_id[count++] = ptr_type_id;
-    }
-    function_type_id = vkd3d_spirv_get_op_type_function(builder, void_id, param_type_id, count);
-
-    vkd3d_spirv_build_op_function(builder, void_id, function_id,
-            SpvFunctionControlMaskNone, function_type_id);
-
-    for (i = 0; i < ARRAY_SIZE(compiler->private_output_variable); ++i)
-    {
-        if (compiler->private_output_variable[i])
-            param_id[i] = vkd3d_spirv_build_op_function_parameter(builder, ptr_type_id);
-    }
-
-    vkd3d_spirv_build_op_label(builder, vkd3d_spirv_alloc_id(builder));
-
-    for (i = 0; i < ARRAY_SIZE(compiler->private_output_variable); ++i)
-    {
-        if (compiler->private_output_variable[i])
-            param_id[i] = vkd3d_spirv_build_op_load(builder, type_id, param_id[i], SpvMemoryAccessMaskNone);
-    }
-
-    for (i = 0; i < signature->element_count; ++i)
-    {
-        variable_idx = vkd3d_dxbc_compiler_get_output_variable_index(compiler,
-                signature->elements[i].register_index);
-
-        if (!param_id[variable_idx])
-            continue;
-
-        vkd3d_dxbc_compiler_emit_store_shader_output(compiler,
-                &signature->elements[i], &compiler->output_info[i], param_id[variable_idx]);
-    }
-
-    vkd3d_spirv_build_op_return(&compiler->spirv_builder);
-    vkd3d_spirv_build_op_function_end(builder);
-}
-
 int vkd3d_dxbc_compiler_generate_spirv(struct vkd3d_dxbc_compiler *compiler,
         struct vkd3d_shader_code *spirv)
 {
-- 
2.19.2




More information about the wine-devel mailing list