mirror of
https://gitlab.winehq.org/wine/vkd3d.git
synced 2025-01-28 13:05:02 -08:00
vkd3d-shader/dxil: Support patch constant functions and signatures.
This commit is contained in:
parent
d5c6e12dd3
commit
4457181b2a
Notes:
Alexandre Julliard
2024-04-22 23:38:15 +02:00
Approved-by: Giovanni Mascellani (@giomasce) Approved-by: Henri Verbeet (@hverbeet) Approved-by: Alexandre Julliard (@julliard) Merge-Request: https://gitlab.winehq.org/wine/vkd3d/-/merge_requests/768
@ -799,6 +799,7 @@ struct sm6_parser
|
||||
|
||||
struct vkd3d_shader_dst_param *output_params;
|
||||
struct vkd3d_shader_dst_param *input_params;
|
||||
struct vkd3d_shader_dst_param *patch_constant_params;
|
||||
uint32_t io_regs_declared[(VKD3DSPR_COUNT + 0x1f) / 0x20];
|
||||
|
||||
struct sm6_function *functions;
|
||||
@ -2515,7 +2516,7 @@ static size_t sm6_parser_compute_max_value_count(struct sm6_parser *sm6,
|
||||
* overestimate the value count somewhat, but this should be no problem. */
|
||||
value_count = size_add_with_overflow_check(value_count, max(block->record_count, 1u) - 1);
|
||||
sm6->value_capacity = max(sm6->value_capacity, value_count);
|
||||
sm6->functions[sm6->function_count].value_count = value_count;
|
||||
sm6->functions[sm6->function_count++].value_count = value_count;
|
||||
/* The value count returns to its previous value after handling a function. */
|
||||
if (value_count < SIZE_MAX)
|
||||
value_count = old_value_count;
|
||||
@ -3689,12 +3690,35 @@ static enum vkd3d_shader_register_type register_type_from_dxil_semantic_kind(
|
||||
}
|
||||
|
||||
static void sm6_parser_init_signature(struct sm6_parser *sm6, const struct shader_signature *s,
|
||||
enum vkd3d_shader_register_type reg_type, struct vkd3d_shader_dst_param *params)
|
||||
bool is_input, enum vkd3d_shader_register_type reg_type, struct vkd3d_shader_dst_param *params)
|
||||
{
|
||||
enum vkd3d_shader_type shader_type = sm6->p.program.shader_version.type;
|
||||
bool is_patch_constant, is_control_point;
|
||||
struct vkd3d_shader_dst_param *param;
|
||||
const struct signature_element *e;
|
||||
unsigned int i, count;
|
||||
|
||||
is_patch_constant = reg_type == VKD3DSPR_PATCHCONST;
|
||||
|
||||
is_control_point = false;
|
||||
if (!is_patch_constant)
|
||||
{
|
||||
switch (shader_type)
|
||||
{
|
||||
case VKD3D_SHADER_TYPE_DOMAIN:
|
||||
case VKD3D_SHADER_TYPE_GEOMETRY:
|
||||
is_control_point = is_input;
|
||||
break;
|
||||
|
||||
case VKD3D_SHADER_TYPE_HULL:
|
||||
is_control_point = true;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < s->element_count; ++i)
|
||||
{
|
||||
e = &s->elements[i];
|
||||
@ -3709,8 +3733,18 @@ static void sm6_parser_init_signature(struct sm6_parser *sm6, const struct shade
|
||||
|
||||
dst_param_io_init(param, e, reg_type);
|
||||
count = 0;
|
||||
if (e->register_count > 1)
|
||||
|
||||
if (is_control_point)
|
||||
{
|
||||
if (reg_type == VKD3DSPR_OUTPUT)
|
||||
param->reg.idx[count].rel_addr = instruction_array_create_outpointid_param(&sm6->p.program.instructions);
|
||||
param->reg.idx[count++].offset = 0;
|
||||
}
|
||||
|
||||
if (e->register_count > 1 || (is_patch_constant && vsir_sysval_semantic_is_tess_factor(e->sysval_semantic)))
|
||||
param->reg.idx[count++].offset = 0;
|
||||
|
||||
assert(count < ARRAY_SIZE(param->reg.idx));
|
||||
param->reg.idx[count++].offset = i;
|
||||
param->reg.idx_count = count;
|
||||
}
|
||||
@ -3718,12 +3752,21 @@ static void sm6_parser_init_signature(struct sm6_parser *sm6, const struct shade
|
||||
|
||||
static void sm6_parser_init_output_signature(struct sm6_parser *sm6, const struct shader_signature *output_signature)
|
||||
{
|
||||
sm6_parser_init_signature(sm6, output_signature, VKD3DSPR_OUTPUT, sm6->output_params);
|
||||
sm6_parser_init_signature(sm6, output_signature, false, VKD3DSPR_OUTPUT, sm6->output_params);
|
||||
}
|
||||
|
||||
static void sm6_parser_init_input_signature(struct sm6_parser *sm6, const struct shader_signature *input_signature)
|
||||
{
|
||||
sm6_parser_init_signature(sm6, input_signature, VKD3DSPR_INPUT, sm6->input_params);
|
||||
sm6_parser_init_signature(sm6, input_signature, true, VKD3DSPR_INPUT, sm6->input_params);
|
||||
}
|
||||
|
||||
static void sm6_parser_init_patch_constant_signature(struct sm6_parser *sm6,
|
||||
const struct shader_signature *patch_constant_signature)
|
||||
{
|
||||
bool is_input = sm6->p.program.shader_version.type == VKD3D_SHADER_TYPE_DOMAIN;
|
||||
|
||||
sm6_parser_init_signature(sm6, patch_constant_signature, is_input, VKD3DSPR_PATCHCONST,
|
||||
sm6->patch_constant_params);
|
||||
}
|
||||
|
||||
static const struct sm6_value *sm6_parser_next_function_definition(struct sm6_parser *sm6)
|
||||
@ -7286,11 +7329,6 @@ static enum vkd3d_result sm6_parser_function_init(struct sm6_parser *sm6, const
|
||||
struct sm6_block *code_block;
|
||||
struct sm6_value *dst;
|
||||
|
||||
if (sm6->function_count)
|
||||
{
|
||||
FIXME("Multiple functions are not supported yet.\n");
|
||||
return VKD3D_ERROR_INVALID_SHADER;
|
||||
}
|
||||
if (!(function->declaration = sm6_parser_next_function_definition(sm6)))
|
||||
{
|
||||
WARN("Failed to find definition to match function body.\n");
|
||||
@ -8976,10 +9014,15 @@ static enum vkd3d_result sm6_parser_signatures_init(struct sm6_parser *sm6, cons
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
/* TODO: patch constant signature in operand 2. */
|
||||
if (m->u.node->operand_count > 1 && (ret = sm6_parser_read_signature(sm6, m->u.node->operands[2],
|
||||
&sm6->p.program.patch_constant_signature, tessellator_domain)) < 0)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
|
||||
sm6_parser_init_input_signature(sm6, &sm6->p.program.input_signature);
|
||||
sm6_parser_init_output_signature(sm6, &sm6->p.program.output_signature);
|
||||
sm6_parser_init_patch_constant_signature(sm6, &sm6->p.program.patch_constant_signature);
|
||||
|
||||
return VKD3D_OK;
|
||||
}
|
||||
@ -9509,9 +9552,10 @@ static struct sm6_function *sm6_parser_get_function(const struct sm6_parser *sm6
|
||||
static enum vkd3d_result sm6_parser_init(struct sm6_parser *sm6, const char *source_name,
|
||||
struct vkd3d_shader_message_context *message_context, struct dxbc_shader_desc *dxbc_desc)
|
||||
{
|
||||
size_t count, length, function_count, expected_function_count, byte_code_size = dxbc_desc->byte_code_size;
|
||||
const struct shader_signature *patch_constant_signature = &sm6->p.program.patch_constant_signature;
|
||||
const struct shader_signature *output_signature = &sm6->p.program.output_signature;
|
||||
const struct shader_signature *input_signature = &sm6->p.program.input_signature;
|
||||
size_t count, length, function_count, byte_code_size = dxbc_desc->byte_code_size;
|
||||
const struct vkd3d_shader_location location = {.source_name = source_name};
|
||||
uint32_t version_token, dxil_version, token_count, magic;
|
||||
const uint32_t *byte_code = dxbc_desc->byte_code;
|
||||
@ -9674,7 +9718,9 @@ static enum vkd3d_result sm6_parser_init(struct sm6_parser *sm6, const char *sou
|
||||
}
|
||||
|
||||
if (!(sm6->output_params = vsir_program_get_dst_params(&sm6->p.program, output_signature->element_count))
|
||||
|| !(sm6->input_params = vsir_program_get_dst_params(&sm6->p.program, input_signature->element_count)))
|
||||
|| !(sm6->input_params = vsir_program_get_dst_params(&sm6->p.program, input_signature->element_count))
|
||||
|| !(sm6->patch_constant_params = vsir_program_get_dst_params(&sm6->p.program,
|
||||
patch_constant_signature->element_count)))
|
||||
{
|
||||
ERR("Failed to allocate input/output parameters.\n");
|
||||
vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_OUT_OF_MEMORY,
|
||||
@ -9705,6 +9751,7 @@ static enum vkd3d_result sm6_parser_init(struct sm6_parser *sm6, const char *sou
|
||||
"Out of memory allocating DXIL value array.");
|
||||
return VKD3D_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
sm6->function_count = 0;
|
||||
sm6->ssa_next_id = 1;
|
||||
|
||||
if ((ret = sm6_parser_globals_init(sm6)) < 0)
|
||||
@ -9754,7 +9801,8 @@ static enum vkd3d_result sm6_parser_init(struct sm6_parser *sm6, const char *sou
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (!sm6_parser_require_space(sm6, output_signature->element_count + input_signature->element_count))
|
||||
if (!sm6_parser_require_space(sm6, output_signature->element_count + input_signature->element_count
|
||||
+ patch_constant_signature->element_count))
|
||||
{
|
||||
vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_OUT_OF_MEMORY,
|
||||
"Out of memory emitting shader signature declarations.");
|
||||
@ -9771,9 +9819,41 @@ static enum vkd3d_result sm6_parser_init(struct sm6_parser *sm6, const char *sou
|
||||
return VKD3D_ERROR_INVALID_SHADER;
|
||||
}
|
||||
|
||||
assert(sm6->function_count == 1);
|
||||
if ((ret = sm6_function_emit_blocks(fn, sm6)) < 0)
|
||||
return ret;
|
||||
if (version.type == VKD3D_SHADER_TYPE_HULL)
|
||||
{
|
||||
sm6_parser_add_instruction(sm6, VKD3DSIH_HS_CONTROL_POINT_PHASE);
|
||||
|
||||
if ((ret = sm6_function_emit_blocks(fn, sm6)) < 0)
|
||||
return ret;
|
||||
|
||||
if (!(fn = sm6_parser_get_function(sm6, sm6->patch_constant_function)))
|
||||
{
|
||||
WARN("Failed to find patch constant function '%s'.\n", sm6->patch_constant_function);
|
||||
vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_MODULE,
|
||||
"Failed to find the patch constant function '%s' for a hull shader.",
|
||||
sm6->patch_constant_function);
|
||||
return VKD3D_ERROR_INVALID_SHADER;
|
||||
}
|
||||
|
||||
sm6_parser_add_instruction(sm6, VKD3DSIH_HS_FORK_PHASE);
|
||||
if ((ret = sm6_function_emit_blocks(fn, sm6)) < 0)
|
||||
return ret;
|
||||
|
||||
expected_function_count = 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((ret = sm6_function_emit_blocks(fn, sm6)) < 0)
|
||||
return ret;
|
||||
expected_function_count = 1;
|
||||
}
|
||||
|
||||
if (sm6->function_count > expected_function_count)
|
||||
{
|
||||
FIXME("%zu unhandled functions.\n", sm6->function_count - expected_function_count);
|
||||
vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_MODULE,
|
||||
"%zu functions were not emitted.", sm6->function_count - expected_function_count);
|
||||
}
|
||||
|
||||
dxil_block_destroy(&sm6->root_block);
|
||||
|
||||
|
@ -636,11 +636,14 @@ static bool control_point_normaliser_is_in_control_point_phase(const struct cont
|
||||
return normaliser->phase == VKD3DSIH_HS_CONTROL_POINT_PHASE;
|
||||
}
|
||||
|
||||
static struct vkd3d_shader_src_param *instruction_array_create_outpointid_param(
|
||||
struct vkd3d_shader_src_param *instruction_array_create_outpointid_param(
|
||||
struct vkd3d_shader_instruction_array *instructions)
|
||||
{
|
||||
struct vkd3d_shader_src_param *rel_addr;
|
||||
|
||||
if (instructions->outpointid_param)
|
||||
return instructions->outpointid_param;
|
||||
|
||||
if (!(rel_addr = shader_src_param_allocator_get(&instructions->src_params, 1)))
|
||||
return NULL;
|
||||
|
||||
@ -648,6 +651,7 @@ static struct vkd3d_shader_src_param *instruction_array_create_outpointid_param(
|
||||
rel_addr->swizzle = 0;
|
||||
rel_addr->modifiers = 0;
|
||||
|
||||
instructions->outpointid_param = rel_addr;
|
||||
return rel_addr;
|
||||
}
|
||||
|
||||
@ -3344,6 +3348,14 @@ static enum vkd3d_result vsir_cfg_init(struct vsir_cfg *cfg, struct vsir_program
|
||||
enum vkd3d_result ret;
|
||||
size_t i;
|
||||
|
||||
if (program->shader_version.type == VKD3D_SHADER_TYPE_HULL)
|
||||
{
|
||||
FIXME("Hull shaders are not supported.\n");
|
||||
vkd3d_shader_error(message_context, NULL, VKD3D_SHADER_ERROR_VSIR_NOT_IMPLEMENTED,
|
||||
"The structurizer does not support hull shaders.");
|
||||
return VKD3D_ERROR_INVALID_SHADER;
|
||||
}
|
||||
|
||||
memset(cfg, 0, sizeof(*cfg));
|
||||
cfg->message_context = message_context;
|
||||
cfg->program = program;
|
||||
|
@ -1300,6 +1300,8 @@ struct vkd3d_shader_instruction_array
|
||||
struct vkd3d_shader_immediate_constant_buffer **icbs;
|
||||
size_t icb_capacity;
|
||||
size_t icb_count;
|
||||
|
||||
struct vkd3d_shader_src_param *outpointid_param;
|
||||
};
|
||||
|
||||
bool shader_instruction_array_init(struct vkd3d_shader_instruction_array *instructions, unsigned int reserve);
|
||||
@ -1310,6 +1312,8 @@ bool shader_instruction_array_add_icb(struct vkd3d_shader_instruction_array *ins
|
||||
struct vkd3d_shader_immediate_constant_buffer *icb);
|
||||
bool shader_instruction_array_clone_instruction(struct vkd3d_shader_instruction_array *instructions,
|
||||
unsigned int dst, unsigned int src);
|
||||
struct vkd3d_shader_src_param *instruction_array_create_outpointid_param(
|
||||
struct vkd3d_shader_instruction_array *instructions);
|
||||
void shader_instruction_array_destroy(struct vkd3d_shader_instruction_array *instructions);
|
||||
|
||||
enum vkd3d_shader_config_flags
|
||||
|
Loading…
x
Reference in New Issue
Block a user