mirror of
https://gitlab.winehq.org/wine/vkd3d.git
synced 2025-09-12 18:50:22 -07:00
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@codeweavers.com> Signed-off-by: Henri Verbeet <hverbeet@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
committed by
Alexandre Julliard
parent
9a1f6c7daf
commit
c41931c750
@@ -4416,6 +4416,13 @@ static bool needs_private_io_variable(const struct vkd3d_shader_signature *signa
|
|||||||
bool have_sysval = false;
|
bool have_sysval = false;
|
||||||
unsigned int i, count;
|
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)
|
if (*component_count == VKD3D_VEC4_SIZE)
|
||||||
return false;
|
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);
|
component_idx = vkd3d_write_mask_get_component_idx(signature_element->mask);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(use_private_var = builtin && builtin->fixup_pfn)
|
if (needs_private_io_variable(shader_signature, reg_idx, builtin, &input_component_count, &write_mask)
|
||||||
&& needs_private_io_variable(shader_signature, reg_idx, builtin, &input_component_count, &write_mask)
|
|
||||||
&& (compiler->shader_type != VKD3D_SHADER_TYPE_HULL
|
&& (compiler->shader_type != VKD3D_SHADER_TYPE_HULL
|
||||||
|| (reg->type != VKD3DSPR_INCONTROLPOINT && reg->type != VKD3DSPR_PATCHCONST)))
|
|| (reg->type != VKD3DSPR_INCONTROLPOINT && reg->type != VKD3DSPR_PATCHCONST)))
|
||||||
use_private_var = true;
|
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);
|
val_id = vkd3d_spirv_build_op_in_bounds_access_chain1(builder, ptr_type_id, input_id, index);
|
||||||
dst_reg.idx[0].offset = i;
|
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);
|
val_id = vkd3d_spirv_build_op_load(builder, type_id, val_id, SpvMemoryAccessMaskNone);
|
||||||
|
|
||||||
if (builtin && builtin->fixup_pfn)
|
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_spirv_builtin *builtin;
|
||||||
const struct vkd3d_shader_phase *phase;
|
const struct vkd3d_shader_phase *phase;
|
||||||
struct vkd3d_symbol *symbol = NULL;
|
struct vkd3d_symbol *symbol = NULL;
|
||||||
|
bool use_private_variable = false;
|
||||||
struct vkd3d_symbol reg_symbol;
|
struct vkd3d_symbol reg_symbol;
|
||||||
SpvStorageClass storage_class;
|
SpvStorageClass storage_class;
|
||||||
struct rb_entry *entry = NULL;
|
struct rb_entry *entry = NULL;
|
||||||
unsigned int signature_idx;
|
unsigned int signature_idx;
|
||||||
bool use_private_variable;
|
|
||||||
unsigned int write_mask;
|
unsigned int write_mask;
|
||||||
unsigned int array_size;
|
unsigned int array_size;
|
||||||
bool is_patch_constant;
|
bool is_patch_constant;
|
||||||
@@ -4991,11 +5007,10 @@ static void vkd3d_dxbc_compiler_emit_output(struct vkd3d_dxbc_compiler *compiler
|
|||||||
|
|
||||||
storage_class = SpvStorageClassOutput;
|
storage_class = SpvStorageClassOutput;
|
||||||
|
|
||||||
if (!(use_private_variable = builtin && builtin->spirv_array_size)
|
if (get_shader_output_swizzle(compiler, signature_element->register_index) != VKD3D_SHADER_NO_SWIZZLE
|
||||||
&& (get_shader_output_swizzle(compiler, signature_element->register_index) != VKD3D_SHADER_NO_SWIZZLE
|
|
||||||
|| needs_private_io_variable(shader_signature, signature_element->register_index,
|
|| needs_private_io_variable(shader_signature, signature_element->register_index,
|
||||||
builtin, &output_component_count, &write_mask)
|
builtin, &output_component_count, &write_mask)
|
||||||
|| is_patch_constant))
|
|| is_patch_constant)
|
||||||
use_private_variable = true;
|
use_private_variable = true;
|
||||||
else
|
else
|
||||||
component_idx = vkd3d_write_mask_get_component_idx(write_mask);
|
component_idx = vkd3d_write_mask_get_component_idx(write_mask);
|
||||||
|
Reference in New Issue
Block a user