From: Józef Kucia jkucia@codeweavers.com
Signed-off-by: Józef Kucia jkucia@codeweavers.com --- libs/vkd3d-shader/spirv.c | 34 +++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-)
diff --git a/libs/vkd3d-shader/spirv.c b/libs/vkd3d-shader/spirv.c index e169aa0567ee..a925d68eeeb4 100644 --- a/libs/vkd3d-shader/spirv.c +++ b/libs/vkd3d-shader/spirv.c @@ -5124,9 +5124,12 @@ static void vkd3d_dxbc_compiler_emit_dcl_thread_group(struct vkd3d_dxbc_compiler static void vkd3d_dxbc_compiler_leave_shader_phase(struct vkd3d_dxbc_compiler *compiler, const struct vkd3d_shader_phase *phase) { + const struct vkd3d_shader_signature *signature = compiler->output_signature; struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; struct vkd3d_shader_register reg; struct vkd3d_symbol reg_symbol; + struct rb_entry *entry; + unsigned int i;
vkd3d_spirv_build_op_function_end(builder);
@@ -5139,12 +5142,41 @@ static void vkd3d_dxbc_compiler_leave_shader_phase(struct vkd3d_dxbc_compiler *c compiler->temp_id = 0; compiler->temp_count = 0;
+ /* + * Output regsiters have a different purpose in the control point phase and + * in fork/join phases. We have to remove all output registers' symbols + * when leaving the control point phase. + */ + if (phase->type == VKD3DSIH_HS_CONTROL_POINT_PHASE) + { + memset(®, 0, sizeof(reg)); + reg.type = VKD3DSPR_OUTPUT; + reg.idx[1].offset = ~0u; + + for (i = 0; i < signature->element_count; ++i) + { + const struct vkd3d_shader_signature_element *e = &signature->elements[i]; + + reg.idx[0].offset = e->register_index; + vkd3d_symbol_make_register(®_symbol, ®); + if ((entry = rb_get(&compiler->symbol_table, ®_symbol))) + { + rb_remove(&compiler->symbol_table, entry); + vkd3d_symbol_free(entry, NULL); + } + } + } + if (phase->instance_count) { reg.type = phase->type == VKD3DSIH_HS_FORK_PHASE ? VKD3DSPR_FORKINSTID : VKD3DSPR_JOININSTID; reg.idx[0].offset = ~0u; vkd3d_symbol_make_register(®_symbol, ®); - rb_remove_key(&compiler->symbol_table, ®_symbol); + if ((entry = rb_get(&compiler->symbol_table, ®_symbol))) + { + rb_remove(&compiler->symbol_table, entry); + vkd3d_symbol_free(entry, NULL); + } } }