vkd3d-shader: Lower shader model 1/2 inter-stage I/O to a flat array.

An alternative is that we stash the reg_type in the signature, but this seems
far simpler for the backend to deal with.
This commit is contained in:
Zebediah Figura 2023-10-27 12:44:08 -05:00 committed by Alexandre Julliard
parent 3bafee344d
commit 3f52fda8ad
Notes: Alexandre Julliard 2024-01-04 23:09:22 +01:00
Approved-by: Henri Verbeet (@hverbeet)
Approved-by: Alexandre Julliard (@julliard)
Merge-Request: https://gitlab.winehq.org/wine/vkd3d/-/merge_requests/527
3 changed files with 76 additions and 27 deletions

View File

@ -518,8 +518,6 @@ static struct signature_element *find_signature_element_by_register_index(
return NULL;
}
#define SM1_COLOR_REGISTER_OFFSET 8
static bool add_signature_element(struct vkd3d_shader_sm1_parser *sm1, bool output,
const char *name, unsigned int index, enum vkd3d_shader_sysval_semantic sysval,
unsigned int register_index, bool is_dcl, unsigned int mask)

View File

@ -533,6 +533,7 @@ struct io_normaliser
{
struct vkd3d_shader_instruction_array instructions;
enum vkd3d_shader_type shader_type;
uint8_t major;
struct shader_signature *input_signature;
struct shader_signature *output_signature;
struct shader_signature *patch_constant_signature;
@ -867,34 +868,65 @@ static bool shader_dst_param_io_normalise(struct vkd3d_shader_dst_param *dst_par
const struct shader_signature *signature;
const struct signature_element *e;
if ((reg->type == VKD3DSPR_OUTPUT && io_normaliser_is_in_fork_or_join_phase(normaliser))
|| reg->type == VKD3DSPR_PATCHCONST)
switch (reg->type)
{
signature = normaliser->patch_constant_signature;
/* Convert patch constant outputs to the patch constant register type to avoid the need
* to convert compiler symbols when accessed as inputs in a later stage. */
reg->type = VKD3DSPR_PATCHCONST;
dcl_params = normaliser->pc_dcl_params;
}
else if (reg->type == VKD3DSPR_OUTPUT || dst_param->reg.type == VKD3DSPR_COLOROUT)
{
signature = normaliser->output_signature;
reg->type = VKD3DSPR_OUTPUT;
dcl_params = normaliser->output_dcl_params;
}
else if (dst_param->reg.type == VKD3DSPR_INCONTROLPOINT || dst_param->reg.type == VKD3DSPR_INPUT)
{
signature = normaliser->input_signature;
reg->type = VKD3DSPR_INPUT;
dcl_params = normaliser->input_dcl_params;
}
else
{
return true;
case VKD3DSPR_OUTPUT:
reg_idx = reg->idx[reg->idx_count - 1].offset;
if (io_normaliser_is_in_fork_or_join_phase(normaliser))
{
signature = normaliser->patch_constant_signature;
/* Convert patch constant outputs to the patch constant register type to avoid the need
* to convert compiler symbols when accessed as inputs in a later stage. */
reg->type = VKD3DSPR_PATCHCONST;
dcl_params = normaliser->pc_dcl_params;
}
else
{
signature = normaliser->output_signature;
dcl_params = normaliser->output_dcl_params;
}
break;
case VKD3DSPR_PATCHCONST:
reg_idx = reg->idx[reg->idx_count - 1].offset;
signature = normaliser->patch_constant_signature;
dcl_params = normaliser->pc_dcl_params;
break;
case VKD3DSPR_COLOROUT:
reg_idx = reg->idx[0].offset;
signature = normaliser->output_signature;
reg->type = VKD3DSPR_OUTPUT;
dcl_params = normaliser->output_dcl_params;
break;
case VKD3DSPR_INCONTROLPOINT:
case VKD3DSPR_INPUT:
reg_idx = reg->idx[reg->idx_count - 1].offset;
signature = normaliser->input_signature;
reg->type = VKD3DSPR_INPUT;
dcl_params = normaliser->input_dcl_params;
break;
case VKD3DSPR_ATTROUT:
reg_idx = SM1_COLOR_REGISTER_OFFSET + reg->idx[0].offset;
signature = normaliser->output_signature;
reg->type = VKD3DSPR_OUTPUT;
dcl_params = normaliser->output_dcl_params;
break;
case VKD3DSPR_RASTOUT:
reg_idx = reg->idx[0].offset;
signature = normaliser->output_signature;
reg->type = VKD3DSPR_OUTPUT;
dcl_params = normaliser->output_dcl_params;
break;
default:
return true;
}
id_idx = reg->idx_count - 1;
reg_idx = reg->idx[id_idx].offset;
write_mask = dst_param->write_mask;
element_idx = shader_signature_find_element_for_reg(signature, reg_idx, write_mask);
e = &signature->elements[element_idx];
@ -982,26 +1014,42 @@ static void shader_src_param_io_normalise(struct vkd3d_shader_src_param *src_par
switch (reg->type)
{
case VKD3DSPR_PATCHCONST:
reg_idx = reg->idx[reg->idx_count - 1].offset;
signature = normaliser->patch_constant_signature;
break;
case VKD3DSPR_INCONTROLPOINT:
reg->type = VKD3DSPR_INPUT;
/* fall through */
case VKD3DSPR_INPUT:
if (normaliser->major < 3 && normaliser->shader_type == VKD3D_SHADER_TYPE_PIXEL)
reg_idx = SM1_COLOR_REGISTER_OFFSET + reg->idx[0].offset;
else
reg_idx = reg->idx[reg->idx_count - 1].offset;
signature = normaliser->input_signature;
break;
case VKD3DSPR_OUTCONTROLPOINT:
reg->type = VKD3DSPR_OUTPUT;
/* fall through */
case VKD3DSPR_OUTPUT:
reg_idx = reg->idx[reg->idx_count - 1].offset;
signature = normaliser->output_signature;
break;
case VKD3DSPR_TEXTURE:
if (normaliser->shader_type != VKD3D_SHADER_TYPE_PIXEL)
return;
reg->type = VKD3DSPR_INPUT;
reg_idx = reg->idx[0].offset;
signature = normaliser->input_signature;
break;
default:
return;
}
id_idx = reg->idx_count - 1;
reg_idx = reg->idx[id_idx].offset;
write_mask = VKD3DSP_WRITEMASK_0 << vsir_swizzle_get_component(src_param->swizzle, 0);
element_idx = shader_signature_find_element_for_reg(signature, reg_idx, write_mask);
@ -1084,6 +1132,7 @@ static enum vkd3d_result shader_normalise_io_registers(struct vkd3d_shader_parse
normaliser.phase = VKD3DSIH_INVALID;
normaliser.shader_type = parser->shader_version.type;
normaliser.major = parser->shader_version.major;
normaliser.input_signature = &parser->shader_desc.input_signature;
normaliser.output_signature = &parser->shader_desc.output_signature;
normaliser.patch_constant_signature = &parser->shader_desc.patch_constant_signature;

View File

@ -955,6 +955,8 @@ enum vkd3d_shader_input_sysval_semantic
VKD3D_SIV_LINE_DENSITY_TESS_FACTOR = 22,
};
#define SM1_COLOR_REGISTER_OFFSET 8
#define SIGNATURE_TARGET_LOCATION_UNUSED (~0u)
struct signature_element