vkd3d-shader: Merge i/o variables using the same location.
Fixes a number of issues observed in tessellation shaders, and potentially geometry shaders, when inputs and/or outputs are array variables. Signed-off-by: Philip Rebohle <philip.rebohle@tu-dortmund.de>
This commit is contained in:
parent
740e23ea8a
commit
890ba87a7c
|
@ -1244,17 +1244,6 @@ static void vkd3d_spirv_build_op_storev(struct vkd3d_spirv_builder *builder,
|
|||
pointer_id, object_id, memory_access, operands, operand_count);
|
||||
}
|
||||
|
||||
static void vkd3d_spirv_build_op_copy_memory(struct vkd3d_spirv_builder *builder,
|
||||
uint32_t target_id, uint32_t source_id, uint32_t memory_access)
|
||||
{
|
||||
if (!memory_access)
|
||||
vkd3d_spirv_build_op2(&builder->function_stream, SpvOpCopyMemory,
|
||||
target_id, source_id);
|
||||
else
|
||||
vkd3d_spirv_build_op3(&builder->function_stream, SpvOpCopyMemory,
|
||||
target_id, source_id, memory_access);
|
||||
}
|
||||
|
||||
static uint32_t vkd3d_spirv_build_op_select(struct vkd3d_spirv_builder *builder,
|
||||
uint32_t result_type, uint32_t condition_id, uint32_t object0_id, uint32_t object1_id)
|
||||
{
|
||||
|
@ -2281,11 +2270,15 @@ struct vkd3d_dxbc_compiler
|
|||
const struct vkd3d_shader_signature *input_signature;
|
||||
const struct vkd3d_shader_signature *output_signature;
|
||||
const struct vkd3d_shader_signature *patch_constant_signature;
|
||||
uint32_t input_vars[MAX_REG_OUTPUT];
|
||||
uint32_t output_vars[MAX_REG_OUTPUT];
|
||||
uint32_t patch_constant_vars[MAX_REG_OUTPUT];
|
||||
struct vkd3d_shader_output_info
|
||||
{
|
||||
uint32_t id;
|
||||
enum vkd3d_component_type component_type;
|
||||
uint32_t array_element_mask;
|
||||
uint32_t dst_write_mask;
|
||||
} *output_info;
|
||||
uint32_t private_output_variable[MAX_REG_OUTPUT + 1]; /* 1 entry for oDepth */
|
||||
uint32_t private_output_variable_array_idx[MAX_REG_OUTPUT + 1]; /* 1 entry for oDepth */
|
||||
|
@ -3282,6 +3275,34 @@ static uint32_t vkd3d_dxbc_compiler_emit_vector_shuffle(struct vkd3d_dxbc_compil
|
|||
type_id, vector1_id, vector2_id, components, component_count);
|
||||
}
|
||||
|
||||
static uint32_t vkd3d_dxbc_compiler_select_components(struct vkd3d_dxbc_compiler *compiler,
|
||||
uint32_t vector_id, enum vkd3d_component_type component_type, unsigned int component_count,
|
||||
uint32_t write_mask)
|
||||
{
|
||||
struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
|
||||
uint32_t components[VKD3D_VEC4_SIZE];
|
||||
unsigned int i, j;
|
||||
uint32_t type_id;
|
||||
|
||||
if (vkd3d_write_mask_component_count(write_mask) == component_count)
|
||||
return vector_id;
|
||||
|
||||
for (i = 0, j = 0; i < component_count; ++i)
|
||||
{
|
||||
if (write_mask & (VKD3DSP_WRITEMASK_0 << i))
|
||||
components[j++] = i;
|
||||
}
|
||||
|
||||
type_id = vkd3d_spirv_get_type_id(builder, component_type, j);
|
||||
|
||||
if (j == 1)
|
||||
return vkd3d_spirv_build_op_composite_extract1(builder,
|
||||
type_id, vector_id, components[0]);
|
||||
else
|
||||
return vkd3d_spirv_build_op_vector_shuffle(builder,
|
||||
type_id, vector_id, vector_id, components, j);
|
||||
}
|
||||
|
||||
static uint32_t vkd3d_dxbc_compiler_emit_load_constant(struct vkd3d_dxbc_compiler *compiler,
|
||||
const struct vkd3d_shader_register *reg, DWORD swizzle, DWORD write_mask)
|
||||
{
|
||||
|
@ -4420,23 +4441,118 @@ static bool needs_private_io_variable(const struct vkd3d_shader_signature *signa
|
|||
if (builtin || have_sysval)
|
||||
return true;
|
||||
|
||||
if (!vkd3d_bitmask_is_contiguous(write_mask))
|
||||
{
|
||||
FIXME("Write mask %#x is non-contiguous.\n", write_mask);
|
||||
return true;
|
||||
}
|
||||
|
||||
assert(vkd3d_write_mask_component_count(write_mask) >= *component_count);
|
||||
*component_count = vkd3d_write_mask_component_count(write_mask);
|
||||
*out_write_mask = write_mask;
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool is_dual_source_blending(const struct vkd3d_dxbc_compiler *compiler)
|
||||
{
|
||||
const struct vkd3d_shader_compile_arguments *compile_args = compiler->compile_args;
|
||||
|
||||
return compiler->shader_type == VKD3D_SHADER_TYPE_PIXEL
|
||||
&& compile_args && compile_args->dual_source_blending;
|
||||
}
|
||||
|
||||
static uint32_t vkd3d_dxbc_compiler_get_io_variable(struct vkd3d_dxbc_compiler *compiler,
|
||||
SpvStorageClass storage_class, uint32_t reg_idx, uint32_t array_size,
|
||||
enum vkd3d_shader_interpolation_mode interpolation_mode, bool is_patch_constant,
|
||||
unsigned int *out_component_count, enum vkd3d_component_type *out_component_type)
|
||||
{
|
||||
struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
|
||||
const struct vkd3d_shader_signature *signature;
|
||||
unsigned int component_count, i, write_mask;
|
||||
enum vkd3d_component_type component_type;
|
||||
uint32_t location, var_id, *var_ids;
|
||||
|
||||
if (is_patch_constant)
|
||||
{
|
||||
signature = compiler->patch_constant_signature;
|
||||
var_ids = compiler->patch_constant_vars;
|
||||
}
|
||||
else if (storage_class == SpvStorageClassInput)
|
||||
{
|
||||
signature = compiler->input_signature;
|
||||
var_ids = compiler->input_vars;
|
||||
}
|
||||
else
|
||||
{
|
||||
signature = compiler->output_signature;
|
||||
var_ids = compiler->output_vars;
|
||||
}
|
||||
|
||||
component_type = VKD3D_TYPE_VOID;
|
||||
component_count = 0;
|
||||
write_mask = 0;
|
||||
|
||||
for (i = 0; i < signature->element_count; ++i)
|
||||
{
|
||||
const struct vkd3d_shader_signature_element *current = &signature->elements[i];
|
||||
|
||||
if (current->register_index != reg_idx)
|
||||
continue;
|
||||
|
||||
if (current->component_type != VKD3D_TYPE_FLOAT)
|
||||
interpolation_mode = VKD3DSIM_CONSTANT;
|
||||
|
||||
if (component_type == VKD3D_TYPE_VOID)
|
||||
component_type = current->component_type;
|
||||
else if (current->component_type != component_type)
|
||||
component_type = VKD3D_TYPE_UINT;
|
||||
|
||||
write_mask |= current->mask & 0xff;
|
||||
}
|
||||
|
||||
while ((1u << component_count) <= write_mask)
|
||||
component_count++;
|
||||
|
||||
if (out_component_count)
|
||||
*out_component_count = component_count;
|
||||
|
||||
if (out_component_type)
|
||||
*out_component_type = component_type;
|
||||
|
||||
if (var_ids[reg_idx])
|
||||
return var_ids[reg_idx];
|
||||
|
||||
var_id = vkd3d_dxbc_compiler_emit_array_variable(compiler, &builder->global_stream,
|
||||
storage_class, component_type, component_count, array_size);
|
||||
|
||||
location = reg_idx;
|
||||
|
||||
if (is_patch_constant)
|
||||
{
|
||||
vkd3d_spirv_build_op_decorate(builder, var_id, SpvDecorationPatch, NULL, 0);
|
||||
|
||||
location += storage_class == SpvStorageClassInput
|
||||
? compiler->input_signature->element_count
|
||||
: compiler->output_signature->element_count;
|
||||
}
|
||||
|
||||
if (storage_class == SpvStorageClassOutput && is_dual_source_blending(compiler) && location < 2)
|
||||
{
|
||||
vkd3d_spirv_build_op_decorate1(builder, var_id, SpvDecorationLocation, 0);
|
||||
vkd3d_spirv_build_op_decorate1(builder, var_id, SpvDecorationIndex, location);
|
||||
}
|
||||
else
|
||||
{
|
||||
vkd3d_spirv_build_op_decorate1(builder, var_id, SpvDecorationLocation, location);
|
||||
}
|
||||
|
||||
if (compiler->shader_type == VKD3D_SHADER_TYPE_PIXEL && storage_class == SpvStorageClassInput)
|
||||
vkd3d_dxbc_compiler_emit_interpolation_decorations(compiler, var_id, interpolation_mode);
|
||||
|
||||
vkd3d_spirv_add_iface_variable(builder, var_id);
|
||||
var_ids[reg_idx] = var_id;
|
||||
return var_id;
|
||||
}
|
||||
|
||||
static uint32_t vkd3d_dxbc_compiler_emit_input(struct vkd3d_dxbc_compiler *compiler,
|
||||
const struct vkd3d_shader_dst_param *dst, enum vkd3d_shader_input_sysval_semantic sysval,
|
||||
enum vkd3d_shader_interpolation_mode interpolation_mode)
|
||||
{
|
||||
unsigned int component_idx, component_count, input_component_count;
|
||||
unsigned int component_count, input_component_count;
|
||||
struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
|
||||
const struct vkd3d_shader_signature_element *signature_element;
|
||||
const struct vkd3d_shader_signature *shader_signature;
|
||||
|
@ -4444,6 +4560,7 @@ static uint32_t vkd3d_dxbc_compiler_emit_input(struct vkd3d_dxbc_compiler *compi
|
|||
uint32_t type_id, ptr_type_id, float_type_id;
|
||||
const struct vkd3d_spirv_builtin *builtin;
|
||||
enum vkd3d_component_type component_type;
|
||||
bool apply_patch_decoration = true;
|
||||
uint32_t val_id, input_id, var_id;
|
||||
struct vkd3d_symbol reg_symbol;
|
||||
struct vkd3d_symbol tmp_symbol;
|
||||
|
@ -4452,6 +4569,7 @@ static uint32_t vkd3d_dxbc_compiler_emit_input(struct vkd3d_dxbc_compiler *compi
|
|||
bool use_private_var = false;
|
||||
unsigned int write_mask;
|
||||
unsigned int array_size;
|
||||
bool is_patch_constant;
|
||||
unsigned int reg_idx;
|
||||
uint32_t i, index;
|
||||
|
||||
|
@ -4469,8 +4587,8 @@ static uint32_t vkd3d_dxbc_compiler_emit_input(struct vkd3d_dxbc_compiler *compi
|
|||
reg_idx = reg->idx[0].offset;
|
||||
}
|
||||
|
||||
shader_signature = reg->type == VKD3DSPR_PATCHCONST
|
||||
? compiler->patch_constant_signature : compiler->input_signature;
|
||||
is_patch_constant = reg->type == VKD3DSPR_PATCHCONST;
|
||||
shader_signature = is_patch_constant ? compiler->patch_constant_signature : compiler->input_signature;
|
||||
|
||||
if (!(signature_element = vkd3d_find_signature_element_for_reg(shader_signature,
|
||||
NULL, reg_idx, dst->write_mask)))
|
||||
|
@ -4491,13 +4609,11 @@ static uint32_t vkd3d_dxbc_compiler_emit_input(struct vkd3d_dxbc_compiler *compi
|
|||
{
|
||||
component_type = builtin->component_type;
|
||||
input_component_count = builtin->component_count;
|
||||
component_idx = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
component_type = signature_element->component_type;
|
||||
input_component_count = vkd3d_write_mask_component_count(signature_element->mask & 0xff);
|
||||
component_idx = vkd3d_write_mask_get_component_idx(signature_element->mask & 0xff);
|
||||
}
|
||||
|
||||
if ((use_private_var = builtin && builtin->fixup_pfn))
|
||||
|
@ -4511,10 +4627,6 @@ static uint32_t vkd3d_dxbc_compiler_emit_input(struct vkd3d_dxbc_compiler *compi
|
|||
component_count = VKD3D_VEC4_SIZE;
|
||||
write_mask = VKD3DSP_WRITEMASK_ALL;
|
||||
}
|
||||
else
|
||||
{
|
||||
component_idx = vkd3d_write_mask_get_component_idx(write_mask);
|
||||
}
|
||||
|
||||
storage_class = SpvStorageClassInput;
|
||||
|
||||
|
@ -4531,21 +4643,10 @@ static uint32_t vkd3d_dxbc_compiler_emit_input(struct vkd3d_dxbc_compiler *compi
|
|||
|
||||
if (use_private_var)
|
||||
{
|
||||
/* We still need to declare an input I/O variable.
|
||||
* This input will be swizzled into the existing private variable. */
|
||||
unsigned int location = reg_idx;
|
||||
|
||||
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);
|
||||
input_id = vkd3d_dxbc_compiler_get_io_variable(compiler, SpvStorageClassInput,
|
||||
reg_idx, array_size, interpolation_mode, is_patch_constant,
|
||||
&input_component_count, &component_type);
|
||||
apply_patch_decoration = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -4569,23 +4670,14 @@ static uint32_t vkd3d_dxbc_compiler_emit_input(struct vkd3d_dxbc_compiler *compi
|
|||
|
||||
if (!entry)
|
||||
{
|
||||
unsigned int location = reg_idx;
|
||||
|
||||
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);
|
||||
input_id = vkd3d_dxbc_compiler_get_io_variable(compiler, SpvStorageClassInput,
|
||||
reg_idx, array_size, interpolation_mode, is_patch_constant,
|
||||
&input_component_count, &component_type);
|
||||
apply_patch_decoration = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (reg->type == VKD3DSPR_PATCHCONST)
|
||||
if (reg->type == VKD3DSPR_PATCHCONST && apply_patch_decoration)
|
||||
vkd3d_spirv_build_op_decorate(builder, input_id, SpvDecorationPatch, NULL, 0);
|
||||
|
||||
if (entry || !use_private_var)
|
||||
|
@ -4648,7 +4740,7 @@ static uint32_t vkd3d_dxbc_compiler_emit_input(struct vkd3d_dxbc_compiler *compi
|
|||
|
||||
val_id = vkd3d_dxbc_compiler_emit_swizzle(compiler, val_id,
|
||||
vkd3d_write_mask_from_component_count(input_component_count),
|
||||
VKD3D_TYPE_FLOAT, VKD3D_NO_SWIZZLE, dst->write_mask >> component_idx);
|
||||
VKD3D_TYPE_FLOAT, VKD3D_NO_SWIZZLE, dst->write_mask);
|
||||
|
||||
vkd3d_dxbc_compiler_emit_store_reg(compiler, &dst_reg, dst->write_mask, val_id);
|
||||
}
|
||||
|
@ -4778,14 +4870,6 @@ static unsigned int get_shader_output_swizzle(const struct vkd3d_dxbc_compiler *
|
|||
return compile_args->output_swizzles[register_idx];
|
||||
}
|
||||
|
||||
static bool is_dual_source_blending(const struct vkd3d_dxbc_compiler *compiler)
|
||||
{
|
||||
const struct vkd3d_shader_compile_arguments *compile_args = compiler->compile_args;
|
||||
|
||||
return compiler->shader_type == VKD3D_SHADER_TYPE_PIXEL
|
||||
&& compile_args && compile_args->dual_source_blending;
|
||||
}
|
||||
|
||||
static void calculate_clip_or_cull_distance_mask(const struct vkd3d_shader_signature_element *e,
|
||||
uint32_t *mask)
|
||||
{
|
||||
|
@ -4880,12 +4964,14 @@ static void vkd3d_dxbc_compiler_emit_clip_cull_outputs(struct vkd3d_dxbc_compile
|
|||
compiler->output_info[i].id = clip_distance_id;
|
||||
compiler->output_info[i].component_type = VKD3D_TYPE_FLOAT;
|
||||
compiler->output_info[i].array_element_mask = clip_distance_mask;
|
||||
compiler->output_info[i].dst_write_mask = VKD3DSP_WRITEMASK_0;
|
||||
break;
|
||||
|
||||
case VKD3D_SV_CULL_DISTANCE:
|
||||
compiler->output_info[i].id = cull_distance_id;
|
||||
compiler->output_info[i].component_type = VKD3D_TYPE_FLOAT;
|
||||
compiler->output_info[i].array_element_mask = cull_distance_mask;
|
||||
compiler->output_info[i].dst_write_mask = VKD3DSP_WRITEMASK_0;
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -4960,6 +5046,7 @@ static void vkd3d_dxbc_compiler_emit_output(struct vkd3d_dxbc_compiler *compiler
|
|||
const struct vkd3d_spirv_builtin *builtin;
|
||||
enum vkd3d_component_type component_type;
|
||||
const struct vkd3d_shader_phase *phase;
|
||||
bool apply_patch_decoration = true;
|
||||
struct vkd3d_symbol reg_symbol;
|
||||
SpvStorageClass storage_class;
|
||||
struct rb_entry *entry = NULL;
|
||||
|
@ -5054,30 +5141,13 @@ static void vkd3d_dxbc_compiler_emit_output(struct vkd3d_dxbc_compiler *compiler
|
|||
}
|
||||
else
|
||||
{
|
||||
unsigned int location = reg->idx[0].offset;
|
||||
|
||||
if (is_patch_constant)
|
||||
location += compiler->output_signature->element_count;
|
||||
|
||||
id = vkd3d_dxbc_compiler_emit_array_variable(compiler, &builder->global_stream,
|
||||
storage_class, component_type, output_component_count, array_size);
|
||||
vkd3d_spirv_add_iface_variable(builder, id);
|
||||
|
||||
if (is_dual_source_blending(compiler) && reg->idx[0].offset < 2)
|
||||
{
|
||||
vkd3d_spirv_build_op_decorate1(builder, id, SpvDecorationLocation, 0);
|
||||
vkd3d_spirv_build_op_decorate1(builder, id, SpvDecorationIndex, reg->idx[0].offset);
|
||||
}
|
||||
else
|
||||
{
|
||||
vkd3d_spirv_build_op_decorate1(builder, id, SpvDecorationLocation, location);
|
||||
}
|
||||
|
||||
if (component_idx)
|
||||
vkd3d_spirv_build_op_decorate1(builder, id, SpvDecorationComponent, component_idx);
|
||||
id = vkd3d_dxbc_compiler_get_io_variable(compiler, storage_class,
|
||||
reg->idx[0].offset, array_size, VKD3DSIM_NONE, is_patch_constant,
|
||||
&output_component_count, &component_type);
|
||||
apply_patch_decoration = false;
|
||||
}
|
||||
|
||||
if (is_patch_constant)
|
||||
if (is_patch_constant && apply_patch_decoration)
|
||||
vkd3d_spirv_build_op_decorate(builder, id, SpvDecorationPatch, NULL, 0);
|
||||
|
||||
vkd3d_dxbc_compiler_decorate_xfb_output(compiler, id, output_component_count, signature_element);
|
||||
|
@ -5085,6 +5155,10 @@ static void vkd3d_dxbc_compiler_emit_output(struct vkd3d_dxbc_compiler *compiler
|
|||
|
||||
compiler->output_info[signature_idx].id = id;
|
||||
compiler->output_info[signature_idx].component_type = component_type;
|
||||
compiler->output_info[signature_idx].dst_write_mask = (VKD3DSP_WRITEMASK_0 << output_component_count) - 1;
|
||||
|
||||
if (!builtin)
|
||||
compiler->output_info[signature_idx].dst_write_mask &= write_mask;
|
||||
|
||||
if (use_private_variable)
|
||||
storage_class = SpvStorageClassPrivate;
|
||||
|
@ -5162,8 +5236,8 @@ static void vkd3d_dxbc_compiler_emit_store_shader_output(struct vkd3d_dxbc_compi
|
|||
unsigned int i, index, array_idx;
|
||||
uint32_t output_id;
|
||||
|
||||
dst_write_mask = output->mask & 0xff;
|
||||
write_mask &= dst_write_mask;
|
||||
dst_write_mask = output_info->dst_write_mask;
|
||||
write_mask &= output->mask & 0xff;
|
||||
use_mask = (output->mask >> 8) & 0xff;
|
||||
|
||||
if (!write_mask)
|
||||
|
@ -5176,7 +5250,7 @@ static void vkd3d_dxbc_compiler_emit_store_shader_output(struct vkd3d_dxbc_compi
|
|||
}
|
||||
|
||||
swizzle = get_shader_output_swizzle(compiler, output->register_index);
|
||||
uninit_mask = dst_write_mask & use_mask;
|
||||
uninit_mask = output->mask & use_mask;
|
||||
if (uninit_mask)
|
||||
{
|
||||
/* Set values to 0 for not initialized shader output components. */
|
||||
|
@ -7323,19 +7397,33 @@ static const struct vkd3d_shader_phase *vkd3d_dxbc_compiler_get_control_point_ph
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static uint32_t vkd3d_dxbc_compiler_load_invocation_input(struct vkd3d_dxbc_compiler *compiler,
|
||||
uint32_t input_id, uint32_t invocation_id, enum vkd3d_component_type component_type,
|
||||
unsigned int component_count, uint32_t write_mask)
|
||||
{
|
||||
struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
|
||||
uint32_t type_id, ptr_type_id, ptr_id, value_id;
|
||||
|
||||
type_id = vkd3d_spirv_get_type_id(builder, component_type, component_count);
|
||||
ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, SpvStorageClassInput, type_id);
|
||||
ptr_id = vkd3d_spirv_build_op_access_chain1(builder, ptr_type_id, input_id, invocation_id);
|
||||
|
||||
value_id = vkd3d_spirv_build_op_load(builder, type_id, ptr_id, SpvMemoryAccessMaskNone);
|
||||
return vkd3d_dxbc_compiler_select_components(compiler, value_id, component_type, component_count, write_mask);
|
||||
}
|
||||
|
||||
static void vkd3d_dxbc_compiler_emit_default_control_point_phase(struct vkd3d_dxbc_compiler *compiler)
|
||||
{
|
||||
const struct vkd3d_shader_signature *output_signature = compiler->output_signature;
|
||||
const struct vkd3d_shader_signature *input_signature = compiler->input_signature;
|
||||
enum vkd3d_component_type input_component_type, output_component_type;
|
||||
uint32_t output_ptr_type_id, input_id, output_id, dst_id, src_id;
|
||||
struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
|
||||
uint32_t type_id, input_ptr_type_id, output_ptr_type_id;
|
||||
unsigned int input_component_count, output_component_count;
|
||||
const struct vkd3d_spirv_builtin *input_builtin;
|
||||
uint32_t input_id, output_id, dst_id, src_id;
|
||||
struct vkd3d_shader_register_info input_info;
|
||||
enum vkd3d_component_type component_type;
|
||||
struct vkd3d_shader_register input_reg;
|
||||
unsigned int component_count;
|
||||
uint32_t invocation_id;
|
||||
uint32_t invocation_id, dst_write_mask;
|
||||
unsigned int i;
|
||||
|
||||
invocation_id = vkd3d_dxbc_compiler_emit_load_invocation_id(compiler);
|
||||
|
@ -7360,50 +7448,50 @@ static void vkd3d_dxbc_compiler_emit_default_control_point_phase(struct vkd3d_dx
|
|||
{
|
||||
input_id = input_info.id;
|
||||
|
||||
component_type = input_info.component_type;
|
||||
component_count = vkd3d_write_mask_component_count(input_info.write_mask);
|
||||
input_component_type = input_info.component_type;
|
||||
input_component_count = vkd3d_write_mask_component_count(input_info.write_mask);
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((input_builtin = get_spirv_builtin_for_sysval(compiler, vkd3d_siv_from_sysval(input->sysval_semantic))))
|
||||
{
|
||||
component_type = input_builtin->component_type;
|
||||
component_count = input_builtin->component_count;
|
||||
}
|
||||
else
|
||||
{
|
||||
component_type = input->component_type;
|
||||
component_count = vkd3d_write_mask_component_count(input->mask & 0xff);
|
||||
}
|
||||
input_component_type = input_builtin->component_type;
|
||||
input_component_count = input_builtin->component_count;
|
||||
|
||||
if (input_builtin)
|
||||
{
|
||||
input_id = vkd3d_dxbc_compiler_emit_builtin_variable(compiler,
|
||||
input_builtin, SpvStorageClassInput, compiler->input_control_point_count);
|
||||
}
|
||||
else
|
||||
{
|
||||
input_id = vkd3d_dxbc_compiler_emit_array_variable(compiler, &builder->global_stream,
|
||||
SpvStorageClassInput, component_type, component_count, compiler->input_control_point_count);
|
||||
vkd3d_spirv_add_iface_variable(builder, input_id);
|
||||
vkd3d_spirv_build_op_decorate1(builder, input_id, SpvDecorationLocation, input->register_index);
|
||||
input_id = vkd3d_dxbc_compiler_get_io_variable(compiler, SpvStorageClassInput,
|
||||
input->register_index, compiler->input_control_point_count, VKD3DSIM_NONE,
|
||||
false, &input_component_count, &input_component_type);
|
||||
}
|
||||
|
||||
vkd3d_spirv_build_op_name(builder, input_id, "vicp%u", input->register_index);
|
||||
}
|
||||
|
||||
output_id = vkd3d_dxbc_compiler_emit_array_variable(compiler, &builder->global_stream,
|
||||
SpvStorageClassOutput, component_type, component_count, compiler->output_control_point_count);
|
||||
vkd3d_spirv_add_iface_variable(builder, output_id);
|
||||
vkd3d_spirv_build_op_decorate1(builder, output_id, SpvDecorationLocation, output->register_index);
|
||||
output_id = vkd3d_dxbc_compiler_get_io_variable(compiler, SpvStorageClassOutput,
|
||||
output->register_index, compiler->output_control_point_count, VKD3DSIM_NONE,
|
||||
false, &output_component_count, &output_component_type);
|
||||
vkd3d_spirv_build_op_name(builder, output_id, "vocp%u", output->register_index);
|
||||
|
||||
type_id = vkd3d_spirv_get_type_id(builder, component_type, component_count);
|
||||
output_ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, SpvStorageClassOutput, type_id);
|
||||
input_ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, SpvStorageClassInput, type_id);
|
||||
src_id = vkd3d_dxbc_compiler_load_invocation_input(compiler, input_id, invocation_id,
|
||||
input_component_type, input_component_count, input->mask & 0xff);
|
||||
|
||||
if (output_component_type != input_component_type)
|
||||
{
|
||||
uint32_t type_id = vkd3d_spirv_get_type_id(builder, output_component_type, input_component_count);
|
||||
src_id = vkd3d_spirv_build_op_bitcast(builder, type_id, src_id);
|
||||
}
|
||||
|
||||
output_ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, SpvStorageClassOutput,
|
||||
vkd3d_spirv_get_type_id(builder, output_component_type, output_component_count));
|
||||
dst_id = vkd3d_spirv_build_op_access_chain1(builder, output_ptr_type_id, output_id, invocation_id);
|
||||
src_id = vkd3d_spirv_build_op_access_chain1(builder, input_ptr_type_id, input_id, invocation_id);
|
||||
vkd3d_spirv_build_op_copy_memory(builder, dst_id, src_id, SpvMemoryAccessMaskNone);
|
||||
dst_write_mask = (VKD3DSP_WRITEMASK_0 << output_component_count) - 1;
|
||||
|
||||
vkd3d_dxbc_compiler_emit_store(compiler, dst_id, dst_write_mask,
|
||||
output_component_type, SpvStorageClassOutput, output->mask & 0xff, src_id);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue