From: Philip Rebohle Subject: [PATCH vkd3d 11/11] vkd3d-shader: Support vicp inputs for hull shader fork/join phases. Message-Id: <20191016195544.23720-12-philip.rebohle@tu-dortmund.de> Date: Wed, 16 Oct 2019 21:55:45 +0200 In-Reply-To: <20191016195544.23720-1-philip.rebohle@tu-dortmund.de> References: <20191016195544.23720-1-philip.rebohle@tu-dortmund.de> This case needs special care since both VKD3DSPR_INPUT in the control point phase and VKD3DSPR_INCONTROLPOINT in fork/join phases refer to the same set of input variables, and we should not declare input variables with the same location twice. Encountered in Shadow of the Tomb Raider. Signed-off-by: Philip Rebohle --- libs/vkd3d-shader/spirv.c | 42 +++++++++++++++++++++++++++++---------- 1 file changed, 32 insertions(+), 10 deletions(-) diff --git a/libs/vkd3d-shader/spirv.c b/libs/vkd3d-shader/spirv.c index 7678db0..f5f1d6b 100644 --- a/libs/vkd3d-shader/spirv.c +++ b/libs/vkd3d-shader/spirv.c @@ -3916,6 +3916,7 @@ static uint32_t vkd3d_dxbc_compiler_emit_input(struct vkd3d_dxbc_compiler *compi enum vkd3d_component_type component_type; uint32_t val_id, input_id, var_id; struct vkd3d_symbol reg_symbol; + struct vkd3d_symbol tmp_symbol; SpvStorageClass storage_class; struct rb_entry *entry = NULL; bool use_private_var = false; @@ -4000,19 +4001,39 @@ static uint32_t vkd3d_dxbc_compiler_emit_input(struct vkd3d_dxbc_compiler *compi } else { - unsigned int location = reg_idx; + input_id = 0; - if (reg->type == VKD3DSPR_PATCHCONST) - location += compiler->input_signature->element_count; + if (compiler->shader_type == VKD3D_SHADER_TYPE_HULL && reg->type == VKD3DSPR_INCONTROLPOINT) + { + tmp_symbol = reg_symbol; + tmp_symbol.key.reg.type = VKD3DSPR_INPUT; - input_id = vkd3d_dxbc_compiler_emit_array_variable(compiler, &builder->global_stream, - storage_class, component_type, input_component_count, array_size); - vkd3d_spirv_add_iface_variable(builder, input_id); - vkd3d_spirv_build_op_decorate1(builder, input_id, SpvDecorationLocation, location); - if (component_idx) - vkd3d_spirv_build_op_decorate1(builder, input_id, SpvDecorationComponent, component_idx); + if ((entry = rb_get(&compiler->symbol_table, &tmp_symbol))) + { + tmp_symbol = *RB_ENTRY_VALUE(entry, const struct vkd3d_symbol, entry); + tmp_symbol.key.reg.type = VKD3DSPR_INCONTROLPOINT; + vkd3d_dxbc_compiler_put_symbol(compiler, &tmp_symbol); + + input_id = tmp_symbol.id; + } + } + + if (!entry) + { + unsigned int location = reg_idx; - vkd3d_dxbc_compiler_emit_interpolation_decorations(compiler, input_id, interpolation_mode); + if (reg->type == VKD3DSPR_PATCHCONST) + location += compiler->input_signature->element_count; + + input_id = vkd3d_dxbc_compiler_emit_array_variable(compiler, &builder->global_stream, + storage_class, component_type, input_component_count, array_size); + vkd3d_spirv_add_iface_variable(builder, input_id); + vkd3d_spirv_build_op_decorate1(builder, input_id, SpvDecorationLocation, location); + if (component_idx) + vkd3d_spirv_build_op_decorate1(builder, input_id, SpvDecorationComponent, component_idx); + + vkd3d_dxbc_compiler_emit_interpolation_decorations(compiler, input_id, interpolation_mode); + } } if (reg->type == VKD3DSPR_PATCHCONST) @@ -4121,6 +4142,7 @@ static void vkd3d_dxbc_compiler_emit_shader_phase_input(struct vkd3d_dxbc_compil switch (reg->type) { case VKD3DSPR_INPUT: + case VKD3DSPR_INCONTROLPOINT: vkd3d_dxbc_compiler_emit_input(compiler, dst, VKD3D_SIV_NONE, VKD3DSIM_NONE); return; case VKD3DSPR_PRIMID: -- 2.23.0