Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- libs/vkd3d-shader/hlsl.c | 16 +++++----------- libs/vkd3d-shader/hlsl.y | 34 ++++++++++++++++++++-------------- 2 files changed, 25 insertions(+), 25 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl.c b/libs/vkd3d-shader/hlsl.c index 3544b9d6..01d5e773 100644 --- a/libs/vkd3d-shader/hlsl.c +++ b/libs/vkd3d-shader/hlsl.c @@ -1278,7 +1278,6 @@ void hlsl_free_instr_list(struct list *list) * the "uses" list. */ LIST_FOR_EACH_ENTRY_SAFE_REV(node, next_node, list, struct hlsl_ir_node, entry) hlsl_free_instr(node); - vkd3d_free(list); }
static void free_ir_constant(struct hlsl_ir_constant *constant) @@ -1297,12 +1296,8 @@ static void free_ir_expr(struct hlsl_ir_expr *expr)
static void free_ir_if(struct hlsl_ir_if *if_node) { - struct hlsl_ir_node *node, *next_node; - - LIST_FOR_EACH_ENTRY_SAFE(node, next_node, &if_node->then_instrs, struct hlsl_ir_node, entry) - hlsl_free_instr(node); - LIST_FOR_EACH_ENTRY_SAFE(node, next_node, &if_node->else_instrs, struct hlsl_ir_node, entry) - hlsl_free_instr(node); + hlsl_free_instr_list(&if_node->then_instrs); + hlsl_free_instr_list(&if_node->else_instrs); hlsl_src_remove(&if_node->condition); vkd3d_free(if_node); } @@ -1320,10 +1315,7 @@ static void free_ir_load(struct hlsl_ir_load *load)
static void free_ir_loop(struct hlsl_ir_loop *loop) { - struct hlsl_ir_node *node, *next_node; - - LIST_FOR_EACH_ENTRY_SAFE(node, next_node, &loop->body, struct hlsl_ir_node, entry) - hlsl_free_instr(node); + hlsl_free_instr_list(&loop->body); vkd3d_free(loop); }
@@ -1342,6 +1334,8 @@ static void free_ir_swizzle(struct hlsl_ir_swizzle *swizzle)
void hlsl_free_instr(struct hlsl_ir_node *node) { + assert(list_empty(&node->uses)); + switch (node->type) { case HLSL_IR_CONSTANT: diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index 5f1e9167..cb4fd7c8 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -136,6 +136,12 @@ static struct list *make_empty_list(struct hlsl_ctx *ctx) return list; }
+static void destroy_instr_list(struct list *list) +{ + hlsl_free_instr_list(list); + vkd3d_free(list); +} + static void check_invalid_matrix_modifiers(struct hlsl_ctx *ctx, DWORD modifiers, struct vkd3d_shader_location loc) { if (modifiers & HLSL_MODIFIERS_MAJORITY_MASK) @@ -385,10 +391,10 @@ oom: vkd3d_free(loop); vkd3d_free(cond_jump); vkd3d_free(list); - hlsl_free_instr_list(init); - hlsl_free_instr_list(cond); - hlsl_free_instr_list(iter); - hlsl_free_instr_list(body); + destroy_instr_list(init); + destroy_instr_list(cond); + destroy_instr_list(iter); + destroy_instr_list(body); return NULL; }
@@ -405,7 +411,7 @@ static unsigned int initializer_size(const struct parse_initializer *initializer
static void free_parse_initializer(struct parse_initializer *initializer) { - hlsl_free_instr_list(initializer->instrs); + destroy_instr_list(initializer->instrs); vkd3d_free(initializer->args); }
@@ -1789,7 +1795,7 @@ hlsl_prog: { if (!list_empty($2)) hlsl_fixme(ctx, @2, "Uniform initializer."); - hlsl_free_instr_list($2); + destroy_instr_list($2); } | hlsl_prog preproc_directive | hlsl_prog ';' @@ -2364,7 +2370,7 @@ arrays: unsigned int size = evaluate_array_dimension(node_from_list($2)); uint32_t *new_array;
- hlsl_free_instr_list($2); + destroy_instr_list($2);
$$ = $4;
@@ -2656,7 +2662,7 @@ postfix_expr: { if (!add_increment(ctx, $1, false, true, @2)) { - hlsl_free_instr_list($1); + destroy_instr_list($1); YYABORT; } $$ = $1; @@ -2665,7 +2671,7 @@ postfix_expr: { if (!add_increment(ctx, $1, true, true, @2)) { - hlsl_free_instr_list($1); + destroy_instr_list($1); YYABORT; } $$ = $1; @@ -2717,20 +2723,20 @@ postfix_expr: if (index->data_type->type != HLSL_CLASS_SCALAR) { hlsl_error(ctx, @3, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, "Array index is not scalar."); - hlsl_free_instr_list($1); + destroy_instr_list($1); YYABORT; }
if (!(cast = hlsl_new_cast(ctx, index, ctx->builtin_types.scalar[HLSL_TYPE_UINT], &index->loc))) { - hlsl_free_instr_list($1); + destroy_instr_list($1); YYABORT; } list_add_tail($1, &cast->node.entry);
if (!add_array_load(ctx, $1, array, &cast->node, @2)) { - hlsl_free_instr_list($1); + destroy_instr_list($1); YYABORT; } $$ = $1; @@ -2821,7 +2827,7 @@ unary_expr: { if (!add_increment(ctx, $2, false, false, @1)) { - hlsl_free_instr_list($2); + destroy_instr_list($2); YYABORT; } $$ = $2; @@ -2830,7 +2836,7 @@ unary_expr: { if (!add_increment(ctx, $2, true, false, @1)) { - hlsl_free_instr_list($2); + destroy_instr_list($2); YYABORT; } $$ = $2;
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- Makefile.am | 1 + libs/vkd3d-shader/dxbc.c | 75 +++++++++++++++++++----- libs/vkd3d-shader/hlsl.h | 2 + libs/vkd3d-shader/hlsl_codegen.c | 2 +- libs/vkd3d-shader/hlsl_sm4.c | 31 ++++++++++ libs/vkd3d-shader/vkd3d_shader_private.h | 35 +++++++++++ tests/d3d12_test_utils.h | 2 +- tests/shader_runner_d3d12.c | 2 + 8 files changed, 132 insertions(+), 18 deletions(-) create mode 100644 libs/vkd3d-shader/hlsl_sm4.c
diff --git a/Makefile.am b/Makefile.am index 9624485b..5cdccc52 100644 --- a/Makefile.am +++ b/Makefile.am @@ -173,6 +173,7 @@ libvkd3d_shader_la_SOURCES = \ libs/vkd3d-shader/hlsl.h \ libs/vkd3d-shader/hlsl_codegen.c \ libs/vkd3d-shader/hlsl_sm1.c \ + libs/vkd3d-shader/hlsl_sm4.c \ libs/vkd3d-shader/preproc.h \ libs/vkd3d-shader/sm4.h \ libs/vkd3d-shader/spirv.c \ diff --git a/libs/vkd3d-shader/dxbc.c b/libs/vkd3d-shader/dxbc.c index 5dfe9295..83f91960 100644 --- a/libs/vkd3d-shader/dxbc.c +++ b/libs/vkd3d-shader/dxbc.c @@ -1,5 +1,6 @@ /* * Copyright 2008-2009 Henri Verbeet for CodeWeavers + * Copyright 2010 Rico Schüller * Copyright 2017 Józef Kucia for CodeWeavers * * This library is free software; you can redistribute it and/or @@ -20,6 +21,64 @@ #include "vkd3d_shader_private.h" #include "sm4.h"
+void dxbc_writer_init(struct dxbc_writer *dxbc) +{ + memset(dxbc, 0, sizeof(*dxbc)); +} + +void dxbc_writer_add_section(struct dxbc_writer *dxbc, uint32_t tag, const void *data, size_t size) +{ + struct dxbc_writer_section *section; + + assert(dxbc->section_count < ARRAY_SIZE(dxbc->sections)); + + section = &dxbc->sections[dxbc->section_count++]; + section->tag = tag; + section->data = data; + section->size = size; +} + +int dxbc_writer_write(struct dxbc_writer *dxbc, struct vkd3d_shader_code *out) +{ + size_t size_position, offsets_position, checksum_position, i; + struct vkd3d_bytecode_buffer buffer = {0}; + uint32_t checksum[4]; + + put_u32(&buffer, TAG_DXBC); + + checksum_position = bytecode_get_size(&buffer); + for (i = 0; i < 4; ++i) + put_u32(&buffer, 0); + + put_u32(&buffer, 1); /* version */ + size_position = put_u32(&buffer, 0); + put_u32(&buffer, dxbc->section_count); + + offsets_position = bytecode_get_size(&buffer); + for (i = 0; i < dxbc->section_count; ++i) + put_u32(&buffer, 0); + + for (i = 0; i < dxbc->section_count; ++i) + { + set_u32(&buffer, offsets_position + i * sizeof(uint32_t), bytecode_get_size(&buffer)); + put_u32(&buffer, dxbc->sections[i].tag); + put_u32(&buffer, dxbc->sections[i].size); + bytecode_put_bytes(&buffer, dxbc->sections[i].data, dxbc->sections[i].size); + } + set_u32(&buffer, size_position, bytecode_get_size(&buffer)); + + vkd3d_compute_dxbc_checksum(buffer.data, buffer.size, checksum); + for (i = 0; i < 4; ++i) + set_u32(&buffer, checksum_position + i * sizeof(uint32_t), checksum[i]); + + if (!buffer.status) + { + out->code = buffer.data; + out->size = buffer.size; + } + return buffer.status; +} + struct vkd3d_shader_src_param_entry { struct list entry; @@ -1592,22 +1651,6 @@ bool shader_sm4_is_end(void *data, const DWORD **ptr) return *ptr == priv->end; }
-#define MAKE_TAG(ch0, ch1, ch2, ch3) \ - ((DWORD)(ch0) | ((DWORD)(ch1) << 8) | \ - ((DWORD)(ch2) << 16) | ((DWORD)(ch3) << 24 )) -#define TAG_DXBC MAKE_TAG('D', 'X', 'B', 'C') -#define TAG_ISGN MAKE_TAG('I', 'S', 'G', 'N') -#define TAG_ISG1 MAKE_TAG('I', 'S', 'G', '1') -#define TAG_OSGN MAKE_TAG('O', 'S', 'G', 'N') -#define TAG_OSG5 MAKE_TAG('O', 'S', 'G', '5') -#define TAG_OSG1 MAKE_TAG('O', 'S', 'G', '1') -#define TAG_PCSG MAKE_TAG('P', 'C', 'S', 'G') -#define TAG_PSG1 MAKE_TAG('P', 'S', 'G', '1') -#define TAG_SHDR MAKE_TAG('S', 'H', 'D', 'R') -#define TAG_SHEX MAKE_TAG('S', 'H', 'E', 'X') -#define TAG_AON9 MAKE_TAG('A', 'o', 'n', '9') -#define TAG_RTS0 MAKE_TAG('R', 'T', 'S', '0') - static bool require_space(size_t offset, size_t count, size_t size, size_t data_size) { return !count || (data_size - offset) / count >= size; diff --git a/libs/vkd3d-shader/hlsl.h b/libs/vkd3d-shader/hlsl.h index da309a6b..41c16b07 100644 --- a/libs/vkd3d-shader/hlsl.h +++ b/libs/vkd3d-shader/hlsl.h @@ -683,6 +683,8 @@ bool hlsl_sm1_register_from_semantic(struct hlsl_ctx *ctx, const struct hlsl_sem bool hlsl_sm1_usage_from_semantic(const struct hlsl_semantic *semantic, D3DDECLUSAGE *usage, uint32_t *usage_idx); int hlsl_sm1_write(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_func, struct vkd3d_shader_code *out);
+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);
#endif diff --git a/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d-shader/hlsl_codegen.c index db340a78..b5f7832f 100644 --- a/libs/vkd3d-shader/hlsl_codegen.c +++ b/libs/vkd3d-shader/hlsl_codegen.c @@ -1272,5 +1272,5 @@ int hlsl_emit_dxbc(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_fun if (ctx->profile->major_version < 4) return hlsl_sm1_write(ctx, entry_func, out); else - return VKD3D_ERROR_NOT_IMPLEMENTED; + return hlsl_sm4_write(ctx, entry_func, out); } diff --git a/libs/vkd3d-shader/hlsl_sm4.c b/libs/vkd3d-shader/hlsl_sm4.c new file mode 100644 index 00000000..977b8395 --- /dev/null +++ b/libs/vkd3d-shader/hlsl_sm4.c @@ -0,0 +1,31 @@ +/* + * HLSL code generation for DXBC shader models 4-5 + * + * Copyright 2019-2020 Zebediah Figura for CodeWeavers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "hlsl.h" +#include <stdio.h> + +int hlsl_sm4_write(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_func, struct vkd3d_shader_code *out) +{ + struct dxbc_writer dxbc; + + dxbc_writer_init(&dxbc); + + return dxbc_writer_write(&dxbc, out); +} diff --git a/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d-shader/vkd3d_shader_private.h index 85503800..9320c517 100644 --- a/libs/vkd3d-shader/vkd3d_shader_private.h +++ b/libs/vkd3d-shader/vkd3d_shader_private.h @@ -1135,4 +1135,39 @@ static inline void *vkd3d_find_struct_(const struct vkd3d_struct *chain, #define VKD3D_DXBC_MAX_SOURCE_COUNT 6 #define VKD3D_DXBC_HEADER_SIZE (8 * sizeof(uint32_t))
+#define MAKE_TAG(ch0, ch1, ch2, ch3) \ + ((DWORD)(ch0) | ((DWORD)(ch1) << 8) | \ + ((DWORD)(ch2) << 16) | ((DWORD)(ch3) << 24 )) +#define TAG_AON9 MAKE_TAG('A', 'o', 'n', '9') +#define TAG_DXBC MAKE_TAG('D', 'X', 'B', 'C') +#define TAG_ISG1 MAKE_TAG('I', 'S', 'G', '1') +#define TAG_ISGN MAKE_TAG('I', 'S', 'G', 'N') +#define TAG_OSG1 MAKE_TAG('O', 'S', 'G', '1') +#define TAG_OSG5 MAKE_TAG('O', 'S', 'G', '5') +#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_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') + +struct dxbc_writer_section +{ + uint32_t tag; + const uint8_t *data; + size_t size; +}; + +#define DXBC_MAX_SECTION_COUNT 5 + +struct dxbc_writer +{ + unsigned int section_count; + struct dxbc_writer_section sections[DXBC_MAX_SECTION_COUNT]; +}; + +void dxbc_writer_add_section(struct dxbc_writer *dxbc, uint32_t tag, const void *data, size_t size); +void dxbc_writer_init(struct dxbc_writer *dxbc); +int dxbc_writer_write(struct dxbc_writer *dxbc, struct vkd3d_shader_code *code); + #endif /* __VKD3D_SHADER_PRIVATE_H */ diff --git a/tests/d3d12_test_utils.h b/tests/d3d12_test_utils.h index 5fe6f1ef..0374d8d1 100644 --- a/tests/d3d12_test_utils.h +++ b/tests/d3d12_test_utils.h @@ -844,7 +844,7 @@ static ID3D12PipelineState *create_pipeline_state_(unsigned int line, ID3D12Devi &IID_ID3D12PipelineState, (void **)&pipeline_state); ok_(line)(SUCCEEDED(hr), "Failed to create graphics pipeline state, hr %#x.\n", hr);
- return pipeline_state; + return SUCCEEDED(hr) ? pipeline_state : NULL; }
struct test_context_desc diff --git a/tests/shader_runner_d3d12.c b/tests/shader_runner_d3d12.c index 353e42c7..3cc859ab 100644 --- a/tests/shader_runner_d3d12.c +++ b/tests/shader_runner_d3d12.c @@ -141,6 +141,8 @@ static void parse_test_directive(struct shader_context *context, const char *lin
pso = create_pipeline_state(context->c.device, context->c.root_signature, context->c.render_target_desc.Format, NULL, &ps, NULL); + if (!pso) + return;
ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context->c.root_signature); ID3D12GraphicsCommandList_SetGraphicsRoot32BitConstants(command_list, 0,
Signed-off-by: Matteo Bruni mbruni@codeweavers.com
On Tue, 17 Aug 2021 at 19:39, Zebediah Figura zfigura@codeweavers.com wrote:
@@ -1272,5 +1272,5 @@ int hlsl_emit_dxbc(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_fun if (ctx->profile->major_version < 4) return hlsl_sm1_write(ctx, entry_func, out); else
return VKD3D_ERROR_NOT_IMPLEMENTED;
return hlsl_sm4_write(ctx, entry_func, out);
}
It's perhaps worth pointing out that there's an interaction with the target type here as well. Shader model 1-3 bytecode can either be output as-is, which is the legacy D3D bytecode format, or inside an "Aon9" section embedded inside a DXBC container. Neither of those is technically dxbc-tpf, but it's also possible to output DXBC containers that contain both TPF and "Aon9" sections.
On 8/19/21 10:54 AM, Henri Verbeet wrote:
On Tue, 17 Aug 2021 at 19:39, Zebediah Figura zfigura@codeweavers.com wrote:
@@ -1272,5 +1272,5 @@ int hlsl_emit_dxbc(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_fun if (ctx->profile->major_version < 4) return hlsl_sm1_write(ctx, entry_func, out); else
return VKD3D_ERROR_NOT_IMPLEMENTED;
}return hlsl_sm4_write(ctx, entry_func, out);
It's perhaps worth pointing out that there's an interaction with the target type here as well. Shader model 1-3 bytecode can either be output as-is, which is the legacy D3D bytecode format, or inside an "Aon9" section embedded inside a DXBC container. Neither of those is technically dxbc-tpf, but it's also possible to output DXBC containers that contain both TPF and "Aon9" sections.
I was assuming TPF referred to both SM1 and SM4 formats, since they are tokenized. What's the naming convention then? and what is the API convention?
On Thu, 19 Aug 2021 at 17:57, Zebediah Figura (she/her) zfigura@codeweavers.com wrote:
I was assuming TPF referred to both SM1 and SM4 formats, since they are tokenized. What's the naming convention then? and what is the API convention?
TPF is specifically the format used for shader model 4 and 5 shaders, mostly as opposed to DXIL for shader model 6. I've been using "VKD3D_SHADER_SOURCE_D3D_BYTECODE" for shader model 1-3 sources, and "d3dbc" as the vkd3d-compiler string. We'd then potentially have the following:
"d3dbc" - Legacy Direct3D bytecode, no container. "dxbc-d3dbc" - Legacy Direct3D bytecode embedded in a DXBC container. "dxbc-tpf" - TPF (shader model 4/5) embedded in a DXBC container. "dxbc-dxil" - DXIL (shader model 6) embedded in a DXBC container.
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- libs/vkd3d-shader/hlsl_sm4.c | 34 +++++++++++++++++++++++++++++++++- libs/vkd3d-shader/sm4.h | 1 + 2 files changed, 34 insertions(+), 1 deletion(-)
diff --git a/libs/vkd3d-shader/hlsl_sm4.c b/libs/vkd3d-shader/hlsl_sm4.c index 977b8395..c9a427d8 100644 --- a/libs/vkd3d-shader/hlsl_sm4.c +++ b/libs/vkd3d-shader/hlsl_sm4.c @@ -20,12 +20,44 @@
#include "hlsl.h" #include <stdio.h> +#include "sm4.h" + +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}; + + static const uint16_t shader_types[VKD3D_SHADER_TYPE_COUNT] = + { + VKD3D_SM4_PS, + VKD3D_SM4_VS, + VKD3D_SM4_GS, + VKD3D_SM5_HS, + VKD3D_SM5_DS, + VKD3D_SM5_CS, + 0, /* EFFECT */ + 0, /* TEXTURE */ + VKD3D_SM4_LIB, + }; + + put_u32(&buffer, (shader_types[profile->type] << 16) | (profile->major_version << 4) | profile->minor_version); + put_u32(&buffer, 0); /* FIXME: instruction token count */ + + dxbc_writer_add_section(dxbc, TAG_SHDR, buffer.data, buffer.size); +}
int hlsl_sm4_write(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_func, struct vkd3d_shader_code *out) { struct dxbc_writer dxbc; + size_t i; + int ret;
dxbc_writer_init(&dxbc);
- return dxbc_writer_write(&dxbc, out); + write_sm4_shdr(ctx, &dxbc); + + ret = dxbc_writer_write(&dxbc, out); + for (i = 0; i < dxbc.section_count; ++i) + vkd3d_free((void *)dxbc.sections[i].data); + return ret; } diff --git a/libs/vkd3d-shader/sm4.h b/libs/vkd3d-shader/sm4.h index 5622d6df..b4dd1632 100644 --- a/libs/vkd3d-shader/sm4.h +++ b/libs/vkd3d-shader/sm4.h @@ -25,6 +25,7 @@ #define VKD3D_SM5_HS 0x0003u #define VKD3D_SM5_DS 0x0004u #define VKD3D_SM5_CS 0x0005u +#define VKD3D_SM4_LIB 0xfff0u
#define VKD3D_SM4_INSTRUCTION_MODIFIER (0x1u << 31)
Signed-off-by: Matteo Bruni mbruni@codeweavers.com
On Tue, Aug 17, 2021 at 7:39 PM Zebediah Figura zfigura@codeweavers.com wrote:
Signed-off-by: Zebediah Figura zfigura@codeweavers.com
libs/vkd3d-shader/hlsl_sm4.c | 34 +++++++++++++++++++++++++++++++++- libs/vkd3d-shader/sm4.h | 1 + 2 files changed, 34 insertions(+), 1 deletion(-)
diff --git a/libs/vkd3d-shader/hlsl_sm4.c b/libs/vkd3d-shader/hlsl_sm4.c index 977b8395..c9a427d8 100644 --- a/libs/vkd3d-shader/hlsl_sm4.c +++ b/libs/vkd3d-shader/hlsl_sm4.c @@ -20,12 +20,44 @@
#include "hlsl.h" #include <stdio.h> +#include "sm4.h"
+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};
- static const uint16_t shader_types[VKD3D_SHADER_TYPE_COUNT] =
- {
VKD3D_SM4_PS,
VKD3D_SM4_VS,
VKD3D_SM4_GS,
VKD3D_SM5_HS,
VKD3D_SM5_DS,
VKD3D_SM5_CS,
0, /* EFFECT */
0, /* TEXTURE */
VKD3D_SM4_LIB,
- };
- put_u32(&buffer, (shader_types[profile->type] << 16) | (profile->major_version << 4) | profile->minor_version);
It might make sense to use vkd3d_make_u32() here. There are other similar occurrences in patch 4/6 and 5/6.
On 8/19/21 10:29 AM, Matteo Bruni wrote:
On Tue, Aug 17, 2021 at 7:39 PM Zebediah Figura zfigura@codeweavers.com wrote:
Signed-off-by: Zebediah Figura zfigura@codeweavers.com
libs/vkd3d-shader/hlsl_sm4.c | 34 +++++++++++++++++++++++++++++++++- libs/vkd3d-shader/sm4.h | 1 + 2 files changed, 34 insertions(+), 1 deletion(-)
diff --git a/libs/vkd3d-shader/hlsl_sm4.c b/libs/vkd3d-shader/hlsl_sm4.c index 977b8395..c9a427d8 100644 --- a/libs/vkd3d-shader/hlsl_sm4.c +++ b/libs/vkd3d-shader/hlsl_sm4.c @@ -20,12 +20,44 @@
#include "hlsl.h" #include <stdio.h> +#include "sm4.h"
+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};
- static const uint16_t shader_types[VKD3D_SHADER_TYPE_COUNT] =
- {
VKD3D_SM4_PS,
VKD3D_SM4_VS,
VKD3D_SM4_GS,
VKD3D_SM5_HS,
VKD3D_SM5_DS,
VKD3D_SM5_CS,
0, /* EFFECT */
0, /* TEXTURE */
VKD3D_SM4_LIB,
- };
- put_u32(&buffer, (shader_types[profile->type] << 16) | (profile->major_version << 4) | profile->minor_version);
It might make sense to use vkd3d_make_u32() here. There are other similar occurrences in patch 4/6 and 5/6.
Yes, that's pretty much exactly what I added it for. Sadly I wrote that patch after most of these...
I'll send a follow-up.
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com
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')
Signed-off-by: Matteo Bruni mbruni@codeweavers.com
On Tue, Aug 17, 2021 at 7:40 PM Zebediah Figura zfigura@codeweavers.com wrote:
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/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
- 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 */
Mostly for my own reference, the variable name is left unset here. It will be filled in the next patch, together with the type.
On 8/19/21 10:31 AM, Matteo Bruni wrote:
On Tue, Aug 17, 2021 at 7:40 PM Zebediah Figura zfigura@codeweavers.com wrote:
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/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
- 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 */
Mostly for my own reference, the variable name is left unset here. It will be filled in the next patch, together with the type.
That was probably a mistake, either in patch naming or contents, though I guess it's not worth fixing at this point.
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- include/vkd3d_d3dcommon.idl | 70 +++++++++++++++ libs/vkd3d-shader/hlsl_sm4.c | 160 ++++++++++++++++++++++++++++++++++- 2 files changed, 228 insertions(+), 2 deletions(-)
diff --git a/include/vkd3d_d3dcommon.idl b/include/vkd3d_d3dcommon.idl index 97765c80..0359a749 100644 --- a/include/vkd3d_d3dcommon.idl +++ b/include/vkd3d_d3dcommon.idl @@ -115,6 +115,19 @@ typedef enum _D3D_SHADER_INPUT_TYPE D3D_SIT_UAV_RWSTRUCTURED_WITH_COUNTER, } D3D_SHADER_INPUT_TYPE;
+typedef enum _D3D_SHADER_VARIABLE_CLASS +{ + D3D_SVC_SCALAR, + D3D_SVC_VECTOR, + D3D_SVC_MATRIX_ROWS, + D3D_SVC_MATRIX_COLUMNS, + D3D_SVC_OBJECT, + D3D_SVC_STRUCT, + D3D_SVC_INTERFACE_CLASS, + D3D_SVC_INTERFACE_POINTER, + D3D_SVC_FORCE_DWORD = 0x7fffffff, +} D3D_SHADER_VARIABLE_CLASS; + typedef enum _D3D_SHADER_VARIABLE_FLAGS { D3D_SVF_USERPACKED = 0x01, @@ -124,6 +137,63 @@ typedef enum _D3D_SHADER_VARIABLE_FLAGS D3D_SVF_FORCE_DWORD = 0x7fffffff, } D3D_SHADER_VARIABLE_FLAGS;
+typedef enum _D3D_SHADER_VARIABLE_TYPE +{ + D3D_SVT_VOID, + D3D_SVT_BOOL, + D3D_SVT_INT, + D3D_SVT_FLOAT, + D3D_SVT_STRING, + D3D_SVT_TEXTURE, + D3D_SVT_TEXTURE1D, + D3D_SVT_TEXTURE2D, + D3D_SVT_TEXTURE3D, + D3D_SVT_TEXTURECUBE, + D3D_SVT_SAMPLER, + D3D_SVT_SAMPLER1D, + D3D_SVT_SAMPLER2D, + D3D_SVT_SAMPLER3D, + D3D_SVT_SAMPLERCUBE, + D3D_SVT_PIXELSHADER, + D3D_SVT_VERTEXSHADER, + D3D_SVT_PIXELFRAGMENT, + D3D_SVT_VERTEXFRAGMENT, + D3D_SVT_UINT, + D3D_SVT_UINT8, + D3D_SVT_GEOMETRYSHADER, + D3D_SVT_RASTERIZER, + D3D_SVT_DEPTHSTENCIL, + D3D_SVT_BLEND, + D3D_SVT_BUFFER, + D3D_SVT_CBUFFER, + D3D_SVT_TBUFFER, + D3D_SVT_TEXTURE1DARRAY, + D3D_SVT_TEXTURE2DARRAY, + D3D_SVT_RENDERTARGETVIEW, + D3D_SVT_DEPTHSTENCILVIEW, + D3D_SVT_TEXTURE2DMS, + D3D_SVT_TEXTURE2DMSARRAY, + D3D_SVT_TEXTURECUBEARRAY, + D3D_SVT_HULLSHADER, + D3D_SVT_DOMAINSHADER, + D3D_SVT_INTERFACE_POINTER, + D3D_SVT_COMPUTESHADER, + D3D_SVT_DOUBLE, + D3D_SVT_RWTEXTURE1D, + D3D_SVT_RWTEXTURE1DARRAY, + D3D_SVT_RWTEXTURE2D, + D3D_SVT_RWTEXTURE2DARRAY, + D3D_SVT_RWTEXTURE3D, + D3D_SVT_RWBUFFER, + D3D_SVT_BYTEADDRESS_BUFFER, + D3D_SVT_RWBYTEADDRESS_BUFFER, + D3D_SVT_STRUCTURED_BUFFER, + D3D_SVT_RWSTRUCTURED_BUFFER, + D3D_SVT_APPEND_STRUCTURED_BUFFER, + D3D_SVT_CONSUME_STRUCTURED_BUFFER, + D3D_SVT_FORCE_DWORD = 0x7fffffff, +} D3D_SHADER_VARIABLE_TYPE; + [ uuid(8ba5fb08-5195-40e2-ac58-0d989c3a0102), object, diff --git a/libs/vkd3d-shader/hlsl_sm4.c b/libs/vkd3d-shader/hlsl_sm4.c index e9cfa2b6..cba56eef 100644 --- a/libs/vkd3d-shader/hlsl_sm4.c +++ b/libs/vkd3d-shader/hlsl_sm4.c @@ -23,14 +23,155 @@ #include "vkd3d_d3dcommon.h" #include "sm4.h"
+static const struct hlsl_type *get_array_type(const struct hlsl_type *type) +{ + if (type->type == HLSL_CLASS_ARRAY) + return get_array_type(type->e.array.type); + return type; +} + +static unsigned int get_array_size(const struct hlsl_type *type) +{ + if (type->type == HLSL_CLASS_ARRAY) + return get_array_size(type->e.array.type) * type->e.array.elements_count; + return 1; +} + +static D3D_SHADER_VARIABLE_CLASS sm4_class(const struct hlsl_type *type) +{ + switch (type->type) + { + case HLSL_CLASS_ARRAY: + return sm4_class(type->e.array.type); + case HLSL_CLASS_MATRIX: + assert(type->modifiers & HLSL_MODIFIERS_MAJORITY_MASK); + if (type->modifiers & HLSL_MODIFIER_COLUMN_MAJOR) + return D3D_SVC_MATRIX_COLUMNS; + else + return D3D_SVC_MATRIX_ROWS; + case HLSL_CLASS_OBJECT: + return D3D_SVC_OBJECT; + case HLSL_CLASS_SCALAR: + return D3D_SVC_SCALAR; + case HLSL_CLASS_STRUCT: + return D3D_SVC_STRUCT; + case HLSL_CLASS_VECTOR: + return D3D_SVC_VECTOR; + default: + ERR("Invalid class %#x.\n", type->type); + assert(0); + return 0; + } +} + +static D3D_SHADER_VARIABLE_TYPE sm4_base_type(const struct hlsl_type *type) +{ + switch (type->base_type) + { + case HLSL_TYPE_BOOL: + return D3D_SVT_BOOL; + case HLSL_TYPE_FLOAT: + case HLSL_TYPE_HALF: + return D3D_SVT_FLOAT; + case HLSL_TYPE_INT: + return D3D_SVT_INT; + case HLSL_TYPE_PIXELSHADER: + return D3D_SVT_PIXELSHADER; + case HLSL_TYPE_SAMPLER: + switch (type->sampler_dim) + { + case HLSL_SAMPLER_DIM_1D: + return D3D_SVT_SAMPLER1D; + case HLSL_SAMPLER_DIM_2D: + return D3D_SVT_SAMPLER2D; + case HLSL_SAMPLER_DIM_3D: + return D3D_SVT_SAMPLER3D; + case HLSL_SAMPLER_DIM_CUBE: + return D3D_SVT_SAMPLERCUBE; + case HLSL_SAMPLER_DIM_GENERIC: + return D3D_SVT_SAMPLER; + default: + assert(0); + } + break; + case HLSL_TYPE_STRING: + return D3D_SVT_STRING; + case HLSL_TYPE_TEXTURE: + switch (type->sampler_dim) + { + case HLSL_SAMPLER_DIM_1D: + return D3D_SVT_TEXTURE1D; + case HLSL_SAMPLER_DIM_2D: + return D3D_SVT_TEXTURE2D; + case HLSL_SAMPLER_DIM_3D: + return D3D_SVT_TEXTURE3D; + case HLSL_SAMPLER_DIM_CUBE: + return D3D_SVT_TEXTURECUBE; + case HLSL_SAMPLER_DIM_GENERIC: + return D3D_SVT_TEXTURE; + default: + assert(0); + } + break; + case HLSL_TYPE_UINT: + return D3D_SVT_UINT; + case HLSL_TYPE_VERTEXSHADER: + return D3D_SVT_VERTEXSHADER; + case HLSL_TYPE_VOID: + return D3D_SVT_VOID; + default: + assert(0); + } + assert(0); + return 0; +} + +static void write_sm4_type(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *buffer, struct hlsl_type *type) +{ + const struct hlsl_type *array_type = get_array_type(type); + unsigned int field_count = 0, array_size = 0; + struct hlsl_struct_field *field; + size_t fields_offset = 0; + + if (type->bytecode_offset) + return; + + if (type->type == HLSL_CLASS_ARRAY) + array_size = get_array_size(type); + + if (array_type->type == HLSL_CLASS_STRUCT) + { + LIST_FOR_EACH_ENTRY(field, array_type->e.elements, struct hlsl_struct_field, entry) + { + field->name_bytecode_offset = put_string(buffer, field->name); + write_sm4_type(ctx, buffer, field->type); + } + + fields_offset = bytecode_get_size(buffer); + + LIST_FOR_EACH_ENTRY(field, array_type->e.elements, struct hlsl_struct_field, entry) + { + put_u32(buffer, field->name_bytecode_offset); + put_u32(buffer, field->type->bytecode_offset); + put_u32(buffer, field->reg_offset); + ++field_count; + } + } + + type->bytecode_offset = put_u32(buffer, sm4_class(type) | (sm4_base_type(type) << 16)); + put_u32(buffer, type->dimy | (type->dimx << 16)); + put_u32(buffer, array_size | (field_count << 16)); + put_u32(buffer, fields_offset); +} + 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}; + unsigned int cbuffer_count = 0, i, j; const struct hlsl_buffer *cbuffer; - unsigned int cbuffer_count = 0, i;
static const uint16_t target_types[] = { @@ -150,10 +291,25 @@ static void write_sm4_rdef(struct hlsl_ctx *ctx, struct dxbc_writer *dxbc) 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); /* type */ put_u32(&buffer, 0); /* FIXME: default value */ } } + + j = 0; + LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry) + { + if (var->is_uniform && var->buffer == cbuffer) + { + size_t var_offset = vars_start + j * 6 * sizeof(uint32_t); + size_t string_offset = put_string(&buffer, var->name); + + set_u32(&buffer, var_offset, string_offset); + write_sm4_type(ctx, &buffer, var->data_type); + set_u32(&buffer, var_offset + 4 * sizeof(uint32_t), var->data_type->bytecode_offset); + ++j; + } + } }
creator_offset = put_string(&buffer, vkd3d_shader_get_version(NULL, NULL));
Signed-off-by: Matteo Bruni mbruni@codeweavers.com --- By any chance, do you know offhand what's missing for "fxc /dumpbin" to start give useful output on a SM4 shader generated by our compiler?
On 8/19/21 10:29 AM, Matteo Bruni wrote:
Signed-off-by: Matteo Bruni mbruni@codeweavers.com
By any chance, do you know offhand what's missing for "fxc /dumpbin" to start give useful output on a SM4 shader generated by our compiler?
It needs signatures to start succeeding, and it needs the instruction token count in order to actually list instructions. Both are in the next batch of patches I'm planning to send.
On Thu, Aug 19, 2021 at 5:54 PM Zebediah Figura (she/her) zfigura@codeweavers.com wrote:
On 8/19/21 10:29 AM, Matteo Bruni wrote:
Signed-off-by: Matteo Bruni mbruni@codeweavers.com
By any chance, do you know offhand what's missing for "fxc /dumpbin" to start give useful output on a SM4 shader generated by our compiler?
It needs signatures to start succeeding, and it needs the instruction token count in order to actually list instructions. Both are in the next batch of patches I'm planning to send.
Cool!
On Tue, 17 Aug 2021 at 19:40, Zebediah Figura zfigura@codeweavers.com wrote:
+typedef enum _D3D_SHADER_VARIABLE_TYPE +{
- D3D_SVT_VOID,
- D3D_SVT_BOOL,
- D3D_SVT_INT,
- D3D_SVT_FLOAT,
- D3D_SVT_STRING,
- D3D_SVT_TEXTURE,
- D3D_SVT_TEXTURE1D,
- D3D_SVT_TEXTURE2D,
- D3D_SVT_TEXTURE3D,
- D3D_SVT_TEXTURECUBE,
- D3D_SVT_SAMPLER,
- D3D_SVT_SAMPLER1D,
- D3D_SVT_SAMPLER2D,
- D3D_SVT_SAMPLER3D,
- D3D_SVT_SAMPLERCUBE,
- D3D_SVT_PIXELSHADER,
- D3D_SVT_VERTEXSHADER,
- D3D_SVT_PIXELFRAGMENT,
- D3D_SVT_VERTEXFRAGMENT,
- D3D_SVT_UINT,
- D3D_SVT_UINT8,
- D3D_SVT_GEOMETRYSHADER,
- D3D_SVT_RASTERIZER,
- D3D_SVT_DEPTHSTENCIL,
- D3D_SVT_BLEND,
- D3D_SVT_BUFFER,
- D3D_SVT_CBUFFER,
- D3D_SVT_TBUFFER,
- D3D_SVT_TEXTURE1DARRAY,
- D3D_SVT_TEXTURE2DARRAY,
- D3D_SVT_RENDERTARGETVIEW,
- D3D_SVT_DEPTHSTENCILVIEW,
- D3D_SVT_TEXTURE2DMS,
- D3D_SVT_TEXTURE2DMSARRAY,
- D3D_SVT_TEXTURECUBEARRAY,
- D3D_SVT_HULLSHADER,
- D3D_SVT_DOMAINSHADER,
- D3D_SVT_INTERFACE_POINTER,
- D3D_SVT_COMPUTESHADER,
- D3D_SVT_DOUBLE,
- D3D_SVT_RWTEXTURE1D,
- D3D_SVT_RWTEXTURE1DARRAY,
- D3D_SVT_RWTEXTURE2D,
- D3D_SVT_RWTEXTURE2DARRAY,
- D3D_SVT_RWTEXTURE3D,
- D3D_SVT_RWBUFFER,
- D3D_SVT_BYTEADDRESS_BUFFER,
- D3D_SVT_RWBYTEADDRESS_BUFFER,
- D3D_SVT_STRUCTURED_BUFFER,
- D3D_SVT_RWSTRUCTURED_BUFFER,
- D3D_SVT_APPEND_STRUCTURED_BUFFER,
- D3D_SVT_CONSUME_STRUCTURED_BUFFER,
- D3D_SVT_FORCE_DWORD = 0x7fffffff,
+} D3D_SHADER_VARIABLE_TYPE;
Is this based on the Wine headers? We have some more values there (added by commit 9702ee8d76f7b3233a43a9aa7c78917f26fdbdfe).
On 8/19/21 10:54 AM, Henri Verbeet wrote:
On Tue, 17 Aug 2021 at 19:40, Zebediah Figura zfigura@codeweavers.com wrote:
+typedef enum _D3D_SHADER_VARIABLE_TYPE +{
- D3D_SVT_VOID,
- D3D_SVT_BOOL,
- D3D_SVT_INT,
- D3D_SVT_FLOAT,
- D3D_SVT_STRING,
- D3D_SVT_TEXTURE,
- D3D_SVT_TEXTURE1D,
- D3D_SVT_TEXTURE2D,
- D3D_SVT_TEXTURE3D,
- D3D_SVT_TEXTURECUBE,
- D3D_SVT_SAMPLER,
- D3D_SVT_SAMPLER1D,
- D3D_SVT_SAMPLER2D,
- D3D_SVT_SAMPLER3D,
- D3D_SVT_SAMPLERCUBE,
- D3D_SVT_PIXELSHADER,
- D3D_SVT_VERTEXSHADER,
- D3D_SVT_PIXELFRAGMENT,
- D3D_SVT_VERTEXFRAGMENT,
- D3D_SVT_UINT,
- D3D_SVT_UINT8,
- D3D_SVT_GEOMETRYSHADER,
- D3D_SVT_RASTERIZER,
- D3D_SVT_DEPTHSTENCIL,
- D3D_SVT_BLEND,
- D3D_SVT_BUFFER,
- D3D_SVT_CBUFFER,
- D3D_SVT_TBUFFER,
- D3D_SVT_TEXTURE1DARRAY,
- D3D_SVT_TEXTURE2DARRAY,
- D3D_SVT_RENDERTARGETVIEW,
- D3D_SVT_DEPTHSTENCILVIEW,
- D3D_SVT_TEXTURE2DMS,
- D3D_SVT_TEXTURE2DMSARRAY,
- D3D_SVT_TEXTURECUBEARRAY,
- D3D_SVT_HULLSHADER,
- D3D_SVT_DOMAINSHADER,
- D3D_SVT_INTERFACE_POINTER,
- D3D_SVT_COMPUTESHADER,
- D3D_SVT_DOUBLE,
- D3D_SVT_RWTEXTURE1D,
- D3D_SVT_RWTEXTURE1DARRAY,
- D3D_SVT_RWTEXTURE2D,
- D3D_SVT_RWTEXTURE2DARRAY,
- D3D_SVT_RWTEXTURE3D,
- D3D_SVT_RWBUFFER,
- D3D_SVT_BYTEADDRESS_BUFFER,
- D3D_SVT_RWBYTEADDRESS_BUFFER,
- D3D_SVT_STRUCTURED_BUFFER,
- D3D_SVT_RWSTRUCTURED_BUFFER,
- D3D_SVT_APPEND_STRUCTURED_BUFFER,
- D3D_SVT_CONSUME_STRUCTURED_BUFFER,
- D3D_SVT_FORCE_DWORD = 0x7fffffff,
+} D3D_SHADER_VARIABLE_TYPE;
Is this based on the Wine headers? We have some more values there (added by commit 9702ee8d76f7b3233a43a9aa7c78917f26fdbdfe).
Yes, at some point in time. I'll send a follow-up to add more values.
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- libs/vkd3d-shader/hlsl_sm4.c | 39 ++++++++++++++++++++++++++++++++++-- 1 file changed, 37 insertions(+), 2 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl_sm4.c b/libs/vkd3d-shader/hlsl_sm4.c index cba56eef..9f5c18dd 100644 --- a/libs/vkd3d-shader/hlsl_sm4.c +++ b/libs/vkd3d-shader/hlsl_sm4.c @@ -129,13 +129,18 @@ static D3D_SHADER_VARIABLE_TYPE sm4_base_type(const struct hlsl_type *type) static void write_sm4_type(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *buffer, struct hlsl_type *type) { const struct hlsl_type *array_type = get_array_type(type); + const char *name = array_type->name ? array_type->name : "<unnamed>"; + const struct hlsl_profile_info *profile = ctx->profile; unsigned int field_count = 0, array_size = 0; + size_t fields_offset = 0, name_offset = 0; struct hlsl_struct_field *field; - size_t fields_offset = 0;
if (type->bytecode_offset) return;
+ if (profile->major_version >= 5) + name_offset = put_string(buffer, name); + if (type->type == HLSL_CLASS_ARRAY) array_size = get_array_size(type);
@@ -162,6 +167,15 @@ static void write_sm4_type(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *b put_u32(buffer, type->dimy | (type->dimx << 16)); put_u32(buffer, array_size | (field_count << 16)); put_u32(buffer, fields_offset); + + if (profile->major_version >= 5) + { + put_u32(buffer, 0); /* FIXME: unknown */ + put_u32(buffer, 0); /* FIXME: unknown */ + put_u32(buffer, 0); /* FIXME: unknown */ + put_u32(buffer, 0); /* FIXME: unknown */ + put_u32(buffer, name_offset); + } }
static void write_sm4_rdef(struct hlsl_ctx *ctx, struct dxbc_writer *dxbc) @@ -197,6 +211,18 @@ static void write_sm4_rdef(struct hlsl_ctx *ctx, struct dxbc_writer *dxbc) put_u32(&buffer, 0); /* FIXME: compilation flags */ creator_position = put_u32(&buffer, 0);
+ if (profile->major_version >= 5) + { + put_u32(&buffer, TAG_RD11); + put_u32(&buffer, 15 * sizeof(uint32_t)); /* size of RDEF header including this header */ + put_u32(&buffer, 6 * sizeof(uint32_t)); /* size of buffer desc */ + put_u32(&buffer, 8 * sizeof(uint32_t)); /* size of binding desc */ + put_u32(&buffer, 10 * sizeof(uint32_t)); /* size of variable desc */ + put_u32(&buffer, 9 * sizeof(uint32_t)); /* size of type desc */ + put_u32(&buffer, 3 * sizeof(uint32_t)); /* size of member desc */ + put_u32(&buffer, 0); /* unknown; possibly a null terminator */ + } + /* Bound resources. */
resources_offset = bytecode_get_size(&buffer); @@ -293,6 +319,14 @@ static void write_sm4_rdef(struct hlsl_ctx *ctx, struct dxbc_writer *dxbc) put_u32(&buffer, flags); put_u32(&buffer, 0); /* type */ put_u32(&buffer, 0); /* FIXME: default value */ + + if (profile->major_version >= 5) + { + put_u32(&buffer, 0); /* texture start */ + put_u32(&buffer, 0); /* texture count */ + put_u32(&buffer, 0); /* sampler start */ + put_u32(&buffer, 0); /* sampler count */ + } } }
@@ -301,7 +335,8 @@ static void write_sm4_rdef(struct hlsl_ctx *ctx, struct dxbc_writer *dxbc) { if (var->is_uniform && var->buffer == cbuffer) { - size_t var_offset = vars_start + j * 6 * sizeof(uint32_t); + const unsigned int var_size = (profile->major_version >= 5 ? 10 : 6); + size_t var_offset = vars_start + j * var_size * sizeof(uint32_t); size_t string_offset = put_string(&buffer, var->name);
set_u32(&buffer, var_offset, string_offset);
Signed-off-by: Matteo Bruni mbruni@codeweavers.com
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com