mirror of
https://gitlab.winehq.org/wine/vkd3d.git
synced 2025-09-12 18:50:22 -07:00
vkd3d-shader/dxil: Support patch constant functions and signatures.
This commit is contained in:
committed by
Alexandre Julliard
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 *output_params;
|
||||||
struct vkd3d_shader_dst_param *input_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];
|
uint32_t io_regs_declared[(VKD3DSPR_COUNT + 0x1f) / 0x20];
|
||||||
|
|
||||||
struct sm6_function *functions;
|
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. */
|
* 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);
|
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->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. */
|
/* The value count returns to its previous value after handling a function. */
|
||||||
if (value_count < SIZE_MAX)
|
if (value_count < SIZE_MAX)
|
||||||
value_count = old_value_count;
|
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,
|
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;
|
struct vkd3d_shader_dst_param *param;
|
||||||
const struct signature_element *e;
|
const struct signature_element *e;
|
||||||
unsigned int i, count;
|
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)
|
for (i = 0; i < s->element_count; ++i)
|
||||||
{
|
{
|
||||||
e = &s->elements[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);
|
dst_param_io_init(param, e, reg_type);
|
||||||
count = 0;
|
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;
|
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++].offset = i;
|
||||||
param->reg.idx_count = count;
|
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)
|
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)
|
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)
|
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_block *code_block;
|
||||||
struct sm6_value *dst;
|
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)))
|
if (!(function->declaration = sm6_parser_next_function_definition(sm6)))
|
||||||
{
|
{
|
||||||
WARN("Failed to find definition to match function body.\n");
|
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;
|
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_input_signature(sm6, &sm6->p.program.input_signature);
|
||||||
sm6_parser_init_output_signature(sm6, &sm6->p.program.output_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;
|
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,
|
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)
|
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 *output_signature = &sm6->p.program.output_signature;
|
||||||
const struct shader_signature *input_signature = &sm6->p.program.input_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};
|
const struct vkd3d_shader_location location = {.source_name = source_name};
|
||||||
uint32_t version_token, dxil_version, token_count, magic;
|
uint32_t version_token, dxil_version, token_count, magic;
|
||||||
const uint32_t *byte_code = dxbc_desc->byte_code;
|
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))
|
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");
|
ERR("Failed to allocate input/output parameters.\n");
|
||||||
vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_OUT_OF_MEMORY,
|
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.");
|
"Out of memory allocating DXIL value array.");
|
||||||
return VKD3D_ERROR_OUT_OF_MEMORY;
|
return VKD3D_ERROR_OUT_OF_MEMORY;
|
||||||
}
|
}
|
||||||
|
sm6->function_count = 0;
|
||||||
sm6->ssa_next_id = 1;
|
sm6->ssa_next_id = 1;
|
||||||
|
|
||||||
if ((ret = sm6_parser_globals_init(sm6)) < 0)
|
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;
|
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,
|
vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_OUT_OF_MEMORY,
|
||||||
"Out of memory emitting shader signature declarations.");
|
"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;
|
return VKD3D_ERROR_INVALID_SHADER;
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(sm6->function_count == 1);
|
if (version.type == VKD3D_SHADER_TYPE_HULL)
|
||||||
if ((ret = sm6_function_emit_blocks(fn, sm6)) < 0)
|
{
|
||||||
return ret;
|
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);
|
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;
|
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_instruction_array *instructions)
|
||||||
{
|
{
|
||||||
struct vkd3d_shader_src_param *rel_addr;
|
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)))
|
if (!(rel_addr = shader_src_param_allocator_get(&instructions->src_params, 1)))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
@@ -648,6 +651,7 @@ static struct vkd3d_shader_src_param *instruction_array_create_outpointid_param(
|
|||||||
rel_addr->swizzle = 0;
|
rel_addr->swizzle = 0;
|
||||||
rel_addr->modifiers = 0;
|
rel_addr->modifiers = 0;
|
||||||
|
|
||||||
|
instructions->outpointid_param = rel_addr;
|
||||||
return 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;
|
enum vkd3d_result ret;
|
||||||
size_t i;
|
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));
|
memset(cfg, 0, sizeof(*cfg));
|
||||||
cfg->message_context = message_context;
|
cfg->message_context = message_context;
|
||||||
cfg->program = program;
|
cfg->program = program;
|
||||||
|
@@ -1300,6 +1300,8 @@ struct vkd3d_shader_instruction_array
|
|||||||
struct vkd3d_shader_immediate_constant_buffer **icbs;
|
struct vkd3d_shader_immediate_constant_buffer **icbs;
|
||||||
size_t icb_capacity;
|
size_t icb_capacity;
|
||||||
size_t icb_count;
|
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);
|
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);
|
struct vkd3d_shader_immediate_constant_buffer *icb);
|
||||||
bool shader_instruction_array_clone_instruction(struct vkd3d_shader_instruction_array *instructions,
|
bool shader_instruction_array_clone_instruction(struct vkd3d_shader_instruction_array *instructions,
|
||||||
unsigned int dst, unsigned int src);
|
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);
|
void shader_instruction_array_destroy(struct vkd3d_shader_instruction_array *instructions);
|
||||||
|
|
||||||
enum vkd3d_shader_config_flags
|
enum vkd3d_shader_config_flags
|
||||||
|
Reference in New Issue
Block a user