``` On Margate Sands. I can connect Nothing with nothing. ```
-- v2: vkd3d-shader/d3dbc: Scan for the maximum temporary register index. vkd3d-shader: Record a global temporary count per sm4 shader. vkd3d-shader/dxbc: Remove redundant zero-initialization of the vkd3d_shader_desc structure.
From: Zebediah Figura zfigura@codeweavers.com
--- libs/vkd3d-shader/dxbc.c | 6 ------ 1 file changed, 6 deletions(-)
diff --git a/libs/vkd3d-shader/dxbc.c b/libs/vkd3d-shader/dxbc.c index 3c52e332c..716b7bdb7 100644 --- a/libs/vkd3d-shader/dxbc.c +++ b/libs/vkd3d-shader/dxbc.c @@ -531,12 +531,6 @@ int shader_extract_from_dxbc(const struct vkd3d_shader_code *dxbc, { int ret;
- desc->byte_code = NULL; - desc->byte_code_size = 0; - memset(&desc->input_signature, 0, sizeof(desc->input_signature)); - memset(&desc->output_signature, 0, sizeof(desc->output_signature)); - memset(&desc->patch_constant_signature, 0, sizeof(desc->patch_constant_signature)); - ret = for_each_dxbc_section(dxbc, message_context, source_name, shdr_handler, desc); if (!desc->byte_code) ret = VKD3D_ERROR_INVALID_ARGUMENT;
From: Zebediah Figura zfigura@codeweavers.com
Store it in the shader_desc, and declare temps from that when compiling SPIR-V, instead of parsing dcl_instructions.
As part of this change, we declare a single, global temps array (with Private scope instead of Function) which is as large as the maximum of all dcl_temps instructions. It is not clear to me whether this will improve, hurt, or have no significant effect on the lower-level compiler. An alternative is to still redeclare a new temps array every time (although still with a smaller size). --- libs/vkd3d-shader/spirv.c | 17 +++++++---------- libs/vkd3d-shader/tpf.c | 2 ++ libs/vkd3d-shader/vkd3d_shader_private.h | 2 ++ 3 files changed, 11 insertions(+), 10 deletions(-)
diff --git a/libs/vkd3d-shader/spirv.c b/libs/vkd3d-shader/spirv.c index 3542b5fac..8c2ec132d 100644 --- a/libs/vkd3d-shader/spirv.c +++ b/libs/vkd3d-shader/spirv.c @@ -5258,8 +5258,7 @@ static void spirv_compiler_emit_dcl_global_flags(struct spirv_compiler *compiler WARN("Unhandled global flags %#x.\n", flags); }
-static void spirv_compiler_emit_dcl_temps(struct spirv_compiler *compiler, - const struct vkd3d_shader_instruction *instruction) +static void spirv_compiler_emit_temps(struct spirv_compiler *compiler, uint32_t count) { struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; size_t function_location; @@ -5270,11 +5269,11 @@ static void spirv_compiler_emit_dcl_temps(struct spirv_compiler *compiler, vkd3d_spirv_begin_function_stream_insertion(builder, function_location);
assert(!compiler->temp_count); - compiler->temp_count = instruction->declaration.count; + compiler->temp_count = count; for (i = 0; i < compiler->temp_count; ++i) { id = spirv_compiler_emit_variable(compiler, &builder->function_stream, - SpvStorageClassFunction, VKD3D_SHADER_COMPONENT_FLOAT, VKD3D_VEC4_SIZE); + SpvStorageClassPrivate, VKD3D_SHADER_COMPONENT_FLOAT, VKD3D_VEC4_SIZE); if (!i) compiler->temp_id = id; assert(id == compiler->temp_id + i); @@ -6236,9 +6235,6 @@ static void spirv_compiler_leave_shader_phase(struct spirv_compiler *compiler)
vkd3d_spirv_build_op_function_end(builder);
- compiler->temp_id = 0; - compiler->temp_count = 0; - if (is_in_control_point_phase(compiler)) { if (compiler->epilogue_function_id) @@ -9103,9 +9099,6 @@ static int spirv_compiler_handle_instruction(struct spirv_compiler *compiler, case VKD3DSIH_DCL_GLOBAL_FLAGS: spirv_compiler_emit_dcl_global_flags(compiler, instruction); break; - case VKD3DSIH_DCL_TEMPS: - spirv_compiler_emit_dcl_temps(compiler, instruction); - break; case VKD3DSIH_DCL_INDEXABLE_TEMP: spirv_compiler_emit_dcl_indexable_temp(compiler, instruction); break; @@ -9426,6 +9419,7 @@ static int spirv_compiler_handle_instruction(struct spirv_compiler *compiler, spirv_compiler_emit_cut_stream(compiler, instruction); break; case VKD3DSIH_DCL_HS_MAX_TESSFACTOR: + case VKD3DSIH_DCL_TEMPS: case VKD3DSIH_HS_DECLS: case VKD3DSIH_NOP: /* nothing to do */ @@ -9448,6 +9442,9 @@ static int spirv_compiler_generate_spirv(struct spirv_compiler *compiler, enum vkd3d_result result = VKD3D_OK; unsigned int i;
+ if (parser->shader_desc.temp_count) + spirv_compiler_emit_temps(compiler, parser->shader_desc.temp_count); + compiler->location.column = 0; compiler->location.line = 1;
diff --git a/libs/vkd3d-shader/tpf.c b/libs/vkd3d-shader/tpf.c index 677243e15..31c43a5a4 100644 --- a/libs/vkd3d-shader/tpf.c +++ b/libs/vkd3d-shader/tpf.c @@ -989,6 +989,8 @@ static void shader_sm4_read_declaration_count(struct vkd3d_shader_instruction *i uint32_t opcode_token, const uint32_t *tokens, unsigned int token_count, struct vkd3d_shader_sm4_parser *priv) { ins->declaration.count = *tokens; + if (opcode == VKD3D_SM4_OP_DCL_TEMPS) + priv->p.shader_desc.temp_count = max(priv->p.shader_desc.temp_count, *tokens); }
static void shader_sm4_read_declaration_dst(struct vkd3d_shader_instruction *ins, uint32_t opcode, diff --git a/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d-shader/vkd3d_shader_private.h index 398139c3e..85fca9642 100644 --- a/libs/vkd3d-shader/vkd3d_shader_private.h +++ b/libs/vkd3d-shader/vkd3d_shader_private.h @@ -829,6 +829,8 @@ struct vkd3d_shader_desc struct shader_signature input_signature; struct shader_signature output_signature; struct shader_signature patch_constant_signature; + + uint32_t temp_count; };
struct vkd3d_shader_register_semantic
From: Zebediah Figura zfigura@codeweavers.com
--- libs/vkd3d-shader/d3dbc.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-)
diff --git a/libs/vkd3d-shader/d3dbc.c b/libs/vkd3d-shader/d3dbc.c index d2a4666a5..e8a6236bd 100644 --- a/libs/vkd3d-shader/d3dbc.c +++ b/libs/vkd3d-shader/d3dbc.c @@ -729,6 +729,16 @@ static bool add_signature_element_from_semantic(struct vkd3d_shader_sm1_parser * semantic->usage_idx, sysval, reg->idx[0].offset, true, mask); }
+static void shader_sm1_scan_register(struct vkd3d_shader_sm1_parser *sm1, const struct vkd3d_shader_register *reg, unsigned int mask) +{ + uint32_t register_index = reg->idx[0].offset; + + if (reg->type == VKD3DSPR_TEMP) + sm1->p.shader_desc.temp_count = max(sm1->p.shader_desc.temp_count, register_index + 1); + + add_signature_element_from_register(sm1, reg, false, mask); +} + /* Read a parameter token from the input stream, and possibly a relative * addressing token. */ static void shader_sm1_read_param(struct vkd3d_shader_sm1_parser *sm1, @@ -1083,7 +1093,7 @@ static void shader_sm1_read_instruction(struct vkd3d_shader_sm1_parser *sm1, str if (ins->dst_count) { shader_sm1_read_dst_param(sm1, &p, dst_param); - add_signature_element_from_register(sm1, &dst_param->reg, false, dst_param->write_mask); + shader_sm1_scan_register(sm1, &dst_param->reg, dst_param->write_mask); }
/* Predication token */ @@ -1094,8 +1104,7 @@ static void shader_sm1_read_instruction(struct vkd3d_shader_sm1_parser *sm1, str for (i = 0; i < ins->src_count; ++i) { shader_sm1_read_src_param(sm1, &p, &src_params[i]); - add_signature_element_from_register(sm1, &src_params[i].reg, - false, mask_from_swizzle(src_params[i].swizzle)); + shader_sm1_scan_register(sm1, &src_params[i].reg, mask_from_swizzle(src_params[i].swizzle)); } }
Pushed a v2 that does this.