=?UTF-8?Q?J=C3=B3zef=20Kucia=20?=: vkd3d-shader: Add basic support for dcl_index_range.

Alexandre Julliard julliard at winehq.org
Wed Feb 20 16:34:06 CST 2019


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

Author: Józef Kucia <jkucia at codeweavers.com>
Date:   Wed Feb 20 13:42:53 2019 +0100

vkd3d-shader: Add basic support for dcl_index_range.

We can address SPIR-V arrays dynamically.

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/dxbc.c                 |  4 +-
 libs/vkd3d-shader/spirv.c                | 74 ++++++++++++++++++++++++++++++--
 libs/vkd3d-shader/trace.c                |  4 +-
 libs/vkd3d-shader/vkd3d_shader_private.h |  4 +-
 4 files changed, 76 insertions(+), 10 deletions(-)

diff --git a/libs/vkd3d-shader/dxbc.c b/libs/vkd3d-shader/dxbc.c
index 4911668..7cc11e7 100644
--- a/libs/vkd3d-shader/dxbc.c
+++ b/libs/vkd3d-shader/dxbc.c
@@ -619,8 +619,8 @@ static void shader_sm4_read_dcl_index_range(struct vkd3d_shader_instruction *ins
         struct vkd3d_sm4_data *priv)
 {
     shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], VKD3D_DATA_OPAQUE,
