Zebediah Figura : vkd3d-shader/hlsl: Write SM4 semantic declarations.

Alexandre Julliard julliard at winehq.org
Mon Aug 23 16:24:07 CDT 2021


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

Author: Zebediah Figura <zfigura at codeweavers.com>
Date:   Thu Aug 19 18:44:29 2021 -0500

vkd3d-shader/hlsl: Write SM4 semantic declarations.

Signed-off-by: Zebediah Figura <zfigura at codeweavers.com>
Signed-off-by: Matteo Bruni <mbruni at codeweavers.com>
Signed-off-by: Henri Verbeet <hverbeet at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 libs/vkd3d-shader/hlsl.h         |   2 +-
 libs/vkd3d-shader/hlsl_codegen.c |   4 +-
 libs/vkd3d-shader/hlsl_sm4.c     | 117 ++++++++++++++++++++++++++++++++++++++-
 3 files changed, 118 insertions(+), 5 deletions(-)

diff --git a/libs/vkd3d-shader/hlsl.h b/libs/vkd3d-shader/hlsl.h
index 9860ed7..80cea51 100644
--- a/libs/vkd3d-shader/hlsl.h
+++ b/libs/vkd3d-shader/hlsl.h
@@ -688,7 +688,7 @@ int hlsl_sm1_write(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_fun
 bool hlsl_sm4_usage_from_semantic(struct hlsl_ctx *ctx,
         const struct hlsl_semantic *semantic, bool output, D3D_NAME *usage);
 bool hlsl_sm4_register_from_semantic(struct hlsl_ctx *ctx, const struct hlsl_semantic *semantic,
-        bool output, enum vkd3d_sm4_register_type *type, uint32_t *reg);
+        bool output, enum vkd3d_sm4_register_type *type, bool *has_idx);
 int hlsl_sm4_write(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_func, struct vkd3d_shader_code *out);
 
 int hlsl_lexer_compile(struct hlsl_ctx *ctx, const struct vkd3d_shader_code *hlsl);
diff --git a/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d-shader/hlsl_codegen.c
index 939b356..a1d6e8e 100644
--- a/libs/vkd3d-shader/hlsl_codegen.c
+++ b/libs/vkd3d-shader/hlsl_codegen.c
@@ -1048,6 +1048,7 @@ static void allocate_semantic_register(struct hlsl_ctx *ctx, struct hlsl_ir_var
     else
     {
         D3D_NAME usage;
+        bool has_idx;
 
         if (!hlsl_sm4_usage_from_semantic(ctx, &var->semantic, output, &usage))
         {
@@ -1055,7 +1056,8 @@ static void allocate_semantic_register(struct hlsl_ctx *ctx, struct hlsl_ir_var
                     "Invalid semantic '%s'.", var->semantic.name);
             return;
         }
-        builtin = hlsl_sm4_register_from_semantic(ctx, &var->semantic, output, &type, &reg);
+        if ((builtin = hlsl_sm4_register_from_semantic(ctx, &var->semantic, output, &type, &has_idx)))
+            reg = has_idx ? var->semantic.index : 0;
     }
 
     if (builtin)
diff --git a/libs/vkd3d-shader/hlsl_sm4.c b/libs/vkd3d-shader/hlsl_sm4.c
index 029dc3d..92f854c 100644
--- a/libs/vkd3d-shader/hlsl_sm4.c
+++ b/libs/vkd3d-shader/hlsl_sm4.c
@@ -24,7 +24,7 @@
 #include "sm4.h"
 
 bool hlsl_sm4_register_from_semantic(struct hlsl_ctx *ctx, const struct hlsl_semantic *semantic,
-        bool output, enum vkd3d_sm4_register_type *type, uint32_t *reg)
+        bool output, enum vkd3d_sm4_register_type *type, bool *has_idx)
 {
     unsigned int i;
 
@@ -56,7 +56,7 @@ bool hlsl_sm4_register_from_semantic(struct hlsl_ctx *ctx, const struct hlsl_sem
                 && ctx->profile->type == register_table[i].shader_type)
         {
             *type = register_table[i].type;
-            *reg = register_table[i].has_idx ? semantic->index : ~0u;
+            *has_idx = register_table[i].has_idx;
             return true;
         }
     }
