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