diff options
author | Philip Rebohle <philip.rebohle@tu-dortmund.de> | 2019-10-16 22:55:45 +0300 |
---|---|---|
committer | Alexandre Julliard <julliard@winehq.org> | 2019-10-31 21:24:33 +0300 |
commit | 6c65f1b8142b1a6a86e314ffab81f4c0e5ce635a (patch) | |
tree | 3cbb7a72f600183d4222ce680f62b561657c1491 | |
parent | 1707042e624f9598d3bf3b87356f0d32be892f00 (diff) |
vkd3d-shader: Support vicp inputs for hull shader fork/join phases.
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 <philip.rebohle@tu-dortmund.de>
Signed-off-by: Henri Verbeet <hverbeet@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
-rw-r--r-- | libs/vkd3d-shader/spirv.c | 42 |
1 files changed, 32 insertions, 10 deletions
diff --git a/libs/vkd3d-shader/spirv.c b/libs/vkd3d-shader/spirv.c index 13c6fd26..a949e4a5 100644 --- a/libs/vkd3d-shader/spirv.c +++ b/libs/vkd3d-shader/spirv.c @@ -3917,6 +3917,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; @@ -4001,19 +4002,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) @@ -4122,6 +4143,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: |