=?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