=?UTF-8?Q?J=C3=B3zef=20Kucia=20?=: libs/vkd3d-shader: Fix returning multiple components from dot product instructions.

Alexandre Julliard julliard at winehq.org
Tue Jun 26 15:01:10 CDT 2018


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

Author: Józef Kucia <jkucia at codeweavers.com>
Date:   Tue Jun 26 14:41:53 2018 +0200

libs/vkd3d-shader: Fix returning multiple components from dot product instructions.

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 | 76 +++++++++++++++++++++++++----------------------
 tests/d3d12.c             | 23 ++++++++++++++
 2 files changed, 64 insertions(+), 35 deletions(-)

diff --git a/libs/vkd3d-shader/spirv.c b/libs/vkd3d-shader/spirv.c
index a5e51c9..bfa2bc0 100644
--- a/libs/vkd3d-shader/spirv.c
+++ b/libs/vkd3d-shader/spirv.c
@@ -2219,6 +2219,35 @@ static uint32_t vkd3d_dxbc_compiler_emit_array_variable(struct vkd3d_dxbc_compil
     return vkd3d_spirv_build_op_variable(builder, stream, ptr_type_id, storage_class, 0);
 }
 
+static uint32_t vkd3d_dxbc_compiler_emit_construct_vector(struct vkd3d_dxbc_compiler *compiler,
+        enum vkd3d_component_type component_type, unsigned int component_count,
+        uint32_t val_id, unsigned int val_component_idx, unsigned int val_component_count)
+{
+    struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
+    uint32_t components[VKD3D_VEC4_SIZE];
+    uint32_t type_id, result_id;
+    unsigned int i;
+
+    assert(val_component_idx < val_component_count);
+
+    type_id = vkd3d_spirv_get_type_id(builder, component_type, component_count);
+    if (val_component_count == 1)
+    {
+        for (i = 0; i < component_count; ++i)
+            components[i] = val_id;
+        result_id = vkd3d_spirv_build_op_composite_construct(builder,
+                type_id, components, component_count);
+    }
+    else
+    {
+        for (i = 0; i < component_count; ++i)
+            components[i] = val_component_idx;
+        result_id = vkd3d_spirv_build_op_vector_shuffle(builder,
+                type_id, val_id, val_id, components, component_count);
+    }
+    return result_id;
+}
+
 static uint32_t vkd3d_dxbc_compiler_emit_load_src(struct vkd3d_dxbc_compiler *compiler,
         const struct vkd3d_shader_src_param *src, DWORD write_mask);
 
@@ -4202,11 +4231,13 @@ static void vkd3d_dxbc_compiler_emit_dot(struct vkd3d_dxbc_compiler *compiler,
     struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
     const struct vkd3d_shader_dst_param *dst = instruction->dst;
     const struct vkd3d_shader_src_param *src = instruction->src;
+    enum vkd3d_component_type component_type;
     uint32_t type_id, val_id, src_ids[2];
+    unsigned int component_count, i;
     DWORD write_mask;
-    unsigned int i;
 
-    assert(vkd3d_write_mask_component_count(dst->write_mask) == 1);
+    component_count = vkd3d_write_mask_component_count(dst->write_mask);
+    component_type = vkd3d_component_type_from_data_type(dst->reg.data_type);
 
     if (instruction->handler_idx == VKD3DSIH_DP4)
         write_mask = VKD3DSP_WRITEMASK_ALL;
@@ -4219,11 +4250,15 @@ static void vkd3d_dxbc_compiler_emit_dot(struct vkd3d_dxbc_compiler *compiler,
     for (i = 0; i < ARRAY_SIZE(src_ids); ++i)
         src_ids[i] = vkd3d_dxbc_compiler_emit_load_src(compiler, &src[i], write_mask);
 
-    type_id = vkd3d_spirv_get_type_id(builder,
-            vkd3d_component_type_from_data_type(dst->reg.data_type), 1);
+    type_id = vkd3d_spirv_get_type_id(builder, component_type, 1);
 
     val_id = vkd3d_spirv_build_op_tr2(builder, &builder->function_stream,
             SpvOpDot, type_id, src_ids[0], src_ids[1]);
+    if (component_count > 1)
+    {
+        val_id = vkd3d_dxbc_compiler_emit_construct_vector(compiler,
+                component_type, component_count, val_id, 0, 1);
+    }
 
     vkd3d_dxbc_compiler_emit_store_dst(compiler, dst, val_id);
 }
@@ -5270,35 +5305,6 @@ static void vkd3d_dxbc_compiler_emit_ld_raw_structured(struct vkd3d_dxbc_compile
     }
 }
 
-static uint32_t vkd3d_dxbc_compiler_emit_construct_vec4(struct vkd3d_dxbc_compiler *compiler,
-        uint32_t val_id, enum vkd3d_component_type component_type,
-        unsigned int component_idx, unsigned int component_count)
-{
-    struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
-    uint32_t components[VKD3D_VEC4_SIZE];
-    uint32_t type_id, result_id;
-    unsigned int i;
-
-    assert(component_idx < component_count);
-
-    type_id = vkd3d_spirv_get_type_id(builder, component_type, VKD3D_VEC4_SIZE);
-    if (component_count == 1)
-    {
-        for (i = 0; i < VKD3D_VEC4_SIZE; ++i)
-            components[i] = val_id;
-        result_id = vkd3d_spirv_build_op_composite_construct(builder,
-                type_id, components, VKD3D_VEC4_SIZE);
-    }
-    else
-    {
-        for (i = 0; i < VKD3D_VEC4_SIZE; ++i)
-            components[i] = component_idx;
-        result_id = vkd3d_spirv_build_op_vector_shuffle(builder,
-                type_id, val_id, val_id, components, VKD3D_VEC4_SIZE);
-    }
-    return result_id;
-}
-
 static void vkd3d_dxbc_compiler_emit_store_uav_raw_structured(struct vkd3d_dxbc_compiler *compiler,
         const struct vkd3d_shader_instruction *instruction)
 {
@@ -5325,8 +5331,8 @@ static void vkd3d_dxbc_compiler_emit_store_uav_raw_structured(struct vkd3d_dxbc_
     for (component_idx = 0; component_idx < component_count; ++component_idx)
     {
         /* Mesa Vulkan drivers require the texel parameter to be a vector. */
-        texel_id = vkd3d_dxbc_compiler_emit_construct_vec4(compiler,
-                val_id, VKD3D_TYPE_UINT, component_idx, component_count);
+        texel_id = vkd3d_dxbc_compiler_emit_construct_vector(compiler,
+                VKD3D_TYPE_UINT, VKD3D_VEC4_SIZE, val_id, component_idx, component_count);
 
         coordinate_id = base_coordinate_id;
         if (component_idx)
diff --git a/tests/d3d12.c b/tests/d3d12.c
index a761c0d..c6220aa 100644
--- a/tests/d3d12.c
+++ b/tests/d3d12.c
@@ -4919,6 +4919,26 @@ static void test_shader_instructions(void)
         0x00000000, 0x0100003e,
     };
     static const D3D12_SHADER_BYTECODE ps_dot2 = {ps_dot2_code, sizeof(ps_dot2_code)};
+    static const DWORD ps_dot3_code[] =
+    {
+#if 0
+        float4 src0;
+        float3 src1;
+
+        float4 main() : SV_Target
+        {
+            return dot(src0, src1);
+        }
+#endif
+        0x43425844, 0xa75a4a95, 0x5d09936e, 0xdc5c694f, 0x68b6b04f, 0x00000001, 0x000000c8, 0x00000003,
+        0x0000002c, 0x0000003c, 0x00000070, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f,
+        0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003, 0x00000000,
+        0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x58454853, 0x00000050, 0x00000050, 0x00000014,
+        0x0100086a, 0x04000059, 0x00208e46, 0x00000000, 0x00000002, 0x03000065, 0x001020f2, 0x00000000,
+        0x09000010, 0x001020f2, 0x00000000, 0x00208246, 0x00000000, 0x00000000, 0x00208246, 0x00000000,
+        0x00000001, 0x0100003e,
+    };
+    static const D3D12_SHADER_BYTECODE ps_dot3 = {ps_dot3_code, sizeof(ps_dot3_code)};
     static const DWORD ps_eq_code[] =
     {
 #if 0
@@ -6119,6 +6139,9 @@ static void test_shader_instructions(void)
         {&ps_dot2, {{1.0f, 1.0f}, {1.0f, 1.0f}}, {{2.0f}}},
         {&ps_dot2, {{1.0f, 1.0f}, {2.0f, 3.0f}}, {{5.0f}}},
 
+        {&ps_dot3, {{1.0f, 2.0f, 3.0f, 4.0f}, {1.0f, 1.0f, 1.0f, 1.0f}}, {{6.0f, 6.0f, 6.0f, 6.0f}}},
+        {&ps_dot3, {{1.0f, 2.0f, 3.0f}, {3.0f, 1.0f, 2.0f}}, {{11.0f, 11.0f, 11.0f, 11.0f}}},
+
         {&ps_eq, {{0.0f}, {0.0f}}, {.u = {0xffffffff}}},
         {&ps_eq, {{1.0f}, {0.0f}}, {.u = {0x00000000}}},
         {&ps_eq, {{0.0f}, {1.0f}}, {.u = {0x00000000}}},




More information about the wine-cvs mailing list