diff --git a/libs/vkd3d-shader/dxil.c b/libs/vkd3d-shader/dxil.c index b39ec204..62d5ed83 100644 --- a/libs/vkd3d-shader/dxil.c +++ b/libs/vkd3d-shader/dxil.c @@ -2691,8 +2691,8 @@ static void sm6_parser_declare_icb(struct sm6_parser *sm6, const struct sm6_type } static void sm6_parser_declare_indexable_temp(struct sm6_parser *sm6, const struct sm6_type *elem_type, - unsigned int count, unsigned int alignment, unsigned int init, struct vkd3d_shader_instruction *ins, - struct sm6_value *dst) + unsigned int count, unsigned int alignment, bool has_function_scope, unsigned int init, + struct vkd3d_shader_instruction *ins, struct sm6_value *dst) { enum vkd3d_data_type data_type = vkd3d_data_type_from_sm6_type(elem_type); @@ -2705,6 +2705,7 @@ static void sm6_parser_declare_indexable_temp(struct sm6_parser *sm6, const stru ins->declaration.indexable_temp.alignment = alignment; ins->declaration.indexable_temp.data_type = data_type; ins->declaration.indexable_temp.component_count = 1; + ins->declaration.indexable_temp.has_function_scope = has_function_scope; /* The initialiser value index will be resolved later so forward references can be handled. */ ins->declaration.indexable_temp.initialiser = (void *)(uintptr_t)init; @@ -2832,7 +2833,7 @@ static bool sm6_parser_declare_global(struct sm6_parser *sm6, const struct dxil_ if (is_constant) sm6_parser_declare_icb(sm6, scalar_type, count, alignment, init, dst); else - sm6_parser_declare_indexable_temp(sm6, scalar_type, count, alignment, init, NULL, dst); + sm6_parser_declare_indexable_temp(sm6, scalar_type, count, alignment, false, init, NULL, dst); } else if (address_space == ADDRESS_SPACE_GROUPSHARED) { @@ -3103,7 +3104,7 @@ static void sm6_parser_emit_alloca(struct sm6_parser *sm6, const struct dxil_rec if (packed_operands) WARN("Ignoring flags %#"PRIx64".\n", packed_operands); - sm6_parser_declare_indexable_temp(sm6, elem_type, type[0]->u.array.count, alignment, 0, ins, dst); + sm6_parser_declare_indexable_temp(sm6, elem_type, type[0]->u.array.count, alignment, true, 0, ins, dst); } static enum vkd3d_shader_opcode map_binary_op(uint64_t code, const struct sm6_type *type_a, diff --git a/libs/vkd3d-shader/spirv.c b/libs/vkd3d-shader/spirv.c index 8b8d11b5..a5fa58cc 100644 --- a/libs/vkd3d-shader/spirv.c +++ b/libs/vkd3d-shader/spirv.c @@ -5597,7 +5597,10 @@ static void spirv_compiler_emit_dcl_indexable_temp(struct spirv_compiler *compil SpvStorageClass storage_class; size_t function_location; - storage_class = SpvStorageClassFunction; + /* Indexable temps may be used by more than one function in hull shaders, and + * declarations generally should not occur within VSIR code blocks unless function + * scope is specified, e.g. DXIL alloca. */ + storage_class = temp->has_function_scope ? SpvStorageClassFunction : SpvStorageClassPrivate; vsir_register_init(®, VKD3DSPR_IDXTEMP, VKD3D_DATA_FLOAT, 1); reg.idx[0].offset = temp->register_idx; diff --git a/libs/vkd3d-shader/tpf.c b/libs/vkd3d-shader/tpf.c index 1f1944bc..4d9e7dc7 100644 --- a/libs/vkd3d-shader/tpf.c +++ b/libs/vkd3d-shader/tpf.c @@ -1117,6 +1117,8 @@ static void shader_sm4_read_dcl_indexable_temp(struct vkd3d_shader_instruction * ins->declaration.indexable_temp.alignment = 0; ins->declaration.indexable_temp.data_type = VKD3D_DATA_FLOAT; ins->declaration.indexable_temp.component_count = *tokens; + /* Indexable temp declarations are global, but except for hull shaders the backend currently emits them within a function. */ + ins->declaration.indexable_temp.has_function_scope = priv->p.shader_version.type != VKD3D_SHADER_TYPE_HULL; } static void shader_sm4_read_dcl_global_flags(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 714606f7..3d8f907b 100644 --- a/libs/vkd3d-shader/vkd3d_shader_private.h +++ b/libs/vkd3d-shader/vkd3d_shader_private.h @@ -820,6 +820,7 @@ struct vkd3d_shader_indexable_temp unsigned int alignment; enum vkd3d_data_type data_type; unsigned int component_count; + bool has_function_scope; const struct vkd3d_shader_immediate_constant_buffer *initialiser; };