From 6c174beb4bacf98d6900eee84d6f5aedbf013136 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B3zef=20Kucia?= Date: Tue, 25 Jul 2017 14:23:27 +0200 Subject: [PATCH] libs/vkd3d-shader: Use component types from input signatures for shader inputs. Fixes Vulkan validation layers errors. --- libs/vkd3d-shader/spirv.c | 71 ++++++++++++++---------- libs/vkd3d-shader/vkd3d_shader_main.c | 2 +- libs/vkd3d-shader/vkd3d_shader_private.h | 2 +- 3 files changed, 45 insertions(+), 30 deletions(-) diff --git a/libs/vkd3d-shader/spirv.c b/libs/vkd3d-shader/spirv.c index ebbbf595..0b5bf680 100644 --- a/libs/vkd3d-shader/spirv.c +++ b/libs/vkd3d-shader/spirv.c @@ -1365,6 +1365,7 @@ struct vkd3d_dxbc_compiler struct vkd3d_control_flow_info *control_flow_info; size_t control_flow_info_size; + const struct vkd3d_shader_signature *input_signature; const struct vkd3d_shader_signature *output_signature; struct { @@ -1376,8 +1377,9 @@ struct vkd3d_dxbc_compiler }; struct vkd3d_dxbc_compiler *vkd3d_dxbc_compiler_create(const struct vkd3d_shader_version *shader_version, - const struct vkd3d_shader_signature *output_signature, uint32_t compiler_options) + const struct vkd3d_shader_desc *shader_desc, uint32_t compiler_options) { + const struct vkd3d_shader_signature *output_signature = &shader_desc->output_signature; struct vkd3d_dxbc_compiler *compiler; if (!(compiler = vkd3d_malloc(sizeof(*compiler)))) @@ -1422,7 +1424,8 @@ struct vkd3d_dxbc_compiler *vkd3d_dxbc_compiler_create(const struct vkd3d_shader compiler->shader_type = shader_version->type; - compiler->output_signature = output_signature; + compiler->input_signature = &shader_desc->input_signature; + compiler->output_signature = &shader_desc->output_signature; return compiler; } @@ -2035,11 +2038,37 @@ static void vkd3d_dxbc_compiler_decorate_builtin(struct vkd3d_dxbc_compiler *com vkd3d_spirv_build_op_decorate1(builder, target_id, SpvDecorationBuiltIn, builtin); } +static const struct vkd3d_shader_signature_element *vkd3d_find_signature_element_for_reg( + const struct vkd3d_shader_signature *signature, unsigned int *signature_element_index, + const struct vkd3d_shader_register *reg, DWORD write_mask) +{ + unsigned int signature_idx; + + for (signature_idx = 0; signature_idx < signature->element_count; ++signature_idx) + { + if (signature->elements[signature_idx].register_idx == reg->idx[0].offset + && (signature->elements[signature_idx].mask & 0xff) == write_mask) + { + if (signature_element_index) + *signature_element_index = signature_idx; + return &signature->elements[signature_idx]; + } + } + + FIXME("Could not find shader signature element (register %u, write mask %#x).\n", + reg->idx[0].offset, write_mask); + if (signature_element_index) + *signature_element_index = ~0u; + return NULL; +} + static uint32_t vkd3d_dxbc_compiler_emit_input(struct vkd3d_dxbc_compiler *compiler, const struct vkd3d_shader_dst_param *dst, enum vkd3d_shader_input_sysval_semantic sysval) { unsigned int component_idx, component_count, input_component_count; struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; + const struct vkd3d_shader_signature_element *signature_element; + const struct vkd3d_shader_register *reg = &dst->reg; const struct vkd3d_spirv_builtin *builtin; enum vkd3d_component_type component_type; uint32_t val_id = 0, input_id, var_id; @@ -2050,14 +2079,16 @@ static uint32_t vkd3d_dxbc_compiler_emit_input(struct vkd3d_dxbc_compiler *compi bool use_private_var = false; DWORD write_mask; - builtin = vkd3d_get_spirv_builtin(dst->reg.type, sysval); - /* vThreadIDInGroupFlattened is declared with no write mask in shader * bytecode generated by fxc. */ write_mask = dst->write_mask; - if (!write_mask && dst->reg.type == VKD3DSPR_LOCALTHREADINDEX) + if (!write_mask && reg->type == VKD3DSPR_LOCALTHREADINDEX) write_mask = VKD3DSP_WRITEMASK_0; + signature_element = vkd3d_find_signature_element_for_reg(compiler->input_signature, + NULL, reg, write_mask); + builtin = vkd3d_get_spirv_builtin(reg->type, sysval); + component_idx = vkd3d_write_mask_get_component_idx(write_mask); component_count = vkd3d_write_mask_component_count(write_mask); if (builtin) @@ -2067,7 +2098,7 @@ static uint32_t vkd3d_dxbc_compiler_emit_input(struct vkd3d_dxbc_compiler *compi } else { - component_type = VKD3D_TYPE_FLOAT; + component_type = signature_element ? signature_element->component_type : VKD3D_TYPE_FLOAT; input_component_count = component_count; } assert(component_count <= input_component_count); @@ -2084,7 +2115,7 @@ static uint32_t vkd3d_dxbc_compiler_emit_input(struct vkd3d_dxbc_compiler *compi } else { - vkd3d_spirv_build_op_decorate1(builder, input_id, SpvDecorationLocation, dst->reg.idx[0].offset); + vkd3d_spirv_build_op_decorate1(builder, input_id, SpvDecorationLocation, reg->idx[0].offset); if (component_idx) vkd3d_spirv_build_op_decorate1(builder, input_id, SpvDecorationComponent, component_idx); } @@ -2106,7 +2137,7 @@ static uint32_t vkd3d_dxbc_compiler_emit_input(struct vkd3d_dxbc_compiler *compi if (val_id && input_component_count != component_count) val_id = vkd3d_dxbc_compiler_emit_swizzle(compiler, val_id, VKD3DSP_NOSWIZZLE, write_mask); - vkd3d_symbol_make_register(®_symbol, &dst->reg); + vkd3d_symbol_make_register(®_symbol, reg); if (!use_private_var) { @@ -2124,13 +2155,13 @@ static uint32_t vkd3d_dxbc_compiler_emit_input(struct vkd3d_dxbc_compiler *compi reg_symbol.info.storage_class = storage_class; vkd3d_dxbc_compiler_put_symbol(compiler, ®_symbol); - vkd3d_dxbc_compiler_emit_register_debug_name(builder, var_id, &dst->reg); + vkd3d_dxbc_compiler_emit_register_debug_name(builder, var_id, reg); } if (use_private_var) { assert(val_id); - vkd3d_dxbc_compiler_emit_store_reg(compiler, &dst->reg, write_mask, val_id); + vkd3d_dxbc_compiler_emit_store_reg(compiler, reg, write_mask, val_id); } return input_id; @@ -2143,7 +2174,6 @@ static uint32_t vkd3d_dxbc_compiler_emit_output(struct vkd3d_dxbc_compiler *comp struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; const struct vkd3d_shader_signature_element *signature_element; const struct vkd3d_shader_register *reg = &dst->reg; - const struct vkd3d_shader_signature *signature; const struct vkd3d_spirv_builtin *builtin; enum vkd3d_component_type component_type; struct vkd3d_symbol reg_symbol; @@ -2153,23 +2183,8 @@ static uint32_t vkd3d_dxbc_compiler_emit_output(struct vkd3d_dxbc_compiler *comp bool use_private_variable; uint32_t id, var_id; - signature_element = NULL; - signature = compiler->output_signature; - for (signature_idx = 0; signature_idx < signature->element_count; ++signature_idx) - { - if (signature->elements[signature_idx].register_idx == reg->idx[0].offset - && (signature->elements[signature_idx].mask & 0xff) == dst->write_mask) - { - signature_element = &signature->elements[signature_idx]; - break; - } - } - if (!signature_element) - { - FIXME("Could not find shader signature element (register %u, write mask %#x).\n", - reg->idx[0].offset, dst->write_mask); - } - + signature_element = vkd3d_find_signature_element_for_reg(compiler->output_signature, + &signature_idx, reg, dst->write_mask); builtin = vkd3d_get_spirv_builtin(dst->reg.type, sysval); component_idx = vkd3d_write_mask_get_component_idx(dst->write_mask); diff --git a/libs/vkd3d-shader/vkd3d_shader_main.c b/libs/vkd3d-shader/vkd3d_shader_main.c index 947ad717..98c8c3c7 100644 --- a/libs/vkd3d-shader/vkd3d_shader_main.c +++ b/libs/vkd3d-shader/vkd3d_shader_main.c @@ -50,7 +50,7 @@ HRESULT vkd3d_shader_compile_dxbc(const struct vkd3d_shader_code *dxbc, shader_sm4_read_header(parser_data, &ptr, &shader_version); if (!(spirv_compiler = vkd3d_dxbc_compiler_create(&shader_version, - &shader_desc.output_signature, compiler_options))) + &shader_desc, compiler_options))) { ERR("Failed to create DXBC compiler.\n"); shader_sm4_free(parser_data); diff --git a/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d-shader/vkd3d_shader_private.h index b477768b..af7fe251 100644 --- a/libs/vkd3d-shader/vkd3d_shader_private.h +++ b/libs/vkd3d-shader/vkd3d_shader_private.h @@ -822,7 +822,7 @@ void free_shader_desc(struct vkd3d_shader_desc *desc) DECLSPEC_HIDDEN; struct vkd3d_dxbc_compiler; struct vkd3d_dxbc_compiler *vkd3d_dxbc_compiler_create(const struct vkd3d_shader_version *shader_version, - const struct vkd3d_shader_signature *output_signature, uint32_t compiler_options) DECLSPEC_HIDDEN; + const struct vkd3d_shader_desc *shader_desc, uint32_t compiler_options) DECLSPEC_HIDDEN; void vkd3d_dxbc_compiler_handle_instruction(struct vkd3d_dxbc_compiler *compiler, const struct vkd3d_shader_instruction *instruction) DECLSPEC_HIDDEN; bool vkd3d_dxbc_compiler_generate_spirv(struct vkd3d_dxbc_compiler *compiler,