-            &ins->declaration.index_range.first_register);
-    ins->declaration.index_range.last_register = *tokens;
+            &ins->declaration.index_range.dst);
+    ins->declaration.index_range.register_count = *tokens;
 }
 
 static void shader_sm4_read_dcl_output_topology(struct vkd3d_shader_instruction *ins,
diff --git a/libs/vkd3d-shader/spirv.c b/libs/vkd3d-shader/spirv.c
index afed8a2..52c22fe 100644
--- a/libs/vkd3d-shader/spirv.c
+++ b/libs/vkd3d-shader/spirv.c
@@ -2568,14 +2568,17 @@ static void vkd3d_dxbc_compiler_emit_dereference_register(struct vkd3d_dxbc_comp
     }
     else if (register_info->is_aggregate)
     {
-        if (reg->idx[0].rel_addr || reg->idx[1].rel_addr)
+        if (reg->idx[1].rel_addr)
             FIXME("Relative addressing not implemented.\n");
 
-        indexes[index_count++] = vkd3d_dxbc_compiler_get_constant_uint(compiler, register_info->member_idx);
+        if (reg->idx[0].rel_addr)
+            indexes[index_count++] = vkd3d_dxbc_compiler_emit_register_addressing(compiler, &reg->idx[0]);
+        else
+            indexes[index_count++] = vkd3d_dxbc_compiler_get_constant_uint(compiler, register_info->member_idx);
     }
     else
     {
-        if (reg->idx[1].rel_addr)
+        if (reg->idx[1].rel_addr || (reg->idx[1].offset == ~0u && reg->idx[0].rel_addr))
             FIXME("Relative addressing not implemented.\n");
 
         /* Handle arrayed registers, e.g. v[3][0]. */
@@ -4754,6 +4757,64 @@ static void vkd3d_dxbc_compiler_emit_dcl_output_siv(struct vkd3d_dxbc_compiler *
         vkd3d_dxbc_compiler_emit_output(compiler, dst, sysval);
 }
 
+static bool vkd3d_dxbc_compiler_check_index_range(struct vkd3d_dxbc_compiler *compiler,
+        const struct vkd3d_shader_index_range *range)
+{
+    const struct vkd3d_shader_register *reg = &range->dst.reg;
+    struct vkd3d_shader_register_info reg_info;
+    struct vkd3d_shader_register current_reg;
+    struct vkd3d_symbol reg_symbol;
+    unsigned int i;
+    uint32_t id;
+
+    current_reg = *reg;
+    vkd3d_symbol_make_register(&reg_symbol, &current_reg);
+    if (!vkd3d_dxbc_compiler_get_register_info(compiler, &current_reg, &reg_info))
+    {
+        ERR("Failed to get register info.\n");
+        return false;
+    }
+
+    /* FIXME: We should check if it's an array. */
+    if (!reg_info.is_aggregate)
+    {
+        FIXME("Unhandled register %#x.\n", reg->type);
+        return false;
+    }
+    id = reg_info.id;
+
+    for (i = reg->idx[0].offset; i < reg->idx[0].offset + range->register_count; ++i)
+    {
+        current_reg.idx[0].offset = i;
+        vkd3d_symbol_make_register(&reg_symbol, &current_reg);
+
+        if (range->dst.write_mask != reg_info.write_mask
+                || vkd3d_write_mask_component_count(reg_info.write_mask) != 1)
+        {
+            FIXME("Unhandled index range write mask %#x (%#x).\n",
+                    range->dst.write_mask, reg_info.write_mask);
+            return false;
+        }
+
+        if (reg_info.id != id)
+        {
+            FIXME("Unhandled index range %#x, %u.\n", reg->type, i);
+            return false;
+        }
+    }
+
+    return true;
+}
+
+static void vkd3d_dxbc_compiler_emit_dcl_index_range(struct vkd3d_dxbc_compiler *compiler,
+        const struct vkd3d_shader_instruction *instruction)
+{
+    const struct vkd3d_shader_index_range *range = &instruction->declaration.index_range;
+
+    if (!vkd3d_dxbc_compiler_check_index_range(compiler, range))
+        FIXME("Ignoring dcl_index_range %#x %u.\n", range->dst.reg.type, range->register_count);
+}
+
 static void vkd3d_dxbc_compiler_emit_dcl_stream(struct vkd3d_dxbc_compiler *compiler,
         const struct vkd3d_shader_instruction *instruction)
 {
@@ -7388,6 +7449,9 @@ int vkd3d_dxbc_compiler_handle_instruction(struct vkd3d_dxbc_compiler *compiler,
         case VKD3DSIH_DCL_OUTPUT_SIV:
             vkd3d_dxbc_compiler_emit_dcl_output_siv(compiler, instruction);
             break;
+        case VKD3DSIH_DCL_INDEX_RANGE:
+            vkd3d_dxbc_compiler_emit_dcl_index_range(compiler, instruction);
+            break;
         case VKD3DSIH_DCL_STREAM:
             vkd3d_dxbc_compiler_emit_dcl_stream(compiler, instruction);
             break;
@@ -7730,7 +7794,6 @@ static void vkd3d_dxbc_compiler_emit_shader_epilogue_function(struct vkd3d_dxbc_
 
     vkd3d_spirv_build_op_function(builder, void_id, function_id,
             SpvFunctionControlMaskNone, function_type_id);
-    vkd3d_spirv_build_op_name(builder, function_id, "epilogue");
 
     for (i = 0; i < ARRAY_SIZE(compiler->private_output_variable); ++i)
     {
@@ -7789,7 +7852,10 @@ int vkd3d_dxbc_compiler_generate_spirv(struct vkd3d_dxbc_compiler *compiler,
     }
 
     if (compiler->epilogue_function_id)
+    {
+        vkd3d_spirv_build_op_name(builder, compiler->epilogue_function_id, "epilogue");
         vkd3d_dxbc_compiler_emit_shader_epilogue_function(compiler);
+    }
 
     if (compiler->options & VKD3D_SHADER_STRIP_DEBUG)
         vkd3d_spirv_stream_clear(&builder->debug_stream);
diff --git a/libs/vkd3d-shader/trace.c b/libs/vkd3d-shader/trace.c
index 6375e71..bb0e6ad 100644
--- a/libs/vkd3d-shader/trace.c
+++ b/libs/vkd3d-shader/trace.c
@@ -1389,8 +1389,8 @@ static void shader_dump_instruction(struct vkd3d_string_buffer *buffer,
 
         case VKD3DSIH_DCL_INDEX_RANGE:
             shader_addline(buffer, "%s ", shader_opcode_names[ins->handler_idx]);
-            shader_dump_dst_param(buffer, &ins->declaration.index_range.first_register, shader_version);
-            shader_addline(buffer, " %u", ins->declaration.index_range.last_register);
+            shader_dump_dst_param(buffer, &ins->declaration.index_range.dst, shader_version);
+            shader_addline(buffer, " %u", ins->declaration.index_range.register_count);
             break;
 
         case VKD3DSIH_DCL_INDEXABLE_TEMP:
diff --git a/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d-shader/vkd3d_shader_private.h
index 6b095a9..7ffcdd9 100644
--- a/libs/vkd3d-shader/vkd3d_shader_private.h
+++ b/libs/vkd3d-shader/vkd3d_shader_private.h
@@ -584,8 +584,8 @@ struct vkd3d_shader_src_param
 
 struct vkd3d_shader_index_range
 {
-    struct vkd3d_shader_dst_param first_register;
-    unsigned int last_register;
+    struct vkd3d_shader_dst_param dst;
+    unsigned int register_count;
 };
 
 enum vkd3d_decl_usage




More information about the wine-cvs mailing list