vkd3d-shader/ir: Use a separate allocation for the vsir program in struct vkd3d_shader_parser.

This commit is contained in:
Henri Verbeet 2024-05-16 11:41:58 +02:00 committed by Alexandre Julliard
parent 061dc39036
commit 9e4a790de1
Notes: Alexandre Julliard 2024-05-16 23:13:19 +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/869
6 changed files with 134 additions and 101 deletions

View File

@ -418,7 +418,7 @@ static bool has_relative_address(uint32_t param)
static const struct vkd3d_sm1_opcode_info *shader_sm1_get_opcode_info( static const struct vkd3d_sm1_opcode_info *shader_sm1_get_opcode_info(
const struct vkd3d_shader_sm1_parser *sm1, enum vkd3d_sm1_opcode opcode) const struct vkd3d_shader_sm1_parser *sm1, enum vkd3d_sm1_opcode opcode)
{ {
const struct vkd3d_shader_version *version = &sm1->p.program.shader_version; const struct vkd3d_shader_version *version = &sm1->p.program->shader_version;
const struct vkd3d_sm1_opcode_info *info; const struct vkd3d_sm1_opcode_info *info;
unsigned int i = 0; unsigned int i = 0;
@ -541,13 +541,14 @@ static bool add_signature_element(struct vkd3d_shader_sm1_parser *sm1, bool outp
const char *name, unsigned int index, enum vkd3d_shader_sysval_semantic sysval, const char *name, unsigned int index, enum vkd3d_shader_sysval_semantic sysval,
unsigned int register_index, bool is_dcl, unsigned int mask) unsigned int register_index, bool is_dcl, unsigned int mask)
{ {
struct vsir_program *program = sm1->p.program;
struct shader_signature *signature; struct shader_signature *signature;
struct signature_element *element; struct signature_element *element;
if (output) if (output)
signature = &sm1->p.program.output_signature; signature = &program->output_signature;
else else
signature = &sm1->p.program.input_signature; signature = &program->input_signature;
if ((element = find_signature_element(signature, name, index))) if ((element = find_signature_element(signature, name, index)))
{ {
@ -572,7 +573,7 @@ static bool add_signature_element(struct vkd3d_shader_sm1_parser *sm1, bool outp
element->register_count = 1; element->register_count = 1;
element->mask = mask; element->mask = mask;
element->used_mask = is_dcl ? 0 : mask; element->used_mask = is_dcl ? 0 : mask;
if (sm1->p.program.shader_version.type == VKD3D_SHADER_TYPE_PIXEL && !output) if (program->shader_version.type == VKD3D_SHADER_TYPE_PIXEL && !output)
element->interpolation_mode = VKD3DSIM_LINEAR; element->interpolation_mode = VKD3DSIM_LINEAR;
return true; return true;
@ -581,13 +582,14 @@ static bool add_signature_element(struct vkd3d_shader_sm1_parser *sm1, bool outp
static void add_signature_mask(struct vkd3d_shader_sm1_parser *sm1, bool output, static void add_signature_mask(struct vkd3d_shader_sm1_parser *sm1, bool output,
unsigned int register_index, unsigned int mask) unsigned int register_index, unsigned int mask)
{ {
struct vsir_program *program = sm1->p.program;
struct shader_signature *signature; struct shader_signature *signature;
struct signature_element *element; struct signature_element *element;
if (output) if (output)
signature = &sm1->p.program.output_signature; signature = &program->output_signature;
else else
signature = &sm1->p.program.input_signature; signature = &program->input_signature;
if (!(element = find_signature_element_by_register_index(signature, register_index))) if (!(element = find_signature_element_by_register_index(signature, register_index)))
{ {
@ -602,7 +604,7 @@ static void add_signature_mask(struct vkd3d_shader_sm1_parser *sm1, bool output,
static bool add_signature_element_from_register(struct vkd3d_shader_sm1_parser *sm1, static bool add_signature_element_from_register(struct vkd3d_shader_sm1_parser *sm1,
const struct vkd3d_shader_register *reg, bool is_dcl, unsigned int mask) const struct vkd3d_shader_register *reg, bool is_dcl, unsigned int mask)
{ {
const struct vkd3d_shader_version *version = &sm1->p.program.shader_version; const struct vkd3d_shader_version *version = &sm1->p.program->shader_version;
unsigned int register_index = reg->idx[0].offset; unsigned int register_index = reg->idx[0].offset;
switch (reg->type) switch (reg->type)
@ -705,7 +707,7 @@ static bool add_signature_element_from_register(struct vkd3d_shader_sm1_parser *
static bool add_signature_element_from_semantic(struct vkd3d_shader_sm1_parser *sm1, static bool add_signature_element_from_semantic(struct vkd3d_shader_sm1_parser *sm1,
const struct vkd3d_shader_semantic *semantic) const struct vkd3d_shader_semantic *semantic)
{ {
const struct vkd3d_shader_version *version = &sm1->p.program.shader_version; const struct vkd3d_shader_version *version = &sm1->p.program->shader_version;
const struct vkd3d_shader_register *reg = &semantic->resource.reg.reg; const struct vkd3d_shader_register *reg = &semantic->resource.reg.reg;
enum vkd3d_shader_sysval_semantic sysval = VKD3D_SHADER_SV_NONE; enum vkd3d_shader_sysval_semantic sysval = VKD3D_SHADER_SV_NONE;
unsigned int mask = semantic->resource.reg.write_mask; unsigned int mask = semantic->resource.reg.write_mask;
@ -767,7 +769,7 @@ static void record_constant_register(struct vkd3d_shader_sm1_parser *sm1,
static void shader_sm1_scan_register(struct vkd3d_shader_sm1_parser *sm1, static void shader_sm1_scan_register(struct vkd3d_shader_sm1_parser *sm1,
const struct vkd3d_shader_register *reg, unsigned int mask, bool from_def) const struct vkd3d_shader_register *reg, unsigned int mask, bool from_def)
{ {
struct vsir_program *program = &sm1->p.program; struct vsir_program *program = sm1->p.program;
uint32_t register_index = reg->idx[0].offset; uint32_t register_index = reg->idx[0].offset;
switch (reg->type) switch (reg->type)
@ -828,7 +830,7 @@ static void shader_sm1_read_param(struct vkd3d_shader_sm1_parser *sm1,
* VS >= 2.0 have relative addressing (with token) * VS >= 2.0 have relative addressing (with token)
* VS >= 1.0 < 2.0 have relative addressing (without token) * VS >= 1.0 < 2.0 have relative addressing (without token)
* The version check below should work in general. */ * The version check below should work in general. */
if (sm1->p.program.shader_version.major < 2) if (sm1->p.program->shader_version.major < 2)
{ {
*addr_token = (1u << 31) *addr_token = (1u << 31)
| ((VKD3DSPR_ADDR << VKD3D_SM1_REGISTER_TYPE_SHIFT2) & VKD3D_SM1_REGISTER_TYPE_MASK2) | ((VKD3DSPR_ADDR << VKD3D_SM1_REGISTER_TYPE_SHIFT2) & VKD3D_SM1_REGISTER_TYPE_MASK2)
@ -857,7 +859,7 @@ static void shader_sm1_skip_opcode(const struct vkd3d_shader_sm1_parser *sm1, co
/* Version 2.0+ shaders may contain address tokens, but fortunately they /* Version 2.0+ shaders may contain address tokens, but fortunately they
* have a useful length mask - use it here. Version 1.x shaders contain no * have a useful length mask - use it here. Version 1.x shaders contain no
* such tokens. */ * such tokens. */
if (sm1->p.program.shader_version.major >= 2) if (sm1->p.program->shader_version.major >= 2)
{ {
length = (opcode_token & VKD3D_SM1_INSTRUCTION_LENGTH_MASK) >> VKD3D_SM1_INSTRUCTION_LENGTH_SHIFT; length = (opcode_token & VKD3D_SM1_INSTRUCTION_LENGTH_MASK) >> VKD3D_SM1_INSTRUCTION_LENGTH_SHIFT;
*ptr += length; *ptr += length;
@ -887,7 +889,8 @@ static void shader_sm1_destroy(struct vkd3d_shader_parser *parser)
{ {
struct vkd3d_shader_sm1_parser *sm1 = vkd3d_shader_sm1_parser(parser); struct vkd3d_shader_sm1_parser *sm1 = vkd3d_shader_sm1_parser(parser);
vsir_program_cleanup(&parser->program); vsir_program_cleanup(parser->program);
vkd3d_free(parser->program);
vkd3d_free(sm1); vkd3d_free(sm1);
} }
@ -900,7 +903,7 @@ static void shader_sm1_read_src_param(struct vkd3d_shader_sm1_parser *sm1, const
shader_sm1_read_param(sm1, ptr, &token, &addr_token); shader_sm1_read_param(sm1, ptr, &token, &addr_token);
if (has_relative_address(token)) if (has_relative_address(token))
{ {
if (!(src_rel_addr = vsir_program_get_src_params(&sm1->p.program, 1))) if (!(src_rel_addr = vsir_program_get_src_params(sm1->p.program, 1)))
{ {
vkd3d_shader_parser_error(&sm1->p, VKD3D_SHADER_ERROR_D3DBC_OUT_OF_MEMORY, vkd3d_shader_parser_error(&sm1->p, VKD3D_SHADER_ERROR_D3DBC_OUT_OF_MEMORY,
"Out of memory."); "Out of memory.");
@ -921,7 +924,7 @@ static void shader_sm1_read_dst_param(struct vkd3d_shader_sm1_parser *sm1, const
shader_sm1_read_param(sm1, ptr, &token, &addr_token); shader_sm1_read_param(sm1, ptr, &token, &addr_token);
if (has_relative_address(token)) if (has_relative_address(token))
{ {
if (!(dst_rel_addr = vsir_program_get_src_params(&sm1->p.program, 1))) if (!(dst_rel_addr = vsir_program_get_src_params(sm1->p.program, 1)))
{ {
vkd3d_shader_parser_error(&sm1->p, VKD3D_SHADER_ERROR_D3DBC_OUT_OF_MEMORY, vkd3d_shader_parser_error(&sm1->p, VKD3D_SHADER_ERROR_D3DBC_OUT_OF_MEMORY,
"Out of memory."); "Out of memory.");
@ -1090,7 +1093,7 @@ static void shader_sm1_read_instruction(struct vkd3d_shader_sm1_parser *sm1, str
{ {
struct vkd3d_shader_src_param *src_params, *predicate; struct vkd3d_shader_src_param *src_params, *predicate;
const struct vkd3d_sm1_opcode_info *opcode_info; const struct vkd3d_sm1_opcode_info *opcode_info;
struct vsir_program *program = &sm1->p.program; struct vsir_program *program = sm1->p.program;
struct vkd3d_shader_dst_param *dst_param; struct vkd3d_shader_dst_param *dst_param;
const uint32_t **ptr = &sm1->ptr; const uint32_t **ptr = &sm1->ptr;
uint32_t opcode_token; uint32_t opcode_token;
@ -1318,6 +1321,7 @@ int vkd3d_shader_sm1_parser_create(const struct vkd3d_shader_compile_info *compi
struct vkd3d_shader_instruction_array *instructions; struct vkd3d_shader_instruction_array *instructions;
struct vkd3d_shader_instruction *ins; struct vkd3d_shader_instruction *ins;
struct vkd3d_shader_sm1_parser *sm1; struct vkd3d_shader_sm1_parser *sm1;
struct vsir_program *program;
unsigned int i; unsigned int i;
int ret; int ret;
@ -1334,7 +1338,8 @@ int vkd3d_shader_sm1_parser_create(const struct vkd3d_shader_compile_info *compi
return ret; return ret;
} }
instructions = &sm1->p.program.instructions; program = sm1->p.program;
instructions = &program->instructions;
while (!shader_sm1_is_end(sm1)) while (!shader_sm1_is_end(sm1))
{ {
if (!shader_instruction_array_reserve(instructions, instructions->count + 1)) if (!shader_instruction_array_reserve(instructions, instructions->count + 1))
@ -1356,8 +1361,8 @@ int vkd3d_shader_sm1_parser_create(const struct vkd3d_shader_compile_info *compi
++instructions->count; ++instructions->count;
} }
for (i = 0; i < ARRAY_SIZE(sm1->p.program.flat_constant_count); ++i) for (i = 0; i < ARRAY_SIZE(program->flat_constant_count); ++i)
sm1->p.program.flat_constant_count[i] = get_external_constant_count(sm1, i); program->flat_constant_count[i] = get_external_constant_count(sm1, i);
if (!sm1->p.failed) if (!sm1->p.failed)
ret = vkd3d_shader_parser_validate(&sm1->p); ret = vkd3d_shader_parser_validate(&sm1->p);

View File

@ -2305,7 +2305,7 @@ static struct vkd3d_shader_src_param *instruction_src_params_alloc(struct vkd3d_
{ {
struct vkd3d_shader_src_param *params; struct vkd3d_shader_src_param *params;
if (!(params = vsir_program_get_src_params(&sm6->p.program, count))) if (!(params = vsir_program_get_src_params(sm6->p.program, count)))
{ {
ERR("Failed to allocate src params.\n"); ERR("Failed to allocate src params.\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,
@ -2322,7 +2322,7 @@ static struct vkd3d_shader_dst_param *instruction_dst_params_alloc(struct vkd3d_
{ {
struct vkd3d_shader_dst_param *params; struct vkd3d_shader_dst_param *params;
if (!(params = vsir_program_get_dst_params(&sm6->p.program, count))) if (!(params = vsir_program_get_dst_params(sm6->p.program, count)))
{ {
ERR("Failed to allocate dst params.\n"); ERR("Failed to allocate dst params.\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,
@ -2504,7 +2504,7 @@ static void register_index_address_init(struct vkd3d_shader_register_index *idx,
} }
else else
{ {
struct vkd3d_shader_src_param *rel_addr = vsir_program_get_src_params(&sm6->p.program, 1); struct vkd3d_shader_src_param *rel_addr = vsir_program_get_src_params(sm6->p.program, 1);
if (rel_addr) if (rel_addr)
src_param_init_from_value(rel_addr, address); src_param_init_from_value(rel_addr, address);
idx->offset = 0; idx->offset = 0;
@ -2998,7 +2998,7 @@ static enum vkd3d_result value_allocate_constant_array(struct sm6_value *dst, co
"Out of memory allocating an immediate constant buffer of count %u.", count); "Out of memory allocating an immediate constant buffer of count %u.", count);
return VKD3D_ERROR_OUT_OF_MEMORY; return VKD3D_ERROR_OUT_OF_MEMORY;
} }
if (!shader_instruction_array_add_icb(&sm6->p.program.instructions, icb)) if (!shader_instruction_array_add_icb(&sm6->p.program->instructions, icb))
{ {
ERR("Failed to store icb object.\n"); ERR("Failed to store icb object.\n");
vkd3d_free(icb); vkd3d_free(icb);
@ -3385,12 +3385,14 @@ static bool bitcode_parse_alignment(uint64_t encoded_alignment, unsigned int *al
static struct vkd3d_shader_instruction *sm6_parser_require_space(struct sm6_parser *sm6, size_t extra) static struct vkd3d_shader_instruction *sm6_parser_require_space(struct sm6_parser *sm6, size_t extra)
{ {
if (!shader_instruction_array_reserve(&sm6->p.program.instructions, sm6->p.program.instructions.count + extra)) struct vkd3d_shader_instruction_array *instructions = &sm6->p.program->instructions;
if (!shader_instruction_array_reserve(instructions, instructions->count + extra))
{ {
ERR("Failed to allocate instruction.\n"); ERR("Failed to allocate instruction.\n");
return NULL; return NULL;
} }
return &sm6->p.program.instructions.elements[sm6->p.program.instructions.count]; return &instructions->elements[instructions->count];
} }
/* Space should be reserved before calling this. It is intended to require no checking of the returned pointer. */ /* Space should be reserved before calling this. It is intended to require no checking of the returned pointer. */
@ -3400,7 +3402,7 @@ static struct vkd3d_shader_instruction *sm6_parser_add_instruction(struct sm6_pa
struct vkd3d_shader_instruction *ins = sm6_parser_require_space(sm6, 1); struct vkd3d_shader_instruction *ins = sm6_parser_require_space(sm6, 1);
assert(ins); assert(ins);
vsir_instruction_init(ins, &sm6->p.location, handler_idx); vsir_instruction_init(ins, &sm6->p.location, handler_idx);
++sm6->p.program.instructions.count; ++sm6->p.program->instructions.count;
return ins; return ins;
} }
@ -3755,9 +3757,9 @@ static enum vkd3d_result sm6_parser_globals_init(struct sm6_parser *sm6)
} }
/* Resolve initialiser forward references. */ /* Resolve initialiser forward references. */
for (i = 0; i < sm6->p.program.instructions.count; ++i) for (i = 0; i < sm6->p.program->instructions.count; ++i)
{ {
ins = &sm6->p.program.instructions.elements[i]; ins = &sm6->p.program->instructions.elements[i];
if (ins->handler_idx == VKD3DSIH_DCL_INDEXABLE_TEMP && ins->declaration.indexable_temp.initialiser) if (ins->handler_idx == VKD3DSIH_DCL_INDEXABLE_TEMP && ins->declaration.indexable_temp.initialiser)
{ {
ins->declaration.indexable_temp.initialiser = resolve_forward_initialiser( ins->declaration.indexable_temp.initialiser = resolve_forward_initialiser(
@ -3837,7 +3839,7 @@ 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,
bool is_input, 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; enum vkd3d_shader_type shader_type = sm6->p.program->shader_version.type;
bool is_patch_constant, is_control_point; 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;
@ -3882,7 +3884,7 @@ static void sm6_parser_init_signature(struct sm6_parser *sm6, const struct shade
if (is_control_point) if (is_control_point)
{ {
if (reg_type == VKD3DSPR_OUTPUT) if (reg_type == VKD3DSPR_OUTPUT)
param->reg.idx[count].rel_addr = instruction_array_create_outpointid_param(&sm6->p.program.instructions); 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;
} }
@ -3908,7 +3910,7 @@ static void sm6_parser_init_input_signature(struct sm6_parser *sm6, const struct
static void sm6_parser_init_patch_constant_signature(struct sm6_parser *sm6, static void sm6_parser_init_patch_constant_signature(struct sm6_parser *sm6,
const struct shader_signature *patch_constant_signature) const struct shader_signature *patch_constant_signature)
{ {
bool is_input = sm6->p.program.shader_version.type == VKD3D_SHADER_TYPE_DOMAIN; 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_parser_init_signature(sm6, patch_constant_signature, is_input, VKD3DSPR_PATCHCONST,
sm6->patch_constant_params); sm6->patch_constant_params);
@ -5279,6 +5281,7 @@ static void sm6_parser_emit_dx_load_input(struct sm6_parser *sm6, enum dx_intrin
bool is_control_point = op == DX_LOAD_OUTPUT_CONTROL_POINT; bool is_control_point = op == DX_LOAD_OUTPUT_CONTROL_POINT;
bool is_patch_constant = op == DX_LOAD_PATCH_CONSTANT; bool is_patch_constant = op == DX_LOAD_PATCH_CONSTANT;
struct vkd3d_shader_instruction *ins = state->ins; struct vkd3d_shader_instruction *ins = state->ins;
struct vsir_program *program = sm6->p.program;
unsigned int count, row_index, column_index; unsigned int count, row_index, column_index;
const struct vkd3d_shader_dst_param *params; const struct vkd3d_shader_dst_param *params;
struct vkd3d_shader_src_param *src_param; struct vkd3d_shader_src_param *src_param;
@ -5300,17 +5303,17 @@ static void sm6_parser_emit_dx_load_input(struct sm6_parser *sm6, enum dx_intrin
if (is_patch_constant) if (is_patch_constant)
{ {
signature = &sm6->p.program.patch_constant_signature; signature = &program->patch_constant_signature;
params = sm6->patch_constant_params; params = sm6->patch_constant_params;
} }
else if (is_control_point) else if (is_control_point)
{ {
signature = &sm6->p.program.output_signature; signature = &program->output_signature;
params = sm6->output_params; params = sm6->output_params;
} }
else else
{ {
signature = &sm6->p.program.input_signature; signature = &program->input_signature;
params = sm6->input_params; params = sm6->input_params;
} }
if (row_index >= signature->element_count) if (row_index >= signature->element_count)
@ -5801,6 +5804,7 @@ static void sm6_parser_emit_dx_store_output(struct sm6_parser *sm6, enum dx_intr
{ {
bool is_patch_constant = op == DX_STORE_PATCH_CONSTANT; bool is_patch_constant = op == DX_STORE_PATCH_CONSTANT;
struct vkd3d_shader_instruction *ins = state->ins; struct vkd3d_shader_instruction *ins = state->ins;
struct vsir_program *program = sm6->p.program;
struct vkd3d_shader_src_param *src_param; struct vkd3d_shader_src_param *src_param;
struct vkd3d_shader_dst_param *dst_param; struct vkd3d_shader_dst_param *dst_param;
const struct shader_signature *signature; const struct shader_signature *signature;
@ -5811,7 +5815,7 @@ static void sm6_parser_emit_dx_store_output(struct sm6_parser *sm6, enum dx_intr
row_index = sm6_value_get_constant_uint(operands[0]); row_index = sm6_value_get_constant_uint(operands[0]);
column_index = sm6_value_get_constant_uint(operands[2]); column_index = sm6_value_get_constant_uint(operands[2]);
signature = is_patch_constant ? &sm6->p.program.patch_constant_signature : &sm6->p.program.output_signature; signature = is_patch_constant ? &program->patch_constant_signature : &program->output_signature;
if (row_index >= signature->element_count) if (row_index >= signature->element_count)
{ {
WARN("Invalid row index %u.\n", row_index); WARN("Invalid row index %u.\n", row_index);
@ -7771,6 +7775,7 @@ static enum vkd3d_result sm6_function_resolve_phi_incomings(const struct sm6_fun
static enum vkd3d_result sm6_parser_function_init(struct sm6_parser *sm6, const struct dxil_block *block, static enum vkd3d_result sm6_parser_function_init(struct sm6_parser *sm6, const struct dxil_block *block,
struct sm6_function *function) struct sm6_function *function)
{ {
struct vsir_program *program = sm6->p.program;
struct vkd3d_shader_instruction *ins; struct vkd3d_shader_instruction *ins;
size_t i, block_idx, block_count; size_t i, block_idx, block_count;
const struct dxil_record *record; const struct dxil_record *record;
@ -7862,7 +7867,7 @@ static enum vkd3d_result sm6_parser_function_init(struct sm6_parser *sm6, const
{ {
struct function_emission_state state = {code_block, ins}; struct function_emission_state state = {code_block, ins};
sm6_parser_emit_atomicrmw(sm6, record, &state, dst); sm6_parser_emit_atomicrmw(sm6, record, &state, dst);
sm6->p.program.temp_count = max(sm6->p.program.temp_count, state.temp_idx); program->temp_count = max(program->temp_count, state.temp_idx);
break; break;
} }
case FUNC_CODE_INST_BINOP: case FUNC_CODE_INST_BINOP:
@ -7876,7 +7881,7 @@ static enum vkd3d_result sm6_parser_function_init(struct sm6_parser *sm6, const
{ {
struct function_emission_state state = {code_block, ins}; struct function_emission_state state = {code_block, ins};
sm6_parser_emit_call(sm6, record, &state, dst); sm6_parser_emit_call(sm6, record, &state, dst);
sm6->p.program.temp_count = max(sm6->p.program.temp_count, state.temp_idx); program->temp_count = max(program->temp_count, state.temp_idx);
break; break;
} }
case FUNC_CODE_INST_CAST: case FUNC_CODE_INST_CAST:
@ -8150,9 +8155,10 @@ static void sm6_parser_emit_label(struct sm6_parser *sm6, unsigned int label_id)
static enum vkd3d_result sm6_function_emit_blocks(const struct sm6_function *function, struct sm6_parser *sm6) static enum vkd3d_result sm6_function_emit_blocks(const struct sm6_function *function, struct sm6_parser *sm6)
{ {
struct vsir_program *program = sm6->p.program;
unsigned int i; unsigned int i;
sm6->p.program.block_count = function->block_count; program->block_count = function->block_count;
for (i = 0; i < function->block_count; ++i) for (i = 0; i < function->block_count; ++i)
{ {
@ -8168,9 +8174,9 @@ static enum vkd3d_result sm6_function_emit_blocks(const struct sm6_function *fun
sm6_parser_emit_label(sm6, block->id); sm6_parser_emit_label(sm6, block->id);
sm6_block_emit_phi(block, sm6); sm6_block_emit_phi(block, sm6);
memcpy(&sm6->p.program.instructions.elements[sm6->p.program.instructions.count], block->instructions, memcpy(&program->instructions.elements[program->instructions.count], block->instructions,
block->instruction_count * sizeof(*block->instructions)); block->instruction_count * sizeof(*block->instructions));
sm6->p.program.instructions.count += block->instruction_count; program->instructions.count += block->instruction_count;
sm6_block_emit_terminator(block, sm6); sm6_block_emit_terminator(block, sm6);
} }
@ -9140,7 +9146,7 @@ static enum vkd3d_result sm6_parser_descriptor_type_init(struct sm6_parser *sm6,
} }
++sm6->descriptor_count; ++sm6->descriptor_count;
++sm6->p.program.instructions.count; ++sm6->p.program->instructions.count;
} }
return VKD3D_OK; return VKD3D_OK;
@ -9454,6 +9460,7 @@ static enum vkd3d_result sm6_parser_read_signature(struct sm6_parser *sm6, const
static enum vkd3d_result sm6_parser_signatures_init(struct sm6_parser *sm6, const struct sm6_metadata_value *m, static enum vkd3d_result sm6_parser_signatures_init(struct sm6_parser *sm6, const struct sm6_metadata_value *m,
enum vkd3d_tessellator_domain tessellator_domain) enum vkd3d_tessellator_domain tessellator_domain)
{ {
struct vsir_program *program = sm6->p.program;
enum vkd3d_result ret; enum vkd3d_result ret;
if (!sm6_metadata_value_is_node(m)) if (!sm6_metadata_value_is_node(m))
@ -9465,24 +9472,24 @@ static enum vkd3d_result sm6_parser_signatures_init(struct sm6_parser *sm6, cons
} }
if (m->u.node->operand_count && (ret = sm6_parser_read_signature(sm6, m->u.node->operands[0], if (m->u.node->operand_count && (ret = sm6_parser_read_signature(sm6, m->u.node->operands[0],
&sm6->p.program.input_signature, tessellator_domain)) < 0) &program->input_signature, tessellator_domain)) < 0)
{ {
return ret; return ret;
} }
if (m->u.node->operand_count > 1 && (ret = sm6_parser_read_signature(sm6, m->u.node->operands[1], if (m->u.node->operand_count > 1 && (ret = sm6_parser_read_signature(sm6, m->u.node->operands[1],
&sm6->p.program.output_signature, tessellator_domain)) < 0) &program->output_signature, tessellator_domain)) < 0)
{ {
return ret; return ret;
} }
if (m->u.node->operand_count > 1 && (ret = sm6_parser_read_signature(sm6, m->u.node->operands[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) &program->patch_constant_signature, tessellator_domain)) < 0)
{ {
return ret; return ret;
} }
sm6_parser_init_input_signature(sm6, &sm6->p.program.input_signature); sm6_parser_init_input_signature(sm6, &program->input_signature);
sm6_parser_init_output_signature(sm6, &sm6->p.program.output_signature); sm6_parser_init_output_signature(sm6, &program->output_signature);
sm6_parser_init_patch_constant_signature(sm6, &sm6->p.program.patch_constant_signature); sm6_parser_init_patch_constant_signature(sm6, &program->patch_constant_signature);
return VKD3D_OK; return VKD3D_OK;
} }
@ -9511,14 +9518,15 @@ static void sm6_parser_emit_global_flags(struct sm6_parser *sm6, const struct sm
static enum vkd3d_result sm6_parser_emit_thread_group(struct sm6_parser *sm6, const struct sm6_metadata_value *m) static enum vkd3d_result sm6_parser_emit_thread_group(struct sm6_parser *sm6, const struct sm6_metadata_value *m)
{ {
struct vkd3d_shader_version *version = &sm6->p.program->shader_version;
const struct sm6_metadata_node *node; const struct sm6_metadata_node *node;
struct vkd3d_shader_instruction *ins; struct vkd3d_shader_instruction *ins;
unsigned int group_sizes[3]; unsigned int group_sizes[3];
unsigned int i; unsigned int i;
if (sm6->p.program.shader_version.type != VKD3D_SHADER_TYPE_COMPUTE) if (version->type != VKD3D_SHADER_TYPE_COMPUTE)
{ {
WARN("Shader of type %#x has thread group dimensions.\n", sm6->p.program.shader_version.type); WARN("Shader of type %#x has thread group dimensions.\n", version->type);
vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_PROPERTIES, vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_PROPERTIES,
"Shader has thread group dimensions but is not a compute shader."); "Shader has thread group dimensions but is not a compute shader.");
return VKD3D_ERROR_INVALID_SHADER; return VKD3D_ERROR_INVALID_SHADER;
@ -9754,7 +9762,7 @@ static void sm6_parser_gs_properties_init(struct sm6_parser *sm6, const struct s
} }
sm6_parser_emit_dcl_primitive_topology(sm6, VKD3DSIH_DCL_INPUT_PRIMITIVE, input_primitive, patch_vertex_count); sm6_parser_emit_dcl_primitive_topology(sm6, VKD3DSIH_DCL_INPUT_PRIMITIVE, input_primitive, patch_vertex_count);
sm6->p.program.input_control_point_count = input_control_point_count; sm6->p.program->input_control_point_count = input_control_point_count;
i = operands[1]; i = operands[1];
/* Max total scalar count sets an upper limit. We would need to scan outputs to be more precise. */ /* Max total scalar count sets an upper limit. We would need to scan outputs to be more precise. */
@ -9836,7 +9844,7 @@ static enum vkd3d_tessellator_domain sm6_parser_ds_properties_init(struct sm6_pa
sm6_parser_emit_dcl_tessellator_domain(sm6, operands[0]); sm6_parser_emit_dcl_tessellator_domain(sm6, operands[0]);
sm6_parser_validate_control_point_count(sm6, operands[1], "Domain shader input"); sm6_parser_validate_control_point_count(sm6, operands[1], "Domain shader input");
sm6->p.program.input_control_point_count = operands[1]; sm6->p.program->input_control_point_count = operands[1];
return operands[0]; return operands[0];
} }
@ -9844,6 +9852,7 @@ static enum vkd3d_tessellator_domain sm6_parser_ds_properties_init(struct sm6_pa
static enum vkd3d_tessellator_domain sm6_parser_hs_properties_init(struct sm6_parser *sm6, static enum vkd3d_tessellator_domain sm6_parser_hs_properties_init(struct sm6_parser *sm6,
const struct sm6_metadata_value *m) const struct sm6_metadata_value *m)
{ {
struct vsir_program *program = sm6->p.program;
const struct sm6_metadata_node *node; const struct sm6_metadata_node *node;
unsigned int operands[6] = {0}; unsigned int operands[6] = {0};
unsigned int i; unsigned int i;
@ -9894,10 +9903,10 @@ static enum vkd3d_tessellator_domain sm6_parser_hs_properties_init(struct sm6_pa
} }
sm6_parser_validate_control_point_count(sm6, operands[1], "Hull shader input"); sm6_parser_validate_control_point_count(sm6, operands[1], "Hull shader input");
sm6->p.program.input_control_point_count = operands[1]; program->input_control_point_count = operands[1];
sm6_parser_validate_control_point_count(sm6, operands[2], "Hull shader output"); sm6_parser_validate_control_point_count(sm6, operands[2], "Hull shader output");
sm6_parser_emit_dcl_count(sm6, VKD3DSIH_DCL_OUTPUT_CONTROL_POINT_COUNT, operands[2]); sm6_parser_emit_dcl_count(sm6, VKD3DSIH_DCL_OUTPUT_CONTROL_POINT_COUNT, operands[2]);
sm6->p.program.output_control_point_count = operands[2]; program->output_control_point_count = operands[2];
sm6_parser_emit_dcl_tessellator_domain(sm6, operands[3]); sm6_parser_emit_dcl_tessellator_domain(sm6, operands[3]);
sm6_parser_emit_dcl_tessellator_partitioning(sm6, operands[4]); sm6_parser_emit_dcl_tessellator_partitioning(sm6, operands[4]);
sm6_parser_emit_dcl_tessellator_output_primitive(sm6, operands[5]); sm6_parser_emit_dcl_tessellator_output_primitive(sm6, operands[5]);
@ -10121,7 +10130,8 @@ static void sm6_parser_destroy(struct vkd3d_shader_parser *parser)
dxil_block_destroy(&sm6->root_block); dxil_block_destroy(&sm6->root_block);
dxil_global_abbrevs_cleanup(sm6->abbrevs, sm6->abbrev_count); dxil_global_abbrevs_cleanup(sm6->abbrevs, sm6->abbrev_count);
vsir_program_cleanup(&parser->program); vsir_program_cleanup(parser->program);
vkd3d_free(parser->program);
sm6_type_table_cleanup(sm6->types, sm6->type_count); sm6_type_table_cleanup(sm6->types, sm6->type_count);
sm6_symtab_cleanup(sm6->global_symbols, sm6->global_symbol_count); sm6_symtab_cleanup(sm6->global_symbols, sm6->global_symbol_count);
sm6_functions_cleanup(sm6->functions, sm6->function_count); sm6_functions_cleanup(sm6->functions, sm6->function_count);
@ -10149,15 +10159,14 @@ static enum vkd3d_result sm6_parser_init(struct sm6_parser *sm6, const char *sou
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; 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; struct shader_signature *patch_constant_signature, *output_signature, *input_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 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;
unsigned int chunk_offset, chunk_size; unsigned int chunk_offset, chunk_size;
enum bitcode_block_abbreviation abbr; enum bitcode_block_abbreviation abbr;
struct vkd3d_shader_version version; struct vkd3d_shader_version version;
struct vsir_program *program;
struct dxil_block *block; struct dxil_block *block;
struct sm6_function *fn; struct sm6_function *fn;
enum vkd3d_result ret; enum vkd3d_result ret;
@ -10248,9 +10257,13 @@ static enum vkd3d_result sm6_parser_init(struct sm6_parser *sm6, const char *sou
sm6->ptr = &sm6->start[1]; sm6->ptr = &sm6->start[1];
sm6->bitpos = 2; sm6->bitpos = 2;
sm6->p.program.input_signature = dxbc_desc->input_signature; program = sm6->p.program;
sm6->p.program.output_signature = dxbc_desc->output_signature; input_signature = &program->input_signature;
sm6->p.program.patch_constant_signature = dxbc_desc->patch_constant_signature; output_signature = &program->output_signature;
patch_constant_signature = &program->patch_constant_signature;
*input_signature = dxbc_desc->input_signature;
*output_signature = dxbc_desc->output_signature;
*patch_constant_signature = dxbc_desc->patch_constant_signature;
memset(dxbc_desc, 0, sizeof(*dxbc_desc)); memset(dxbc_desc, 0, sizeof(*dxbc_desc));
block = &sm6->root_block; block = &sm6->root_block;
@ -10313,9 +10326,9 @@ static enum vkd3d_result sm6_parser_init(struct sm6_parser *sm6, const char *sou
return ret; return ret;
} }
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(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(program, input_signature->element_count))
|| !(sm6->patch_constant_params = vsir_program_get_dst_params(&sm6->p.program, || !(sm6->patch_constant_params = vsir_program_get_dst_params(program,
patch_constant_signature->element_count))) patch_constant_signature->element_count)))
{ {
ERR("Failed to allocate input/output parameters.\n"); ERR("Failed to allocate input/output parameters.\n");
@ -10405,7 +10418,7 @@ static enum vkd3d_result sm6_parser_init(struct sm6_parser *sm6, const char *sou
return VKD3D_ERROR_OUT_OF_MEMORY; return VKD3D_ERROR_OUT_OF_MEMORY;
} }
sm6->p.program.ssa_count = sm6->ssa_next_id; program->ssa_count = sm6->ssa_next_id;
if (!(fn = sm6_parser_get_function(sm6, sm6->entry_point))) if (!(fn = sm6_parser_get_function(sm6, sm6->entry_point)))
{ {

View File

@ -4010,7 +4010,7 @@ int hlsl_compile_shader(const struct vkd3d_shader_code *hlsl, const struct vkd3d
} }
if (ret >= 0) if (ret >= 0)
{ {
ret = vsir_program_compile(&parser->program, parser->config_flags, &info, out, message_context); ret = vsir_program_compile(parser->program, parser->config_flags, &info, out, message_context);
vkd3d_shader_parser_destroy(parser); vkd3d_shader_parser_destroy(parser);
} }
vkd3d_shader_free_shader_code(&info.source); vkd3d_shader_free_shader_code(&info.source);

View File

@ -726,7 +726,7 @@ static struct vkd3d_shader_sm4_parser *vkd3d_shader_sm4_parser(struct vkd3d_shad
static bool shader_is_sm_5_1(const struct vkd3d_shader_sm4_parser *sm4) static bool shader_is_sm_5_1(const struct vkd3d_shader_sm4_parser *sm4)
{ {
const struct vkd3d_shader_version *version = &sm4->p.program.shader_version; const struct vkd3d_shader_version *version = &sm4->p.program->shader_version;
return version->major >= 5 && version->minor >= 1; return version->major >= 5 && version->minor >= 1;
} }
@ -811,7 +811,7 @@ static void shader_sm4_read_shader_data(struct vkd3d_shader_instruction *ins, ui
icb->element_count = icb_size / VKD3D_VEC4_SIZE; icb->element_count = icb_size / VKD3D_VEC4_SIZE;
icb->is_null = false; icb->is_null = false;
memcpy(icb->data, tokens, sizeof(*tokens) * icb_size); memcpy(icb->data, tokens, sizeof(*tokens) * icb_size);
shader_instruction_array_add_icb(&priv->p.program.instructions, icb); shader_instruction_array_add_icb(&priv->p.program->instructions, icb);
ins->declaration.icb = icb; ins->declaration.icb = icb;
} }
@ -933,6 +933,7 @@ static void shader_sm4_read_dcl_index_range(struct vkd3d_shader_instruction *ins
uint32_t opcode_token, const uint32_t *tokens, unsigned int token_count, struct vkd3d_shader_sm4_parser *priv) uint32_t opcode_token, const uint32_t *tokens, unsigned int token_count, struct vkd3d_shader_sm4_parser *priv)
{ {
struct vkd3d_shader_index_range *index_range = &ins->declaration.index_range; struct vkd3d_shader_index_range *index_range = &ins->declaration.index_range;
struct vsir_program *program = priv->p.program;
unsigned int i, register_idx, register_count; unsigned int i, register_idx, register_count;
const struct shader_signature *signature; const struct shader_signature *signature;
enum vkd3d_shader_register_type type; enum vkd3d_shader_register_type type;
@ -954,32 +955,32 @@ static void shader_sm4_read_dcl_index_range(struct vkd3d_shader_instruction *ins
case VKD3DSPR_INCONTROLPOINT: case VKD3DSPR_INCONTROLPOINT:
io_masks = priv->input_register_masks; io_masks = priv->input_register_masks;
ranges = &priv->input_index_ranges; ranges = &priv->input_index_ranges;
signature = &priv->p.program.input_signature; signature = &program->input_signature;
break; break;
case VKD3DSPR_OUTPUT: case VKD3DSPR_OUTPUT:
if (sm4_parser_is_in_fork_or_join_phase(priv)) if (sm4_parser_is_in_fork_or_join_phase(priv))
{ {
io_masks = priv->patch_constant_register_masks; io_masks = priv->patch_constant_register_masks;
ranges = &priv->patch_constant_index_ranges; ranges = &priv->patch_constant_index_ranges;
signature = &priv->p.program.patch_constant_signature; signature = &program->patch_constant_signature;
} }
else else
{ {
io_masks = priv->output_register_masks; io_masks = priv->output_register_masks;
ranges = &priv->output_index_ranges; ranges = &priv->output_index_ranges;
signature = &priv->p.program.output_signature; signature = &program->output_signature;
} }
break; break;
case VKD3DSPR_COLOROUT: case VKD3DSPR_COLOROUT:
case VKD3DSPR_OUTCONTROLPOINT: case VKD3DSPR_OUTCONTROLPOINT:
io_masks = priv->output_register_masks; io_masks = priv->output_register_masks;
ranges = &priv->output_index_ranges; ranges = &priv->output_index_ranges;
signature = &priv->p.program.output_signature; signature = &program->output_signature;
break; break;
case VKD3DSPR_PATCHCONST: case VKD3DSPR_PATCHCONST:
io_masks = priv->patch_constant_register_masks; io_masks = priv->patch_constant_register_masks;
ranges = &priv->patch_constant_index_ranges; ranges = &priv->patch_constant_index_ranges;
signature = &priv->p.program.patch_constant_signature; signature = &program->patch_constant_signature;
break; break;
default: default:
@ -1057,16 +1058,17 @@ static void shader_sm4_read_dcl_output_topology(struct vkd3d_shader_instruction
} }
static void shader_sm4_read_dcl_input_primitive(struct vkd3d_shader_instruction *ins, uint32_t opcode, static void shader_sm4_read_dcl_input_primitive(struct vkd3d_shader_instruction *ins, uint32_t opcode,
uint32_t opcode_token, const uint32_t *tokens, unsigned int token_count, struct vkd3d_shader_sm4_parser *priv) uint32_t opcode_token, const uint32_t *tokens, unsigned int token_count, struct vkd3d_shader_sm4_parser *sm4)
{ {
enum vkd3d_sm4_input_primitive_type primitive_type; enum vkd3d_sm4_input_primitive_type primitive_type;
struct vsir_program *program = sm4->p.program;
primitive_type = (opcode_token & VKD3D_SM4_PRIMITIVE_TYPE_MASK) >> VKD3D_SM4_PRIMITIVE_TYPE_SHIFT; primitive_type = (opcode_token & VKD3D_SM4_PRIMITIVE_TYPE_MASK) >> VKD3D_SM4_PRIMITIVE_TYPE_SHIFT;
if (VKD3D_SM5_INPUT_PT_PATCH1 <= primitive_type && primitive_type <= VKD3D_SM5_INPUT_PT_PATCH32) if (VKD3D_SM5_INPUT_PT_PATCH1 <= primitive_type && primitive_type <= VKD3D_SM5_INPUT_PT_PATCH32)
{ {
ins->declaration.primitive_type.type = VKD3D_PT_PATCH; ins->declaration.primitive_type.type = VKD3D_PT_PATCH;
ins->declaration.primitive_type.patch_vertex_count = primitive_type - VKD3D_SM5_INPUT_PT_PATCH1 + 1; ins->declaration.primitive_type.patch_vertex_count = primitive_type - VKD3D_SM5_INPUT_PT_PATCH1 + 1;
priv->p.program.input_control_point_count = ins->declaration.primitive_type.patch_vertex_count; program->input_control_point_count = ins->declaration.primitive_type.patch_vertex_count;
} }
else if (primitive_type >= ARRAY_SIZE(input_primitive_type_table)) else if (primitive_type >= ARRAY_SIZE(input_primitive_type_table))
{ {
@ -1075,7 +1077,7 @@ static void shader_sm4_read_dcl_input_primitive(struct vkd3d_shader_instruction
else else
{ {
ins->declaration.primitive_type.type = input_primitive_type_table[primitive_type].vkd3d_type; ins->declaration.primitive_type.type = input_primitive_type_table[primitive_type].vkd3d_type;
priv->p.program.input_control_point_count = input_primitive_type_table[primitive_type].control_point_count; program->input_control_point_count = input_primitive_type_table[primitive_type].control_point_count;
} }
if (ins->declaration.primitive_type.type == VKD3D_PT_UNDEFINED) if (ins->declaration.primitive_type.type == VKD3D_PT_UNDEFINED)
@ -1083,11 +1085,13 @@ static void shader_sm4_read_dcl_input_primitive(struct vkd3d_shader_instruction
} }
static void shader_sm4_read_declaration_count(struct vkd3d_shader_instruction *ins, uint32_t opcode, static void shader_sm4_read_declaration_count(struct vkd3d_shader_instruction *ins, uint32_t opcode,
uint32_t opcode_token, const uint32_t *tokens, unsigned int token_count, struct vkd3d_shader_sm4_parser *priv) uint32_t opcode_token, const uint32_t *tokens, unsigned int token_count, struct vkd3d_shader_sm4_parser *sm4)
{ {
struct vsir_program *program = sm4->p.program;
ins->declaration.count = *tokens; ins->declaration.count = *tokens;
if (opcode == VKD3D_SM4_OP_DCL_TEMPS) if (opcode == VKD3D_SM4_OP_DCL_TEMPS)
priv->p.program.temp_count = max(priv->p.program.temp_count, *tokens); program->temp_count = max(program->temp_count, *tokens);
} }
static void shader_sm4_read_declaration_dst(struct vkd3d_shader_instruction *ins, uint32_t opcode, static void shader_sm4_read_declaration_dst(struct vkd3d_shader_instruction *ins, uint32_t opcode,
@ -1113,7 +1117,7 @@ static void shader_sm4_read_dcl_input_ps(struct vkd3d_shader_instruction *ins, u
if (shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], VKD3D_DATA_FLOAT, dst)) if (shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], VKD3D_DATA_FLOAT, dst))
{ {
struct signature_element *e = vsir_signature_find_element_for_reg( struct signature_element *e = vsir_signature_find_element_for_reg(
&priv->p.program.input_signature, dst->reg.idx[dst->reg.idx_count - 1].offset, dst->write_mask); &priv->p.program->input_signature, dst->reg.idx[dst->reg.idx_count - 1].offset, dst->write_mask);
e->interpolation_mode = ins->flags; e->interpolation_mode = ins->flags;
} }
@ -1128,7 +1132,7 @@ static void shader_sm4_read_dcl_input_ps_siv(struct vkd3d_shader_instruction *in
if (shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], VKD3D_DATA_FLOAT, dst)) if (shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], VKD3D_DATA_FLOAT, dst))
{ {
struct signature_element *e = vsir_signature_find_element_for_reg( struct signature_element *e = vsir_signature_find_element_for_reg(
&priv->p.program.input_signature, dst->reg.idx[dst->reg.idx_count - 1].offset, dst->write_mask); &priv->p.program->input_signature, dst->reg.idx[dst->reg.idx_count - 1].offset, dst->write_mask);
e->interpolation_mode = ins->flags; e->interpolation_mode = ins->flags;
} }
@ -1183,15 +1187,17 @@ static void shader_sm5_read_dcl_interface(struct vkd3d_shader_instruction *ins,
} }
static void shader_sm5_read_control_point_count(struct vkd3d_shader_instruction *ins, uint32_t opcode, static void shader_sm5_read_control_point_count(struct vkd3d_shader_instruction *ins, uint32_t opcode,
uint32_t opcode_token, const uint32_t *tokens, unsigned int token_count, struct vkd3d_shader_sm4_parser *priv) uint32_t opcode_token, const uint32_t *tokens, unsigned int token_count, struct vkd3d_shader_sm4_parser *sm4)
{ {
struct vsir_program *program = sm4->p.program;
ins->declaration.count = (opcode_token & VKD3D_SM5_CONTROL_POINT_COUNT_MASK) ins->declaration.count = (opcode_token & VKD3D_SM5_CONTROL_POINT_COUNT_MASK)
>> VKD3D_SM5_CONTROL_POINT_COUNT_SHIFT; >> VKD3D_SM5_CONTROL_POINT_COUNT_SHIFT;
if (opcode == VKD3D_SM5_OP_DCL_INPUT_CONTROL_POINT_COUNT) if (opcode == VKD3D_SM5_OP_DCL_INPUT_CONTROL_POINT_COUNT)
priv->p.program.input_control_point_count = ins->declaration.count; program->input_control_point_count = ins->declaration.count;
else else
priv->p.program.output_control_point_count = ins->declaration.count; program->output_control_point_count = ins->declaration.count;
} }
static void shader_sm5_read_dcl_tessellator_domain(struct vkd3d_shader_instruction *ins, uint32_t opcode, static void shader_sm5_read_dcl_tessellator_domain(struct vkd3d_shader_instruction *ins, uint32_t opcode,
@ -1749,7 +1755,8 @@ static void shader_sm4_destroy(struct vkd3d_shader_parser *parser)
{ {
struct vkd3d_shader_sm4_parser *sm4 = vkd3d_shader_sm4_parser(parser); struct vkd3d_shader_sm4_parser *sm4 = vkd3d_shader_sm4_parser(parser);
vsir_program_cleanup(&parser->program); vsir_program_cleanup(parser->program);
vkd3d_free(parser->program);
vkd3d_free(sm4); vkd3d_free(sm4);
} }
@ -1758,7 +1765,7 @@ static bool shader_sm4_read_reg_idx(struct vkd3d_shader_sm4_parser *priv, const
{ {
if (addressing & VKD3D_SM4_ADDRESSING_RELATIVE) if (addressing & VKD3D_SM4_ADDRESSING_RELATIVE)
{ {
struct vkd3d_shader_src_param *rel_addr = vsir_program_get_src_params(&priv->p.program, 1); struct vkd3d_shader_src_param *rel_addr = vsir_program_get_src_params(priv->p.program, 1);
if (!(reg_idx->rel_addr = rel_addr)) if (!(reg_idx->rel_addr = rel_addr))
{ {
@ -2036,7 +2043,7 @@ static bool register_is_control_point_input(const struct vkd3d_shader_register *
{ {
return reg->type == VKD3DSPR_INCONTROLPOINT || reg->type == VKD3DSPR_OUTCONTROLPOINT return reg->type == VKD3DSPR_INCONTROLPOINT || reg->type == VKD3DSPR_OUTCONTROLPOINT
|| (reg->type == VKD3DSPR_INPUT && (priv->phase == VKD3DSIH_HS_CONTROL_POINT_PHASE || (reg->type == VKD3DSPR_INPUT && (priv->phase == VKD3DSIH_HS_CONTROL_POINT_PHASE
|| priv->p.program.shader_version.type == VKD3D_SHADER_TYPE_GEOMETRY)); || priv->p.program->shader_version.type == VKD3D_SHADER_TYPE_GEOMETRY));
} }
static uint32_t mask_from_swizzle(uint32_t swizzle) static uint32_t mask_from_swizzle(uint32_t swizzle)
@ -2360,7 +2367,7 @@ static void shader_sm4_read_instruction_modifier(uint32_t modifier, struct vkd3d
static void shader_sm4_read_instruction(struct vkd3d_shader_sm4_parser *sm4, struct vkd3d_shader_instruction *ins) static void shader_sm4_read_instruction(struct vkd3d_shader_sm4_parser *sm4, struct vkd3d_shader_instruction *ins)
{ {
const struct vkd3d_sm4_opcode_info *opcode_info; const struct vkd3d_sm4_opcode_info *opcode_info;
struct vsir_program *program = &sm4->p.program; struct vsir_program *program = sm4->p.program;
uint32_t opcode_token, opcode, previous_token; uint32_t opcode_token, opcode, previous_token;
struct vkd3d_shader_dst_param *dst_params; struct vkd3d_shader_dst_param *dst_params;
struct vkd3d_shader_src_param *src_params; struct vkd3d_shader_src_param *src_params;
@ -2652,6 +2659,7 @@ int vkd3d_shader_sm4_parser_create(const struct vkd3d_shader_compile_info *compi
struct vkd3d_shader_instruction *ins; struct vkd3d_shader_instruction *ins;
struct vkd3d_shader_sm4_parser *sm4; struct vkd3d_shader_sm4_parser *sm4;
struct dxbc_shader_desc dxbc_desc = {0}; struct dxbc_shader_desc dxbc_desc = {0};
struct vsir_program *program;
int ret; int ret;
if (!(sm4 = vkd3d_calloc(1, sizeof(*sm4)))) if (!(sm4 = vkd3d_calloc(1, sizeof(*sm4))))
@ -2678,29 +2686,30 @@ int vkd3d_shader_sm4_parser_create(const struct vkd3d_shader_compile_info *compi
return VKD3D_ERROR_INVALID_ARGUMENT; return VKD3D_ERROR_INVALID_ARGUMENT;
} }
sm4->p.program.input_signature = dxbc_desc.input_signature; program = sm4->p.program;
sm4->p.program.output_signature = dxbc_desc.output_signature; program->input_signature = dxbc_desc.input_signature;
sm4->p.program.patch_constant_signature = dxbc_desc.patch_constant_signature; program->output_signature = dxbc_desc.output_signature;
program->patch_constant_signature = dxbc_desc.patch_constant_signature;
memset(&dxbc_desc, 0, sizeof(dxbc_desc)); memset(&dxbc_desc, 0, sizeof(dxbc_desc));
/* DXBC stores used masks inverted for output signatures, for some reason. /* DXBC stores used masks inverted for output signatures, for some reason.
* We return them un-inverted. */ * We return them un-inverted. */
uninvert_used_masks(&sm4->p.program.output_signature); uninvert_used_masks(&program->output_signature);
if (sm4->p.program.shader_version.type == VKD3D_SHADER_TYPE_HULL) if (program->shader_version.type == VKD3D_SHADER_TYPE_HULL)
uninvert_used_masks(&sm4->p.program.patch_constant_signature); uninvert_used_masks(&program->patch_constant_signature);
if (!shader_sm4_parser_validate_signature(sm4, &sm4->p.program.input_signature, if (!shader_sm4_parser_validate_signature(sm4, &program->input_signature,
sm4->input_register_masks, "Input") sm4->input_register_masks, "Input")
|| !shader_sm4_parser_validate_signature(sm4, &sm4->p.program.output_signature, || !shader_sm4_parser_validate_signature(sm4, &program->output_signature,
sm4->output_register_masks, "Output") sm4->output_register_masks, "Output")
|| !shader_sm4_parser_validate_signature(sm4, &sm4->p.program.patch_constant_signature, || !shader_sm4_parser_validate_signature(sm4, &program->patch_constant_signature,
sm4->patch_constant_register_masks, "Patch constant")) sm4->patch_constant_register_masks, "Patch constant"))
{ {
shader_sm4_destroy(&sm4->p); shader_sm4_destroy(&sm4->p);
return VKD3D_ERROR_INVALID_SHADER; return VKD3D_ERROR_INVALID_SHADER;
} }
instructions = &sm4->p.program.instructions; instructions = &program->instructions;
while (sm4->ptr != sm4->end) while (sm4->ptr != sm4->end)
{ {
if (!shader_instruction_array_reserve(instructions, instructions->count + 1)) if (!shader_instruction_array_reserve(instructions, instructions->count + 1))
@ -2721,7 +2730,7 @@ int vkd3d_shader_sm4_parser_create(const struct vkd3d_shader_compile_info *compi
} }
++instructions->count; ++instructions->count;
} }
if (sm4->p.program.shader_version.type == VKD3D_SHADER_TYPE_HULL if (program->shader_version.type == VKD3D_SHADER_TYPE_HULL
&& !sm4->has_control_point_phase && !sm4->p.failed) && !sm4->has_control_point_phase && !sm4->p.failed)
shader_sm4_validate_default_phase_index_ranges(sm4); shader_sm4_validate_default_phase_index_ranges(sm4);

View File

@ -559,13 +559,19 @@ bool vkd3d_shader_parser_init(struct vkd3d_shader_parser *parser,
const struct vkd3d_shader_version *version, const struct vkd3d_shader_parser_ops *ops, const struct vkd3d_shader_version *version, const struct vkd3d_shader_parser_ops *ops,
unsigned int instruction_reserve) unsigned int instruction_reserve)
{ {
bool ret;
parser->message_context = message_context; parser->message_context = message_context;
parser->location.source_name = source_name; parser->location.source_name = source_name;
parser->location.line = 1; parser->location.line = 1;
parser->location.column = 0; parser->location.column = 0;
parser->ops = ops; parser->ops = ops;
parser->config_flags = vkd3d_shader_init_config_flags(); parser->config_flags = vkd3d_shader_init_config_flags();
return vsir_program_init(&parser->program, version, instruction_reserve); if (!(parser->program = vkd3d_calloc(1, sizeof(*parser->program))))
return false;
if (!(ret = vsir_program_init(parser->program, version, instruction_reserve)))
vkd3d_free(parser->program);
return ret;
} }
void VKD3D_PRINTF_FUNC(3, 4) vkd3d_shader_parser_error(struct vkd3d_shader_parser *parser, void VKD3D_PRINTF_FUNC(3, 4) vkd3d_shader_parser_error(struct vkd3d_shader_parser *parser,
@ -1544,7 +1550,7 @@ int vkd3d_shader_scan(const struct vkd3d_shader_compile_info *compile_info, char
} }
else else
{ {
ret = vsir_program_scan(&parser->program, compile_info, &message_context, NULL); ret = vsir_program_scan(parser->program, compile_info, &message_context, NULL);
vkd3d_shader_parser_destroy(parser); vkd3d_shader_parser_destroy(parser);
} }
} }
@ -1665,7 +1671,7 @@ int vkd3d_shader_compile(const struct vkd3d_shader_compile_info *compile_info,
} }
else else
{ {
ret = vsir_program_compile(&parser->program, parser->config_flags, compile_info, out, &message_context); ret = vsir_program_compile(parser->program, parser->config_flags, compile_info, out, &message_context);
vkd3d_shader_parser_destroy(parser); vkd3d_shader_parser_destroy(parser);
} }
} }

View File

@ -1392,10 +1392,10 @@ struct vkd3d_shader_parser
{ {
struct vkd3d_shader_message_context *message_context; struct vkd3d_shader_message_context *message_context;
struct vkd3d_shader_location location; struct vkd3d_shader_location location;
struct vsir_program *program;
bool failed; bool failed;
const struct vkd3d_shader_parser_ops *ops; const struct vkd3d_shader_parser_ops *ops;
struct vsir_program program;
uint64_t config_flags; uint64_t config_flags;
}; };
@ -1421,7 +1421,7 @@ static inline void vkd3d_shader_parser_destroy(struct vkd3d_shader_parser *parse
static inline enum vkd3d_result vkd3d_shader_parser_validate(struct vkd3d_shader_parser *parser) static inline enum vkd3d_result vkd3d_shader_parser_validate(struct vkd3d_shader_parser *parser)
{ {
return vsir_program_validate(&parser->program, parser->config_flags, return vsir_program_validate(parser->program, parser->config_flags,
parser->location.source_name, parser->message_context); parser->location.source_name, parser->message_context);
} }