Signed-off-by: Zebediah Figura zfigura@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')