Conor McCarthy : vkd3d-shader/spirv: Handle arrayed builtin inputs.
Alexandre Julliard
julliard at winehq.org
Wed Nov 17 16:25:40 CST 2021
Module: vkd3d
Branch: master
Commit: c41931c7508e0f2e6467db55319438ec2b24e16b
URL: https://source.winehq.org/git/vkd3d.git/?a=commit;h=c41931c7508e0f2e6467db55319438ec2b24e16b
Author: Conor McCarthy <cmccarthy at codeweavers.com>
Date: Wed Nov 17 13:05:59 2021 +0100
vkd3d-shader/spirv: Handle arrayed builtin inputs.
Fixes invalid SPIR-V being generated in Monster Hunter: World.
Based on vkd3d-proton patches by Hans-Kristian Arntzen and Philip Rebohle.
Signed-off-by: Conor McCarthy <cmccarthy at codeweavers.com>
Signed-off-by: Henri Verbeet <hverbeet at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
libs/vkd3d-shader/spirv.c | 27 +++++++++++++++++++++------
1 file changed, 21 insertions(+), 6 deletions(-)
diff --git a/libs/vkd3d-shader/spirv.c b/libs/vkd3d-shader/spirv.c
index 8827c43..e1a7dd3 100644
--- a/libs/vkd3d-shader/spirv.c
+++ b/libs/vkd3d-shader/spirv.c
@@ -4416,6 +4416,13 @@ static bool needs_private_io_variable(const struct vkd3d_shader_signature *signa
bool have_sysval = false;
unsigned int i, count;
+ /* Always use private variables for arrayed builtins. These are generally
+ * scalars on the D3D side, so would need extra array indices when
+ * accessing them. It may be feasible to insert those indices at the point
+ * where the builtins are used, but it's not clear it's worth the effort. */
+ if (builtin && (builtin->spirv_array_size || builtin->fixup_pfn))
+ return true;
+
if (*component_count == VKD3D_VEC4_SIZE)
return false;
@@ -4519,8 +4526,7 @@ static uint32_t vkd3d_dxbc_compiler_emit_input(struct vkd3d_dxbc_compiler *compi
component_idx = vkd3d_write_mask_get_component_idx(signature_element->mask);
}
- if (!(use_private_var = builtin && builtin->fixup_pfn)
- && needs_private_io_variable(shader_signature, reg_idx, builtin, &input_component_count, &write_mask)
+ if (needs_private_io_variable(shader_signature, reg_idx, builtin, &input_component_count, &write_mask)
&& (compiler->shader_type != VKD3D_SHADER_TYPE_HULL
|| (reg->type != VKD3DSPR_INCONTROLPOINT && reg->type != VKD3DSPR_PATCHCONST)))
use_private_var = true;
@@ -4644,6 +4650,16 @@ static uint32_t vkd3d_dxbc_compiler_emit_input(struct vkd3d_dxbc_compiler *compi
val_id = vkd3d_spirv_build_op_in_bounds_access_chain1(builder, ptr_type_id, input_id, index);
dst_reg.idx[0].offset = i;
}
+ else if (builtin && builtin->spirv_array_size)
+ {
+ /* The D3D builtin is not an array, but the SPIR-V builtin is,
+ * so we'll need to index into the SPIR-V builtin when loading
+ * it. This happens when reading TessLevel in domain shaders. */
+ ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, SpvStorageClassInput, type_id);
+ index = vkd3d_dxbc_compiler_get_constant_uint(compiler, builtin->member_idx);
+ val_id = vkd3d_spirv_build_op_in_bounds_access_chain1(builder, ptr_type_id, input_id, index);
+ dst_reg.idx[0].offset = reg_idx + i;
+ }
val_id = vkd3d_spirv_build_op_load(builder, type_id, val_id, SpvMemoryAccessMaskNone);
if (builtin && builtin->fixup_pfn)
@@ -4947,11 +4963,11 @@ static void vkd3d_dxbc_compiler_emit_output(struct vkd3d_dxbc_compiler *compiler
const struct vkd3d_spirv_builtin *builtin;
const struct vkd3d_shader_phase *phase;
struct vkd3d_symbol *symbol = NULL;
+ bool use_private_variable = false;
struct vkd3d_symbol reg_symbol;
SpvStorageClass storage_class;
struct rb_entry *entry = NULL;
unsigned int signature_idx;
- bool use_private_variable;
unsigned int write_mask;
unsigned int array_size;
bool is_patch_constant;
@@ -4991,11 +5007,10 @@ static void vkd3d_dxbc_compiler_emit_output(struct vkd3d_dxbc_compiler *compiler
storage_class = SpvStorageClassOutput;
- if (!(use_private_variable = builtin && builtin->spirv_array_size)
- && (get_shader_output_swizzle(compiler, signature_element->register_index) != VKD3D_SHADER_NO_SWIZZLE
+ if (get_shader_output_swizzle(compiler, signature_element->register_index) != VKD3D_SHADER_NO_SWIZZLE
|| needs_private_io_variable(shader_signature, signature_element->register_index,
builtin, &output_component_count, &write_mask)
- || is_patch_constant))
+ || is_patch_constant)
use_private_variable = true;
else
component_idx = vkd3d_write_mask_get_component_idx(write_mask);
More information about the wine-cvs
mailing list