@@ -137,6 +137,7 @@ static void write_sm4_signature(struct hlsl_ctx *ctx, struct dxbc_writer *dxbc,
         enum vkd3d_sm4_register_type type;
         uint32_t usage_idx, reg_idx;
         D3D_NAME usage;
+        bool has_idx;
 
         if ((output && !var->is_output_semantic) || (!output && !var->is_input_semantic))
             continue;
@@ -145,7 +146,11 @@ static void write_sm4_signature(struct hlsl_ctx *ctx, struct dxbc_writer *dxbc,
         assert(ret);
         usage_idx = var->semantic.index;
 
-        if (!hlsl_sm4_register_from_semantic(ctx, &var->semantic, output, &type, &reg_idx))
+        if (hlsl_sm4_register_from_semantic(ctx, &var->semantic, output, &type, &has_idx))
+        {
+            reg_idx = has_idx ? var->semantic.index : ~0u;
+        }
+        else
         {
             assert(var->reg.allocated);
             type = VKD3D_SM4_RT_INPUT;
@@ -574,6 +579,9 @@ struct sm4_instruction
     } srcs[2];
     unsigned int src_count;
 
+    uint32_t idx[2];
+    unsigned int idx_count;
+
     unsigned int has_dst;
 };
 
@@ -582,6 +590,7 @@ static unsigned int sm4_swizzle_type(enum vkd3d_sm4_register_type type)
     switch (type)
     {
         case VKD3D_SM4_RT_CONSTBUFFER:
+        case VKD3D_SM4_RT_INPUT:
             return VKD3D_SM4_SWIZZLE_VEC4;
 
         default:
@@ -615,6 +624,7 @@ static void write_sm4_instruction(struct vkd3d_bytecode_buffer *buffer, const st
         size += sm4_register_order(&instr->dst.reg);
     for (i = 0; i < instr->src_count; ++i)
         size += sm4_register_order(&instr->srcs[i].reg);
+    size += instr->idx_count;
 
     token |= (size << VKD3D_SM4_INSTRUCTION_LENGTH_SHIFT);
     put_u32(buffer, token);
@@ -640,6 +650,9 @@ static void write_sm4_instruction(struct vkd3d_bytecode_buffer *buffer, const st
         for (j = 0; j < instr->srcs[i].reg.idx_count; ++j)
             put_u32(buffer, instr->srcs[i].reg.idx[j]);
     }
+
+    for (j = 0; j < instr->idx_count; ++j)
+        put_u32(buffer, instr->idx[j]);
 }
 
 static void write_sm4_dcl_constant_buffer(struct vkd3d_bytecode_buffer *buffer, const struct hlsl_buffer *cbuffer)
@@ -658,11 +671,103 @@ static void write_sm4_dcl_constant_buffer(struct vkd3d_bytecode_buffer *buffer,
     write_sm4_instruction(buffer, &instr);
 }
 
+static void write_sm4_dcl_semantic(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *buffer, const struct hlsl_ir_var *var)
+{
+    const struct hlsl_profile_info *profile = ctx->profile;
+    const bool output = var->is_output_semantic;
+    D3D_NAME usage;
+    bool has_idx;
+
+    struct sm4_instruction instr =
+    {
+        .dst.reg.dim = VKD3D_SM4_DIMENSION_VEC4,
+        .has_dst = 1,
+    };
+
+    if (hlsl_sm4_register_from_semantic(ctx, &var->semantic, output, &instr.dst.reg.type, &has_idx))
+    {
+        if (has_idx)
+        {
+            instr.dst.reg.idx[0] = var->semantic.index;
+            instr.dst.reg.idx_count = 1;
+        }
+        else
+        {
+            instr.dst.reg.idx_count = 0;
+        }
+        instr.dst.writemask = (1 << var->data_type->dimx) - 1;
+    }
+    else
+    {
+        instr.dst.reg.type = output ? VKD3D_SM4_RT_OUTPUT : VKD3D_SM4_RT_INPUT;
+        instr.dst.reg.idx[0] = var->reg.id;
+        instr.dst.reg.idx_count = 1;
+        instr.dst.writemask = var->reg.writemask;
+    }
+
+    if (instr.dst.reg.type == VKD3D_SM4_RT_DEPTHOUT)
+        instr.dst.reg.dim = VKD3D_SM4_DIMENSION_SCALAR;
+
+    hlsl_sm4_usage_from_semantic(ctx, &var->semantic, output, &usage);
+
+    if (var->is_input_semantic)
+    {
+        switch (usage)
+        {
+            case D3D_NAME_UNDEFINED:
+                instr.opcode = (profile->type == VKD3D_SHADER_TYPE_PIXEL)
+                        ? VKD3D_SM4_OP_DCL_INPUT_PS : VKD3D_SM4_OP_DCL_INPUT;
+                break;
+
+            case D3D_NAME_INSTANCE_ID:
+            case D3D_NAME_PRIMITIVE_ID:
+            case D3D_NAME_VERTEX_ID:
+                instr.opcode = (profile->type == VKD3D_SHADER_TYPE_PIXEL)
+                        ? VKD3D_SM4_OP_DCL_INPUT_PS_SGV : VKD3D_SM4_OP_DCL_INPUT_SGV;
+                break;
+
+            default:
+                instr.opcode = (profile->type == VKD3D_SHADER_TYPE_PIXEL)
+                        ? VKD3D_SM4_OP_DCL_INPUT_PS_SIV : VKD3D_SM4_OP_DCL_INPUT_SIV;
+                break;
+        }
+
+        if (profile->type == VKD3D_SHADER_TYPE_PIXEL)
+            instr.opcode |= VKD3DSIM_LINEAR << VKD3D_SM4_INTERPOLATION_MODE_SHIFT;
+    }
+    else
+    {
+        if (usage == D3D_NAME_UNDEFINED || profile->type == VKD3D_SHADER_TYPE_PIXEL)
+            instr.opcode = VKD3D_SM4_OP_DCL_OUTPUT;
+        else
+            instr.opcode = VKD3D_SM4_OP_DCL_OUTPUT_SIV;
+    }
+
+    switch (usage)
+    {
+        case D3D_NAME_COVERAGE:
+        case D3D_NAME_DEPTH:
+        case D3D_NAME_DEPTH_GREATER_EQUAL:
+        case D3D_NAME_DEPTH_LESS_EQUAL:
+        case D3D_NAME_TARGET:
+        case D3D_NAME_UNDEFINED:
+            break;
+
+        default:
+            instr.idx_count = 1;
+            instr.idx[0] = usage;
+            break;
+    }
+
+    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;
+    const struct hlsl_ir_var *var;
 
     static const uint16_t shader_types[VKD3D_SHADER_TYPE_COUNT] =
     {
@@ -686,6 +791,12 @@ static void write_sm4_shdr(struct hlsl_ctx *ctx, struct dxbc_writer *dxbc)
             write_sm4_dcl_constant_buffer(&buffer, cbuffer);
     }
 
+    LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry)
+    {
+        if ((var->is_input_semantic && var->last_read) || (var->is_output_semantic && var->first_write))
+            write_sm4_dcl_semantic(ctx, &buffer, var);
+    }
+
     dxbc_writer_add_section(dxbc, TAG_SHDR, buffer.data, buffer.size);
 }
 




More information about the wine-cvs mailing list