[PATCH vkd3d 4/6] vkd3d-shader/hlsl: Write the RDEF section.

Zebediah Figura zfigura at codeweavers.com
Tue Aug 17 12:38:59 CDT 2021


Signed-off-by: Zebediah Figura <zfigura at codeweavers.com>
---
 include/vkd3d_d3dcommon.idl              |  45 ++++++++
 libs/vkd3d-shader/hlsl_sm4.c             | 141 +++++++++++++++++++++++
 libs/vkd3d-shader/vkd3d_shader_private.h |   2 +
 3 files changed, 188 insertions(+)

diff --git a/include/vkd3d_d3dcommon.idl b/include/vkd3d_d3dcommon.idl
index e43cbe41..97765c80 100644
--- a/include/vkd3d_d3dcommon.idl
+++ b/include/vkd3d_d3dcommon.idl
@@ -1,4 +1,5 @@
 /*
+ * Copyright 2010 Matteo Bruni for CodeWeavers
  * Copyright 2016 Józef Kucia for CodeWeavers
  *
  * This library is free software; you can redistribute it and/or
@@ -79,6 +80,50 @@ typedef enum D3D_FEATURE_LEVEL
     D3D_FEATURE_LEVEL_12_1 = 0xc100,
 } D3D_FEATURE_LEVEL;
 
+typedef enum D3D_CBUFFER_TYPE
+{
+    D3D_CT_CBUFFER,
+    D3D_CT_TBUFFER,
+    D3D_CT_INTERFACE_POINTERS,
+    D3D_CT_RESOURCE_BIND_INFO,
+} D3D_CBUFFER_TYPE;
+
+typedef enum _D3D_SHADER_INPUT_FLAGS
+{
+    D3D_SIF_USERPACKED          = 0x01,
+    D3D_SIF_COMPARISON_SAMPLER  = 0x02,
+    D3D_SIF_TEXTURE_COMPONENT_0 = 0x04,
+    D3D_SIF_TEXTURE_COMPONENT_1 = 0x08,
+    D3D_SIF_TEXTURE_COMPONENTS  = 0x0c,
+    D3D_SIF_UNUSED              = 0x10,
+    D3D_SIF_FORCE_DWORD         = 0x7fffffff,
+} D3D_SHADER_INPUT_FLAGS;
+
+typedef enum _D3D_SHADER_INPUT_TYPE
+{
+    D3D_SIT_CBUFFER,
+    D3D_SIT_TBUFFER,
+    D3D_SIT_TEXTURE,
+    D3D_SIT_SAMPLER,
+    D3D_SIT_UAV_RWTYPED,
+    D3D_SIT_STRUCTURED,
+    D3D_SIT_UAV_RWSTRUCTURED,
+    D3D_SIT_BYTEADDRESS,
+    D3D_SIT_UAV_RWBYTEADDRESS,
+    D3D_SIT_UAV_APPEND_STRUCTURED,
+    D3D_SIT_UAV_CONSUME_STRUCTURED,
+    D3D_SIT_UAV_RWSTRUCTURED_WITH_COUNTER,
+} D3D_SHADER_INPUT_TYPE;
+
+typedef enum _D3D_SHADER_VARIABLE_FLAGS
+{
+    D3D_SVF_USERPACKED          = 0x01,
+    D3D_SVF_USED                = 0x02,
+    D3D_SVF_INTERFACE_POINTER   = 0x04,
+    D3D_SVF_INTERFACE_PARAMETER = 0x08,
+    D3D_SVF_FORCE_DWORD         = 0x7fffffff,
+} D3D_SHADER_VARIABLE_FLAGS;
+
 [
     uuid(8ba5fb08-5195-40e2-ac58-0d989c3a0102),
     object,
diff --git a/libs/vkd3d-shader/hlsl_sm4.c b/libs/vkd3d-shader/hlsl_sm4.c
index c9a427d8..e9cfa2b6 100644
--- a/libs/vkd3d-shader/hlsl_sm4.c
+++ b/libs/vkd3d-shader/hlsl_sm4.c
@@ -20,8 +20,148 @@
 
 #include "hlsl.h"
 #include <stdio.h>
+#include "vkd3d_d3dcommon.h"
 #include "sm4.h"
 
+static void write_sm4_rdef(struct hlsl_ctx *ctx, struct dxbc_writer *dxbc)
+{
+    size_t cbuffers_offset, resources_offset, creator_offset, string_offset;
+    size_t cbuffer_position, resource_position, creator_position;
+    const struct hlsl_profile_info *profile = ctx->profile;
+    struct vkd3d_bytecode_buffer buffer = {0};
+    const struct hlsl_buffer *cbuffer;
+    unsigned int cbuffer_count = 0, i;
+
+    static const uint16_t target_types[] =
+    {
+        0xffff, /* PIXEL */
+        0xfffe, /* VERTEX */
+        0x4753, /* GEOMETRY */
+        0x4853, /* HULL */
+        0x4453, /* DOMAIN */
+        0x4353, /* COMPUTE */
+    };
+
+    LIST_FOR_EACH_ENTRY(cbuffer, &ctx->buffers, struct hlsl_buffer, entry)
+    {
+        if (cbuffer->reg.allocated)
+            ++cbuffer_count;
+    }
+
+    put_u32(&buffer, cbuffer_count);
+    cbuffer_position = put_u32(&buffer, 0);
+    put_u32(&buffer, cbuffer_count); /* bound resource count */
+    resource_position = put_u32(&buffer, 0);
+    put_u32(&buffer, (target_types[profile->type] << 16) | (profile->major_version << 8) | profile->minor_version);
+    put_u32(&buffer, 0); /* FIXME: compilation flags */
+    creator_position = put_u32(&buffer, 0);
+
+    /* Bound resources. */
+
+    resources_offset = bytecode_get_size(&buffer);
+    set_u32(&buffer, resource_position, resources_offset);
+    LIST_FOR_EACH_ENTRY(cbuffer, &ctx->buffers, struct hlsl_buffer, entry)
+    {
+        uint32_t flags = 0;
+
+        if (!cbuffer->reg.allocated)
+            continue;
+
+        if (cbuffer->reservation.type)
+            flags |= D3D_SIF_USERPACKED;
+
+        put_u32(&buffer, 0); /* name */
+        put_u32(&buffer, cbuffer->type == HLSL_BUFFER_CONSTANT ? D3D_SIT_CBUFFER : D3D_SIT_TBUFFER);
+        put_u32(&buffer, 0); /* return type */
+        put_u32(&buffer, 0); /* dimension */
+        put_u32(&buffer, 0); /* multisample count */
+        put_u32(&buffer, cbuffer->reg.id); /* bind point */
+        put_u32(&buffer, 1); /* bind count */
+        put_u32(&buffer, flags); /* flags */
+    }
+
+    i = 0;
+    LIST_FOR_EACH_ENTRY(cbuffer, &ctx->buffers, struct hlsl_buffer, entry)
+    {
+        if (!cbuffer->reg.allocated)
+            continue;
+
+        string_offset = put_string(&buffer, cbuffer->name);
+        set_u32(&buffer, resources_offset + i++ * 8 * sizeof(uint32_t), string_offset);
+    }
+
+    /* Buffers. */
+
+    cbuffers_offset = bytecode_get_size(&buffer);
+    set_u32(&buffer, cbuffer_position, cbuffers_offset);
+    LIST_FOR_EACH_ENTRY(cbuffer, &ctx->buffers, struct hlsl_buffer, entry)
+    {
+        const struct hlsl_ir_var *var;
+        unsigned int var_count = 0;
+
+        if (!cbuffer->reg.allocated)
+            continue;
+
+        LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry)
+        {
+            if (var->is_uniform && var->buffer == cbuffer)
+                ++var_count;
+        }
+
+        put_u32(&buffer, 0); /* name */
+        put_u32(&buffer, var_count);
+        put_u32(&buffer, 0); /* variable offset */
+        put_u32(&buffer, align(cbuffer->size, 4) * sizeof(float));
+        put_u32(&buffer, 0); /* FIXME: flags */
+        put_u32(&buffer, cbuffer->type == HLSL_BUFFER_CONSTANT ? D3D_CT_CBUFFER : D3D_CT_TBUFFER);
+    }
+
+    i = 0;
+    LIST_FOR_EACH_ENTRY(cbuffer, &ctx->buffers, struct hlsl_buffer, entry)
+    {
+        if (!cbuffer->reg.allocated)
+            continue;
+
+        string_offset = put_string(&buffer, cbuffer->name);
+        set_u32(&buffer, cbuffers_offset + i++ * 6 * sizeof(uint32_t), string_offset);
+    }
+
+    i = 0;
+    LIST_FOR_EACH_ENTRY(cbuffer, &ctx->buffers, struct hlsl_buffer, entry)
+    {
+        size_t vars_start = bytecode_get_size(&buffer);
+        const struct hlsl_ir_var *var;
+
+        if (!cbuffer->reg.allocated)
+            continue;
+
+        set_u32(&buffer, cbuffers_offset + (i++ * 6 + 2) * sizeof(uint32_t), vars_start);
+
+        LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry)
+        {
+            if (var->is_uniform && var->buffer == cbuffer)
+            {
+                uint32_t flags = 0;
+
+                if (var->last_read)
+                    flags |= D3D_SVF_USED;
+
+                put_u32(&buffer, 0); /* name */
+                put_u32(&buffer, var->buffer_offset);
+                put_u32(&buffer, var->data_type->reg_size * sizeof(float));
+                put_u32(&buffer, flags);
+                put_u32(&buffer, 0); /* FIXME: type */
+                put_u32(&buffer, 0); /* FIXME: default value */
+            }
+        }
+    }
+
+    creator_offset = put_string(&buffer, vkd3d_shader_get_version(NULL, NULL));
+    set_u32(&buffer, creator_position, creator_offset);
+
+    dxbc_writer_add_section(dxbc, TAG_RDEF, buffer.data, buffer.size);
+}
+
 static void write_sm4_shdr(struct hlsl_ctx *ctx, struct dxbc_writer *dxbc)
 {
     const struct hlsl_profile_info *profile = ctx->profile;
@@ -54,6 +194,7 @@ int hlsl_sm4_write(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_fun
 
     dxbc_writer_init(&dxbc);
 
+    write_sm4_rdef(ctx, &dxbc);
     write_sm4_shdr(ctx, &dxbc);
 
     ret = dxbc_writer_write(&dxbc, out);
diff --git a/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d-shader/vkd3d_shader_private.h
index 9320c517..a699a156 100644
--- a/libs/vkd3d-shader/vkd3d_shader_private.h
+++ b/libs/vkd3d-shader/vkd3d_shader_private.h
@@ -1147,6 +1147,8 @@ static inline void *vkd3d_find_struct_(const struct vkd3d_struct *chain,
 #define TAG_OSGN MAKE_TAG('O', 'S', 'G', 'N')
 #define TAG_PCSG MAKE_TAG('P', 'C', 'S', 'G')
 #define TAG_PSG1 MAKE_TAG('P', 'S', 'G', '1')
+#define TAG_RD11 MAKE_TAG('R', 'D', '1', '1')
+#define TAG_RDEF MAKE_TAG('R', 'D', 'E', 'F')
 #define TAG_RTS0 MAKE_TAG('R', 'T', 'S', '0')
 #define TAG_SHDR MAKE_TAG('S', 'H', 'D', 'R')
 #define TAG_SHEX MAKE_TAG('S', 'H', 'E', 'X')
-- 
2.32.0




More information about the wine-devel mailing list