Conor McCarthy : vkd3d-shader: Handle 64-bit immediate constant registers.
Alexandre Julliard
julliard at winehq.org
Tue Aug 3 16:51:51 CDT 2021
Module: vkd3d
Branch: master
Commit: 506c98b4a2c7e2874f69b4c0f87156ecc41da855
URL: https://source.winehq.org/git/vkd3d.git/?a=commit;h=506c98b4a2c7e2874f69b4c0f87156ecc41da855
Author: Conor McCarthy <cmccarthy at codeweavers.com>
Date: Fri Jul 30 23:27:21 2021 +1000
vkd3d-shader: Handle 64-bit immediate constant registers.
Signed-off-by: Conor McCarthy <cmccarthy 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 | 81 ++++++++++++++++++++++++++++++--
libs/vkd3d-shader/vkd3d_shader_private.h | 7 +++
2 files changed, 84 insertions(+), 4 deletions(-)
diff --git a/libs/vkd3d-shader/spirv.c b/libs/vkd3d-shader/spirv.c
index 0abc2d6..b5f20ce 100644
--- a/libs/vkd3d-shader/spirv.c
+++ b/libs/vkd3d-shader/spirv.c
@@ -1147,6 +1147,21 @@ static uint32_t vkd3d_spirv_get_op_constant(struct vkd3d_spirv_builder *builder,
vkd3d_spirv_build_op_constant);
}
+static uint32_t vkd3d_spirv_build_op_constant64(struct vkd3d_spirv_builder *builder,
+ uint32_t result_type, const uint32_t *values, unsigned int value_count)
+{
+ assert(value_count == 2);
+ return vkd3d_spirv_build_op_trv(builder, &builder->global_stream,
+ SpvOpConstant, result_type, values, value_count);
+}
+
+static uint32_t vkd3d_spirv_get_op_constant64(struct vkd3d_spirv_builder *builder,
+ uint32_t result_type, uint64_t value)
+{
+ return vkd3d_spirv_build_once1v(builder, SpvOpConstant, result_type,
+ (const uint32_t *)&value, 2, vkd3d_spirv_build_op_constant64);
+}
+
static uint32_t vkd3d_spirv_build_op_constant_composite(struct vkd3d_spirv_builder *builder,
uint32_t result_type, const uint32_t *constituents, unsigned int constituent_count)
{
@@ -2709,6 +2724,35 @@ static uint32_t vkd3d_dxbc_compiler_get_constant(struct vkd3d_dxbc_compiler *com
}
}
+static uint32_t vkd3d_dxbc_compiler_get_constant64(struct vkd3d_dxbc_compiler *compiler,
+ enum vkd3d_shader_component_type component_type, unsigned int component_count, const uint64_t *values)
+{
+ uint32_t type_id, scalar_type_id, component_ids[VKD3D_DVEC2_SIZE];
+ struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
+ unsigned int i;
+
+ assert(0 < component_count && component_count <= VKD3D_DVEC2_SIZE);
+ type_id = vkd3d_spirv_get_type_id(builder, component_type, component_count);
+
+ if (component_type != VKD3D_SHADER_COMPONENT_DOUBLE)
+ {
+ FIXME("Unhandled component_type %#x.\n", component_type);
+ return vkd3d_spirv_build_op_undef(builder, &builder->global_stream, type_id);
+ }
+
+ if (component_count == 1)
+ {
+ return vkd3d_spirv_get_op_constant64(builder, type_id, *values);
+ }
+ else
+ {
+ scalar_type_id = vkd3d_spirv_get_type_id(builder, component_type, 1);
+ for (i = 0; i < component_count; ++i)
+ component_ids[i] = vkd3d_spirv_get_op_constant64(builder, scalar_type_id, values[i]);
+ return vkd3d_spirv_get_op_constant_composite(builder, type_id, component_ids, component_count);
+ }
+}
+
static uint32_t vkd3d_dxbc_compiler_get_constant_uint(struct vkd3d_dxbc_compiler *compiler,
uint32_t value)
{
@@ -3079,7 +3123,7 @@ static bool vkd3d_dxbc_compiler_get_register_info(const struct vkd3d_dxbc_compil
struct vkd3d_symbol reg_symbol, *symbol;
struct rb_entry *entry;
- assert(reg->type != VKD3DSPR_IMMCONST);
+ assert(reg->type != VKD3DSPR_IMMCONST && reg->type != VKD3DSPR_IMMCONST64);
if (reg->type == VKD3DSPR_TEMP)
{
@@ -3390,6 +3434,33 @@ static uint32_t vkd3d_dxbc_compiler_emit_load_constant(struct vkd3d_dxbc_compile
vkd3d_component_type_from_data_type(reg->data_type), component_count, values);
}
+static uint32_t vkd3d_dxbc_compiler_emit_load_constant64(struct vkd3d_dxbc_compiler *compiler,
+ const struct vkd3d_shader_register *reg, DWORD swizzle, DWORD write_mask)
+{
+ unsigned int component_count = vkd3d_write_mask_component_count(write_mask);
+ uint64_t values[VKD3D_DVEC2_SIZE] = {0};
+ unsigned int i, j;
+
+ assert(reg->type == VKD3DSPR_IMMCONST64);
+
+ if (reg->immconst_type == VKD3D_IMMCONST_SCALAR)
+ {
+ for (i = 0; i < component_count; ++i)
+ values[i] = *reg->u.immconst_uint64;
+ }
+ else
+ {
+ for (i = 0, j = 0; i < VKD3D_DVEC2_SIZE; ++i)
+ {
+ if (write_mask & (VKD3DSP_WRITEMASK_0 << i))
+ values[j++] = reg->u.immconst_uint64[vkd3d_swizzle_get_component64(swizzle, i)];
+ }
+ }
+
+ return vkd3d_dxbc_compiler_get_constant64(compiler,
+ vkd3d_component_type_from_data_type(reg->data_type), component_count, values);
+}
+
static uint32_t vkd3d_dxbc_compiler_emit_load_scalar(struct vkd3d_dxbc_compiler *compiler,
const struct vkd3d_shader_register *reg, DWORD swizzle, DWORD write_mask,
const struct vkd3d_shader_register_info *reg_info)
@@ -3400,7 +3471,7 @@ static uint32_t vkd3d_dxbc_compiler_emit_load_scalar(struct vkd3d_dxbc_compiler
enum vkd3d_shader_component_type component_type;
unsigned int skipped_component_mask;
- assert(reg->type != VKD3DSPR_IMMCONST);
+ assert(reg->type != VKD3DSPR_IMMCONST && reg->type != VKD3DSPR_IMMCONST64);
assert(vkd3d_write_mask_component_count(write_mask) == 1);
component_idx = vkd3d_write_mask_get_component_idx(write_mask);
@@ -3450,6 +3521,8 @@ static uint32_t vkd3d_dxbc_compiler_emit_load_reg(struct vkd3d_dxbc_compiler *co
if (reg->type == VKD3DSPR_IMMCONST)
return vkd3d_dxbc_compiler_emit_load_constant(compiler, reg, swizzle, write_mask);
+ else if (reg->type == VKD3DSPR_IMMCONST64)
+ return vkd3d_dxbc_compiler_emit_load_constant64(compiler, reg, swizzle, write_mask);
component_count = vkd3d_write_mask_component_count(write_mask);
component_type = vkd3d_component_type_from_data_type(reg->data_type);
@@ -3665,7 +3738,7 @@ static void vkd3d_dxbc_compiler_emit_store_reg(struct vkd3d_dxbc_compiler *compi
unsigned int src_write_mask = write_mask;
uint32_t type_id;
- assert(reg->type != VKD3DSPR_IMMCONST);
+ assert(reg->type != VKD3DSPR_IMMCONST && reg->type != VKD3DSPR_IMMCONST64);
if (!vkd3d_dxbc_compiler_get_register_info(compiler, reg, ®_info))
return;
@@ -6840,7 +6913,7 @@ static void vkd3d_dxbc_compiler_emit_mov(struct vkd3d_dxbc_compiler *compiler,
uint32_t components[VKD3D_VEC4_SIZE];
unsigned int i, component_count;
- if (src->reg.type == VKD3DSPR_IMMCONST || dst->modifiers || src->modifiers)
+ if (src->reg.type == VKD3DSPR_IMMCONST || src->reg.type == VKD3DSPR_IMMCONST64 || dst->modifiers || src->modifiers)
goto general_implementation;
vkd3d_dxbc_compiler_get_register_info(compiler, &dst->reg, &dst_reg_info);
diff --git a/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d-shader/vkd3d_shader_private.h
index b3cd8ce..c450049 100644
--- a/libs/vkd3d-shader/vkd3d_shader_private.h
+++ b/libs/vkd3d-shader/vkd3d_shader_private.h
@@ -621,6 +621,7 @@ struct vkd3d_shader_register
{
DWORD immconst_uint[VKD3D_VEC4_SIZE];
float immconst_float[VKD3D_VEC4_SIZE];
+ uint64_t immconst_uint64[VKD3D_DVEC2_SIZE];
double immconst_double[VKD3D_DVEC2_SIZE];
unsigned fp_body_idx;
} u;
@@ -1087,6 +1088,12 @@ static inline unsigned int vkd3d_swizzle_get_component(DWORD swizzle,
return (swizzle >> VKD3D_SHADER_SWIZZLE_SHIFT(idx)) & VKD3D_SHADER_SWIZZLE_MASK;
}
+static inline unsigned int vkd3d_swizzle_get_component64(DWORD swizzle,
+ unsigned int idx)
+{
+ return ((swizzle >> VKD3D_SHADER_SWIZZLE_SHIFT(idx * 2)) & VKD3D_SHADER_SWIZZLE_MASK) / 2u;
+}
+
static inline unsigned int vkd3d_compact_swizzle(unsigned int swizzle, unsigned int write_mask)
{
unsigned int i, compacted_swizzle = 0;
More information about the wine-cvs
mailing list