Zebediah Figura : vkd3d-shader/hlsl: Write SM4 constant buffer declarations.
Alexandre Julliard
julliard at winehq.org
Mon Aug 23 16:24:07 CDT 2021
Module: vkd3d
Branch: master
Commit: 5da4949f7c4aa39b5156ab6dbfa1af188ff4a748
URL: https://source.winehq.org/git/vkd3d.git/?a=commit;h=5da4949f7c4aa39b5156ab6dbfa1af188ff4a748
Author: Zebediah Figura <zfigura at codeweavers.com>
Date: Thu Aug 19 18:44:28 2021 -0500
vkd3d-shader/hlsl: Write SM4 constant buffer declarations.
Signed-off-by: Zebediah Figura <zfigura at codeweavers.com>
Signed-off-by: Henri Verbeet <hverbeet at codeweavers.com>
Signed-off-by: Matteo Bruni <mbruni at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
libs/vkd3d-shader/hlsl_sm4.c | 116 +++++++++++++++++++++++++++++++++++++++++++
1 file changed, 116 insertions(+)
diff --git a/libs/vkd3d-shader/hlsl_sm4.c b/libs/vkd3d-shader/hlsl_sm4.c
index 894c513..029dc3d 100644
--- a/libs/vkd3d-shader/hlsl_sm4.c
+++ b/libs/vkd3d-shader/hlsl_sm4.c
@@ -549,10 +549,120 @@ static void write_sm4_rdef(struct hlsl_ctx *ctx, struct dxbc_writer *dxbc)
dxbc_writer_add_section(dxbc, TAG_RDEF, buffer.data, buffer.size);
}
+struct sm4_register
+{
+ enum vkd3d_sm4_register_type type;
+ uint32_t idx[2];
+ unsigned int idx_count;
+ enum vkd3d_sm4_dimension dim;
+};
+
+struct sm4_instruction
+{
+ enum vkd3d_sm4_opcode opcode;
+
+ struct
+ {
+ struct sm4_register reg;
+ unsigned int writemask;
+ } dst;
+
+ struct
+ {
+ struct sm4_register reg;
+ unsigned int swizzle;
+ } srcs[2];
+ unsigned int src_count;
+
+ unsigned int has_dst;
+};
+
+static unsigned int sm4_swizzle_type(enum vkd3d_sm4_register_type type)
+{
+ switch (type)
+ {
+ case VKD3D_SM4_RT_CONSTBUFFER:
+ return VKD3D_SM4_SWIZZLE_VEC4;
+
+ default:
+ FIXME("Unhandled register type %#x.\n", type);
+ return VKD3D_SM4_SWIZZLE_VEC4;
+ }
+}
+
+static uint32_t sm4_encode_register(const struct sm4_register *reg)
+{
+ return (reg->type << VKD3D_SM4_REGISTER_TYPE_SHIFT)
+ | (reg->idx_count << VKD3D_SM4_REGISTER_ORDER_SHIFT)
+ | (reg->dim << VKD3D_SM4_DIMENSION_SHIFT);
+}
+
+static uint32_t sm4_register_order(const struct sm4_register *reg)
+{
+ uint32_t order = 1;
+ if (reg->type == VKD3D_SM4_RT_IMMCONST)
+ order += reg->dim == VKD3D_SM4_DIMENSION_VEC4 ? 4 : 1;
+ order += reg->idx_count;
+ return order;
+}
+
+static void write_sm4_instruction(struct vkd3d_bytecode_buffer *buffer, const struct sm4_instruction *instr)
+{
+ uint32_t token = instr->opcode;
+ unsigned int size = 1, i, j;
+
+ if (instr->has_dst)
+ size += sm4_register_order(&instr->dst.reg);
+ for (i = 0; i < instr->src_count; ++i)
+ size += sm4_register_order(&instr->srcs[i].reg);
+
+ token |= (size << VKD3D_SM4_INSTRUCTION_LENGTH_SHIFT);
+ put_u32(buffer, token);
+
+ if (instr->has_dst)
+ {
+ token = sm4_encode_register(&instr->dst.reg);
+ if (instr->dst.reg.dim == VKD3D_SM4_DIMENSION_VEC4)
+ token |= instr->dst.writemask << VKD3D_SM4_WRITEMASK_SHIFT;
+ put_u32(buffer, token);
+
+ for (j = 0; j < instr->dst.reg.idx_count; ++j)
+ put_u32(buffer, instr->dst.reg.idx[j]);
+ }
+
+ for (i = 0; i < instr->src_count; ++i)
+ {
+ token = sm4_encode_register(&instr->srcs[i].reg);
+ token |= sm4_swizzle_type(instr->srcs[i].reg.type) << VKD3D_SM4_SWIZZLE_TYPE_SHIFT;
+ token |= instr->srcs[i].swizzle << VKD3D_SM4_SWIZZLE_SHIFT;
+ put_u32(buffer, token);
+
+ for (j = 0; j < instr->srcs[i].reg.idx_count; ++j)
+ put_u32(buffer, instr->srcs[i].reg.idx[j]);
+ }
+}
+
+static void write_sm4_dcl_constant_buffer(struct vkd3d_bytecode_buffer *buffer, const struct hlsl_buffer *cbuffer)
+{
+ const struct sm4_instruction instr =
+ {
+ .opcode = VKD3D_SM4_OP_DCL_CONSTANT_BUFFER,
+
+ .srcs[0].reg.dim = VKD3D_SM4_DIMENSION_VEC4,
+ .srcs[0].reg.type = VKD3D_SM4_RT_CONSTBUFFER,
+ .srcs[0].reg.idx = {cbuffer->reg.id, (cbuffer->used_size + 3) / 4},
+ .srcs[0].reg.idx_count = 2,
+ .srcs[0].swizzle = HLSL_SWIZZLE(X, Y, Z, W),
+ .src_count = 1,
+ };
+ write_sm4_instruction(buffer, &instr);
+}
+
static void write_sm4_shdr(struct hlsl_ctx *ctx, struct dxbc_writer *dxbc)
{
const struct hlsl_profile_info *profile = ctx->profile;
struct vkd3d_bytecode_buffer buffer = {0};
+ const struct hlsl_buffer *cbuffer;
static const uint16_t shader_types[VKD3D_SHADER_TYPE_COUNT] =
{
@@ -570,6 +680,12 @@ static void write_sm4_shdr(struct hlsl_ctx *ctx, struct dxbc_writer *dxbc)
put_u32(&buffer, vkd3d_make_u32((profile->major_version << 4) | profile->minor_version, shader_types[profile->type]));
put_u32(&buffer, 0); /* FIXME: instruction token count */
+ LIST_FOR_EACH_ENTRY(cbuffer, &ctx->buffers, struct hlsl_buffer, entry)
+ {
+ if (cbuffer->reg.allocated)
+ write_sm4_dcl_constant_buffer(&buffer, cbuffer);
+ }
+
dxbc_writer_add_section(dxbc, TAG_SHDR, buffer.data, buffer.size);
}
More information about the wine-cvs
mailing list