From 55e98ca5107db1afba25205f66972abed9ff9f1c Mon Sep 17 00:00:00 2001 From: Alistair Leslie-Hughes Date: Tue, 14 Oct 2025 10:43:27 +1100 Subject: [PATCH] Updated vkd3d to b5b5c67b34be0c54bb4ee8a5439d65c2d1d6ba5d. --- libs/vkd3d/include/vkd3d_shader.h | 61 ++ libs/vkd3d/libs/vkd3d-shader/d3d_asm.c | 5 - libs/vkd3d/libs/vkd3d-shader/d3dbc.c | 92 +- libs/vkd3d/libs/vkd3d-shader/dxil.c | 118 ++- libs/vkd3d/libs/vkd3d-shader/glsl.c | 54 +- libs/vkd3d/libs/vkd3d-shader/hlsl.c | 4 +- libs/vkd3d/libs/vkd3d-shader/hlsl.h | 4 +- libs/vkd3d/libs/vkd3d-shader/hlsl.l | 1 - libs/vkd3d/libs/vkd3d-shader/hlsl.y | 54 +- libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c | 897 ++++++++++-------- libs/vkd3d/libs/vkd3d-shader/ir.c | 653 +++++++++++-- libs/vkd3d/libs/vkd3d-shader/msl.c | 26 +- libs/vkd3d/libs/vkd3d-shader/spirv.c | 334 ++----- .../libs/vkd3d-shader/vkd3d_shader_main.c | 77 +- .../libs/vkd3d-shader/vkd3d_shader_private.h | 52 +- 15 files changed, 1455 insertions(+), 977 deletions(-) diff --git a/libs/vkd3d/include/vkd3d_shader.h b/libs/vkd3d/include/vkd3d_shader.h index 3a2f54c8f22..df1f5d5250d 100644 --- a/libs/vkd3d/include/vkd3d_shader.h +++ b/libs/vkd3d/include/vkd3d_shader.h @@ -125,6 +125,11 @@ enum vkd3d_shader_structure_type * \since 1.18 */ VKD3D_SHADER_STRUCTURE_TYPE_SCAN_THREAD_GROUP_SIZE_INFO, + /** + * The structure is a vkd3d_shader_d3dbc_source_info structure. + * \since 1.18 + */ + VKD3D_SHADER_STRUCTURE_TYPE_D3DBC_SOURCE_INFO, VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_STRUCTURE_TYPE), }; @@ -2312,6 +2317,61 @@ struct vkd3d_shader_scan_thread_group_size_info unsigned int x, y, z; }; +/** + * A chained structure containing legacy Direct3D bytecode compilation parameters. + * This structure specifies some information about the source environment that + * is not specified in the source shader format, but may be necessary for the + * target format. + * + * This structure is optional. + * + * This structure extends vkd3d_shader_compile_info. + * + * This structure contains only input parameters. + * + * \since 1.18 + */ +struct vkd3d_shader_d3dbc_source_info +{ + /** Must be set to VKD3D_SHADER_STRUCTURE_TYPE_D3DBC_SOURCE_INFO. */ + enum vkd3d_shader_structure_type type; + /** Optional pointer to a structure containing further parameters. */ + const void *next; + + /** + * The dimension of each texture bound to the shader. + * + * If this structure is not specified, the dimension for all textures will + * be VKD3D_SHADER_RESOURCE_TEXTURE_2D. + * + * The dimension of textures in this array not used by the shader will be + * ignored. + * + * This field is ignored for shader models 2 and higher. + */ + enum vkd3d_shader_resource_type texture_dimensions[6]; + + /** + * A mask indicating which samplers should be shadow (i.e. comparison-mode) + * samplers. When legacy Direct3D shaders are used with the Direct3D 8 and 9 + * APIs, this is implied by the format of the sampled resource; e.g. a + * D3DFMT_D24S8 texture implies shadow sampling, while a D3DFMT_A8R8G8B8 + * or D3DFMT_INTZ texture does not. + * This information is necessary when converting to other formats + * (e.g. SPIR-V, GLSL) which specify this in the shader. + * + * For example, if bit 1 is set (so the value is 0x2), this indicates that + * the sampler at bind point 1 (and no others) should be a shadow sampler. + * + * Bits in this mask corresponding to textures not used by the shader will + * be ignored. + * + * If this structure is not specified, no samplers will be considered to + * be shadow samplers. + */ + uint32_t shadow_samplers; +}; + /** * Data type of a shader varying, returned as part of struct * vkd3d_shader_signature_element. @@ -2805,6 +2865,7 @@ VKD3D_SHADER_API const enum vkd3d_shader_target_type *vkd3d_shader_get_supported * * Depending on the source and target types, this function may support the * following chained structures: + * - vkd3d_shader_d3dbc_source_info * - vkd3d_shader_descriptor_offset_info * - vkd3d_shader_hlsl_source_info * - vkd3d_shader_interface_info diff --git a/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c b/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c index 6f8fbe84b90..4573cb67fb5 100644 --- a/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c +++ b/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c @@ -145,11 +145,6 @@ static void shader_dump_global_flags(struct vkd3d_d3d_asm_compiler *compiler, en static void shader_dump_atomic_op_flags(struct vkd3d_d3d_asm_compiler *compiler, uint32_t atomic_flags) { - if (atomic_flags & VKD3DARF_SEQ_CST) - { - vkd3d_string_buffer_printf(&compiler->buffer, "_seqCst"); - atomic_flags &= ~VKD3DARF_SEQ_CST; - } if (atomic_flags & VKD3DARF_VOLATILE) { vkd3d_string_buffer_printf(&compiler->buffer, "_volatile"); diff --git a/libs/vkd3d/libs/vkd3d-shader/d3dbc.c b/libs/vkd3d/libs/vkd3d-shader/d3dbc.c index 2379efd3a02..b2d4ec23c6e 100644 --- a/libs/vkd3d/libs/vkd3d-shader/d3dbc.c +++ b/libs/vkd3d/libs/vkd3d-shader/d3dbc.c @@ -248,6 +248,10 @@ struct vkd3d_shader_sm1_parser struct vkd3d_shader_parser p; struct vsir_program *program; + const struct vkd3d_shader_d3dbc_source_info *d3dbc_source_info; + + uint16_t texture_descriptors; + struct { #define MAX_CONSTANT_COUNT 8192 @@ -938,6 +942,27 @@ static void shader_sm1_scan_register(struct vkd3d_shader_sm1_parser *sm1, add_signature_element_from_register(sm1, reg, false, mask, 0); } +static void d3dbc_add_combined_sampler_descriptor(struct vkd3d_shader_sm1_parser *d3dbc, + unsigned int sampler_idx, enum vkd3d_shader_resource_type resource_type) +{ + struct vkd3d_shader_register_range range = {.first = sampler_idx, .last = sampler_idx}; + const struct vkd3d_shader_d3dbc_source_info *source_info = d3dbc->d3dbc_source_info; + struct vsir_program *program = d3dbc->program; + struct vkd3d_shader_descriptor_info1 *d; + + if (!vsir_program_add_descriptor(program, VKD3D_SHADER_DESCRIPTOR_TYPE_SRV, + sampler_idx, &range, resource_type, VSIR_DATA_F32)) + vkd3d_shader_parser_error(&d3dbc->p, VKD3D_SHADER_ERROR_D3DBC_OUT_OF_MEMORY, + "Failed to create SRV descriptor for combined sampler %u.", sampler_idx); + + if (!(d = vsir_program_add_descriptor(program, VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER, + sampler_idx, &range, VKD3D_SHADER_RESOURCE_NONE, VSIR_DATA_UNUSED))) + vkd3d_shader_parser_error(&d3dbc->p, VKD3D_SHADER_ERROR_D3DBC_OUT_OF_MEMORY, + "Failed to create sampler descriptor for combined sampler %u.", sampler_idx); + else if (source_info && source_info->shadow_samplers & (1u << sampler_idx)) + d->flags |= VKD3D_SHADER_DESCRIPTOR_INFO_FLAG_SAMPLER_COMPARISON_MODE; +} + /* Read a parameter token from the input stream, and possibly a relative * addressing token. */ static void shader_sm1_read_param(struct vkd3d_shader_sm1_parser *sm1, @@ -1102,6 +1127,11 @@ static void shader_sm1_read_semantic(struct vkd3d_shader_sm1_parser *sm1, range->first = range->last = semantic->resource.reg.reg.idx[0].offset; add_signature_element_from_semantic(sm1, semantic); + if (semantic->resource_type) + { + d3dbc_add_combined_sampler_descriptor(sm1, range->first, semantic->resource_type); + sm1->texture_descriptors |= (1u << range->first); + } } static void shader_sm1_read_immconst(struct vkd3d_shader_sm1_parser *sm1, const uint32_t **ptr, @@ -1196,6 +1226,43 @@ static void shader_sm1_read_comment(struct vkd3d_shader_sm1_parser *sm1) } } +static void d3dbc_update_descriptors(struct vkd3d_shader_sm1_parser *d3dbc, + const struct vkd3d_shader_instruction *ins) +{ + enum vkd3d_shader_resource_type type = VKD3D_SHADER_RESOURCE_TEXTURE_2D; + const struct vkd3d_shader_d3dbc_source_info *source_info; + unsigned int sampler_idx; + + switch (ins->opcode) + { + case VSIR_OP_TEX: + case VSIR_OP_TEXBEM: + case VSIR_OP_TEXBEML: + case VSIR_OP_TEXDP3TEX: + case VSIR_OP_TEXLD: + case VSIR_OP_TEXM3x2TEX: + case VSIR_OP_TEXM3x3SPEC: + case VSIR_OP_TEXM3x3TEX: + case VSIR_OP_TEXM3x3VSPEC: + case VSIR_OP_TEXREG2AR: + case VSIR_OP_TEXREG2GB: + case VSIR_OP_TEXREG2RGB: + sampler_idx = ins->dst[0].reg.idx[0].offset; + if ((d3dbc->texture_descriptors & (1u << sampler_idx))) + break; + + if ((source_info = d3dbc->d3dbc_source_info) + && sampler_idx < ARRAY_SIZE(source_info->texture_dimensions)) + type = source_info->texture_dimensions[sampler_idx]; + d3dbc_add_combined_sampler_descriptor(d3dbc, sampler_idx, type); + d3dbc->texture_descriptors |= (1u << sampler_idx); + break; + + default: + break; + } +} + static void shader_sm1_validate_instruction(struct vkd3d_shader_sm1_parser *sm1, struct vkd3d_shader_instruction *ins) { if ((ins->opcode == VSIR_OP_BREAKP || ins->opcode == VSIR_OP_IF) && ins->flags) @@ -1360,6 +1427,9 @@ static void shader_sm1_read_instruction(struct vkd3d_shader_sm1_parser *sm1, str goto fail; } + if (program->shader_version.major == 1) + d3dbc_update_descriptors(sm1, ins); + shader_sm1_validate_instruction(sm1, ins); return; @@ -1397,6 +1467,8 @@ static enum vkd3d_result shader_sm1_init(struct vkd3d_shader_sm1_parser *sm1, st uint16_t shader_type; size_t token_count; + sm1->d3dbc_source_info = vkd3d_find_struct(compile_info->next, D3DBC_SOURCE_INFO); + token_count = code_size / sizeof(*sm1->start); if (token_count < 2) @@ -1478,6 +1550,7 @@ int d3dbc_parse(const struct vkd3d_shader_compile_info *compile_info, uint64_t c struct vkd3d_shader_message_context *message_context, struct vsir_program *program) { struct vkd3d_shader_sm1_parser sm1 = {0}; + struct vkd3d_shader_descriptor_info1 *d; struct vkd3d_shader_instruction *ins; unsigned int i; int ret; @@ -1506,8 +1579,23 @@ int d3dbc_parse(const struct vkd3d_shader_compile_info *compile_info, uint64_t c } } - for (i = 0; i < ARRAY_SIZE(program->flat_constant_count); ++i) - program->flat_constant_count[i] = get_external_constant_count(&sm1, i); + for (i = 0; i < 3; ++i) + { + struct vkd3d_shader_register_range range = {.space = 0, .first = i, .last = i}; + unsigned int size = get_external_constant_count(&sm1, i); + + if (size) + { + if (!(d = vsir_program_add_descriptor(program, VKD3D_SHADER_DESCRIPTOR_TYPE_CBV, + i, &range, VKD3D_SHADER_RESOURCE_BUFFER, VSIR_DATA_U32))) + vkd3d_shader_parser_error(&sm1.p, VKD3D_SHADER_ERROR_D3DBC_OUT_OF_MEMORY, + "Failed to create CBV descriptor."); + else + d->buffer_size = size * 16; + } + } + + program->has_descriptor_info = true; if (ret >= 0 && sm1.p.status < 0) ret = sm1.p.status; diff --git a/libs/vkd3d/libs/vkd3d-shader/dxil.c b/libs/vkd3d/libs/vkd3d-shader/dxil.c index f82644d4679..c7af58118df 100644 --- a/libs/vkd3d/libs/vkd3d-shader/dxil.c +++ b/libs/vkd3d/libs/vkd3d-shader/dxil.c @@ -2430,9 +2430,9 @@ static unsigned int sm6_parser_alloc_ssa_id(struct sm6_parser *sm6) } static void instruction_init_with_resource(struct vkd3d_shader_instruction *ins, - enum vkd3d_shader_opcode handler_idx, const struct sm6_value *resource, struct sm6_parser *sm6) + enum vkd3d_shader_opcode opcode, const struct sm6_value *resource, struct sm6_parser *dxil) { - vsir_instruction_init(ins, &sm6->p.location, handler_idx); + vsir_instruction_init(ins, &dxil->p.location, opcode); ins->resource_type = resource->u.handle.d->resource_type; ins->raw = resource->u.handle.d->kind == RESOURCE_KIND_RAWBUFFER; ins->structured = resource->u.handle.d->kind == RESOURCE_KIND_STRUCTUREDBUFFER; @@ -4467,6 +4467,8 @@ static void sm6_parser_emit_atomicrmw(struct sm6_parser *sm6, const struct dxil_ /* It's currently not possible to specify an atomic ordering in HLSL, and it defaults to seq_cst. */ if ((code = record->operands[i++]) != ORDERING_SEQCST) FIXME("Unhandled atomic ordering %"PRIu64".\n", code); + else + WARN("Ignoring atomic ordering %"PRIu64".\n", code); if ((code = record->operands[i]) != 1) WARN("Ignoring synchronisation scope %"PRIu64".\n", code); @@ -4484,7 +4486,7 @@ static void sm6_parser_emit_atomicrmw(struct sm6_parser *sm6, const struct dxil_ ins = state->ins; vsir_instruction_init(ins, &sm6->p.location, op); - ins->flags = is_volatile ? VKD3DARF_SEQ_CST | VKD3DARF_VOLATILE : VKD3DARF_SEQ_CST; + ins->flags = is_volatile ? VKD3DARF_VOLATILE : 0; if (!(src_params = instruction_src_params_alloc(ins, 2, sm6))) return; @@ -4509,7 +4511,7 @@ static void sm6_parser_emit_atomicrmw(struct sm6_parser *sm6, const struct dxil_ } static enum vkd3d_shader_opcode map_binary_op(uint64_t code, const struct sm6_type *type_a, - const struct sm6_type *type_b, struct sm6_parser *sm6) + const struct sm6_type *type_b, struct sm6_parser *sm6, enum vkd3d_shader_opcode *aux_opcode) { bool is_int = sm6_type_is_bool_i16_i32_i64(type_a); bool is_double = sm6_type_is_double(type_a); @@ -4532,12 +4534,17 @@ static enum vkd3d_shader_opcode map_binary_op(uint64_t code, const struct sm6_ty "Type mismatch in binary operation arguments."); } + *aux_opcode = VSIR_OP_NOP; + switch (code) { case BINOP_ADD: + op = is_int ? VSIR_OP_IADD : (is_double ? VSIR_OP_DADD : VSIR_OP_ADD); + is_valid = !is_bool; + break; case BINOP_SUB: - /* NEG is applied later for subtraction. */ op = is_int ? VSIR_OP_IADD : (is_double ? VSIR_OP_DADD : VSIR_OP_ADD); + *aux_opcode = is_int ? VSIR_OP_INEG : VSIR_OP_NEG; is_valid = !is_bool; break; case BINOP_AND: @@ -4601,12 +4608,13 @@ static enum vkd3d_shader_opcode map_binary_op(uint64_t code, const struct sm6_ty } static void sm6_parser_emit_binop(struct sm6_parser *sm6, const struct dxil_record *record, - struct vkd3d_shader_instruction *ins, struct sm6_value *dst) + struct sm6_block *code_block, struct vkd3d_shader_instruction *ins, struct sm6_value *dst) { + enum vkd3d_shader_opcode opcode, aux_opcode; struct vkd3d_shader_src_param *src_params; - enum vkd3d_shader_opcode handler_idx; + struct vkd3d_shader_dst_param *dst_params; + uint32_t type_flags = 0, aux_id = 0; const struct sm6_value *a, *b; - uint32_t type_flags = 0; uint64_t code, flags; bool silence_warning; unsigned int i = 0; @@ -4622,15 +4630,34 @@ static void sm6_parser_emit_binop(struct sm6_parser *sm6, const struct dxil_reco return; code = record->operands[i++]; - if ((handler_idx = map_binary_op(code, a->type, b->type, sm6)) == VSIR_OP_INVALID) + if ((opcode = map_binary_op(code, a->type, b->type, sm6, &aux_opcode)) == VSIR_OP_INVALID) return; - vsir_instruction_init(ins, &sm6->p.location, handler_idx); + if (aux_opcode != VSIR_OP_NOP) + { + vsir_instruction_init(ins, &sm6->p.location, aux_opcode); + + if (!(dst_params = instruction_dst_params_alloc(ins, 1, sm6)) + || !(src_params = instruction_src_params_alloc(ins, 1, sm6))) + return; + + aux_id = sm6_parser_alloc_ssa_id(sm6); + + src_param_init_from_value(&src_params[0], b, DXIL_TYPE_SIGNED, sm6); + + dst_param_init(&dst_params[0]); + register_init_with_id(&dst_params[0].reg, VKD3DSPR_SSA, src_params[0].reg.data_type, aux_id); + + ++ins; + ++code_block->instruction_count; + } + + vsir_instruction_init(ins, &sm6->p.location, opcode); flags = (record->operand_count > i) ? record->operands[i] : 0; silence_warning = false; - switch (handler_idx) + switch (opcode) { case VSIR_OP_ADD: case VSIR_OP_MUL: @@ -4674,14 +4701,22 @@ static void sm6_parser_emit_binop(struct sm6_parser *sm6, const struct dxil_reco if (!(src_params = instruction_src_params_alloc(ins, 2, sm6))) return; + src_param_init_from_value(&src_params[0], a, type_flags, sm6); - src_param_init_from_value(&src_params[1], b, type_flags, sm6); - if (code == BINOP_SUB) - src_params[1].modifiers = VKD3DSPSM_NEG; + + if (aux_opcode == VSIR_OP_NOP) + { + src_param_init_from_value(&src_params[1], b, type_flags, sm6); + } + else + { + src_param_init(&src_params[1]); + register_init_with_id(&src_params[1].reg, VKD3DSPR_SSA, src_params[0].reg.data_type, aux_id); + } dst->type = a->type; - if (handler_idx == VSIR_OP_ISHL || handler_idx == VSIR_OP_ISHR || handler_idx == VSIR_OP_USHR) + if (opcode == VSIR_OP_ISHL || opcode == VSIR_OP_ISHR || opcode == VSIR_OP_USHR) { /* DXC emits AND instructions where necessary to mask shift counts. * Shift binops do not imply masking the shift as the TPF equivalents @@ -5041,18 +5076,18 @@ static void sm6_parser_emit_dx_atomic_binop(struct sm6_parser *sm6, enum dx_intr unsigned int i, coord_idx, coord_count = 1; struct vkd3d_shader_dst_param *dst_params; struct vkd3d_shader_src_param *src_params; - enum vkd3d_shader_opcode handler_idx; struct vkd3d_shader_instruction *ins; const struct sm6_value *resource; struct vkd3d_shader_register reg; + enum vkd3d_shader_opcode opcode; resource = operands[0]; if (!sm6_value_validate_is_handle(resource, sm6)) return; if (is_cmp_xchg) - handler_idx = VSIR_OP_IMM_ATOMIC_CMP_EXCH; - else if ((handler_idx = map_dx_atomic_binop(operands[1], sm6)) == VSIR_OP_INVALID) + opcode = VSIR_OP_IMM_ATOMIC_CMP_EXCH; + else if ((opcode = map_dx_atomic_binop(operands[1], sm6)) == VSIR_OP_INVALID) return; coord_idx = 2 - is_cmp_xchg; @@ -5074,13 +5109,13 @@ static void sm6_parser_emit_dx_atomic_binop(struct sm6_parser *sm6, enum dx_intr { WARN("Ignoring unexpected operand.\n"); vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_WARNING_DXIL_IGNORING_OPERANDS, - "Ignoring an unexpected defined operand value for atomic instruction %u.", handler_idx); + "Ignoring an unexpected defined operand value for atomic instruction %u.", opcode); break; } } ins = state->ins; - vsir_instruction_init(ins, &sm6->p.location, handler_idx); + vsir_instruction_init(ins, &sm6->p.location, opcode); if (!(src_params = instruction_src_params_alloc(ins, 2 + is_cmp_xchg, sm6))) return; @@ -5223,16 +5258,16 @@ static void sm6_parser_emit_dx_cbuffer_load(struct sm6_parser *sm6, enum dx_intr instruction_dst_param_init_ssa_vector(ins, sm6_type_max_vector_size(type), sm6); } -static void sm6_parser_dcl_register_builtin(struct sm6_parser *sm6, enum vkd3d_shader_opcode handler_idx, +static void sm6_parser_dcl_register_builtin(struct sm6_parser *dxil, enum vkd3d_shader_opcode opcode, enum vkd3d_shader_register_type reg_type, enum vsir_data_type data_type, unsigned int component_count) { struct vkd3d_shader_dst_param *dst_param; struct vkd3d_shader_instruction *ins; - if (!bitmap_is_set(sm6->io_regs_declared, reg_type)) + if (!bitmap_is_set(dxil->io_regs_declared, reg_type)) { - bitmap_set(sm6->io_regs_declared, reg_type); - if (!(ins = sm6_parser_add_instruction(sm6, handler_idx))) + bitmap_set(dxil->io_regs_declared, reg_type); + if (!(ins = sm6_parser_add_instruction(dxil, opcode))) return; dst_param = &ins->declaration.dst; vsir_register_init(&dst_param->reg, reg_type, data_type, 0); @@ -5394,21 +5429,21 @@ static void sm6_parser_emit_dx_dot(struct sm6_parser *sm6, enum dx_intrinsic_opc struct vkd3d_shader_src_param *src_params; struct vkd3d_shader_instruction *ins; struct vkd3d_shader_register regs[2]; - enum vkd3d_shader_opcode handler_idx; + enum vkd3d_shader_opcode opcode; unsigned int component_count; switch (op) { case DX_DOT2: - handler_idx = VSIR_OP_DP2; + opcode = VSIR_OP_DP2; component_count = 2; break; case DX_DOT3: - handler_idx = VSIR_OP_DP3; + opcode = VSIR_OP_DP3; component_count = 3; break; case DX_DOT4: - handler_idx = VSIR_OP_DP4; + opcode = VSIR_OP_DP4; component_count = 4; break; default: @@ -5421,7 +5456,7 @@ static void sm6_parser_emit_dx_dot(struct sm6_parser *sm6, enum dx_intrinsic_opc return; ins = state->ins; - vsir_instruction_init(ins, &sm6->p.location, handler_idx); + vsir_instruction_init(ins, &sm6->p.location, opcode); if (!(src_params = instruction_src_params_alloc(ins, 2, sm6))) return; src_param_init_vector_from_reg(&src_params[0], ®s[0]); @@ -5483,11 +5518,10 @@ static void sm6_parser_emit_dx_fabs(struct sm6_parser *sm6, enum dx_intrinsic_op struct vkd3d_shader_instruction *ins = state->ins; struct vkd3d_shader_src_param *src_param; - vsir_instruction_init(ins, &sm6->p.location, VSIR_OP_MOV); + vsir_instruction_init(ins, &sm6->p.location, VSIR_OP_ABS); if (!(src_param = instruction_src_params_alloc(ins, 1, sm6))) return; src_param_init_from_value(src_param, operands[0], 0, sm6); - src_param->modifiers = VKD3DSPSM_ABS; instruction_dst_param_init_ssa_scalar(ins, 0, sm6); } @@ -7125,7 +7159,7 @@ static void sm6_parser_emit_cast(struct sm6_parser *dxil, const struct dxil_reco struct sm6_cmp_info { - enum vkd3d_shader_opcode handler_idx; + enum vkd3d_shader_opcode opcode; bool src_swap; uint32_t type_flags; }; @@ -7227,7 +7261,7 @@ static void sm6_parser_emit_cmp2(struct sm6_parser *sm6, const struct dxil_recor "Type mismatch in comparison operation arguments."); } - if (!(cmp = sm6_map_cmp2_op(code)) || !cmp->handler_idx || cmp->handler_idx == VSIR_OP_INVALID) + if (!(cmp = sm6_map_cmp2_op(code)) || !cmp->opcode || cmp->opcode == VSIR_OP_INVALID) { FIXME("Unhandled operation %"PRIu64".\n", code); vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, @@ -7235,7 +7269,7 @@ static void sm6_parser_emit_cmp2(struct sm6_parser *sm6, const struct dxil_recor return; } - vsir_instruction_init(ins, &sm6->p.location, cmp->handler_idx); + vsir_instruction_init(ins, &sm6->p.location, cmp->opcode); flags = (record->operand_count > i) ? record->operands[i] : 0; silence_warning = false; @@ -7327,6 +7361,8 @@ static void sm6_parser_emit_cmpxchg(struct sm6_parser *sm6, const struct dxil_re /* It's currently not possible to specify an atomic ordering in HLSL, and it defaults to seq_cst. */ if (success_ordering != ORDERING_SEQCST) FIXME("Unhandled success ordering %"PRIu64".\n", success_ordering); + else + WARN("Ignoring success ordering %"PRIu64".\n", success_ordering); if (success_ordering != failure_ordering) FIXME("Unhandled failure ordering %"PRIu64".\n", failure_ordering); @@ -7334,7 +7370,7 @@ static void sm6_parser_emit_cmpxchg(struct sm6_parser *sm6, const struct dxil_re FIXME("Ignoring weak cmpxchg.\n"); vsir_instruction_init(ins, &sm6->p.location, VSIR_OP_IMM_ATOMIC_CMP_EXCH); - ins->flags = is_volatile ? VKD3DARF_SEQ_CST | VKD3DARF_VOLATILE : VKD3DARF_SEQ_CST; + ins->flags = is_volatile ? VKD3DARF_VOLATILE : 0; if (!(src_params = instruction_src_params_alloc(ins, 3, sm6))) return; @@ -8342,7 +8378,7 @@ static enum vkd3d_result sm6_parser_function_init(struct sm6_parser *sm6, const break; } case FUNC_CODE_INST_BINOP: - sm6_parser_emit_binop(sm6, record, ins, dst); + sm6_parser_emit_binop(sm6, record, code_block, ins, dst); break; case FUNC_CODE_INST_BR: sm6_parser_emit_br(sm6, record, function, code_block, ins); @@ -10121,22 +10157,22 @@ static enum vkd3d_result sm6_parser_emit_thread_group(struct sm6_parser *sm6, co return VKD3D_OK; } -static void sm6_parser_emit_dcl_count(struct sm6_parser *sm6, enum vkd3d_shader_opcode handler_idx, unsigned int count) +static void sm6_parser_emit_dcl_count(struct sm6_parser *dxil, enum vkd3d_shader_opcode opcode, unsigned int count) { struct vkd3d_shader_instruction *ins; - if (!(ins = sm6_parser_add_instruction(sm6, handler_idx))) + if (!(ins = sm6_parser_add_instruction(dxil, opcode))) return; ins->declaration.count = count; } -static void sm6_parser_emit_dcl_primitive_topology(struct sm6_parser *sm6, - enum vkd3d_shader_opcode handler_idx, enum vkd3d_primitive_type primitive_type, +static void sm6_parser_emit_dcl_primitive_topology(struct sm6_parser *dxil, + enum vkd3d_shader_opcode opcode, enum vkd3d_primitive_type primitive_type, unsigned int patch_vertex_count) { struct vkd3d_shader_instruction *ins; - if (!(ins = sm6_parser_add_instruction(sm6, handler_idx))) + if (!(ins = sm6_parser_add_instruction(dxil, opcode))) return; ins->declaration.primitive_type.type = primitive_type; ins->declaration.primitive_type.patch_vertex_count = patch_vertex_count; diff --git a/libs/vkd3d/libs/vkd3d-shader/glsl.c b/libs/vkd3d/libs/vkd3d-shader/glsl.c index b2679beff9f..88c87ae33ee 100644 --- a/libs/vkd3d/libs/vkd3d-shader/glsl.c +++ b/libs/vkd3d/libs/vkd3d-shader/glsl.c @@ -280,7 +280,7 @@ static void shader_glsl_print_register_name(struct vkd3d_string_buffer *buffer, break; case VKD3DSPR_THREADID: - vkd3d_string_buffer_printf(buffer, "gl_GlobalInvocationID"); + vkd3d_string_buffer_printf(buffer, "uvec4(gl_GlobalInvocationID, 0)"); break; case VKD3DSPR_IDXTEMP: @@ -419,25 +419,11 @@ static void shader_glsl_print_src(struct vkd3d_string_buffer *buffer, struct vkd if (reg->dimension == VSIR_DIMENSION_VEC4) shader_glsl_print_swizzle(str, vsir_src->swizzle, mask); - switch (vsir_src->modifiers) + if (vsir_src->modifiers) { - case VKD3DSPSM_NONE: - break; - case VKD3DSPSM_NEG: - vkd3d_string_buffer_printf(buffer, "-%s", str->buffer); - break; - case VKD3DSPSM_ABS: - vkd3d_string_buffer_printf(buffer, "abs(%s)", str->buffer); - break; - case VKD3DSPSM_ABSNEG: - vkd3d_string_buffer_printf(buffer, "-abs(%s)", str->buffer); - break; - default: - vkd3d_string_buffer_printf(buffer, "(%s)", - vsir_src->modifiers, str->buffer); - vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, - "Internal compiler error: Unhandled source modifier(s) %#x.", vsir_src->modifiers); - break; + vkd3d_string_buffer_printf(buffer, "(%s)", vsir_src->modifiers, str->buffer); + vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, + "Internal compiler error: Unhandled source modifier(s) %#x.", vsir_src->modifiers); } if (str != buffer) @@ -1240,25 +1226,33 @@ static void shader_glsl_mov(struct vkd3d_glsl_generator *gen, const struct vkd3d static void shader_glsl_movc(struct vkd3d_glsl_generator *gen, const struct vkd3d_shader_instruction *ins) { + struct vkd3d_string_buffer *src1, *src2; unsigned int component_count; - struct glsl_src src[3]; + struct glsl_src src[1]; struct glsl_dst dst; uint32_t mask; + /* Sadly, mix() in unextended GLSL 4.40 can only select between + * floating-point sources. The earliest version able to select between + * integer sources is version 4.50; the same functionality is also + * provided by the EXT_shader_integer_mix extension. */ + mask = glsl_dst_init(&dst, gen, ins, &ins->dst[0]); glsl_src_init(&src[0], gen, &ins->src[0], mask); - glsl_src_init(&src[1], gen, &ins->src[1], mask); - glsl_src_init(&src[2], gen, &ins->src[2], mask); + src1 = vkd3d_string_buffer_get(&gen->string_buffers); + src2 = vkd3d_string_buffer_get(&gen->string_buffers); + shader_glsl_print_src(src1, gen, &ins->src[1], mask, VSIR_DATA_F32); + shader_glsl_print_src(src2, gen, &ins->src[2], mask, VSIR_DATA_F32); if ((component_count = vsir_write_mask_component_count(mask)) > 1) - shader_glsl_print_assignment(gen, &dst, "mix(%s, %s, bvec%u(%s))", - src[2].str->buffer, src[1].str->buffer, component_count, src[0].str->buffer); + shader_glsl_print_assignment_ext(gen, &dst, VSIR_DATA_F32, "mix(%s, %s, bvec%u(%s))", + src2->buffer, src1->buffer, component_count, src[0].str->buffer); else - shader_glsl_print_assignment(gen, &dst, "mix(%s, %s, bool(%s))", - src[2].str->buffer, src[1].str->buffer, src[0].str->buffer); + shader_glsl_print_assignment_ext(gen, &dst, VSIR_DATA_F32, "mix(%s, %s, bool(%s))", + src2->buffer, src1->buffer, src[0].str->buffer); - glsl_src_cleanup(&src[2], &gen->string_buffers); - glsl_src_cleanup(&src[1], &gen->string_buffers); + vkd3d_string_buffer_release(&gen->string_buffers, src2); + vkd3d_string_buffer_release(&gen->string_buffers, src1); glsl_src_cleanup(&src[0], &gen->string_buffers); glsl_dst_cleanup(&dst, &gen->string_buffers); } @@ -1485,6 +1479,9 @@ static void vkd3d_glsl_handle_instruction(struct vkd3d_glsl_generator *gen, switch (ins->opcode) { + case VSIR_OP_ABS: + shader_glsl_intrinsic(gen, ins, "abs"); + break; case VSIR_OP_ADD: case VSIR_OP_IADD: shader_glsl_binop(gen, ins, "+"); @@ -1597,6 +1594,7 @@ static void vkd3d_glsl_handle_instruction(struct vkd3d_glsl_generator *gen, shader_glsl_relop(gen, ins, "!=", "notEqual"); break; case VSIR_OP_INEG: + case VSIR_OP_NEG: shader_glsl_unary_op(gen, ins, "-"); break; case VSIR_OP_ISHL: diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.c b/libs/vkd3d/libs/vkd3d-shader/hlsl.c index ec1e27d9496..3b0a7acb52a 100644 --- a/libs/vkd3d/libs/vkd3d-shader/hlsl.c +++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.c @@ -2205,11 +2205,11 @@ static struct hlsl_ir_node *hlsl_new_resource_store(struct hlsl_ctx *ctx, return &store->node; } -void hlsl_block_add_resource_store(struct hlsl_ctx *ctx, struct hlsl_block *block, +struct hlsl_ir_node *hlsl_block_add_resource_store(struct hlsl_ctx *ctx, struct hlsl_block *block, enum hlsl_resource_store_type type, const struct hlsl_deref *resource, struct hlsl_ir_node *coords, struct hlsl_ir_node *value, uint32_t writemask, const struct vkd3d_shader_location *loc) { - append_new_instr(ctx, block, hlsl_new_resource_store(ctx, type, resource, coords, value, writemask, loc)); + return append_new_instr(ctx, block, hlsl_new_resource_store(ctx, type, resource, coords, value, writemask, loc)); } struct hlsl_ir_node *hlsl_new_swizzle(struct hlsl_ctx *ctx, uint32_t s, unsigned int component_count, diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.h b/libs/vkd3d/libs/vkd3d-shader/hlsl.h index 6c6243db799..829fcba0aab 100644 --- a/libs/vkd3d/libs/vkd3d-shader/hlsl.h +++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.h @@ -534,6 +534,8 @@ struct hlsl_ir_var struct { bool used; + bool uav_read; + bool uav_atomics; enum hlsl_sampler_dim sampler_dim; struct vkd3d_shader_location first_sampler_dim_loc; } *objects_usage[HLSL_REGSET_LAST_OBJECT + 1]; @@ -1599,7 +1601,7 @@ void hlsl_block_add_loop(struct hlsl_ctx *ctx, struct hlsl_block *block, unsigned int unroll_limit, const struct vkd3d_shader_location *loc); struct hlsl_ir_node *hlsl_block_add_resource_load(struct hlsl_ctx *ctx, struct hlsl_block *block, const struct hlsl_resource_load_params *params, const struct vkd3d_shader_location *loc); -void hlsl_block_add_resource_store(struct hlsl_ctx *ctx, struct hlsl_block *block, +struct hlsl_ir_node *hlsl_block_add_resource_store(struct hlsl_ctx *ctx, struct hlsl_block *block, enum hlsl_resource_store_type type, const struct hlsl_deref *resource, struct hlsl_ir_node *coords, struct hlsl_ir_node *value, uint32_t writemask, const struct vkd3d_shader_location *loc); struct hlsl_ir_node *hlsl_block_add_simple_load(struct hlsl_ctx *ctx, struct hlsl_block *block, diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.l b/libs/vkd3d/libs/vkd3d-shader/hlsl.l index da9f0d39136..c41d807cca1 100644 --- a/libs/vkd3d/libs/vkd3d-shader/hlsl.l +++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.l @@ -83,7 +83,6 @@ ComputeShader {return KW_COMPUTESHADER; } compile {return KW_COMPILE; } CompileShader {return KW_COMPILESHADER; } const {return KW_CONST; } -ConstructGSWithSO {return KW_CONSTRUCTGSWITHSO; } continue {return KW_CONTINUE; } DepthStencilState {return KW_DEPTHSTENCILSTATE; } DepthStencilView {return KW_DEPTHSTENCILVIEW; } diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.y b/libs/vkd3d/libs/vkd3d-shader/hlsl.y index 37b116bed40..27afac71320 100644 --- a/libs/vkd3d/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.y @@ -5337,6 +5337,23 @@ static bool intrinsic_AllMemoryBarrierWithGroupSync(struct hlsl_ctx *ctx, | VKD3DSSF_GROUP_SHARED_MEMORY | VKD3DSSF_THREAD_GROUP, loc); } +static bool intrinsic_ConstructGSWithSO(struct hlsl_ctx *ctx, + const struct parse_initializer *params, const struct vkd3d_shader_location *loc) +{ + struct hlsl_ir_node *compile; + + if (params->args_count != 2 && params->args_count != 6) + hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_WRONG_PARAMETER_COUNT, + "Wrong number of arguments to ConstructGSWithSO(): expected 2 or 6, but got %u.", params->args_count); + + if (!(compile = hlsl_new_compile(ctx, HLSL_COMPILE_TYPE_CONSTRUCTGSWITHSO, + NULL, params->args, params->args_count, params->instrs, loc))) + return false; + + hlsl_block_add_instr(params->instrs, compile); + return true; +} + static bool intrinsic_DeviceMemoryBarrier(struct hlsl_ctx *ctx, const struct parse_initializer *params, const struct vkd3d_shader_location *loc) { @@ -5386,6 +5403,7 @@ intrinsic_functions[] = /* Note: these entries should be kept in alphabetical order. */ {"AllMemoryBarrier", 0, true, intrinsic_AllMemoryBarrier}, {"AllMemoryBarrierWithGroupSync", 0, true, intrinsic_AllMemoryBarrierWithGroupSync}, + {"ConstructGSWithSO", -1, false, intrinsic_ConstructGSWithSO}, {"D3DCOLORtoUBYTE4", 1, true, intrinsic_d3dcolor_to_ubyte4}, {"DeviceMemoryBarrier", 0, true, intrinsic_DeviceMemoryBarrier}, {"DeviceMemoryBarrierWithGroupSync", 0, true, intrinsic_DeviceMemoryBarrierWithGroupSync}, @@ -5629,36 +5647,6 @@ static struct hlsl_block *add_shader_compilation(struct hlsl_ctx *ctx, const cha return make_block(ctx, compile); } -static struct hlsl_block *add_compile_variant(struct hlsl_ctx *ctx, enum hlsl_compile_type compile_type, - struct parse_initializer *args, const struct vkd3d_shader_location *loc) -{ - struct hlsl_ir_node *compile; - - switch (compile_type) - { - case HLSL_COMPILE_TYPE_COMPILE: - vkd3d_unreachable(); - - case HLSL_COMPILE_TYPE_CONSTRUCTGSWITHSO: - if (args->args_count != 2 && args->args_count != 6) - { - hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_WRONG_PARAMETER_COUNT, - "Wrong number of arguments to ConstructGSWithSO: expected 2 or 6, but got %u.", - args->args_count); - } - break; - } - - if (!(compile = hlsl_new_compile(ctx, compile_type, NULL, args->args, args->args_count, args->instrs, loc))) - { - free_parse_initializer(args); - return NULL; - } - - free_parse_initializer(args); - return make_block(ctx, compile); -} - static struct hlsl_block *add_constructor(struct hlsl_ctx *ctx, struct hlsl_type *type, struct parse_initializer *params, const struct vkd3d_shader_location *loc) { @@ -6939,7 +6927,6 @@ static void validate_uav_type(struct hlsl_ctx *ctx, enum hlsl_sampler_dim dim, %token KW_COMPILESHADER %token KW_COMPUTESHADER %token KW_CONST -%token KW_CONSTRUCTGSWITHSO %token KW_CONTINUE %token KW_DEFAULT %token KW_DEPTHSTENCILSTATE @@ -9453,11 +9440,6 @@ primary_expr: vkd3d_free($3); vkd3d_free($5); } - | KW_CONSTRUCTGSWITHSO '(' func_arguments ')' - { - if (!($$ = add_compile_variant(ctx, HLSL_COMPILE_TYPE_CONSTRUCTGSWITHSO, &$3, &@1))) - YYABORT; - } | var_identifier '(' func_arguments ')' { if (!($$ = add_call(ctx, $1, &$3, &@1))) diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c index d22330cedb7..8f4e4cda73f 100644 --- a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c +++ b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c @@ -926,18 +926,17 @@ bool hlsl_transform_ir(struct hlsl_ctx *ctx, bool (*func)(struct hlsl_ctx *ctx, return progress; } -typedef bool (*PFN_lower_func)(struct hlsl_ctx *, struct hlsl_ir_node *, struct hlsl_block *); +typedef struct hlsl_ir_node *(*PFN_replace_func)(struct hlsl_ctx *, struct hlsl_ir_node *, struct hlsl_block *); -static bool call_lower_func(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) +static bool call_replace_func(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) { - PFN_lower_func func = context; + struct hlsl_ir_node *replacement; + PFN_replace_func func = context; struct hlsl_block block; hlsl_block_init(&block); - if (func(ctx, instr, &block)) + if ((replacement = func(ctx, instr, &block))) { - struct hlsl_ir_node *replacement = LIST_ENTRY(list_tail(&block.instrs), struct hlsl_ir_node, entry); - list_move_before(&instr->entry, &block.instrs); hlsl_replace_node(instr, replacement); return true; @@ -949,12 +948,17 @@ static bool call_lower_func(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, vo } } -/* Specific form of transform_ir() for passes which convert a single instruction - * to a block of one or more instructions. This helper takes care of setting up - * the block and calling hlsl_replace_node_with_block(). */ -static bool lower_ir(struct hlsl_ctx *ctx, PFN_lower_func func, struct hlsl_block *block) +/* Specific form of transform_ir() for passes which replace a single instruction + * with another instruction. This includes passes which lower an instruction + * to one or more new instructions, and passes which fold away a redundant + * instruction. + * + * New instructions should be added to "block", and the replacement instruction + * should be returned. If the instruction should be left alone, NULL should be + * returned instead. */ +static bool replace_ir(struct hlsl_ctx *ctx, PFN_replace_func func, struct hlsl_block *block) { - return hlsl_transform_ir(ctx, call_lower_func, block, func); + return hlsl_transform_ir(ctx, call_replace_func, block, func); } static bool transform_instr_derefs(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) @@ -1295,7 +1299,8 @@ static struct hlsl_ir_node *add_zero_mipmap_level(struct hlsl_ctx *ctx, struct h return hlsl_block_add_simple_load(ctx, block, coords, loc); } -static bool lower_complex_casts(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) +static struct hlsl_ir_node *lower_complex_casts(struct hlsl_ctx *ctx, + struct hlsl_ir_node *instr, struct hlsl_block *block) { unsigned int src_comp_count, dst_comp_count; struct hlsl_type *src_type, *dst_type; @@ -1306,17 +1311,17 @@ static bool lower_complex_casts(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr unsigned int dst_idx; if (instr->type != HLSL_IR_EXPR) - return false; + return NULL; if (hlsl_ir_expr(instr)->op != HLSL_OP1_CAST) - return false; + return NULL; arg = hlsl_ir_expr(instr)->operands[0].node; dst_type = instr->data_type; src_type = arg->data_type; if (src_type->class <= HLSL_CLASS_VECTOR && dst_type->class <= HLSL_CLASS_VECTOR) - return false; + return NULL; src_comp_count = hlsl_type_component_count(src_type); dst_comp_count = hlsl_type_component_count(dst_type); @@ -1332,7 +1337,7 @@ static bool lower_complex_casts(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr } if (!(var = hlsl_new_synthetic_var(ctx, "cast", dst_type, &instr->loc))) - return false; + return NULL; hlsl_init_simple_deref_from_var(&var_deref, var); for (dst_idx = 0; dst_idx < dst_comp_count; ++dst_idx) @@ -1363,8 +1368,7 @@ static bool lower_complex_casts(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr hlsl_block_add_store_component(ctx, block, &var_deref, dst_idx, cast); } - hlsl_block_add_simple_load(ctx, block, var, &instr->loc); - return true; + return hlsl_block_add_simple_load(ctx, block, var, &instr->loc); } /* hlsl_ir_swizzle nodes that directly point to a matrix value are only a parse-time construct that @@ -1372,7 +1376,8 @@ static bool lower_complex_casts(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr * an assignment or as a value made from different components of the matrix. The former cases should * have already been split into several separate assignments, but the latter are lowered by this * pass. */ -static bool lower_matrix_swizzles(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) +static struct hlsl_ir_node *lower_matrix_swizzles(struct hlsl_ctx *ctx, + struct hlsl_ir_node *instr, struct hlsl_block *block) { struct hlsl_ir_swizzle *swizzle; struct hlsl_deref var_deref; @@ -1381,14 +1386,14 @@ static bool lower_matrix_swizzles(struct hlsl_ctx *ctx, struct hlsl_ir_node *ins unsigned int k, i; if (instr->type != HLSL_IR_SWIZZLE) - return false; + return NULL; swizzle = hlsl_ir_swizzle(instr); matrix_type = swizzle->val.node->data_type; if (matrix_type->class != HLSL_CLASS_MATRIX) - return false; + return NULL; if (!(var = hlsl_new_synthetic_var(ctx, "matrix-swizzle", instr->data_type, &instr->loc))) - return false; + return NULL; hlsl_init_simple_deref_from_var(&var_deref, var); for (i = 0; i < instr->data_type->e.numeric.dimx; ++i) @@ -1401,8 +1406,7 @@ static bool lower_matrix_swizzles(struct hlsl_ctx *ctx, struct hlsl_ir_node *ins hlsl_block_add_store_component(ctx, block, &var_deref, i, load); } - hlsl_block_add_simple_load(ctx, block, var, &instr->loc); - return true; + return hlsl_block_add_simple_load(ctx, block, var, &instr->loc); } /* hlsl_ir_index nodes are a parse-time construct used to represent array indexing and struct @@ -1411,7 +1415,8 @@ static bool lower_matrix_swizzles(struct hlsl_ctx *ctx, struct hlsl_ir_node *ins * For the latter case, this pass takes care of lowering hlsl_ir_indexes into individual * hlsl_ir_loads, or individual hlsl_ir_resource_loads, in case the indexing is a * resource access. */ -static bool lower_index_loads(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) +static struct hlsl_ir_node *lower_index_loads(struct hlsl_ctx *ctx, + struct hlsl_ir_node *instr, struct hlsl_block *block) { struct hlsl_deref var_deref; struct hlsl_ir_index *index; @@ -1420,7 +1425,7 @@ static bool lower_index_loads(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_ir_var *var; if (instr->type != HLSL_IR_INDEX) - return false; + return NULL; index = hlsl_ir_index(instr); val = index->val.node; @@ -1435,14 +1440,13 @@ static bool lower_index_loads(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, VKD3D_ASSERT(coords->data_type->e.numeric.dimx == dim_count); if (!(coords = add_zero_mipmap_level(ctx, block, coords, &instr->loc))) - return false; + return NULL; params.type = HLSL_RESOURCE_LOAD; params.resource = val; params.coords = coords; params.format = val->data_type->e.resource.format; - hlsl_block_add_resource_load(ctx, block, ¶ms, &instr->loc); - return true; + return hlsl_block_add_resource_load(ctx, block, ¶ms, &instr->loc); } if (val->type == HLSL_IR_RESOURCE_LOAD) @@ -1459,7 +1463,7 @@ static bool lower_index_loads(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_deref row_deref; if (!(var = hlsl_new_synthetic_var(ctx, "row", instr->data_type, &instr->loc))) - return false; + return NULL; hlsl_init_simple_deref_from_var(&row_deref, var); for (unsigned int i = 0; i < mat->data_type->e.numeric.dimx; ++i) @@ -1488,7 +1492,7 @@ static bool lower_index_loads(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, hlsl_block_add_store_component(ctx, block, &row_deref, i, &column_load->node); } - hlsl_block_add_simple_load(ctx, block, var, &instr->loc); + return hlsl_block_add_simple_load(ctx, block, var, &instr->loc); } else { @@ -1506,14 +1510,13 @@ static bool lower_index_loads(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, appended_load->node.data_type = type; hlsl_block_add_instr(block, &appended_load->node); + return &appended_load->node; } - - return true; } } if (!(var = hlsl_new_synthetic_var(ctx, "index-val", val->data_type, &instr->loc))) - return false; + return NULL; hlsl_init_simple_deref_from_var(&var_deref, var); hlsl_block_add_simple_store(ctx, block, var, val); @@ -1527,7 +1530,7 @@ static bool lower_index_loads(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, VKD3D_ASSERT(!hlsl_type_is_row_major(mat->data_type)); if (!(var = hlsl_new_synthetic_var(ctx, "row", instr->data_type, &instr->loc))) - return false; + return NULL; hlsl_init_simple_deref_from_var(&row_deref, var); for (i = 0; i < mat->data_type->e.numeric.dimx; ++i) @@ -1537,37 +1540,34 @@ static bool lower_index_loads(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, c = hlsl_block_add_uint_constant(ctx, block, i, &instr->loc); if (!(load = hlsl_new_load_index(ctx, &var_deref, c, &instr->loc))) - return false; + return NULL; hlsl_block_add_instr(block, &load->node); if (!(load = hlsl_new_load_index(ctx, &load->src, index->idx.node, &instr->loc))) - return false; + return NULL; hlsl_block_add_instr(block, &load->node); hlsl_block_add_store_index(ctx, block, &row_deref, c, &load->node, 0, &instr->loc); } - hlsl_block_add_simple_load(ctx, block, var, &instr->loc); - } - else - { - hlsl_block_add_load_index(ctx, block, &var_deref, index->idx.node, &instr->loc); + return hlsl_block_add_simple_load(ctx, block, var, &instr->loc); } - return true; + + return hlsl_block_add_load_index(ctx, block, &var_deref, index->idx.node, &instr->loc); } /* Lower casts from vec1 to vecN to swizzles. */ -static bool lower_broadcasts(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) +static struct hlsl_ir_node *lower_broadcasts(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) { const struct hlsl_type *src_type, *dst_type; struct hlsl_type *dst_scalar_type; struct hlsl_ir_expr *cast; if (instr->type != HLSL_IR_EXPR) - return false; + return NULL; cast = hlsl_ir_expr(instr); if (cast->op != HLSL_OP1_CAST) - return false; + return NULL; src_type = cast->operands[0].node->data_type; dst_type = cast->node.data_type; @@ -1581,17 +1581,17 @@ static bool lower_broadcasts(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, s new_cast = hlsl_block_add_cast(ctx, block, cast->operands[0].node, dst_scalar_type, &cast->node.loc); if (dst_type->e.numeric.dimx != 1) - hlsl_block_add_swizzle(ctx, block, HLSL_SWIZZLE(X, X, X, X), + return hlsl_block_add_swizzle(ctx, block, HLSL_SWIZZLE(X, X, X, X), dst_type->e.numeric.dimx, new_cast, &cast->node.loc); - return true; + return new_cast; } - return false; + return NULL; } /* Lowers loads from TGSMs to resource loads. */ -static bool lower_tgsm_loads(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) +static struct hlsl_ir_node *lower_tgsm_loads(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) { struct hlsl_resource_load_params params = {.type = HLSL_RESOURCE_LOAD}; const struct vkd3d_shader_location *loc = &instr->loc; @@ -1599,29 +1599,28 @@ static bool lower_tgsm_loads(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, s struct hlsl_deref *deref; if (instr->type != HLSL_IR_LOAD || !hlsl_is_numeric_type(instr->data_type)) - return false; + return NULL; load = hlsl_ir_load(instr); deref = &load->src; if (!deref->var->is_tgsm) - return false; + return NULL; if (deref->path_len) { hlsl_fixme(ctx, &instr->loc, "Load from indexed TGSM."); - return false; + return NULL; } params.resource = hlsl_block_add_simple_load(ctx, block, deref->var, loc); params.format = instr->data_type; params.coords = hlsl_block_add_uint_constant(ctx, block, 0, &instr->loc); - hlsl_block_add_resource_load(ctx, block, ¶ms, loc); - - return true; + return hlsl_block_add_resource_load(ctx, block, ¶ms, loc); } /* Lowers stores to TGSMs to resource stores. */ -static bool lower_tgsm_stores(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) +static struct hlsl_ir_node *lower_tgsm_stores(struct hlsl_ctx *ctx, + struct hlsl_ir_node *instr, struct hlsl_block *block) { struct hlsl_ir_store *store; struct hlsl_ir_node *coords; @@ -1629,26 +1628,24 @@ static bool lower_tgsm_stores(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_deref *deref; if (instr->type != HLSL_IR_STORE) - return false; + return NULL; store = hlsl_ir_store(instr); deref = &store->lhs; if (!deref->var->is_tgsm) - return false; + return NULL; if (deref->path_len) { hlsl_fixme(ctx, &instr->loc, "Store to indexed TGSM."); - return false; + return NULL; } hlsl_init_simple_deref_from_var(&res_deref, deref->var); coords = hlsl_block_add_uint_constant(ctx, block, 0, &instr->loc); - hlsl_block_add_resource_store(ctx, block, HLSL_RESOURCE_STORE, &res_deref, + return hlsl_block_add_resource_store(ctx, block, HLSL_RESOURCE_STORE, &res_deref, coords, store->rhs.node, store->writemask, &instr->loc); - - return true; } /* Allocate a unique, ordered index to each instruction, which will be used for @@ -3567,7 +3564,8 @@ static bool validate_dereferences(struct hlsl_ctx *ctx, struct hlsl_ir_node *ins return false; } -static bool fold_redundant_casts(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) +static struct hlsl_ir_node *fold_redundant_casts(struct hlsl_ctx *ctx, + struct hlsl_ir_node *instr, struct hlsl_block *block) { if (instr->type == HLSL_IR_EXPR) { @@ -3576,20 +3574,17 @@ static bool fold_redundant_casts(struct hlsl_ctx *ctx, struct hlsl_ir_node *inst const struct hlsl_type *src_type; if (expr->op != HLSL_OP1_CAST) - return false; + return NULL; src_type = expr->operands[0].node->data_type; if (hlsl_types_are_equal(src_type, dst_type) || (src_type->e.numeric.type == dst_type->e.numeric.type && hlsl_is_vec1(src_type) && hlsl_is_vec1(dst_type))) - { - hlsl_replace_node(&expr->node, expr->operands[0].node); - return true; - } + return expr->operands[0].node; } - return false; + return NULL; } /* Copy an element of a complex variable. Helper for @@ -3824,17 +3819,18 @@ static bool split_matrix_copies(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr return true; } -static bool lower_narrowing_casts(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) +static struct hlsl_ir_node *lower_narrowing_casts(struct hlsl_ctx *ctx, + struct hlsl_ir_node *instr, struct hlsl_block *block) { const struct hlsl_type *src_type, *dst_type; struct hlsl_type *dst_vector_type; struct hlsl_ir_expr *cast; if (instr->type != HLSL_IR_EXPR) - return false; + return NULL; cast = hlsl_ir_expr(instr); if (cast->op != HLSL_OP1_CAST) - return false; + return NULL; src_type = cast->operands[0].node->data_type; dst_type = cast->node.data_type; @@ -3847,65 +3843,58 @@ static bool lower_narrowing_casts(struct hlsl_ctx *ctx, struct hlsl_ir_node *ins /* We need to preserve the cast since it might be doing more than just * narrowing the vector. */ new_cast = hlsl_block_add_cast(ctx, block, cast->operands[0].node, dst_vector_type, &cast->node.loc); - hlsl_block_add_swizzle(ctx, block, HLSL_SWIZZLE(X, Y, Z, W), + return hlsl_block_add_swizzle(ctx, block, HLSL_SWIZZLE(X, Y, Z, W), dst_type->e.numeric.dimx, new_cast, &cast->node.loc); - return true; } - return false; + return NULL; } -static bool fold_swizzle_chains(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) +static struct hlsl_ir_node *fold_swizzle_chains(struct hlsl_ctx *ctx, + struct hlsl_ir_node *instr, struct hlsl_block *block) { struct hlsl_ir_swizzle *swizzle; struct hlsl_ir_node *next_instr; if (instr->type != HLSL_IR_SWIZZLE) - return false; + return NULL; swizzle = hlsl_ir_swizzle(instr); next_instr = swizzle->val.node; if (next_instr->type == HLSL_IR_SWIZZLE) { - struct hlsl_ir_node *new_swizzle; uint32_t combined_swizzle; combined_swizzle = hlsl_combine_swizzles(hlsl_ir_swizzle(next_instr)->u.vector, swizzle->u.vector, instr->data_type->e.numeric.dimx); next_instr = hlsl_ir_swizzle(next_instr)->val.node; - if (!(new_swizzle = hlsl_new_swizzle(ctx, combined_swizzle, - instr->data_type->e.numeric.dimx, next_instr, &instr->loc))) - return false; - - list_add_before(&instr->entry, &new_swizzle->entry); - hlsl_replace_node(instr, new_swizzle); - return true; + return hlsl_block_add_swizzle(ctx, block, combined_swizzle, + instr->data_type->e.numeric.dimx, next_instr, &instr->loc); } - return false; + return NULL; } -static bool remove_trivial_swizzles(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) +static struct hlsl_ir_node *fold_trivial_swizzles(struct hlsl_ctx *ctx, + struct hlsl_ir_node *instr, struct hlsl_block *block) { struct hlsl_ir_swizzle *swizzle; unsigned int i; if (instr->type != HLSL_IR_SWIZZLE) - return false; + return NULL; swizzle = hlsl_ir_swizzle(instr); if (instr->data_type->e.numeric.dimx != swizzle->val.node->data_type->e.numeric.dimx) - return false; + return NULL; for (i = 0; i < instr->data_type->e.numeric.dimx; ++i) if (hlsl_swizzle_get_component(swizzle->u.vector, i) != i) - return false; - - hlsl_replace_node(instr, swizzle->val.node); + return NULL; - return true; + return swizzle->val.node; } static bool remove_trivial_conditional_branches(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) @@ -4028,7 +4017,8 @@ static bool normalize_switch_cases(struct hlsl_ctx *ctx, struct hlsl_ir_node *in return true; } -static bool lower_nonconstant_vector_derefs(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) +static struct hlsl_ir_node *lower_nonconstant_vector_derefs(struct hlsl_ctx *ctx, + struct hlsl_ir_node *instr, struct hlsl_block *block) { struct hlsl_ir_node *idx; struct hlsl_deref *deref; @@ -4036,13 +4026,13 @@ static bool lower_nonconstant_vector_derefs(struct hlsl_ctx *ctx, struct hlsl_ir unsigned int i; if (instr->type != HLSL_IR_LOAD) - return false; + return NULL; deref = &hlsl_ir_load(instr)->src; VKD3D_ASSERT(deref->var); if (deref->path_len == 0) - return false; + return NULL; type = deref->var->data_type; for (i = 0; i < deref->path_len - 1; ++i) @@ -4059,7 +4049,7 @@ static bool lower_nonconstant_vector_derefs(struct hlsl_ctx *ctx, struct hlsl_ir enum hlsl_ir_expr_op op; if (!(vector_load = hlsl_new_load_parent(ctx, deref, &instr->loc))) - return false; + return NULL; hlsl_block_add_instr(block, &vector_load->node); swizzle = hlsl_block_add_swizzle(ctx, block, HLSL_SWIZZLE(X, X, X, X), width, idx, &instr->loc); @@ -4069,7 +4059,7 @@ static bool lower_nonconstant_vector_derefs(struct hlsl_ctx *ctx, struct hlsl_ir value.u[2].u = 2; value.u[3].u = 3; if (!(c = hlsl_new_constant(ctx, hlsl_get_vector_type(ctx, HLSL_TYPE_UINT, width), &value, &instr->loc))) - return false; + return NULL; hlsl_block_add_instr(block, c); operands[0] = swizzle; @@ -4086,14 +4076,14 @@ static bool lower_nonconstant_vector_derefs(struct hlsl_ctx *ctx, struct hlsl_ir * LOGIC_OR + LOGIC_AND. */ operands[0] = &vector_load->node; operands[1] = eq; - hlsl_block_add_expr(ctx, block, op, operands, instr->data_type, &instr->loc); - return true; + return hlsl_block_add_expr(ctx, block, op, operands, instr->data_type, &instr->loc); } - return false; + return NULL; } -static bool validate_nonconstant_vector_store_derefs(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) +static struct hlsl_ir_node *validate_nonconstant_vector_store_derefs(struct hlsl_ctx *ctx, + struct hlsl_ir_node *instr, struct hlsl_block *block) { struct hlsl_ir_node *idx; struct hlsl_deref *deref; @@ -4101,13 +4091,13 @@ static bool validate_nonconstant_vector_store_derefs(struct hlsl_ctx *ctx, struc unsigned int i; if (instr->type != HLSL_IR_STORE) - return false; + return NULL; deref = &hlsl_ir_store(instr)->lhs; VKD3D_ASSERT(deref->var); if (deref->path_len == 0) - return false; + return NULL; type = deref->var->data_type; for (i = 0; i < deref->path_len - 1; ++i) @@ -4122,7 +4112,7 @@ static bool validate_nonconstant_vector_store_derefs(struct hlsl_ctx *ctx, struc hlsl_fixme(ctx, &instr->loc, "Non-constant vector addressing on store. Unrolling may be missing."); } - return false; + return NULL; } static bool deref_supports_sm1_indirect_addressing(struct hlsl_ctx *ctx, const struct hlsl_deref *deref) @@ -4136,8 +4126,8 @@ static bool deref_supports_sm1_indirect_addressing(struct hlsl_ctx *ctx, const s * This is achieved through a synthetic variable. The non-constant index is compared for equality * with every possible value it can have within the array bounds, and the ternary operator is used * to update the value of the synthetic var when the equality check passes. */ -static bool lower_nonconstant_array_loads(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, - struct hlsl_block *block) +static struct hlsl_ir_node *lower_nonconstant_array_loads(struct hlsl_ctx *ctx, + struct hlsl_ir_node *instr, struct hlsl_block *block) { struct hlsl_constant_value zero_value = {0}; struct hlsl_ir_node *cut_index, *zero; @@ -4149,15 +4139,15 @@ static bool lower_nonconstant_array_loads(struct hlsl_ctx *ctx, struct hlsl_ir_n bool row_major; if (instr->type != HLSL_IR_LOAD) - return false; + return NULL; load = hlsl_ir_load(instr); deref = &load->src; if (deref->path_len == 0) - return false; + return NULL; if (deref_supports_sm1_indirect_addressing(ctx, deref)) - return false; + return NULL; for (i = deref->path_len - 1; ; --i) { @@ -4168,7 +4158,7 @@ static bool lower_nonconstant_array_loads(struct hlsl_ctx *ctx, struct hlsl_ir_n } if (i == 0) - return false; + return NULL; } cut_index = deref->path[i_cut].node; @@ -4180,10 +4170,10 @@ static bool lower_nonconstant_array_loads(struct hlsl_ctx *ctx, struct hlsl_ir_n VKD3D_ASSERT(cut_type->class == HLSL_CLASS_ARRAY || row_major); if (!(var = hlsl_new_synthetic_var(ctx, row_major ? "row_major-load" : "array-load", instr->data_type, &instr->loc))) - return false; + return NULL; if (!(zero = hlsl_new_constant(ctx, instr->data_type, &zero_value, &instr->loc))) - return false; + return NULL; hlsl_block_add_instr(block, zero); hlsl_block_add_simple_store(ctx, block, var, zero); @@ -4209,7 +4199,7 @@ static bool lower_nonconstant_array_loads(struct hlsl_ctx *ctx, struct hlsl_ir_n var_load = hlsl_block_add_simple_load(ctx, block, var, &cut_index->loc); if (!hlsl_copy_deref(ctx, &deref_copy, deref)) - return false; + return NULL; hlsl_src_remove(&deref_copy.path[i_cut]); hlsl_src_from_node(&deref_copy.path[i_cut], const_i); specific_load = hlsl_block_add_load_index(ctx, block, &deref_copy, NULL, &cut_index->loc); @@ -4223,8 +4213,7 @@ static bool lower_nonconstant_array_loads(struct hlsl_ctx *ctx, struct hlsl_ir_n hlsl_block_add_simple_store(ctx, block, var, ternary); } - hlsl_block_add_simple_load(ctx, block, var, &instr->loc); - return true; + return hlsl_block_add_simple_load(ctx, block, var, &instr->loc); } static struct hlsl_type *clone_texture_array_as_combined_sampler_array(struct hlsl_ctx *ctx, struct hlsl_type *type) @@ -4495,31 +4484,30 @@ static bool sort_synthetic_separated_samplers_first(struct hlsl_ctx *ctx) } /* Turn CAST to int or uint into TRUNC + REINTERPRET */ -static bool lower_casts_to_int(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) +static struct hlsl_ir_node *lower_casts_to_int(struct hlsl_ctx *ctx, + struct hlsl_ir_node *instr, struct hlsl_block *block) { struct hlsl_ir_node *operands[HLSL_MAX_OPERANDS] = { 0 }; struct hlsl_ir_node *arg, *trunc; struct hlsl_ir_expr *expr; if (instr->type != HLSL_IR_EXPR) - return false; + return NULL; expr = hlsl_ir_expr(instr); if (expr->op != HLSL_OP1_CAST) - return false; + return NULL; arg = expr->operands[0].node; if (!hlsl_type_is_integer(instr->data_type) || instr->data_type->e.numeric.type == HLSL_TYPE_BOOL) - return false; + return NULL; if (!hlsl_type_is_floating_point(arg->data_type)) - return false; + return NULL; trunc = hlsl_block_add_unary_expr(ctx, block, HLSL_OP1_TRUNC, arg, &instr->loc); memset(operands, 0, sizeof(operands)); operands[0] = trunc; - hlsl_block_add_expr(ctx, block, HLSL_OP1_REINTERPRET, operands, instr->data_type, &instr->loc); - - return true; + return hlsl_block_add_expr(ctx, block, HLSL_OP1_REINTERPRET, operands, instr->data_type, &instr->loc); } /* Turn TRUNC into: @@ -4533,16 +4521,16 @@ static bool lower_casts_to_int(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, * where the comparisons in the extra term are performed using CMP or SLT * depending on whether this is a pixel or vertex shader, respectively. */ -static bool lower_trunc(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) +static struct hlsl_ir_node *lower_trunc(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) { struct hlsl_ir_node *arg, *res; struct hlsl_ir_expr *expr; if (instr->type != HLSL_IR_EXPR) - return false; + return NULL; expr = hlsl_ir_expr(instr); if (expr->op != HLSL_OP1_TRUNC) - return false; + return NULL; arg = expr->operands[0].node; @@ -4553,7 +4541,7 @@ static bool lower_trunc(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct memset(&zero_value, 0, sizeof(zero_value)); if (!(zero = hlsl_new_constant(ctx, arg->data_type, &zero_value, &instr->loc))) - return false; + return NULL; hlsl_block_add_instr(block, zero); one_value.u[0].f = 1.0; @@ -4561,22 +4549,22 @@ static bool lower_trunc(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct one_value.u[2].f = 1.0; one_value.u[3].f = 1.0; if (!(one = hlsl_new_constant(ctx, arg->data_type, &one_value, &instr->loc))) - return false; + return NULL; hlsl_block_add_instr(block, one); fract = hlsl_block_add_unary_expr(ctx, block, HLSL_OP1_FRACT, arg, &instr->loc); neg_fract = hlsl_block_add_unary_expr(ctx, block, HLSL_OP1_NEG, fract, &instr->loc); if (!(has_fract = hlsl_new_ternary_expr(ctx, HLSL_OP3_CMP, neg_fract, zero, one))) - return false; + return NULL; hlsl_block_add_instr(block, has_fract); if (!(extra = hlsl_new_ternary_expr(ctx, HLSL_OP3_CMP, arg, zero, has_fract))) - return false; + return NULL; hlsl_block_add_instr(block, extra); floor = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_ADD, arg, neg_fract); - res = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_ADD, floor, extra); + return hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_ADD, floor, extra); } else { @@ -4590,11 +4578,10 @@ static bool lower_trunc(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct floor = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_ADD, arg, neg_fract); if (!(res = hlsl_new_ternary_expr(ctx, HLSL_OP3_MAD, is_neg, has_fract, floor))) - return false; + return NULL; hlsl_block_add_instr(block, res); + return res; } - - return true; } /* Lower modulus using: @@ -4602,7 +4589,8 @@ static bool lower_trunc(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct * mod(x, y) = x - trunc(x / y) * y; * */ -static bool lower_int_modulus_sm1(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) +static struct hlsl_ir_node *lower_int_modulus_sm1(struct hlsl_ctx *ctx, + struct hlsl_ir_node *instr, struct hlsl_block *block) { struct hlsl_ir_node *div, *trunc, *mul, *neg, *operands[2], *ret; struct hlsl_type *float_type; @@ -4610,15 +4598,15 @@ static bool lower_int_modulus_sm1(struct hlsl_ctx *ctx, struct hlsl_ir_node *ins bool is_float; if (instr->type != HLSL_IR_EXPR) - return false; + return NULL; expr = hlsl_ir_expr(instr); if (expr->op != HLSL_OP2_MOD) - return false; + return NULL; is_float = instr->data_type->e.numeric.type == HLSL_TYPE_FLOAT || instr->data_type->e.numeric.type == HLSL_TYPE_HALF; if (is_float) - return false; + return NULL; float_type = hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, instr->data_type->e.numeric.dimx); for (unsigned int i = 0; i < 2; ++i) @@ -4631,13 +4619,11 @@ static bool lower_int_modulus_sm1(struct hlsl_ctx *ctx, struct hlsl_ir_node *ins mul = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_MUL, trunc, operands[1]); neg = hlsl_block_add_unary_expr(ctx, block, HLSL_OP1_NEG, mul, &instr->loc); ret = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_ADD, operands[0], neg); - hlsl_block_add_cast(ctx, block, ret, instr->data_type, &instr->loc); - - return true; + return hlsl_block_add_cast(ctx, block, ret, instr->data_type, &instr->loc); } /* Lower DIV to RCP + MUL. */ -static bool lower_division(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) +static struct hlsl_ir_node *lower_division(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) { struct hlsl_ir_node *rcp, *ret, *operands[2]; struct hlsl_type *float_type; @@ -4645,10 +4631,10 @@ static bool lower_division(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, str bool is_float; if (instr->type != HLSL_IR_EXPR) - return false; + return NULL; expr = hlsl_ir_expr(instr); if (expr->op != HLSL_OP2_DIV) - return false; + return NULL; is_float = instr->data_type->e.numeric.type == HLSL_TYPE_FLOAT || instr->data_type->e.numeric.type == HLSL_TYPE_HALF; @@ -4665,42 +4651,40 @@ static bool lower_division(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, str ret = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_MUL, operands[0], rcp); if (!is_float) ret = hlsl_block_add_cast(ctx, block, ret, instr->data_type, &instr->loc); - - return true; + return ret; } /* Lower SQRT to RSQ + RCP. */ -static bool lower_sqrt(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) +static struct hlsl_ir_node *lower_sqrt(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) { struct hlsl_ir_expr *expr; struct hlsl_ir_node *rsq; if (instr->type != HLSL_IR_EXPR) - return false; + return NULL; expr = hlsl_ir_expr(instr); if (expr->op != HLSL_OP1_SQRT) - return false; + return NULL; rsq = hlsl_block_add_unary_expr(ctx, block, HLSL_OP1_RSQ, expr->operands[0].node, &instr->loc); - hlsl_block_add_unary_expr(ctx, block, HLSL_OP1_RCP, rsq, &instr->loc); - return true; + return hlsl_block_add_unary_expr(ctx, block, HLSL_OP1_RCP, rsq, &instr->loc); } /* Lower DP2 to MUL + ADD */ -static bool lower_dot(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) +static struct hlsl_ir_node *lower_dot(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) { struct hlsl_ir_node *arg1, *arg2, *mul, *add_x, *add_y; struct hlsl_ir_expr *expr; if (instr->type != HLSL_IR_EXPR) - return false; + return NULL; expr = hlsl_ir_expr(instr); arg1 = expr->operands[0].node; arg2 = expr->operands[1].node; if (expr->op != HLSL_OP2_DOT) - return false; + return NULL; if (arg1->data_type->e.numeric.dimx != 2) - return false; + return NULL; if (ctx->profile->type == VKD3D_SHADER_TYPE_PIXEL) { @@ -4710,7 +4694,7 @@ static bool lower_dot(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct h operands[1] = arg2; operands[2] = hlsl_block_add_float_constant(ctx, block, 0.0f, &expr->node.loc); - hlsl_block_add_expr(ctx, block, HLSL_OP3_DP2ADD, operands, instr->data_type, &expr->node.loc); + return hlsl_block_add_expr(ctx, block, HLSL_OP3_DP2ADD, operands, instr->data_type, &expr->node.loc); } else { @@ -4720,32 +4704,29 @@ static bool lower_dot(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct h instr->data_type->e.numeric.dimx, mul, &expr->node.loc); add_y = hlsl_block_add_swizzle(ctx, block, HLSL_SWIZZLE(Y, Y, Y, Y), instr->data_type->e.numeric.dimx, mul, &expr->node.loc); - hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_ADD, add_x, add_y); + return hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_ADD, add_x, add_y); } - - return true; } /* Lower ABS to MAX */ -static bool lower_abs(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) +static struct hlsl_ir_node *lower_abs(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) { struct hlsl_ir_node *arg, *neg; struct hlsl_ir_expr *expr; if (instr->type != HLSL_IR_EXPR) - return false; + return NULL; expr = hlsl_ir_expr(instr); arg = expr->operands[0].node; if (expr->op != HLSL_OP1_ABS) - return false; + return NULL; neg = hlsl_block_add_unary_expr(ctx, block, HLSL_OP1_NEG, arg, &instr->loc); - hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_MAX, neg, arg); - return true; + return hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_MAX, neg, arg); } /* Lower ROUND using FRC, ROUND(x) -> ((x + 0.5) - FRC(x + 0.5)). */ -static bool lower_round(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) +static struct hlsl_ir_node *lower_round(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) { struct hlsl_ir_node *arg, *neg, *sum, *frc, *half; struct hlsl_type *type = instr->data_type; @@ -4754,69 +4735,66 @@ static bool lower_round(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct struct hlsl_ir_expr *expr; if (instr->type != HLSL_IR_EXPR) - return false; + return NULL; expr = hlsl_ir_expr(instr); arg = expr->operands[0].node; if (expr->op != HLSL_OP1_ROUND) - return false; + return NULL; component_count = hlsl_type_component_count(type); for (i = 0; i < component_count; ++i) half_value.u[i].f = 0.5f; if (!(half = hlsl_new_constant(ctx, type, &half_value, &expr->node.loc))) - return false; + return NULL; hlsl_block_add_instr(block, half); sum = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_ADD, arg, half); frc = hlsl_block_add_unary_expr(ctx, block, HLSL_OP1_FRACT, sum, &instr->loc); neg = hlsl_block_add_unary_expr(ctx, block, HLSL_OP1_NEG, frc, &instr->loc); - hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_ADD, sum, neg); - return true; + return hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_ADD, sum, neg); } /* Lower CEIL to FRC */ -static bool lower_ceil(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) +static struct hlsl_ir_node *lower_ceil(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) { struct hlsl_ir_node *arg, *neg, *frc; struct hlsl_ir_expr *expr; if (instr->type != HLSL_IR_EXPR) - return false; + return NULL; expr = hlsl_ir_expr(instr); arg = expr->operands[0].node; if (expr->op != HLSL_OP1_CEIL) - return false; + return NULL; neg = hlsl_block_add_unary_expr(ctx, block, HLSL_OP1_NEG, arg, &instr->loc); frc = hlsl_block_add_unary_expr(ctx, block, HLSL_OP1_FRACT, neg, &instr->loc); - hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_ADD, frc, arg); - return true; + return hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_ADD, frc, arg); } /* Lower FLOOR to FRC */ -static bool lower_floor(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) +static struct hlsl_ir_node *lower_floor(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) { struct hlsl_ir_node *arg, *neg, *frc; struct hlsl_ir_expr *expr; if (instr->type != HLSL_IR_EXPR) - return false; + return NULL; expr = hlsl_ir_expr(instr); arg = expr->operands[0].node; if (expr->op != HLSL_OP1_FLOOR) - return false; + return NULL; frc = hlsl_block_add_unary_expr(ctx, block, HLSL_OP1_FRACT, arg, &instr->loc); neg = hlsl_block_add_unary_expr(ctx, block, HLSL_OP1_NEG, frc, &instr->loc); - hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_ADD, neg, arg); - return true; + return hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_ADD, neg, arg); } /* Lower SIN/COS to SINCOS for SM1. */ -static bool lower_trig(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) +static struct hlsl_ir_node *lower_trig(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) { struct hlsl_ir_node *arg, *half, *two_pi, *reciprocal_two_pi, *neg_pi; struct hlsl_constant_value half_value, two_pi_value, reciprocal_two_pi_value, neg_pi_value; @@ -4828,7 +4806,7 @@ static bool lower_trig(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct int i; if (instr->type != HLSL_IR_EXPR) - return false; + return NULL; expr = hlsl_ir_expr(instr); if (expr->op == HLSL_OP1_SIN) @@ -4836,7 +4814,7 @@ static bool lower_trig(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct else if (expr->op == HLSL_OP1_COS) op = HLSL_OP1_COS_REDUCED; else - return false; + return NULL; arg = expr->operands[0].node; type = arg->data_type; @@ -4854,23 +4832,23 @@ static bool lower_trig(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct || !(two_pi = hlsl_new_constant(ctx, type, &two_pi_value, &instr->loc)) || !(reciprocal_two_pi = hlsl_new_constant(ctx, type, &reciprocal_two_pi_value, &instr->loc)) || !(neg_pi = hlsl_new_constant(ctx, type, &neg_pi_value, &instr->loc))) - return false; + return NULL; hlsl_block_add_instr(block, half); hlsl_block_add_instr(block, two_pi); hlsl_block_add_instr(block, reciprocal_two_pi); hlsl_block_add_instr(block, neg_pi); if (!(mad = hlsl_new_ternary_expr(ctx, HLSL_OP3_MAD, arg, reciprocal_two_pi, half))) - return false; + return NULL; hlsl_block_add_instr(block, mad); frc = hlsl_block_add_unary_expr(ctx, block, HLSL_OP1_FRACT, mad, &instr->loc); if (!(reduced = hlsl_new_ternary_expr(ctx, HLSL_OP3_MAD, frc, two_pi, neg_pi))) - return false; + return NULL; hlsl_block_add_instr(block, reduced); if (type->e.numeric.dimx == 1) { - sincos = hlsl_block_add_unary_expr(ctx, block, op, reduced, &instr->loc); + return hlsl_block_add_unary_expr(ctx, block, op, reduced, &instr->loc); } else { @@ -4886,7 +4864,7 @@ static bool lower_trig(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct } if (!(var = hlsl_new_synthetic_var(ctx, "sincos", type, &instr->loc))) - return false; + return NULL; hlsl_init_simple_deref_from_var(&var_deref, var); for (i = 0; i < type->e.numeric.dimx; ++i) @@ -4895,13 +4873,11 @@ static bool lower_trig(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block_add_store_component(ctx, block, &var_deref, i, sincos); } - hlsl_block_add_load_index(ctx, block, &var_deref, NULL, &instr->loc); + return hlsl_block_add_load_index(ctx, block, &var_deref, NULL, &instr->loc); } - - return true; } -static bool lower_logic_not(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) +static struct hlsl_ir_node *lower_logic_not(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) { struct hlsl_ir_node *arg, *arg_cast, *neg, *one, *sub; struct hlsl_ir_node *operands[HLSL_MAX_OPERANDS]; @@ -4910,10 +4886,10 @@ static bool lower_logic_not(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, st struct hlsl_ir_expr *expr; if (instr->type != HLSL_IR_EXPR) - return false; + return NULL; expr = hlsl_ir_expr(instr); if (expr->op != HLSL_OP1_LOGIC_NOT) - return false; + return NULL; arg = expr->operands[0].node; float_type = hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, arg->data_type->e.numeric.dimx); @@ -4930,19 +4906,18 @@ static bool lower_logic_not(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, st one_value.u[2].f = 1.0; one_value.u[3].f = 1.0; if (!(one = hlsl_new_constant(ctx, float_type, &one_value, &instr->loc))) - return false; + return NULL; hlsl_block_add_instr(block, one); sub = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_ADD, one, neg); memset(operands, 0, sizeof(operands)); operands[0] = sub; - hlsl_block_add_expr(ctx, block, HLSL_OP1_REINTERPRET, operands, instr->data_type, &instr->loc); - return true; + return hlsl_block_add_expr(ctx, block, HLSL_OP1_REINTERPRET, operands, instr->data_type, &instr->loc); } /* Lower TERNARY to CMP for SM1. */ -static bool lower_ternary(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) +static struct hlsl_ir_node *lower_ternary(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) { struct hlsl_ir_node *cond, *first, *second, *float_cond, *neg; struct hlsl_ir_node *operands[HLSL_MAX_OPERANDS] = {0}; @@ -4950,11 +4925,11 @@ static bool lower_ternary(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, stru struct hlsl_type *type; if (instr->type != HLSL_IR_EXPR) - return false; + return NULL; expr = hlsl_ir_expr(instr); if (expr->op != HLSL_OP3_TERNARY) - return false; + return NULL; cond = expr->operands[0].node; first = expr->operands[1].node; @@ -4963,7 +4938,7 @@ static bool lower_ternary(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, stru if (cond->data_type->class > HLSL_CLASS_VECTOR || instr->data_type->class > HLSL_CLASS_VECTOR) { hlsl_fixme(ctx, &instr->loc, "Lower ternary of type other than scalar or vector."); - return false; + return NULL; } VKD3D_ASSERT(cond->data_type->e.numeric.type == HLSL_TYPE_BOOL); @@ -4977,8 +4952,7 @@ static bool lower_ternary(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, stru operands[0] = neg; operands[1] = second; operands[2] = first; - hlsl_block_add_expr(ctx, block, HLSL_OP3_CMP, operands, first->data_type, &instr->loc); - return true; + return hlsl_block_add_expr(ctx, block, HLSL_OP3_CMP, operands, first->data_type, &instr->loc); } static bool lower_resource_load_bias(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) @@ -5026,7 +5000,7 @@ static bool lower_resource_load_bias(struct hlsl_ctx *ctx, struct hlsl_ir_node * return true; } -static bool lower_comparison_operators(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, +static struct hlsl_ir_node *lower_comparison_operators(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) { struct hlsl_ir_node *arg1, *arg1_cast, *arg2, *arg2_cast, *slt, *res; @@ -5036,10 +5010,10 @@ static bool lower_comparison_operators(struct hlsl_ctx *ctx, struct hlsl_ir_node bool negate = false; if (instr->type != HLSL_IR_EXPR) - return false; + return NULL; expr = hlsl_ir_expr(instr); if (!hlsl_is_comparison_op(expr->op)) - return false; + return NULL; arg1 = expr->operands[0].node; arg2 = expr->operands[1].node; @@ -5096,7 +5070,7 @@ static bool lower_comparison_operators(struct hlsl_ctx *ctx, struct hlsl_ir_node one_value.u[2].f = 1.0; one_value.u[3].f = 1.0; if (!(one = hlsl_new_constant(ctx, float_type, &one_value, &instr->loc))) - return false; + return NULL; hlsl_block_add_instr(block, one); slt_neg = hlsl_block_add_unary_expr(ctx, block, HLSL_OP1_NEG, slt, &instr->loc); @@ -5111,8 +5085,7 @@ static bool lower_comparison_operators(struct hlsl_ctx *ctx, struct hlsl_ir_node * and casts to BOOL have already been lowered to "!= 0". */ memset(operands, 0, sizeof(operands)); operands[0] = res; - hlsl_block_add_expr(ctx, block, HLSL_OP1_REINTERPRET, operands, instr->data_type, &instr->loc); - return true; + return hlsl_block_add_expr(ctx, block, HLSL_OP1_REINTERPRET, operands, instr->data_type, &instr->loc); } /* Intended to be used for SM1-SM3, lowers SLT instructions (only available in vertex shaders) to @@ -5123,7 +5096,7 @@ static bool lower_comparison_operators(struct hlsl_ctx *ctx, struct hlsl_ir_node * = ((x - y) >= 0) ? 0.0 : 1.0 * = CMP(x - y, 0.0, 1.0) */ -static bool lower_slt(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) +static struct hlsl_ir_node *lower_slt(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) { struct hlsl_ir_node *arg1, *arg2, *arg1_cast, *arg2_cast, *neg, *sub, *zero, *one, *cmp; struct hlsl_constant_value zero_value, one_value; @@ -5131,10 +5104,10 @@ static bool lower_slt(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct h struct hlsl_ir_expr *expr; if (instr->type != HLSL_IR_EXPR) - return false; + return NULL; expr = hlsl_ir_expr(instr); if (expr->op != HLSL_OP2_SLT) - return false; + return NULL; arg1 = expr->operands[0].node; arg2 = expr->operands[1].node; @@ -5147,7 +5120,7 @@ static bool lower_slt(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct h memset(&zero_value, 0, sizeof(zero_value)); if (!(zero = hlsl_new_constant(ctx, float_type, &zero_value, &instr->loc))) - return false; + return NULL; hlsl_block_add_instr(block, zero); one_value.u[0].f = 1.0; @@ -5155,14 +5128,13 @@ static bool lower_slt(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct h one_value.u[2].f = 1.0; one_value.u[3].f = 1.0; if (!(one = hlsl_new_constant(ctx, float_type, &one_value, &instr->loc))) - return false; + return NULL; hlsl_block_add_instr(block, one); if (!(cmp = hlsl_new_ternary_expr(ctx, HLSL_OP3_CMP, sub, zero, one))) - return false; + return NULL; hlsl_block_add_instr(block, cmp); - - return true; + return cmp; } /* Intended to be used for SM1-SM3, lowers CMP instructions (only available in pixel shaders) to @@ -5173,7 +5145,7 @@ static bool lower_slt(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct h * = z * ((x < 0) ? 1.0 : 0.0) + y * ((x < 0) ? 0.0 : 1.0) * = z * SLT(x, 0.0) + y * (1 - SLT(x, 0.0)) */ -static bool lower_cmp(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) +static struct hlsl_ir_node *lower_cmp(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) { struct hlsl_ir_node *args[3], *args_cast[3], *slt, *neg_slt, *sub, *zero, *one, *mul1, *mul2; struct hlsl_constant_value zero_value, one_value; @@ -5182,10 +5154,10 @@ static bool lower_cmp(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct h unsigned int i; if (instr->type != HLSL_IR_EXPR) - return false; + return NULL; expr = hlsl_ir_expr(instr); if (expr->op != HLSL_OP3_CMP) - return false; + return NULL; float_type = hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, instr->data_type->e.numeric.dimx); @@ -5197,7 +5169,7 @@ static bool lower_cmp(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct h memset(&zero_value, 0, sizeof(zero_value)); if (!(zero = hlsl_new_constant(ctx, float_type, &zero_value, &instr->loc))) - return false; + return NULL; hlsl_block_add_instr(block, zero); one_value.u[0].f = 1.0; @@ -5205,7 +5177,7 @@ static bool lower_cmp(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct h one_value.u[2].f = 1.0; one_value.u[3].f = 1.0; if (!(one = hlsl_new_constant(ctx, float_type, &one_value, &instr->loc))) - return false; + return NULL; hlsl_block_add_instr(block, one); slt = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_SLT, args_cast[0], zero); @@ -5213,11 +5185,11 @@ static bool lower_cmp(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct h neg_slt = hlsl_block_add_unary_expr(ctx, block, HLSL_OP1_NEG, slt, &instr->loc); sub = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_ADD, one, neg_slt); mul2 = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_MUL, args_cast[1], sub); - hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_ADD, mul1, mul2); - return true; + return hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_ADD, mul1, mul2); } -static bool lower_casts_to_bool(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) +static struct hlsl_ir_node *lower_casts_to_bool(struct hlsl_ctx *ctx, + struct hlsl_ir_node *instr, struct hlsl_block *block) { struct hlsl_type *type = instr->data_type, *arg_type; static const struct hlsl_constant_value zero_value; @@ -5225,28 +5197,27 @@ static bool lower_casts_to_bool(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr struct hlsl_ir_expr *expr; if (instr->type != HLSL_IR_EXPR) - return false; + return NULL; expr = hlsl_ir_expr(instr); if (expr->op != HLSL_OP1_CAST) - return false; + return NULL; arg_type = expr->operands[0].node->data_type; if (type->class > HLSL_CLASS_VECTOR || arg_type->class > HLSL_CLASS_VECTOR) - return false; + return NULL; if (type->e.numeric.type != HLSL_TYPE_BOOL) - return false; + return NULL; /* Narrowing casts should have already been lowered. */ VKD3D_ASSERT(type->e.numeric.dimx == arg_type->e.numeric.dimx); zero = hlsl_new_constant(ctx, arg_type, &zero_value, &instr->loc); if (!zero) - return false; + return NULL; hlsl_block_add_instr(block, zero); neq = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_NEQUAL, expr->operands[0].node, zero); neq->data_type = expr->node.data_type; - - return true; + return neq; } struct hlsl_ir_node *hlsl_add_conditional(struct hlsl_ctx *ctx, struct hlsl_block *instrs, @@ -5270,7 +5241,8 @@ struct hlsl_ir_node *hlsl_add_conditional(struct hlsl_ctx *ctx, struct hlsl_bloc return hlsl_block_add_expr(ctx, instrs, HLSL_OP3_TERNARY, operands, if_true->data_type, &condition->loc); } -static bool lower_int_division_sm4(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) +static struct hlsl_ir_node *lower_int_division_sm4(struct hlsl_ctx *ctx, + struct hlsl_ir_node *instr, struct hlsl_block *block) { struct hlsl_ir_node *arg1, *arg2, *xor, *and, *abs1, *abs2, *div, *neg, *cast1, *cast2, *cast3, *high_bit; struct hlsl_type *type = instr->data_type, *utype; @@ -5279,16 +5251,16 @@ static bool lower_int_division_sm4(struct hlsl_ctx *ctx, struct hlsl_ir_node *in unsigned int i; if (instr->type != HLSL_IR_EXPR) - return false; + return NULL; expr = hlsl_ir_expr(instr); arg1 = expr->operands[0].node; arg2 = expr->operands[1].node; if (expr->op != HLSL_OP2_DIV) - return false; + return NULL; if (type->class != HLSL_CLASS_SCALAR && type->class != HLSL_CLASS_VECTOR) - return false; + return NULL; if (type->e.numeric.type != HLSL_TYPE_INT) - return false; + return NULL; utype = hlsl_get_numeric_type(ctx, type->class, HLSL_TYPE_UINT, type->e.numeric.dimx, type->e.numeric.dimy); xor = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_BIT_XOR, arg1, arg2); @@ -5296,7 +5268,7 @@ static bool lower_int_division_sm4(struct hlsl_ctx *ctx, struct hlsl_ir_node *in for (i = 0; i < type->e.numeric.dimx; ++i) high_bit_value.u[i].u = 0x80000000; if (!(high_bit = hlsl_new_constant(ctx, type, &high_bit_value, &instr->loc))) - return false; + return NULL; hlsl_block_add_instr(block, high_bit); and = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_BIT_AND, xor, high_bit); @@ -5310,7 +5282,8 @@ static bool lower_int_division_sm4(struct hlsl_ctx *ctx, struct hlsl_ir_node *in return hlsl_add_conditional(ctx, block, and, neg, cast3); } -static bool lower_int_modulus_sm4(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) +static struct hlsl_ir_node *lower_int_modulus_sm4(struct hlsl_ctx *ctx, + struct hlsl_ir_node *instr, struct hlsl_block *block) { struct hlsl_ir_node *arg1, *arg2, *and, *abs1, *abs2, *div, *neg, *cast1, *cast2, *cast3, *high_bit; struct hlsl_type *type = instr->data_type, *utype; @@ -5319,22 +5292,22 @@ static bool lower_int_modulus_sm4(struct hlsl_ctx *ctx, struct hlsl_ir_node *ins unsigned int i; if (instr->type != HLSL_IR_EXPR) - return false; + return NULL; expr = hlsl_ir_expr(instr); arg1 = expr->operands[0].node; arg2 = expr->operands[1].node; if (expr->op != HLSL_OP2_MOD) - return false; + return NULL; if (type->class != HLSL_CLASS_SCALAR && type->class != HLSL_CLASS_VECTOR) - return false; + return NULL; if (type->e.numeric.type != HLSL_TYPE_INT) - return false; + return NULL; utype = hlsl_get_numeric_type(ctx, type->class, HLSL_TYPE_UINT, type->e.numeric.dimx, type->e.numeric.dimy); for (i = 0; i < type->e.numeric.dimx; ++i) high_bit_value.u[i].u = 0x80000000; if (!(high_bit = hlsl_new_constant(ctx, type, &high_bit_value, &instr->loc))) - return false; + return NULL; hlsl_block_add_instr(block, high_bit); and = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_BIT_AND, arg1, high_bit); @@ -5348,31 +5321,30 @@ static bool lower_int_modulus_sm4(struct hlsl_ctx *ctx, struct hlsl_ir_node *ins return hlsl_add_conditional(ctx, block, and, neg, cast3); } -static bool lower_int_abs(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) +static struct hlsl_ir_node *lower_int_abs(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) { struct hlsl_type *type = instr->data_type; struct hlsl_ir_node *arg, *neg; struct hlsl_ir_expr *expr; if (instr->type != HLSL_IR_EXPR) - return false; + return NULL; expr = hlsl_ir_expr(instr); if (expr->op != HLSL_OP1_ABS) - return false; + return NULL; if (type->class != HLSL_CLASS_SCALAR && type->class != HLSL_CLASS_VECTOR) - return false; + return NULL; if (type->e.numeric.type != HLSL_TYPE_INT) - return false; + return NULL; arg = expr->operands[0].node; neg = hlsl_block_add_unary_expr(ctx, block, HLSL_OP1_NEG, arg, &instr->loc); - hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_MAX, arg, neg); - return true; + return hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_MAX, arg, neg); } -static bool lower_int_dot(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) +static struct hlsl_ir_node *lower_int_dot(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) { struct hlsl_ir_node *arg1, *arg2, *mult, *comps[4] = {0}, *res; struct hlsl_type *type = instr->data_type; @@ -5381,11 +5353,11 @@ static bool lower_int_dot(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, stru bool is_bool; if (instr->type != HLSL_IR_EXPR) - return false; + return NULL; expr = hlsl_ir_expr(instr); if (expr->op != HLSL_OP2_DOT) - return false; + return NULL; if (hlsl_type_is_integer(type)) { @@ -5407,14 +5379,14 @@ static bool lower_int_dot(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, stru res = comps[0]; for (i = 1; i < dimx; ++i) res = hlsl_block_add_binary_expr(ctx, block, is_bool ? HLSL_OP2_LOGIC_OR : HLSL_OP2_ADD, res, comps[i]); - - return true; + return res; } - return false; + return NULL; } -static bool lower_float_modulus(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) +static struct hlsl_ir_node *lower_float_modulus(struct hlsl_ctx *ctx, + struct hlsl_ir_node *instr, struct hlsl_block *block) { struct hlsl_ir_node *arg1, *arg2, *mul1, *neg1, *ge, *neg2, *div, *mul2, *frc, *cond, *one; struct hlsl_type *type = instr->data_type, *btype; @@ -5423,16 +5395,16 @@ static bool lower_float_modulus(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr unsigned int i; if (instr->type != HLSL_IR_EXPR) - return false; + return NULL; expr = hlsl_ir_expr(instr); arg1 = expr->operands[0].node; arg2 = expr->operands[1].node; if (expr->op != HLSL_OP2_MOD) - return false; + return NULL; if (type->class != HLSL_CLASS_SCALAR && type->class != HLSL_CLASS_VECTOR) - return false; + return NULL; if (type->e.numeric.type != HLSL_TYPE_FLOAT) - return false; + return NULL; btype = hlsl_get_numeric_type(ctx, type->class, HLSL_TYPE_BOOL, type->e.numeric.dimx, type->e.numeric.dimy); mul1 = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_MUL, arg2, arg1); @@ -5447,14 +5419,13 @@ static bool lower_float_modulus(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr for (i = 0; i < type->e.numeric.dimx; ++i) one_value.u[i].f = 1.0f; if (!(one = hlsl_new_constant(ctx, type, &one_value, &instr->loc))) - return false; + return NULL; hlsl_block_add_instr(block, one); div = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_DIV, one, cond); mul2 = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_MUL, div, arg1); frc = hlsl_block_add_unary_expr(ctx, block, HLSL_OP1_FRACT, mul2, &instr->loc); - hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_MUL, frc, cond); - return true; + return hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_MUL, frc, cond); } static bool lower_discard_neg(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) @@ -6167,7 +6138,7 @@ static bool track_object_components_sampler_dim(struct hlsl_ctx *ctx, struct hls return false; } -static void register_deref_usage(struct hlsl_ctx *ctx, struct hlsl_deref *deref) +static void register_deref_usage(struct hlsl_ctx *ctx, const struct hlsl_deref *deref) { struct hlsl_ir_var *var = deref->var; enum hlsl_regset regset = hlsl_deref_get_regset(ctx, deref); @@ -6215,18 +6186,43 @@ static bool track_components_usage(struct hlsl_ctx *ctx, struct hlsl_ir_node *in } case HLSL_IR_RESOURCE_LOAD: - register_deref_usage(ctx, &hlsl_ir_resource_load(instr)->resource); - if (hlsl_ir_resource_load(instr)->sampler.var) - register_deref_usage(ctx, &hlsl_ir_resource_load(instr)->sampler); + { + const struct hlsl_ir_resource_load *load = hlsl_ir_resource_load(instr); + + register_deref_usage(ctx, &load->resource); + if (load->sampler.var) + register_deref_usage(ctx, &load->sampler); + + if (hlsl_deref_get_regset(ctx, &load->resource) == HLSL_REGSET_UAVS) + { + unsigned int index; + + hlsl_regset_index_from_deref(ctx, &load->resource, HLSL_REGSET_UAVS, &index); + load->resource.var->objects_usage[HLSL_REGSET_UAVS][index].uav_read = true; + } break; + } case HLSL_IR_RESOURCE_STORE: register_deref_usage(ctx, &hlsl_ir_resource_store(instr)->resource); break; case HLSL_IR_INTERLOCKED: - register_deref_usage(ctx, &hlsl_ir_interlocked(instr)->dst); + { + const struct hlsl_ir_interlocked *interlocked = hlsl_ir_interlocked(instr); + + register_deref_usage(ctx, &interlocked->dst); + + if (hlsl_deref_get_regset(ctx, &interlocked->dst) == HLSL_REGSET_UAVS) + { + unsigned int index; + + hlsl_regset_index_from_deref(ctx, &interlocked->dst, HLSL_REGSET_UAVS, &index); + interlocked->dst.var->objects_usage[HLSL_REGSET_UAVS][index].uav_read = true; + interlocked->dst.var->objects_usage[HLSL_REGSET_UAVS][index].uav_atomics = true; + } break; + } default: break; @@ -8234,7 +8230,7 @@ static void remove_unreachable_code(struct hlsl_ctx *ctx, struct hlsl_block *bod void hlsl_lower_index_loads(struct hlsl_ctx *ctx, struct hlsl_block *body) { - lower_ir(ctx, lower_index_loads, body); + replace_ir(ctx, lower_index_loads, body); } static enum hlsl_ir_expr_op invert_comparison_op(enum hlsl_ir_expr_op op) @@ -8537,27 +8533,27 @@ static void hlsl_run_folding_passes(struct hlsl_ctx *ctx, struct hlsl_block *bod { bool progress; - hlsl_transform_ir(ctx, fold_redundant_casts, body, NULL); + replace_ir(ctx, fold_redundant_casts, body); do { progress = simplify_exprs(ctx, body); progress |= hlsl_copy_propagation_execute(ctx, body); - progress |= hlsl_transform_ir(ctx, fold_swizzle_chains, body, NULL); - progress |= hlsl_transform_ir(ctx, remove_trivial_swizzles, body, NULL); + progress |= replace_ir(ctx, fold_swizzle_chains, body); + progress |= replace_ir(ctx, fold_trivial_swizzles, body); progress |= hlsl_transform_ir(ctx, remove_trivial_conditional_branches, body, NULL); } while (progress); - hlsl_transform_ir(ctx, fold_redundant_casts, body, NULL); + replace_ir(ctx, fold_redundant_casts, body); } void hlsl_run_const_passes(struct hlsl_ctx *ctx, struct hlsl_block *body) { bool progress; - lower_ir(ctx, lower_complex_casts, body); - lower_ir(ctx, lower_matrix_swizzles, body); + replace_ir(ctx, lower_complex_casts, body); + replace_ir(ctx, lower_matrix_swizzles, body); - lower_ir(ctx, lower_broadcasts, body); - while (hlsl_transform_ir(ctx, fold_redundant_casts, body, NULL)); + replace_ir(ctx, lower_broadcasts, body); + while (replace_ir(ctx, fold_redundant_casts, body)); do { progress = hlsl_transform_ir(ctx, split_array_copies, body, NULL); @@ -8566,16 +8562,16 @@ void hlsl_run_const_passes(struct hlsl_ctx *ctx, struct hlsl_block *body) while (progress); hlsl_transform_ir(ctx, split_matrix_copies, body, NULL); - lower_ir(ctx, lower_narrowing_casts, body); - lower_ir(ctx, lower_int_dot, body); + replace_ir(ctx, lower_narrowing_casts, body); + replace_ir(ctx, lower_int_dot, body); if (hlsl_version_ge(ctx, 4, 0)) { - lower_ir(ctx, lower_int_modulus_sm4, body); - lower_ir(ctx, lower_int_division_sm4, body); + replace_ir(ctx, lower_int_modulus_sm4, body); + replace_ir(ctx, lower_int_division_sm4, body); } - lower_ir(ctx, lower_int_abs, body); - lower_ir(ctx, lower_casts_to_bool, body); - lower_ir(ctx, lower_float_modulus, body); + replace_ir(ctx, lower_int_abs, body); + replace_ir(ctx, lower_casts_to_bool, body); + replace_ir(ctx, lower_float_modulus, body); hlsl_run_folding_passes(ctx, body); } @@ -10189,10 +10185,7 @@ static void sm1_generate_vsir(struct hlsl_ctx *ctx, const struct vkd3d_shader_co struct hlsl_ir_function_decl *func, struct list *semantic_vars, struct hlsl_block *body, uint64_t config_flags, struct vsir_program *program) { - struct hlsl_ir_var *var; struct hlsl_block block; - struct hlsl_reg *reg; - unsigned int *count; program->ssa_count = 0; program->temp_count = 0; @@ -10207,17 +10200,6 @@ static void sm1_generate_vsir(struct hlsl_ctx *ctx, const struct vkd3d_shader_co sm1_generate_vsir_block(ctx, body, program); - count = &program->flat_constant_count[VKD3D_SHADER_D3DBC_FLOAT_CONSTANT_REGISTER]; - LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry) - { - if (!var->is_uniform) - continue; - - if (!(reg = &var->regs[HLSL_REGSET_NUMERIC])->allocation_size) - continue; - - *count = max(*count, reg->id + reg->allocation_size); - } program->ssa_count = ctx->ssa_count; program->temp_count = ctx->temp_count; @@ -12785,9 +12767,9 @@ static void sm4_generate_vsir_add_dcl_sampler(struct hlsl_ctx *ctx, } } -static enum vkd3d_shader_resource_type sm4_generate_vsir_get_resource_type(const struct hlsl_type *type) +static enum vkd3d_shader_resource_type get_vsir_resource_type(enum hlsl_sampler_dim sampler_dim) { - switch (type->sampler_dim) + switch (sampler_dim) { case HLSL_SAMPLER_DIM_1D: return VKD3D_SHADER_RESOURCE_TEXTURE_1D; @@ -12816,7 +12798,7 @@ static enum vkd3d_shader_resource_type sm4_generate_vsir_get_resource_type(const } } -static enum vsir_data_type sm4_generate_vsir_get_format_type(const struct hlsl_type *type) +static enum vsir_data_type get_vsir_resource_data_type(const struct hlsl_type *type) { const struct hlsl_type *format = type->e.resource.format; @@ -12953,10 +12935,10 @@ static void sm4_generate_vsir_add_dcl_texture(struct hlsl_ctx *ctx, } else { - ins->declaration.semantic.resource_type = sm4_generate_vsir_get_resource_type(resource->component_type); + ins->declaration.semantic.resource_type = get_vsir_resource_type(resource->component_type->sampler_dim); for (unsigned int j = 0; j < 4; ++j) - ins->declaration.semantic.resource_data_type[j] = sm4_generate_vsir_get_format_type(component_type); + ins->declaration.semantic.resource_data_type[j] = get_vsir_resource_data_type(component_type); if (multisampled) ins->declaration.semantic.sample_count = component_type->sample_count; @@ -13108,6 +13090,140 @@ static void sm4_generate_vsir(struct hlsl_ctx *ctx, program->temp_count = ctx->temp_count; } +static void generate_vsir_descriptors_for_var(struct hlsl_ctx *ctx, struct vsir_program *program, + const struct hlsl_ir_var *var, enum hlsl_regset r, enum vkd3d_shader_descriptor_type type) +{ + unsigned int component_count = hlsl_type_component_count(var->data_type); + + for (unsigned int k = 0; k < component_count; ++k) + { + const struct hlsl_type *component_type = hlsl_type_get_component_type(ctx, var->data_type, k); + struct vkd3d_shader_register_range range; + struct vkd3d_shader_descriptor_info1 *d; + unsigned int regset_offset; + enum hlsl_regset regset; + uint32_t id; + + if (!hlsl_type_is_resource(component_type)) + continue; + regset_offset = hlsl_type_get_component_offset(ctx, var->data_type, k, ®set); + if (regset != r) + continue; + if (regset_offset > var->regs[r].allocation_size) + continue; + + if (!var->objects_usage[r][regset_offset].used) + continue; + + id = var->regs[r].id + regset_offset; + range.space = var->regs[r].space; + range.first = var->regs[r].index + regset_offset; + /* FIXME: 5.1 arrays. */ + range.last = var->regs[r].index + regset_offset; + + if (type == VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER) + { + if (!(d = vsir_program_add_descriptor(program, type, id, + &range, VKD3D_SHADER_RESOURCE_NONE, VSIR_DATA_UNUSED))) + return; + if (component_type->sampler_dim == HLSL_SAMPLER_DIM_COMPARISON) + d->flags |= VKD3D_SHADER_DESCRIPTOR_INFO_FLAG_SAMPLER_COMPARISON_MODE; + } + else + { + if (component_type->class == HLSL_CLASS_SAMPLER) + d = vsir_program_add_descriptor(program, type, id, &range, + get_vsir_resource_type(var->objects_usage[r][regset_offset].sampler_dim), VSIR_DATA_F32); + else + d = vsir_program_add_descriptor(program, type, id, &range, + get_vsir_resource_type(component_type->sampler_dim), + get_vsir_resource_data_type(component_type)); + if (!d) + return; + + if (component_type->sampler_dim == HLSL_SAMPLER_DIM_RAW_BUFFER) + d->flags |= VKD3D_SHADER_DESCRIPTOR_INFO_FLAG_RAW_BUFFER; + else if (component_type->sampler_dim == HLSL_SAMPLER_DIM_STRUCTURED_BUFFER) + d->structure_stride = hlsl_type_get_packed_size(component_type->e.resource.format); + else if (component_type->sampler_dim == HLSL_SAMPLER_DIM_2DMS + || component_type->sampler_dim == HLSL_SAMPLER_DIM_2DMSARRAY) + d->sample_count = component_type->sample_count; + + if (type == VKD3D_SHADER_DESCRIPTOR_TYPE_UAV && component_type->e.resource.rasteriser_ordered) + d->uav_flags |= VKD3DSUF_RASTERISER_ORDERED_VIEW; + + if (var->objects_usage[r][regset_offset].uav_read) + d->flags |= VKD3D_SHADER_DESCRIPTOR_INFO_FLAG_UAV_READ; + if (var->objects_usage[r][regset_offset].uav_atomics) + d->flags |= VKD3D_SHADER_DESCRIPTOR_INFO_FLAG_UAV_ATOMICS; + } + } +} + +static void generate_vsir_descriptors(struct hlsl_ctx *ctx, struct vsir_program *program) +{ + struct vkd3d_shader_register_range range; + struct vkd3d_shader_descriptor_info1 *d; + const struct hlsl_ir_var *var; + + if (program->shader_version.major < 4) + { + uint32_t flat_constant_count = 0; + + LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry) + { + const struct hlsl_reg *reg = &var->regs[HLSL_REGSET_NUMERIC]; + + if (var->is_uniform && reg->allocation_size) + flat_constant_count = max(flat_constant_count, reg->id + reg->allocation_size); + + generate_vsir_descriptors_for_var(ctx, program, var, + HLSL_REGSET_SAMPLERS, VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER); + generate_vsir_descriptors_for_var(ctx, program, var, + HLSL_REGSET_SAMPLERS, VKD3D_SHADER_DESCRIPTOR_TYPE_SRV); + } + + if (flat_constant_count) + { + range.space = 0; + range.first = range.last = VKD3D_SHADER_D3DBC_FLOAT_CONSTANT_REGISTER; + if ((d = vsir_program_add_descriptor(program, VKD3D_SHADER_DESCRIPTOR_TYPE_CBV, + range.first, &range, VKD3D_SHADER_RESOURCE_BUFFER, VSIR_DATA_U32))) + d->buffer_size = flat_constant_count * 16; + } + } + else + { + struct hlsl_buffer *buffer; + + LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry) + { + generate_vsir_descriptors_for_var(ctx, program, var, + HLSL_REGSET_SAMPLERS, VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER); + generate_vsir_descriptors_for_var(ctx, program, var, + HLSL_REGSET_TEXTURES, VKD3D_SHADER_DESCRIPTOR_TYPE_SRV); + generate_vsir_descriptors_for_var(ctx, program, var, + HLSL_REGSET_UAVS, VKD3D_SHADER_DESCRIPTOR_TYPE_UAV); + } + + LIST_FOR_EACH_ENTRY(buffer, &ctx->buffers, struct hlsl_buffer, entry) + { + if (!buffer->reg.allocated) + continue; + + range.space = buffer->reg.space; + range.first = buffer->reg.index; + /* FIXME: 5.1 arrays. */ + range.last = buffer->reg.index; + if ((d = vsir_program_add_descriptor(program, VKD3D_SHADER_DESCRIPTOR_TYPE_CBV, + buffer->reg.id, &range, VKD3D_SHADER_RESOURCE_BUFFER, VSIR_DATA_U32))) + d->buffer_size = align(buffer->size, 4) * sizeof(float); + } + } + + program->has_descriptor_info = true; +} + /* For some reason, for matrices, values from default value initializers end * up in different components than from regular initializers. Default value * initializers fill the matrix in vertical reading order @@ -13877,8 +13993,8 @@ static void loop_unrolling_simplify(struct hlsl_ctx *ctx, struct hlsl_block *blo current_index = index_instructions(block, *index); progress |= copy_propagation_transform_block(ctx, block, state); - progress |= hlsl_transform_ir(ctx, fold_swizzle_chains, block, NULL); - progress |= hlsl_transform_ir(ctx, remove_trivial_swizzles, block, NULL); + progress |= replace_ir(ctx, fold_swizzle_chains, block); + progress |= replace_ir(ctx, fold_trivial_swizzles, block); progress |= hlsl_transform_ir(ctx, remove_trivial_conditional_branches, block, NULL); } while (progress); @@ -14131,7 +14247,7 @@ static void loop_unrolling_execute(struct hlsl_ctx *ctx, struct hlsl_block *bloc hlsl_transform_ir(ctx, resolve_loops, block, NULL); } -static bool lower_countbits(struct hlsl_ctx *ctx, struct hlsl_ir_node *node, struct hlsl_block *block) +static struct hlsl_ir_node *lower_countbits(struct hlsl_ctx *ctx, struct hlsl_ir_node *node, struct hlsl_block *block) { struct hlsl_ir_function_decl *func; struct hlsl_ir_node *call, *rhs; @@ -14150,33 +14266,31 @@ static bool lower_countbits(struct hlsl_ctx *ctx, struct hlsl_ir_node *node, str "}\n"; if (node->type != HLSL_IR_EXPR) - return false; + return NULL; expr = hlsl_ir_expr(node); if (expr->op != HLSL_OP1_COUNTBITS) - return false; + return NULL; rhs = expr->operands[0].node; if (!(body = hlsl_sprintf_alloc(ctx, template, hlsl_type_component_count(rhs->data_type)))) - return false; + return NULL; func = hlsl_compile_internal_function(ctx, "countbits", body); vkd3d_free(body); if (!func) - return false; + return NULL; lhs = func->parameters.vars[0]; hlsl_block_add_simple_store(ctx, block, lhs, rhs); if (!(call = hlsl_new_call(ctx, func, &node->loc))) - return false; + return NULL; hlsl_block_add_instr(block, call); - hlsl_block_add_simple_load(ctx, block, func->return_var, &node->loc); - - return true; + return hlsl_block_add_simple_load(ctx, block, func->return_var, &node->loc); } -static bool lower_ctz(struct hlsl_ctx *ctx, struct hlsl_ir_node *node, struct hlsl_block *block) +static struct hlsl_ir_node *lower_ctz(struct hlsl_ctx *ctx, struct hlsl_ir_node *node, struct hlsl_block *block) { struct hlsl_ir_function_decl *func; struct hlsl_ir_node *call, *rhs; @@ -14201,11 +14315,11 @@ static bool lower_ctz(struct hlsl_ctx *ctx, struct hlsl_ir_node *node, struct hl "}\n"; if (node->type != HLSL_IR_EXPR) - return false; + return NULL; expr = hlsl_ir_expr(node); if (expr->op != HLSL_OP1_CTZ) - return false; + return NULL; rhs = expr->operands[0].node; if (!(body = hlsl_sprintf_alloc(ctx, template, hlsl_type_component_count(rhs->data_type)))) @@ -14213,21 +14327,19 @@ static bool lower_ctz(struct hlsl_ctx *ctx, struct hlsl_ir_node *node, struct hl func = hlsl_compile_internal_function(ctx, "ctz", body); vkd3d_free(body); if (!func) - return false; + return NULL; lhs = func->parameters.vars[0]; hlsl_block_add_simple_store(ctx, block, lhs, rhs); if (!(call = hlsl_new_call(ctx, func, &node->loc))) - return false; + return NULL; hlsl_block_add_instr(block, call); - hlsl_block_add_simple_load(ctx, block, func->return_var, &node->loc); - - return true; + return hlsl_block_add_simple_load(ctx, block, func->return_var, &node->loc); } -static bool lower_f16tof32(struct hlsl_ctx *ctx, struct hlsl_ir_node *node, struct hlsl_block *block) +static struct hlsl_ir_node *lower_f16tof32(struct hlsl_ctx *ctx, struct hlsl_ir_node *node, struct hlsl_block *block) { struct hlsl_ir_function_decl *func; struct hlsl_ir_node *call, *rhs; @@ -14282,29 +14394,28 @@ static bool lower_f16tof32(struct hlsl_ctx *ctx, struct hlsl_ir_node *node, stru expr = hlsl_ir_expr(node); if (expr->op != HLSL_OP1_F16TOF32) - return false; + return NULL; rhs = expr->operands[0].node; component_count = hlsl_type_component_count(rhs->data_type); if (!(body = hlsl_sprintf_alloc(ctx, template, component_count, component_count))) - return false; + return NULL; if (!(func = hlsl_compile_internal_function(ctx, "soft_f16tof32", body))) - return false; + return NULL; lhs = func->parameters.vars[0]; hlsl_block_add_simple_store(ctx, block, lhs, rhs); if (!(call = hlsl_new_call(ctx, func, &node->loc))) - return false; + return NULL; hlsl_block_add_instr(block, call); - hlsl_block_add_simple_load(ctx, block, func->return_var, &node->loc); - return true; + return hlsl_block_add_simple_load(ctx, block, func->return_var, &node->loc); } -static bool lower_f32tof16(struct hlsl_ctx *ctx, struct hlsl_ir_node *node, struct hlsl_block *block) +static struct hlsl_ir_node *lower_f32tof16(struct hlsl_ctx *ctx, struct hlsl_ir_node *node, struct hlsl_block *block) { struct hlsl_ir_function_decl *func; struct hlsl_ir_node *call, *rhs; @@ -14342,34 +14453,33 @@ static bool lower_f32tof16(struct hlsl_ctx *ctx, struct hlsl_ir_node *node, stru "}\n"; if (node->type != HLSL_IR_EXPR) - return false; + return NULL; expr = hlsl_ir_expr(node); if (expr->op != HLSL_OP1_F32TOF16) - return false; + return NULL; rhs = expr->operands[0].node; component_count = hlsl_type_component_count(rhs->data_type); if (!(body = hlsl_sprintf_alloc(ctx, template, component_count, component_count))) - return false; + return NULL; if (!(func = hlsl_compile_internal_function(ctx, "soft_f32tof16", body))) - return false; + return NULL; lhs = func->parameters.vars[0]; hlsl_block_add_simple_store(ctx, block, lhs, rhs); if (!(call = hlsl_new_call(ctx, func, &node->loc))) - return false; + return NULL; hlsl_block_add_instr(block, call); - hlsl_block_add_simple_load(ctx, block, func->return_var, &node->loc); - return true; + return hlsl_block_add_simple_load(ctx, block, func->return_var, &node->loc); } -static bool lower_find_msb(struct hlsl_ctx *ctx, struct hlsl_ir_node *node, struct hlsl_block *block) +static struct hlsl_ir_node *lower_find_msb(struct hlsl_ctx *ctx, struct hlsl_ir_node *node, struct hlsl_block *block) { struct hlsl_ir_function_decl *func; struct hlsl_ir_node *call, *rhs; @@ -14406,33 +14516,31 @@ static bool lower_find_msb(struct hlsl_ctx *ctx, struct hlsl_ir_node *node, stru "}\n"; if (node->type != HLSL_IR_EXPR) - return false; + return NULL; expr = hlsl_ir_expr(node); if (expr->op != HLSL_OP1_FIND_MSB) - return false; + return NULL; rhs = expr->operands[0].node; if (!(body = hlsl_sprintf_alloc(ctx, template, rhs->data_type->name, hlsl_type_component_count(rhs->data_type)))) - return false; + return NULL; func = hlsl_compile_internal_function(ctx, "find_msb", body); vkd3d_free(body); if (!func) - return false; + return NULL; lhs = func->parameters.vars[0]; hlsl_block_add_simple_store(ctx, block, lhs, rhs); if (!(call = hlsl_new_call(ctx, func, &node->loc))) - return false; + return NULL; hlsl_block_add_instr(block, call); - hlsl_block_add_simple_load(ctx, block, func->return_var, &node->loc); - - return true; + return hlsl_block_add_simple_load(ctx, block, func->return_var, &node->loc); } -static bool lower_isinf(struct hlsl_ctx *ctx, struct hlsl_ir_node *node, struct hlsl_block *block) +static struct hlsl_ir_node *lower_isinf(struct hlsl_ctx *ctx, struct hlsl_ir_node *node, struct hlsl_block *block) { struct hlsl_ir_function_decl *func; struct hlsl_ir_node *call, *rhs; @@ -14477,12 +14585,12 @@ static bool lower_isinf(struct hlsl_ctx *ctx, struct hlsl_ir_node *node, struct "}"; if (node->type != HLSL_IR_EXPR) - return false; + return NULL; expr = hlsl_ir_expr(node); if (expr->op != HLSL_OP1_ISINF) - return false; + return NULL; rhs = expr->operands[0].node; @@ -14497,19 +14605,18 @@ static bool lower_isinf(struct hlsl_ctx *ctx, struct hlsl_ir_node *node, struct component_count = hlsl_type_component_count(rhs->data_type); if (!(body = hlsl_sprintf_alloc(ctx, template, component_count, component_count))) - return false; + return NULL; if (!(func = hlsl_compile_internal_function(ctx, "isinf", body))) - return false; + return NULL; hlsl_block_add_simple_store(ctx, block, func->parameters.vars[0], rhs); if (!(call = hlsl_new_call(ctx, func, &node->loc))) - return false; + return NULL; hlsl_block_add_instr(block, call); - hlsl_block_add_simple_load(ctx, block, func->return_var, &node->loc); - return true; + return hlsl_block_add_simple_load(ctx, block, func->return_var, &node->loc); } static void process_entry_function(struct hlsl_ctx *ctx, struct list *semantic_vars, struct hlsl_block *body, @@ -14548,25 +14655,25 @@ static void process_entry_function(struct hlsl_ctx *ctx, struct list *semantic_v if (hlsl_version_ge(ctx, 4, 0) && hlsl_version_lt(ctx, 5, 0)) { - lower_ir(ctx, lower_countbits, body); - lower_ir(ctx, lower_ctz, body); - lower_ir(ctx, lower_f16tof32, body); - lower_ir(ctx, lower_f32tof16, body); - lower_ir(ctx, lower_find_msb, body); + replace_ir(ctx, lower_countbits, body); + replace_ir(ctx, lower_ctz, body); + replace_ir(ctx, lower_f16tof32, body); + replace_ir(ctx, lower_f32tof16, body); + replace_ir(ctx, lower_find_msb, body); } - lower_ir(ctx, lower_isinf, body); + replace_ir(ctx, lower_isinf, body); lower_return(ctx, entry_func, body, false); while (hlsl_transform_ir(ctx, lower_calls, body, NULL)); - lower_ir(ctx, lower_complex_casts, body); - lower_ir(ctx, lower_matrix_swizzles, body); - lower_ir(ctx, lower_index_loads, body); + replace_ir(ctx, lower_complex_casts, body); + replace_ir(ctx, lower_matrix_swizzles, body); + replace_ir(ctx, lower_index_loads, body); - lower_ir(ctx, lower_tgsm_loads, body); - lower_ir(ctx, lower_tgsm_stores, body); + replace_ir(ctx, lower_tgsm_loads, body); + replace_ir(ctx, lower_tgsm_stores, body); if (entry_func->return_var) { @@ -14739,9 +14846,9 @@ static void process_entry_function(struct hlsl_ctx *ctx, struct list *semantic_v remove_unreachable_code(ctx, body); hlsl_transform_ir(ctx, normalize_switch_cases, body, NULL); - lower_ir(ctx, lower_nonconstant_vector_derefs, body); - lower_ir(ctx, lower_casts_to_bool, body); - lower_ir(ctx, lower_int_dot, body); + replace_ir(ctx, lower_nonconstant_vector_derefs, body); + replace_ir(ctx, lower_casts_to_bool, body); + replace_ir(ctx, lower_int_dot, body); if (hlsl_version_lt(ctx, 4, 0)) hlsl_transform_ir(ctx, lower_separate_samples, body, NULL); @@ -14753,8 +14860,8 @@ static void process_entry_function(struct hlsl_ctx *ctx, struct list *semantic_v progress = vectorize_exprs(ctx, body); compute_liveness(ctx, body); progress |= hlsl_transform_ir(ctx, dce, body, NULL); - progress |= hlsl_transform_ir(ctx, fold_swizzle_chains, body, NULL); - progress |= hlsl_transform_ir(ctx, remove_trivial_swizzles, body, NULL); + progress |= replace_ir(ctx, fold_swizzle_chains, body); + progress |= replace_ir(ctx, fold_trivial_swizzles, body); progress |= vectorize_stores(ctx, body); } while (progress); @@ -14782,37 +14889,37 @@ static void process_entry_function(struct hlsl_ctx *ctx, struct list *semantic_v if (profile->major_version < 4) { - while (lower_ir(ctx, lower_nonconstant_array_loads, body)); + while (replace_ir(ctx, lower_nonconstant_array_loads, body)); - lower_ir(ctx, lower_ternary, body); - lower_ir(ctx, lower_int_modulus_sm1, body); - lower_ir(ctx, lower_division, body); + replace_ir(ctx, lower_ternary, body); + replace_ir(ctx, lower_int_modulus_sm1, body); + replace_ir(ctx, lower_division, body); /* Constants casted to float must be folded, and new casts to bool also need to be lowered. */ hlsl_transform_ir(ctx, hlsl_fold_constant_exprs, body, NULL); - lower_ir(ctx, lower_casts_to_bool, body); - - lower_ir(ctx, lower_casts_to_int, body); - lower_ir(ctx, lower_trunc, body); - lower_ir(ctx, lower_sqrt, body); - lower_ir(ctx, lower_dot, body); - lower_ir(ctx, lower_round, body); - lower_ir(ctx, lower_ceil, body); - lower_ir(ctx, lower_floor, body); - lower_ir(ctx, lower_trig, body); - lower_ir(ctx, lower_comparison_operators, body); - lower_ir(ctx, lower_logic_not, body); + replace_ir(ctx, lower_casts_to_bool, body); + + replace_ir(ctx, lower_casts_to_int, body); + replace_ir(ctx, lower_trunc, body); + replace_ir(ctx, lower_sqrt, body); + replace_ir(ctx, lower_dot, body); + replace_ir(ctx, lower_round, body); + replace_ir(ctx, lower_ceil, body); + replace_ir(ctx, lower_floor, body); + replace_ir(ctx, lower_trig, body); + replace_ir(ctx, lower_comparison_operators, body); + replace_ir(ctx, lower_logic_not, body); if (ctx->profile->type == VKD3D_SHADER_TYPE_PIXEL) - lower_ir(ctx, lower_slt, body); + replace_ir(ctx, lower_slt, body); else - lower_ir(ctx, lower_cmp, body); + replace_ir(ctx, lower_cmp, body); } if (profile->major_version < 2) { - lower_ir(ctx, lower_abs, body); + replace_ir(ctx, lower_abs, body); } - lower_ir(ctx, validate_nonconstant_vector_store_derefs, body); + replace_ir(ctx, validate_nonconstant_vector_store_derefs, body); hlsl_run_folding_passes(ctx, body); @@ -14930,6 +15037,8 @@ int hlsl_emit_vsir(struct hlsl_ctx *ctx, const struct vkd3d_shader_compile_info if (program->shader_version.type == VKD3D_SHADER_TYPE_HULL) generate_vsir_signature(ctx, program, ctx->patch_constant_func, &patch_semantic_vars); + generate_vsir_descriptors(ctx, program); + if (program->shader_version.major < 4) sm1_generate_ctab(ctx, reflection_data); else diff --git a/libs/vkd3d/libs/vkd3d-shader/ir.c b/libs/vkd3d/libs/vkd3d-shader/ir.c index 670f6c31cf8..13ea8a433a6 100644 --- a/libs/vkd3d/libs/vkd3d-shader/ir.c +++ b/libs/vkd3d/libs/vkd3d-shader/ir.c @@ -299,6 +299,7 @@ const char *vsir_opcode_get_name(enum vkd3d_shader_opcode op, const char *error) [VSIR_OP_MOVC ] = "movc", [VSIR_OP_MSAD ] = "msad", [VSIR_OP_MUL ] = "mul", + [VSIR_OP_NEG ] = "neg", [VSIR_OP_NEO ] = "ne_ord", [VSIR_OP_NEU ] = "ne", [VSIR_OP_NOP ] = "nop", @@ -747,6 +748,38 @@ bool vsir_signature_find_sysval(const struct shader_signature *signature, return false; } +struct vkd3d_shader_descriptor_info1 *vsir_program_add_descriptor(struct vsir_program *program, + enum vkd3d_shader_descriptor_type type, unsigned int register_id, + const struct vkd3d_shader_register_range *range, + enum vkd3d_shader_resource_type resource_type, enum vsir_data_type resource_data_type) +{ + struct vkd3d_shader_scan_descriptor_info1 *info = &program->descriptors; + struct vkd3d_shader_descriptor_info1 *d; + + if (!info) + return NULL; + + if (!vkd3d_array_reserve((void **)&info->descriptors, &program->descriptors_size, + info->descriptor_count + 1, sizeof(*info->descriptors))) + { + ERR("Failed to allocate descriptor info.\n"); + return NULL; + } + + d = &info->descriptors[info->descriptor_count]; + memset(d, 0, sizeof(*d)); + d->type = type; + d->register_id = register_id; + d->register_space = range->space; + d->register_index = range->first; + d->resource_type = resource_type; + d->resource_data_type = resource_data_type; + d->count = (range->last == ~0u) ? ~0u : range->last - range->first + 1; + ++info->descriptor_count; + + return d; +} + const char *debug_vsir_writemask(unsigned int writemask) { static const char components[] = {'x', 'y', 'z', 'w'}; @@ -1422,8 +1455,8 @@ static enum vkd3d_result vsir_program_lower_imul(struct vsir_program *program, static enum vkd3d_result vsir_program_lower_udiv(struct vsir_program *program, struct vsir_program_iterator *it, struct vsir_transformation_context *ctx) { + unsigned int count = 3, src0_id, src1_id, divisor_id; struct vkd3d_shader_instruction *udiv, *ins, *mov; - unsigned int count = 2; udiv = vsir_program_iterator_current(it); @@ -1437,9 +1470,9 @@ static enum vkd3d_result vsir_program_lower_udiv(struct vsir_program *program, } if (udiv->dst[0].reg.type != VKD3DSPR_NULL) - ++count; + count += 2; if (udiv->dst[1].reg.type != VKD3DSPR_NULL) - ++count; + count += 2; if (!vsir_program_iterator_insert_after(it, count)) return VKD3D_ERROR_OUT_OF_MEMORY; @@ -1451,14 +1484,33 @@ static enum vkd3d_result vsir_program_lower_udiv(struct vsir_program *program, return VKD3D_ERROR_OUT_OF_MEMORY; mov->src[0] = udiv->src[0]; - dst_param_init_ssa(&mov->dst[0], program->ssa_count, udiv->src[0].reg.data_type, udiv->src[0].reg.dimension); + src0_id = program->ssa_count++; + dst_param_init_ssa(&mov->dst[0], src0_id, udiv->src[0].reg.data_type, udiv->src[0].reg.dimension); mov = vsir_program_iterator_next(it); if (!(vsir_instruction_init_with_params(program, mov, &udiv->location, VSIR_OP_MOV, 1, 1))) return VKD3D_ERROR_OUT_OF_MEMORY; mov->src[0] = udiv->src[1]; - dst_param_init_ssa(&mov->dst[0], program->ssa_count + 1, udiv->src[1].reg.data_type, udiv->src[1].reg.dimension); + src1_id = program->ssa_count++; + dst_param_init_ssa(&mov->dst[0], src1_id, udiv->src[1].reg.data_type, udiv->src[1].reg.dimension); + + mov = vsir_program_iterator_next(it); + if (!(vsir_instruction_init_with_params(program, mov, &udiv->location, VSIR_OP_MOVC, 1, 3))) + return VKD3D_ERROR_OUT_OF_MEMORY; + + src_param_init_ssa(&mov->src[0], src1_id, udiv->src[1].reg.data_type, udiv->src[1].reg.dimension); + src_param_init_ssa(&mov->src[1], src1_id, udiv->src[1].reg.data_type, udiv->src[1].reg.dimension); + vsir_register_init(&mov->src[2].reg, VKD3DSPR_IMMCONST, VSIR_DATA_U32, 0); + mov->src[2].reg.dimension = udiv->src[1].reg.dimension; + mov->src[2].reg.u.immconst_u32[0] = 1; + mov->src[2].reg.u.immconst_u32[1] = 1; + mov->src[2].reg.u.immconst_u32[2] = 1; + mov->src[2].reg.u.immconst_u32[3] = 1; + if (mov->src[2].reg.dimension == VSIR_DIMENSION_VEC4) + mov->src[2].swizzle = VKD3D_SHADER_NO_SWIZZLE; + divisor_id = program->ssa_count++; + dst_param_init_ssa(&mov->dst[0], divisor_id, mov->src[1].reg.data_type, mov->src[1].reg.dimension); if (udiv->dst[0].reg.type != VKD3DSPR_NULL) { @@ -1469,11 +1521,30 @@ static enum vkd3d_result vsir_program_lower_udiv(struct vsir_program *program, ins->flags = udiv->flags; - src_param_init_ssa(&ins->src[0], program->ssa_count, - udiv->src[0].reg.data_type, udiv->src[0].reg.dimension); - src_param_init_ssa(&ins->src[1], program->ssa_count + 1, - udiv->src[1].reg.data_type, udiv->src[1].reg.dimension); + src_param_init_ssa(&ins->src[0], src0_id, udiv->src[0].reg.data_type, udiv->src[0].reg.dimension); + src_param_init_ssa(&ins->src[1], divisor_id, udiv->src[1].reg.data_type, udiv->src[1].reg.dimension); + dst_param_init_ssa(&ins->dst[0], program->ssa_count, udiv->src[1].reg.data_type, udiv->src[1].reg.dimension); + + /* Like its TPF equivalent, division by zero is well-defined for + * VSIR_OP_UDIV, and returns UINT_MAX. Division by zero is undefined + * for VSIR_OP_UDIV_SIMPLE and VSIR_OP_UREM, so handle it here. */ + ins = vsir_program_iterator_next(it); + if (!(vsir_instruction_init_with_params(program, ins, &udiv->location, VSIR_OP_MOVC, 1, 3))) + return VKD3D_ERROR_OUT_OF_MEMORY; + + src_param_init_ssa(&ins->src[0], src1_id, udiv->src[1].reg.data_type, udiv->src[1].reg.dimension); + src_param_init_ssa(&ins->src[1], program->ssa_count, udiv->src[1].reg.data_type, udiv->src[1].reg.dimension); + vsir_register_init(&ins->src[2].reg, VKD3DSPR_IMMCONST, VSIR_DATA_U32, 0); + ins->src[2].reg.dimension = udiv->src[1].reg.dimension; + ins->src[2].reg.u.immconst_u32[0] = UINT_MAX; + ins->src[2].reg.u.immconst_u32[1] = UINT_MAX; + ins->src[2].reg.u.immconst_u32[2] = UINT_MAX; + ins->src[2].reg.u.immconst_u32[3] = UINT_MAX; + if (ins->src[2].reg.dimension == VSIR_DIMENSION_VEC4) + ins->src[2].swizzle = VKD3D_SHADER_NO_SWIZZLE; ins->dst[0] = udiv->dst[0]; + + ++program->ssa_count; } if (udiv->dst[1].reg.type != VKD3DSPR_NULL) @@ -1485,15 +1556,30 @@ static enum vkd3d_result vsir_program_lower_udiv(struct vsir_program *program, ins->flags = udiv->flags; - src_param_init_ssa(&ins->src[0], program->ssa_count, - udiv->src[0].reg.data_type, udiv->src[0].reg.dimension); - src_param_init_ssa(&ins->src[1], program->ssa_count + 1, - udiv->src[1].reg.data_type, udiv->src[1].reg.dimension); + src_param_init_ssa(&ins->src[0], src0_id, udiv->src[0].reg.data_type, udiv->src[0].reg.dimension); + src_param_init_ssa(&ins->src[1], divisor_id, udiv->src[1].reg.data_type, udiv->src[1].reg.dimension); + dst_param_init_ssa(&ins->dst[0], program->ssa_count, udiv->src[1].reg.data_type, udiv->src[1].reg.dimension); + + ins = vsir_program_iterator_next(it); + if (!(vsir_instruction_init_with_params(program, ins, &udiv->location, VSIR_OP_MOVC, 1, 3))) + return VKD3D_ERROR_OUT_OF_MEMORY; + + src_param_init_ssa(&ins->src[0], src1_id, udiv->src[1].reg.data_type, udiv->src[1].reg.dimension); + src_param_init_ssa(&ins->src[1], program->ssa_count, udiv->src[1].reg.data_type, udiv->src[1].reg.dimension); + vsir_register_init(&ins->src[2].reg, VKD3DSPR_IMMCONST, VSIR_DATA_U32, 0); + ins->src[2].reg.dimension = udiv->src[1].reg.dimension; + ins->src[2].reg.u.immconst_u32[0] = UINT_MAX; + ins->src[2].reg.u.immconst_u32[1] = UINT_MAX; + ins->src[2].reg.u.immconst_u32[2] = UINT_MAX; + ins->src[2].reg.u.immconst_u32[3] = UINT_MAX; + if (ins->src[2].reg.dimension == VSIR_DIMENSION_VEC4) + ins->src[2].swizzle = VKD3D_SHADER_NO_SWIZZLE; ins->dst[0] = udiv->dst[1]; + + ++program->ssa_count; } vkd3d_shader_instruction_make_nop(udiv); - program->ssa_count += 2; return VKD3D_OK; } @@ -1648,6 +1734,7 @@ static enum vkd3d_result vsir_program_lower_texcrd(struct vsir_program *program, static enum vkd3d_result vsir_program_lower_texld_sm1(struct vsir_program *program, struct vkd3d_shader_instruction *ins, struct vkd3d_shader_message_context *message_context) { + const struct vkd3d_shader_descriptor_info1 *sampler; unsigned int idx = ins->src[0].reg.idx[0].offset; struct vkd3d_shader_src_param *srcs; @@ -1660,7 +1747,7 @@ static enum vkd3d_result vsir_program_lower_texld_sm1(struct vsir_program *progr return VKD3D_ERROR_NOT_IMPLEMENTED; } - if (!(srcs = vsir_program_get_src_params(program, 3))) + if (!(srcs = vsir_program_get_src_params(program, 4))) return VKD3D_ERROR_OUT_OF_MEMORY; /* Note we run before I/O normalization. */ @@ -1668,9 +1755,26 @@ static enum vkd3d_result vsir_program_lower_texld_sm1(struct vsir_program *progr vsir_src_param_init_resource(&srcs[1], idx, idx); vsir_src_param_init_sampler(&srcs[2], idx, idx); - ins->opcode = VSIR_OP_SAMPLE; - ins->src = srcs; - ins->src_count = 3; + sampler = vkd3d_shader_find_descriptor(&program->descriptors, VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER, idx); + if (sampler->flags & VKD3D_SHADER_DESCRIPTOR_INFO_FLAG_SAMPLER_COMPARISON_MODE) + { + enum vkd3d_shader_swizzle_component ref = vsir_swizzle_get_component(srcs[0].swizzle, 2); + + ins->opcode = VSIR_OP_SAMPLE_C; + ins->src = srcs; + ins->src_count = 4; + + srcs[1].swizzle = VKD3D_SHADER_SWIZZLE(X, X, X, X); + + srcs[3] = srcs[0]; + srcs[3].swizzle = vkd3d_shader_create_swizzle(ref, ref, ref, ref); + } + else + { + ins->opcode = VSIR_OP_SAMPLE; + ins->src = srcs; + ins->src_count = 3; + } return VKD3D_OK; } @@ -1730,6 +1834,7 @@ static enum vkd3d_result vsir_program_lower_texldp(struct vsir_program *program, static enum vkd3d_result vsir_program_lower_texld(struct vsir_program *program, struct vkd3d_shader_instruction *tex, struct vkd3d_shader_message_context *message_context) { + const struct vkd3d_shader_descriptor_info1 *sampler; unsigned int idx = tex->src[1].reg.idx[0].offset; struct vkd3d_shader_src_param *srcs; @@ -1743,7 +1848,21 @@ static enum vkd3d_result vsir_program_lower_texld(struct vsir_program *program, vsir_src_param_init_resource(&srcs[1], idx, idx); vsir_src_param_init_sampler(&srcs[2], idx, idx); - if (!tex->flags) + sampler = vkd3d_shader_find_descriptor(&program->descriptors, VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER, idx); + if (sampler->flags & VKD3D_SHADER_DESCRIPTOR_INFO_FLAG_SAMPLER_COMPARISON_MODE) + { + enum vkd3d_shader_swizzle_component ref = vsir_swizzle_get_component(srcs[0].swizzle, 2); + + tex->opcode = VSIR_OP_SAMPLE_C; + tex->src = srcs; + tex->src_count = 4; + + srcs[1].swizzle = VKD3D_SHADER_SWIZZLE(X, X, X, X); + + srcs[3] = srcs[0]; + srcs[3].swizzle = vkd3d_shader_create_swizzle(ref, ref, ref, ref); + } + else if (!tex->flags) { tex->opcode = VSIR_OP_SAMPLE; tex->src = srcs; @@ -1825,6 +1944,7 @@ static enum vkd3d_result vsir_program_lower_texldl(struct vsir_program *program, static enum vkd3d_result vsir_program_lower_tex(struct vsir_program *program, struct vkd3d_shader_instruction *ins) { + const struct vkd3d_shader_descriptor_info1 *sampler; unsigned int idx = ins->dst[0].reg.idx[0].offset; struct vkd3d_shader_src_param *srcs; @@ -1834,7 +1954,7 @@ static enum vkd3d_result vsir_program_lower_tex(struct vsir_program *program, st /* We run before I/O normalization. */ VKD3D_ASSERT(program->normalisation_level < VSIR_NORMALISED_SM6); - if (!(srcs = vsir_program_get_src_params(program, 3))) + if (!(srcs = vsir_program_get_src_params(program, 4))) return VKD3D_ERROR_OUT_OF_MEMORY; vsir_src_param_init(&srcs[0], VKD3DSPR_TEXTURE, VSIR_DATA_F32, 1); @@ -1845,9 +1965,24 @@ static enum vkd3d_result vsir_program_lower_tex(struct vsir_program *program, st vsir_src_param_init_resource(&srcs[1], idx, idx); vsir_src_param_init_sampler(&srcs[2], idx, idx); - ins->opcode = VSIR_OP_SAMPLE; - ins->src = srcs; - ins->src_count = 3; + sampler = vkd3d_shader_find_descriptor(&program->descriptors, VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER, idx); + if (sampler->flags & VKD3D_SHADER_DESCRIPTOR_INFO_FLAG_SAMPLER_COMPARISON_MODE) + { + ins->opcode = VSIR_OP_SAMPLE_C; + ins->src = srcs; + ins->src_count = 4; + + srcs[1].swizzle = VKD3D_SHADER_SWIZZLE(X, X, X, X); + + srcs[3] = srcs[0]; + srcs[3].swizzle = VKD3D_SHADER_SWIZZLE(Z, Z, Z, Z); + } + else + { + ins->opcode = VSIR_OP_SAMPLE; + ins->src = srcs; + ins->src_count = 3; + } return VKD3D_OK; } @@ -2039,6 +2174,72 @@ static enum vkd3d_result vsir_program_lower_d3dbc_instructions(struct vsir_progr return VKD3D_OK; } +static enum vkd3d_result vsir_program_lower_modifiers(struct vsir_program *program, + struct vsir_transformation_context *ctx) +{ + struct vsir_program_iterator it = vsir_program_iterator(&program->instructions), new_it; + struct vkd3d_shader_instruction *ins, *new_ins; + unsigned int i, j; + + for (ins = vsir_program_iterator_head(&it); ins; ins = vsir_program_iterator_next(&it)) + { + for (i = 0; i < ins->src_count; ++i) + { + enum vkd3d_shader_opcode new_opcodes[2] = {VSIR_OP_NOP, VSIR_OP_NOP}; + struct vkd3d_shader_src_param *src = &ins->src[i]; + + /* TODO: support other modifiers, including destination modifiers. */ + switch (src->modifiers) + { + case VKD3DSPSM_ABS: + new_opcodes[0] = VSIR_OP_ABS; + break; + + case VKD3DSPSM_NEG: + new_opcodes[0] = data_type_is_integer(src->reg.data_type) ? VSIR_OP_INEG : VSIR_OP_NEG; + break; + + case VKD3DSPSM_ABSNEG: + new_opcodes[0] = VSIR_OP_ABS; + new_opcodes[1] = VSIR_OP_NEG; + break; + + default: + continue; + } + + for (j = 0; j < 2 && new_opcodes[j] != VSIR_OP_NOP; ++j) + { + if (!(new_ins = vsir_program_iterator_insert_before(&it, &new_it, 1))) + return VKD3D_ERROR_OUT_OF_MEMORY; + ins = vsir_program_iterator_current(&it); + + if (!vsir_instruction_init_with_params(program, new_ins, &ins->location, new_opcodes[j], 1, 1)) + { + vkd3d_shader_instruction_make_nop(new_ins); + return VKD3D_ERROR_OUT_OF_MEMORY; + } + + new_ins->src[0] = *src; + new_ins->src[0].modifiers = VKD3DSPSM_NONE; + + dst_param_init_ssa(&new_ins->dst[0], program->ssa_count, src->reg.data_type, src->reg.dimension); + src_param_init_ssa(src, program->ssa_count, src->reg.data_type, src->reg.dimension); + + if (data_type_is_64_bit(src->reg.data_type)) + { + new_ins->dst[0].write_mask = vsir_write_mask_64_from_32(new_ins->dst[0].write_mask); + src->swizzle = vsir_swizzle_64_from_32(src->swizzle); + } + + ++program->ssa_count; + } + } + } + + return VKD3D_OK; +} + static enum vkd3d_result vsir_program_lower_instructions(struct vsir_program *program, struct vsir_transformation_context *ctx) { @@ -3936,6 +4137,19 @@ static void cf_flattener_set_error(struct cf_flattener *flattener, enum vkd3d_re flattener->status = error; } +static struct vkd3d_shader_instruction *cf_flattener_instruction_append(struct cf_flattener *flattener) +{ + struct vkd3d_shader_instruction *ins; + + if (!(ins = shader_instruction_array_append(&flattener->instructions))) + { + ERR("Failed to allocate instructions.\n"); + cf_flattener_set_error(flattener, VKD3D_ERROR_OUT_OF_MEMORY); + return NULL; + } + return ins; +} + static bool cf_flattener_copy_instruction(struct cf_flattener *flattener, const struct vkd3d_shader_instruction *instruction) { @@ -3944,7 +4158,7 @@ static bool cf_flattener_copy_instruction(struct cf_flattener *flattener, if (instruction->opcode == VSIR_OP_NOP) return true; - if (!(dst_ins = shader_instruction_array_append(&flattener->instructions))) + if (!(dst_ins = cf_flattener_instruction_append(flattener))) return false; *dst_ins = *instruction; @@ -3975,7 +4189,7 @@ static void cf_flattener_emit_label(struct cf_flattener *flattener, unsigned int { struct vkd3d_shader_instruction *ins; - if (!(ins = shader_instruction_array_append(&flattener->instructions))) + if (!(ins = cf_flattener_instruction_append(flattener))) return; if (!vsir_instruction_init_label(ins, &flattener->location, label_id, flattener->program)) { @@ -3993,7 +4207,7 @@ static struct vkd3d_shader_src_param *cf_flattener_emit_branch(struct cf_flatten struct vkd3d_shader_src_param *src_params, *false_branch_param; struct vkd3d_shader_instruction *ins; - if (!(ins = shader_instruction_array_append(&flattener->instructions))) + if (!(ins = cf_flattener_instruction_append(flattener))) return NULL; vsir_instruction_init(ins, &flattener->location, VSIR_OP_BRANCH); @@ -4144,13 +4358,6 @@ static enum vkd3d_result cf_flattener_iterate_instruction_array(struct cf_flatte is_hull_shader = program->shader_version.type == VKD3D_SHADER_TYPE_HULL; after_declarations_section = is_hull_shader; - if (!shader_instruction_array_reserve(&flattener->instructions, instructions->count + 1)) - { - ERR("Failed to allocate instructions.\n"); - cf_flattener_set_error(flattener, VKD3D_ERROR_OUT_OF_MEMORY); - return VKD3D_ERROR_OUT_OF_MEMORY; - } - it = vsir_program_iterator(instructions); for (instruction = vsir_program_iterator_head(&it); instruction; instruction = vsir_program_iterator_next(&it)) { @@ -4609,16 +4816,14 @@ static enum vkd3d_result vsir_program_lower_switch_to_selection_ladder(struct vs vsir_src_param_init_label(&dst_ins->src[0], default_label); } - if (!shader_instruction_array_reserve(&instructions, instructions.count + 3 * case_count - 1)) - goto fail; - if_label = current_label; for (j = 0; j < case_count; ++j) { unsigned int fallthrough_label, case_label = label_from_src_param(&ins->src[3 + 2 * j + 1]); - dst_ins = shader_instruction_array_append(&instructions); + if (!(dst_ins = shader_instruction_array_append(&instructions))) + goto fail; if (!vsir_instruction_init_with_params(program, dst_ins, &ins->location, VSIR_OP_IEQ, 1, 2)) { vkd3d_shader_instruction_make_nop(dst_ins); @@ -4636,7 +4841,8 @@ static enum vkd3d_result vsir_program_lower_switch_to_selection_ladder(struct vs else fallthrough_label = block_count + 1; - dst_ins = shader_instruction_array_append(&instructions); + if (!(dst_ins = shader_instruction_array_append(&instructions))) + goto fail; if (!vsir_instruction_init_with_params(program, dst_ins, &ins->location, VSIR_OP_BRANCH, 0, 3)) { vkd3d_shader_instruction_make_nop(dst_ins); @@ -4660,7 +4866,8 @@ static enum vkd3d_result vsir_program_lower_switch_to_selection_ladder(struct vs } else { - dst_ins = shader_instruction_array_append(&instructions); + if (!(dst_ins = shader_instruction_array_append(&instructions))) + goto fail; if (!vsir_instruction_init_with_params(program, dst_ins, &ins->location, VSIR_OP_LABEL, 0, 1)) { vkd3d_shader_instruction_make_nop(dst_ins); @@ -4755,8 +4962,8 @@ static enum vkd3d_result vsir_program_materialise_phi_ssas_to_temps_in_function( struct vsir_program_iterator it_begin = *it; struct ssas_to_temps_alloc alloc = {0}; struct vkd3d_shader_instruction *ins; - size_t phi_count, incoming_count; unsigned int current_label = 0; + size_t phi_count; VKD3D_ASSERT(program->cf_type == VSIR_CF_BLOCKS); @@ -4770,7 +4977,6 @@ static enum vkd3d_result vsir_program_materialise_phi_ssas_to_temps_in_function( goto fail; phi_count = 0; - incoming_count = 0; for (ins = vsir_program_iterator_current(it); ins; ins = vsir_program_iterator_next(it)) { unsigned int j, temp_idx; @@ -4819,8 +5025,6 @@ static enum vkd3d_result vsir_program_materialise_phi_ssas_to_temps_in_function( incoming->dst = ins->dst; alloc.table[ins->dst->reg.idx[0].offset] = temp_idx; - - ++incoming_count; } materialize_ssas_to_temps_process_reg(program, &alloc, &ins->dst->reg); @@ -4829,9 +5033,6 @@ static enum vkd3d_result vsir_program_materialise_phi_ssas_to_temps_in_function( if (!phi_count) goto done; - if (!shader_instruction_array_reserve(&program->instructions, program->instructions.count + incoming_count)) - goto fail; - *it = it_begin; for (ins = vsir_program_iterator_current(it); ins; ins = vsir_program_iterator_next(it)) @@ -4856,7 +5057,8 @@ static enum vkd3d_result vsir_program_materialise_phi_ssas_to_temps_in_function( case VSIR_OP_SWITCH_MONOLITHIC: info = &block_info[current_label - 1]; - mov_ins = vsir_program_iterator_insert_before_and_move(it, info->incoming_count); + if (!(mov_ins = vsir_program_iterator_insert_before_and_move(it, info->incoming_count))) + goto fail; VKD3D_ASSERT(mov_ins); for (j = 0; j < info->incoming_count; ++j) @@ -6782,23 +6984,14 @@ static enum vkd3d_result vsir_cfg_structure_list_emit_block(struct vsir_cfg *cfg struct vsir_cfg_emit_target *target = cfg->target; struct vkd3d_shader_instruction *ins, *end, *dst; struct vsir_program_iterator it; - size_t ins_count = 0; it = block->begin; end = vsir_program_iterator_current(&block->end); for (ins = vsir_program_iterator_current(&it); ins != end; ins = vsir_program_iterator_next(&it)) { - ++ins_count; - } - - if (!shader_instruction_array_reserve(&target->instructions, target->instructions.count + ins_count)) - return VKD3D_ERROR_OUT_OF_MEMORY; - - it = block->begin; - for (ins = vsir_program_iterator_current(&it); ins != end; ins = vsir_program_iterator_next(&it)) - { - dst = shader_instruction_array_append(&target->instructions); + if (!(dst = shader_instruction_array_append(&target->instructions))) + return VKD3D_ERROR_OUT_OF_MEMORY; VKD3D_ASSERT(dst); *dst = *ins; } @@ -6822,10 +7015,8 @@ static enum vkd3d_result vsir_cfg_structure_list_emit_loop(struct vsir_cfg *cfg, if ((ret = vsir_cfg_structure_list_emit(cfg, &loop->body, loop->idx)) < 0) return ret; - if (!shader_instruction_array_reserve(&target->instructions, target->instructions.count + 5)) + if (!(ins = shader_instruction_array_append(&target->instructions))) return VKD3D_ERROR_OUT_OF_MEMORY; - - ins = shader_instruction_array_append(&target->instructions); vsir_instruction_init(ins, &no_loc, VSIR_OP_ENDLOOP); /* Add a trampoline to implement multilevel jumping depending on the stored @@ -6840,7 +7031,8 @@ static enum vkd3d_result vsir_cfg_structure_list_emit_loop(struct vsir_cfg *cfg, * we have to reach an outer loop, so we keep breaking. */ const unsigned int inner_break_target = loop->idx << 1; - ins = shader_instruction_array_append(&target->instructions); + if (!(ins = shader_instruction_array_append(&target->instructions))) + return VKD3D_ERROR_OUT_OF_MEMORY; if (!vsir_instruction_init_with_params(cfg->program, ins, &no_loc, VSIR_OP_IEQ, 1, 2)) { vkd3d_shader_instruction_make_nop(ins); @@ -6853,7 +7045,8 @@ static enum vkd3d_result vsir_cfg_structure_list_emit_loop(struct vsir_cfg *cfg, src_param_init_temp_uint(&ins->src[0], target->jump_target_temp_idx); src_param_init_const_uint(&ins->src[1], outer_continue_target); - ins = shader_instruction_array_append(&target->instructions); + if (!(ins = shader_instruction_array_append(&target->instructions))) + return VKD3D_ERROR_OUT_OF_MEMORY; if (!vsir_instruction_init_with_params(cfg->program, ins, &no_loc, VSIR_OP_CONTINUEP, 0, 1)) { vkd3d_shader_instruction_make_nop(ins); @@ -6875,7 +7068,8 @@ static enum vkd3d_result vsir_cfg_structure_list_emit_loop(struct vsir_cfg *cfg, src_param_init_temp_uint(&ins->src[0], target->jump_target_temp_idx); src_param_init_const_uint(&ins->src[1], inner_break_target); - ins = shader_instruction_array_append(&target->instructions); + if (!(ins = shader_instruction_array_append(&target->instructions))) + return VKD3D_ERROR_OUT_OF_MEMORY; if (!vsir_instruction_init_with_params(cfg->program, ins, &no_loc, VSIR_OP_BREAKP, 0, 1)) { vkd3d_shader_instruction_make_nop(ins); @@ -6971,12 +7165,10 @@ static enum vkd3d_result vsir_cfg_structure_list_emit_jump(struct vsir_cfg *cfg, vkd3d_unreachable(); } - if (!shader_instruction_array_reserve(&target->instructions, target->instructions.count + 2)) - return VKD3D_ERROR_OUT_OF_MEMORY; - if (jump->needs_launcher) { - ins = shader_instruction_array_append(&target->instructions); + if (!(ins = shader_instruction_array_append(&target->instructions))) + return VKD3D_ERROR_OUT_OF_MEMORY; if (!vsir_instruction_init_with_params(cfg->program, ins, &no_loc, VSIR_OP_MOV, 1, 1)) { vkd3d_shader_instruction_make_nop(ins); @@ -6987,7 +7179,8 @@ static enum vkd3d_result vsir_cfg_structure_list_emit_jump(struct vsir_cfg *cfg, src_param_init_const_uint(&ins->src[0], jump_target); } - ins = shader_instruction_array_append(&target->instructions); + if (!(ins = shader_instruction_array_append(&target->instructions))) + return VKD3D_ERROR_OUT_OF_MEMORY; if (!vsir_instruction_init_with_params(cfg->program, ins, &no_loc, opcode, 0, !!jump->condition)) { vkd3d_shader_instruction_make_nop(ins); @@ -8097,35 +8290,41 @@ static enum vkd3d_result insert_fragment_fog_before_ret(struct vsir_program *pro struct vkd3d_shader_instruction *ins = vsir_program_iterator_current(it); struct vkd3d_shader_location loc = ins->location; uint32_t ssa_factor = program->ssa_count++; - uint32_t ssa_temp, ssa_temp2; + uint32_t ssa_temp, ssa_temp2, ssa_temp3; switch (mode) { case VKD3D_SHADER_FOG_FRAGMENT_LINEAR: /* We generate the following code: * - * add sr0, FOG_END, -vFOG.x - * mul_sat srFACTOR, sr0, FOG_SCALE + * neg sr0, vFOG.x + * add sr1, FOG_END, sr0 + * mul_sat srFACTOR, sr1, FOG_SCALE */ - if (!(ins = vsir_program_iterator_insert_before_and_move(it, 4))) + if (!(ins = vsir_program_iterator_insert_before_and_move(it, 6))) return VKD3D_ERROR_OUT_OF_MEMORY; ssa_temp = program->ssa_count++; + ssa_temp2 = program->ssa_count++; - vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_ADD, 1, 2); + vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_NEG, 1, 1); dst_param_init_ssa_float(&ins->dst[0], ssa_temp); + vsir_src_param_init(&ins->src[0], VKD3DSPR_INPUT, VSIR_DATA_F32, 1); + ins->src[0].reg.idx[0].offset = fog_signature_idx; + ins->src[0].reg.dimension = VSIR_DIMENSION_VEC4; + ins->src[0].swizzle = VKD3D_SHADER_SWIZZLE(X, X, X, X); + ins = vsir_program_iterator_next(it); + + vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_ADD, 1, 2); + dst_param_init_ssa_float(&ins->dst[0], ssa_temp2); src_param_init_parameter(&ins->src[0], VKD3D_SHADER_PARAMETER_NAME_FOG_END, VSIR_DATA_F32); - vsir_src_param_init(&ins->src[1], VKD3DSPR_INPUT, VSIR_DATA_F32, 1); - ins->src[1].reg.idx[0].offset = fog_signature_idx; - ins->src[1].reg.dimension = VSIR_DIMENSION_VEC4; - ins->src[1].swizzle = VKD3D_SHADER_SWIZZLE(X, X, X, X); - ins->src[1].modifiers = VKD3DSPSM_NEG; + src_param_init_ssa_float(&ins->src[1], ssa_temp); ins = vsir_program_iterator_next(it); vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_MUL, 1, 2); dst_param_init_ssa_float(&ins->dst[0], ssa_factor); ins->dst[0].modifiers = VKD3DSPDM_SATURATE; - src_param_init_ssa_float(&ins->src[0], ssa_temp); + src_param_init_ssa_float(&ins->src[0], ssa_temp2); src_param_init_parameter(&ins->src[1], VKD3D_SHADER_PARAMETER_NAME_FOG_SCALE, VSIR_DATA_F32); ins = vsir_program_iterator_next(it); @@ -8135,12 +8334,14 @@ static enum vkd3d_result insert_fragment_fog_before_ret(struct vsir_program *pro /* We generate the following code: * * mul sr0, FOG_SCALE, vFOG.x - * exp_sat srFACTOR, -sr0 + * neg sr1, sr0 + * exp_sat srFACTOR, sr1 */ - if (!(ins = vsir_program_iterator_insert_before_and_move(it, 4))) + if (!(ins = vsir_program_iterator_insert_before_and_move(it, 6))) return VKD3D_ERROR_OUT_OF_MEMORY; ssa_temp = program->ssa_count++; + ssa_temp2 = program->ssa_count++; vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_MUL, 1, 2); dst_param_init_ssa_float(&ins->dst[0], ssa_temp); @@ -8151,11 +8352,15 @@ static enum vkd3d_result insert_fragment_fog_before_ret(struct vsir_program *pro ins->src[1].swizzle = VKD3D_SHADER_SWIZZLE(X, X, X, X); ins = vsir_program_iterator_next(it); + vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_NEG, 1, 1); + dst_param_init_ssa_float(&ins->dst[0], ssa_temp2); + src_param_init_ssa_float(&ins->src[0], ssa_temp); + ins = vsir_program_iterator_next(it); + vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_EXP, 1, 1); dst_param_init_ssa_float(&ins->dst[0], ssa_factor); ins->dst[0].modifiers = VKD3DSPDM_SATURATE; - src_param_init_ssa_float(&ins->src[0], ssa_temp); - ins->src[0].modifiers = VKD3DSPSM_NEG; + src_param_init_ssa_float(&ins->src[0], ssa_temp2); ins = vsir_program_iterator_next(it); break; @@ -8164,13 +8369,15 @@ static enum vkd3d_result insert_fragment_fog_before_ret(struct vsir_program *pro * * mul sr0, FOG_SCALE, vFOG.x * mul sr1, sr0, sr0 - * exp_sat srFACTOR, -sr1 + * neg sr2, sr1 + * exp_sat srFACTOR, sr2 */ - if (!(ins = vsir_program_iterator_insert_before_and_move(it, 5))) + if (!(ins = vsir_program_iterator_insert_before_and_move(it, 7))) return VKD3D_ERROR_OUT_OF_MEMORY; ssa_temp = program->ssa_count++; ssa_temp2 = program->ssa_count++; + ssa_temp3 = program->ssa_count++; vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_MUL, 1, 2); dst_param_init_ssa_float(&ins->dst[0], ssa_temp); @@ -8187,11 +8394,15 @@ static enum vkd3d_result insert_fragment_fog_before_ret(struct vsir_program *pro src_param_init_ssa_float(&ins->src[1], ssa_temp); ins = vsir_program_iterator_next(it); + vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_NEG, 1, 1); + dst_param_init_ssa_float(&ins->dst[0], ssa_temp3); + src_param_init_ssa_float(&ins->src[0], ssa_temp2); + ins = vsir_program_iterator_next(it); + vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_EXP, 1, 1); dst_param_init_ssa_float(&ins->dst[0], ssa_factor); ins->dst[0].modifiers = VKD3DSPDM_SATURATE; - src_param_init_ssa_float(&ins->src[0], ssa_temp2); - ins->src[0].modifiers = VKD3DSPSM_NEG; + src_param_init_ssa_float(&ins->src[0], ssa_temp3); ins = vsir_program_iterator_next(it); break; @@ -8201,21 +8412,28 @@ static enum vkd3d_result insert_fragment_fog_before_ret(struct vsir_program *pro /* We generate the following code: * - * add sr0, FRAG_COLOUR, -FOG_COLOUR - * mad oC0, sr0, srFACTOR, FOG_COLOUR + * neg sr0, FOG_COLOUR + * add sr1, FRAG_COLOUR, sr0 + * mad oC0, sr1, srFACTOR, FOG_COLOUR */ + ssa_temp = program->ssa_count++; + ssa_temp2 = program->ssa_count++; + + vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_NEG, 1, 1); + dst_param_init_ssa_float4(&ins->dst[0], ssa_temp); + src_param_init_parameter_vec4(&ins->src[0], VKD3D_SHADER_PARAMETER_NAME_FOG_COLOUR, VSIR_DATA_F32); + ins = vsir_program_iterator_next(it); vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_ADD, 1, 2); - dst_param_init_ssa_float4(&ins->dst[0], program->ssa_count++); + dst_param_init_ssa_float4(&ins->dst[0], ssa_temp2); src_param_init_temp_float4(&ins->src[0], colour_temp); - src_param_init_parameter_vec4(&ins->src[1], VKD3D_SHADER_PARAMETER_NAME_FOG_COLOUR, VSIR_DATA_F32); - ins->src[1].modifiers = VKD3DSPSM_NEG; + src_param_init_ssa_float4(&ins->src[1], ssa_temp); ins = vsir_program_iterator_next(it); vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_MAD, 1, 3); dst_param_init_output(&ins->dst[0], VSIR_DATA_F32, colour_signature_idx, program->output_signature.elements[colour_signature_idx].mask); - src_param_init_ssa_float4(&ins->src[0], program->ssa_count - 1); + src_param_init_ssa_float4(&ins->src[0], ssa_temp2); src_param_init_ssa_float(&ins->src[1], ssa_factor); src_param_init_parameter_vec4(&ins->src[2], VKD3D_SHADER_PARAMETER_NAME_FOG_COLOUR, VSIR_DATA_F32); ins = vsir_program_iterator_next(it); @@ -8560,6 +8778,7 @@ static bool vsir_src_is_masked(enum vkd3d_shader_opcode opcode, unsigned int src case VSIR_OP_MOVC: case VSIR_OP_MSAD: /* FIXME: Is this correct? */ case VSIR_OP_MUL: + case VSIR_OP_NEG: case VSIR_OP_NEO: case VSIR_OP_NEU: case VSIR_OP_NOT: @@ -11482,6 +11701,18 @@ static void vsir_validate_float_elementwise_operation(struct validation_context vsir_validate_elementwise_operation(ctx, instruction, types); } +static void vsir_validate_float_or_double_elementwise_operation(struct validation_context *ctx, + const struct vkd3d_shader_instruction *instruction) +{ + static const bool types[VSIR_DATA_TYPE_COUNT] = + { + [VSIR_DATA_F32] = true, + [VSIR_DATA_F64] = true, + }; + + vsir_validate_elementwise_operation(ctx, instruction, types); +} + static void vsir_validate_integer_elementwise_operation(struct validation_context *ctx, const struct vkd3d_shader_instruction *instruction) { @@ -12534,7 +12765,7 @@ struct vsir_validator_instruction_desc static const struct vsir_validator_instruction_desc vsir_validator_instructions[] = { - [VSIR_OP_ABS] = {1, 1, vsir_validate_float_elementwise_operation}, + [VSIR_OP_ABS] = {1, 1, vsir_validate_float_or_double_elementwise_operation}, [VSIR_OP_ACOS] = {1, 1, vsir_validate_float_elementwise_operation}, [VSIR_OP_ADD] = {1, 2, vsir_validate_float_elementwise_operation}, [VSIR_OP_AND] = {1, 2, vsir_validate_logic_elementwise_operation}, @@ -12629,6 +12860,7 @@ static const struct vsir_validator_instruction_desc vsir_validator_instructions[ [VSIR_OP_MAX] = {1, 2, vsir_validate_float_elementwise_operation}, [VSIR_OP_MIN] = {1, 2, vsir_validate_float_elementwise_operation}, [VSIR_OP_MUL] = {1, 2, vsir_validate_float_elementwise_operation}, + [VSIR_OP_NEG] = {1, 1, vsir_validate_float_or_double_elementwise_operation}, [VSIR_OP_NEO] = {1, 2, vsir_validate_float_comparison_operation}, [VSIR_OP_NEU] = {1, 2, vsir_validate_float_comparison_operation}, [VSIR_OP_NOP] = {0, 0, vsir_validate_nop}, @@ -12899,8 +13131,6 @@ static void vsir_transform_( struct vsir_transformation_context *ctx, const char *step_name, enum vkd3d_result (*step)(struct vsir_program *program, struct vsir_transformation_context *ctx)) { - ctx->progress = false; - if (ctx->result < 0) return; @@ -13050,6 +13280,7 @@ static bool vsir_instruction_has_side_effects(const struct vkd3d_shader_instruct case VSIR_OP_MOVC: case VSIR_OP_MSAD: case VSIR_OP_MUL: + case VSIR_OP_NEG: case VSIR_OP_NEO: case VSIR_OP_NEU: case VSIR_OP_NOP: @@ -13317,6 +13548,229 @@ static enum vkd3d_result vsir_program_dce(struct vsir_program *program, return VKD3D_OK; } +/* + * This pass attempts to reduce redundant MOVs (copies) by combining them with + * adjacent instructions. The resulting MOVs will subsequently be removed by + * DCE if no longer used. + * + * We attempt to combine two instructions, not necessarily consecutive, + * of the form + * + * mov aaa.bbb, ccc + * XXX ..., aaa.ddd + * + * into + * + * XXX ..., ccc + * + * There are many constraints, including: + * + * - The ddd components of aaa must not have been modified between the + * two instructions. + * Currently, only SSA is supported, so this is trivial. + * + * - The relevant components of ccc must not have been modified between the + * two instructions. + * Currently, we require ccc to be a read-only register, so this is trivial. + * + * - ddd must be a subset of bbb. This is again trivial for SSA. + */ + +struct vsir_copy_propagation_state +{ + /* The sources for each SSA register, if it was written by a + * MOV instruction, or NULL if not. + * + * We do not add or remove instructions in this pass, only modifying their + * content, so these pointers are safe to store. + */ + const struct vkd3d_shader_instruction **ssa_sources; +}; + +static bool is_read_only(const struct vsir_program *program, enum vkd3d_shader_register_type type) +{ + switch (type) + { + case VKD3DSPR_ADDR: + case VKD3DSPR_IDXTEMP: + case VKD3DSPR_LOOP: + case VKD3DSPR_TEMP: + case VKD3DSPR_TEMPFLOAT16: + return false; + + case VKD3DSPR_TEXTURE: + return vkd3d_shader_ver_ge(&program->shader_version, 1, 4); + + /* Not applicable since they're not numeric or can't be sources. */ + case VKD3DSPR_ATTROUT: + case VKD3DSPR_COLOROUT: + case VKD3DSPR_COMBINED_SAMPLER: + case VKD3DSPR_COUNT: + case VKD3DSPR_DEPTHOUT: + case VKD3DSPR_DEPTHOUTGE: + case VKD3DSPR_DEPTHOUTLE: + case VKD3DSPR_FUNCTIONBODY: + case VKD3DSPR_FUNCTIONPOINTER: + case VKD3DSPR_GROUPSHAREDMEM: + case VKD3DSPR_INVALID: + case VKD3DSPR_LABEL: + case VKD3DSPR_NULL: + case VKD3DSPR_OUTPUT: + case VKD3DSPR_OUTSTENCILREF: + case VKD3DSPR_PREDICATE: + case VKD3DSPR_RASTERIZER: + case VKD3DSPR_RASTOUT: + case VKD3DSPR_RESOURCE: + case VKD3DSPR_SAMPLER: + case VKD3DSPR_STREAM: + case VKD3DSPR_TEXCRDOUT: + case VKD3DSPR_UAV: + return false; + + case VKD3DSPR_CONST: + case VKD3DSPR_CONSTBOOL: + case VKD3DSPR_CONSTBUFFER: + case VKD3DSPR_CONSTINT: + case VKD3DSPR_COVERAGE: + case VKD3DSPR_FORKINSTID: + case VKD3DSPR_GSINSTID: + case VKD3DSPR_IMMCONST: + case VKD3DSPR_IMMCONST64: + case VKD3DSPR_IMMCONSTBUFFER: + case VKD3DSPR_INCONTROLPOINT: + case VKD3DSPR_INPUT: + case VKD3DSPR_JOININSTID: + case VKD3DSPR_LOCALTHREADID: + case VKD3DSPR_LOCALTHREADINDEX: + case VKD3DSPR_MISCTYPE: + case VKD3DSPR_OUTCONTROLPOINT: + case VKD3DSPR_OUTPOINTID: + case VKD3DSPR_PARAMETER: + case VKD3DSPR_PATCHCONST: + case VKD3DSPR_POINT_COORD: + case VKD3DSPR_PRIMID: + case VKD3DSPR_SAMPLEMASK: + case VKD3DSPR_SSA: + case VKD3DSPR_TESSCOORD: + case VKD3DSPR_THREADGROUPID: + case VKD3DSPR_THREADID: + case VKD3DSPR_UNDEF: + case VKD3DSPR_WAVELANECOUNT: + case VKD3DSPR_WAVELANEINDEX: + return true; + } + + vkd3d_unreachable(); +} + +static bool can_propagate_ssa_source(const struct vsir_program *program, const struct vkd3d_shader_instruction *ins) +{ + if (ins->opcode != VSIR_OP_MOV) + return false; + /* TODO: Propagate copies for other register types. */ + if (ins->dst[0].reg.type != VKD3DSPR_SSA) + return false; + if (ins->dst[0].modifiers || ins->dst[0].shift) + return false; + + /* TODO: We can perform copy-prop for read-write register types, but we + * have to be sure that the register wasn't modified between the two + * instructions. */ + if (!is_read_only(program, ins->src[0].reg.type)) + return false; + for (unsigned int k = 0; k < ins->src[0].reg.idx_count; ++k) + { + if (ins->src[0].reg.idx[k].rel_addr && !is_read_only(program, ins->src[0].reg.idx[k].rel_addr->reg.type)) + return false; + } + + /* Don't bother with other source modifiers for now; the HLSL compiler + * doesn't emit them. */ + switch (ins->src[0].modifiers) + { + case VKD3DSPSM_ABS: + case VKD3DSPSM_ABSNEG: + case VKD3DSPSM_NEG: + case VKD3DSPSM_NONE: + break; + + default: + return false; + } + return true; +} + +static enum vkd3d_result vsir_program_copy_propagation(struct vsir_program *program, + struct vsir_transformation_context *ctx) +{ + struct vsir_program_iterator it = vsir_program_iterator(&program->instructions); + struct vsir_copy_propagation_state state = {0}; + struct vkd3d_shader_instruction *ins; + + if (!(state.ssa_sources = vkd3d_calloc(program->ssa_count, sizeof(*state.ssa_sources)))) + return VKD3D_ERROR_OUT_OF_MEMORY; + + for (ins = vsir_program_iterator_head(&it); ins; ins = vsir_program_iterator_next(&it)) + { + for (unsigned int j = 0; j < ins->src_count; ++j) + { + struct vkd3d_shader_src_param *src = &ins->src[j]; + const struct vkd3d_shader_src_param *mov_src; + const struct vkd3d_shader_instruction *mov; + enum vsir_data_type data_type; + uint32_t new_swizzle = 0; + + if (src->reg.type != VKD3DSPR_SSA) + continue; + if (data_type_is_64_bit(src->reg.data_type)) + continue; + if (!(mov = state.ssa_sources[src->reg.idx[0].offset])) + continue; + mov_src = &mov->src[0]; + data_type = src->reg.data_type; + + src->reg = mov_src->reg; + src->reg.data_type = data_type; + + if (!shader_register_clone_relative_addresses(&src->reg, program)) + { + vkd3d_free(state.ssa_sources); + return VKD3D_ERROR_OUT_OF_MEMORY; + } + + for (unsigned int k = 0; k < 4; ++k) + { + unsigned int s = vsir_swizzle_get_component(src->swizzle, k); + + if (mov_src->reg.type == VKD3DSPR_IMMCONST) + src->reg.u.immconst_u32[k] = mov_src->reg.u.immconst_u32[s]; + else + vsir_swizzle_set_component(&new_swizzle, k, vsir_swizzle_get_component(mov_src->swizzle, s)); + } + if (mov_src->reg.type != VKD3DSPR_IMMCONST) + src->swizzle = new_swizzle; + + if (src->modifiers == VKD3DSPSM_NONE) + src->modifiers = mov_src->modifiers; + else if (src->modifiers == VKD3DSPSM_NEG && mov_src->modifiers == VKD3DSPSM_ABS) + src->modifiers = VKD3DSPSM_ABSNEG; + else if (src->modifiers == VKD3DSPSM_NEG && mov_src->modifiers == VKD3DSPSM_ABSNEG) + src->modifiers = VKD3DSPSM_ABS; + else if (src->modifiers == VKD3DSPSM_NEG && mov_src->modifiers == VKD3DSPSM_NEG) + src->modifiers = VKD3DSPSM_NONE; + /* Otherwise no change is necessary. */ + + ctx->progress = true; + } + + if (can_propagate_ssa_source(program, ins)) + state.ssa_sources[ins->dst[0].reg.idx[0].offset] = ins; + } + + vkd3d_free(state.ssa_sources); + return VKD3D_OK; +} + enum vkd3d_result vsir_program_optimize(struct vsir_program *program, uint64_t config_flags, const struct vkd3d_shader_compile_info *compile_info, struct vkd3d_shader_message_context *message_context) { @@ -13325,7 +13779,11 @@ enum vkd3d_result vsir_program_optimize(struct vsir_program *program, uint64_t c vsir_transformation_context_init(&ctx, program, config_flags, compile_info, message_context); do + { + ctx.progress = false; + vsir_transform(&ctx, vsir_program_copy_propagation); vsir_transform(&ctx, vsir_program_dce); + } while (ctx.progress); if (TRACE_ON()) @@ -13388,6 +13846,7 @@ enum vkd3d_result vsir_program_transform(struct vsir_program *program, uint64_t struct vsir_transformation_context ctx; vsir_transformation_context_init(&ctx, program, config_flags, compile_info, message_context); + vsir_transform(&ctx, vsir_program_lower_modifiers); vsir_transform(&ctx, vsir_program_lower_instructions); if (program->shader_version.major >= 6) diff --git a/libs/vkd3d/libs/vkd3d-shader/msl.c b/libs/vkd3d/libs/vkd3d-shader/msl.c index 8a89dcabd5e..fc136e3ac98 100644 --- a/libs/vkd3d/libs/vkd3d-shader/msl.c +++ b/libs/vkd3d/libs/vkd3d-shader/msl.c @@ -602,25 +602,11 @@ static void msl_print_src_with_type(struct vkd3d_string_buffer *buffer, struct m if (reg->dimension == VSIR_DIMENSION_VEC4) msl_print_swizzle(str, vsir_src->swizzle, mask); - switch (vsir_src->modifiers) + if (vsir_src->modifiers) { - case VKD3DSPSM_NONE: - break; - case VKD3DSPSM_NEG: - vkd3d_string_buffer_printf(buffer, "-%s", str->buffer); - break; - case VKD3DSPSM_ABS: - vkd3d_string_buffer_printf(buffer, "abs(%s)", str->buffer); - break; - case VKD3DSPSM_ABSNEG: - vkd3d_string_buffer_printf(buffer, "-abs(%s)", str->buffer); - break; - default: - vkd3d_string_buffer_printf(buffer, "(%s)", - vsir_src->modifiers, str->buffer); - msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, - "Internal compiler error: Unhandled source modifier(s) %#x.", vsir_src->modifiers); - break; + vkd3d_string_buffer_printf(buffer, "(%s)", vsir_src->modifiers, str->buffer); + msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, + "Internal compiler error: Unhandled source modifier(s) %#x.", vsir_src->modifiers); } if (str != buffer) @@ -1472,6 +1458,9 @@ static void msl_handle_instruction(struct msl_generator *gen, const struct vkd3d switch (ins->opcode) { + case VSIR_OP_ABS: + msl_intrinsic(gen, ins, "abs"); + break; case VSIR_OP_ACOS: msl_intrinsic(gen, ins, "acos"); break; @@ -1624,6 +1613,7 @@ static void msl_handle_instruction(struct msl_generator *gen, const struct vkd3d msl_relop(gen, ins, "!="); break; case VSIR_OP_INEG: + case VSIR_OP_NEG: msl_unary_op(gen, ins, "-"); break; case VSIR_OP_ITOF: diff --git a/libs/vkd3d/libs/vkd3d-shader/spirv.c b/libs/vkd3d/libs/vkd3d-shader/spirv.c index 3deca660b00..31271660e4f 100644 --- a/libs/vkd3d/libs/vkd3d-shader/spirv.c +++ b/libs/vkd3d/libs/vkd3d-shader/spirv.c @@ -989,7 +989,7 @@ struct vkd3d_spirv_builder uint32_t type_bool_id; uint32_t type_void_id; uint32_t scope_subgroup_id; - uint32_t numeric_type_ids[VKD3D_SHADER_COMPONENT_TYPE_COUNT][VKD3D_VEC4_SIZE]; + uint32_t numeric_type_ids[VSIR_DATA_TYPE_COUNT][VKD3D_VEC4_SIZE]; struct vkd3d_spirv_stream debug_stream; /* debug instructions */ struct vkd3d_spirv_stream annotation_stream; /* decoration instructions */ @@ -2116,20 +2116,6 @@ static uint32_t vkd3d_spirv_build_op_fdiv(struct vkd3d_spirv_builder *builder, SpvOpFDiv, result_type, operand0, operand1); } -static uint32_t vkd3d_spirv_build_op_fnegate(struct vkd3d_spirv_builder *builder, - uint32_t result_type, uint32_t operand) -{ - return vkd3d_spirv_build_op_tr1(builder, &builder->function_stream, - SpvOpFNegate, result_type, operand); -} - -static uint32_t vkd3d_spirv_build_op_snegate(struct vkd3d_spirv_builder *builder, - uint32_t result_type, uint32_t operand) -{ - return vkd3d_spirv_build_op_tr1(builder, &builder->function_stream, - SpvOpSNegate, result_type, operand); -} - static uint32_t vkd3d_spirv_build_op_and(struct vkd3d_spirv_builder *builder, uint32_t result_type, uint32_t operand0, uint32_t operand1) { @@ -2478,19 +2464,6 @@ static uint32_t vkd3d_spirv_build_op_group_nonuniform_broadcast_first(struct vkd result_type, vkd3d_spirv_get_op_scope_subgroup(builder), val_id); } -static uint32_t vkd3d_spirv_build_op_glsl_std450_tr1(struct vkd3d_spirv_builder *builder, - enum GLSLstd450 op, uint32_t result_type, uint32_t operand) -{ - uint32_t id = vkd3d_spirv_get_glsl_std450_instr_set(builder); - return vkd3d_spirv_build_op_ext_inst(builder, result_type, id, op, &operand, 1); -} - -static uint32_t vkd3d_spirv_build_op_glsl_std450_fabs(struct vkd3d_spirv_builder *builder, - uint32_t result_type, uint32_t operand) -{ - return vkd3d_spirv_build_op_glsl_std450_tr1(builder, GLSLstd450FAbs, result_type, operand); -} - static uint32_t vkd3d_spirv_build_op_glsl_std450_max(struct vkd3d_spirv_builder *builder, uint32_t result_type, uint32_t x, uint32_t y) { @@ -2518,71 +2491,69 @@ static uint32_t vkd3d_spirv_build_op_glsl_std450_nclamp(struct vkd3d_spirv_build GLSLstd450NClamp, operands, ARRAY_SIZE(operands)); } -static uint32_t spirv_get_type_id_for_component_type(struct vkd3d_spirv_builder *builder, - enum vkd3d_shader_component_type component_type, unsigned int component_count) +static uint32_t spirv_get_type_id(struct vkd3d_spirv_builder *builder, + enum vsir_data_type data_type, unsigned int component_count) { uint32_t scalar_id, type_id; - VKD3D_ASSERT(component_type < VKD3D_SHADER_COMPONENT_TYPE_COUNT); + VKD3D_ASSERT(data_type < VSIR_DATA_TYPE_COUNT); if (!component_count || component_count > VKD3D_VEC4_SIZE) { ERR("Invalid component count %u.\n", component_count); return 0; } - if ((type_id = builder->numeric_type_ids[component_type][component_count - 1])) + if ((type_id = builder->numeric_type_ids[data_type][component_count - 1])) return type_id; if (component_count == 1) { - switch (component_type) + switch (data_type) { - case VKD3D_SHADER_COMPONENT_VOID: - type_id = vkd3d_spirv_get_op_type_void(builder); + case VSIR_DATA_BOOL: + type_id = vkd3d_spirv_get_op_type_bool(builder); break; - case VKD3D_SHADER_COMPONENT_FLOAT: + + case VSIR_DATA_F32: type_id = vkd3d_spirv_get_op_type_float(builder, 32); break; - case VKD3D_SHADER_COMPONENT_INT: - case VKD3D_SHADER_COMPONENT_UINT: - type_id = vkd3d_spirv_get_op_type_int(builder, 32, component_type == VKD3D_SHADER_COMPONENT_INT); + + case VSIR_DATA_F64: + type_id = vkd3d_spirv_get_op_type_float(builder, 64); break; - case VKD3D_SHADER_COMPONENT_BOOL: - type_id = vkd3d_spirv_get_op_type_bool(builder); + + case VSIR_DATA_I32: + case VSIR_DATA_U32: + type_id = vkd3d_spirv_get_op_type_int(builder, 32, data_type == VSIR_DATA_I32); break; - case VKD3D_SHADER_COMPONENT_DOUBLE: - type_id = vkd3d_spirv_get_op_type_float(builder, 64); + + case VSIR_DATA_I64: + case VSIR_DATA_U64: + type_id = vkd3d_spirv_get_op_type_int(builder, 64, data_type == VSIR_DATA_I64); break; - case VKD3D_SHADER_COMPONENT_INT64: - case VKD3D_SHADER_COMPONENT_UINT64: - type_id = vkd3d_spirv_get_op_type_int(builder, 64, component_type == VKD3D_SHADER_COMPONENT_INT64); + + case VSIR_DATA_UNUSED: + type_id = vkd3d_spirv_get_op_type_void(builder); break; + default: - FIXME("Unhandled component type %#x.\n", component_type); + FIXME("Unhandled data type \"%s\" (%#x).\n", + vsir_data_type_get_name(data_type, ""), data_type); return 0; } } else { - VKD3D_ASSERT(component_type != VKD3D_SHADER_COMPONENT_VOID); - scalar_id = spirv_get_type_id_for_component_type(builder, component_type, 1); + VKD3D_ASSERT(data_type != VSIR_DATA_UNUSED); + scalar_id = spirv_get_type_id(builder, data_type, 1); type_id = vkd3d_spirv_get_op_type_vector(builder, scalar_id, component_count); } - builder->numeric_type_ids[component_type][component_count - 1] = type_id; + builder->numeric_type_ids[data_type][component_count - 1] = type_id; return type_id; } -static uint32_t spirv_get_type_id(struct vkd3d_spirv_builder *builder, - enum vsir_data_type data_type, unsigned int component_count) -{ - enum vkd3d_shader_component_type component_type; - - component_type = vkd3d_component_type_from_data_type(data_type); - return spirv_get_type_id_for_component_type(builder, component_type, component_count); -} - static void vkd3d_spirv_builder_init(struct vkd3d_spirv_builder *builder, const char *entry_point, const char *source_name) { @@ -4846,74 +4817,23 @@ static void spirv_compiler_emit_execution_mode1(struct spirv_compiler *compiler, spirv_compiler_emit_execution_mode(compiler, mode, &literal, 1); } -static uint32_t spirv_compiler_emit_abs(struct spirv_compiler *compiler, - const struct vkd3d_shader_register *reg, uint32_t write_mask, uint32_t val_id) -{ - struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; - uint32_t type_id; - - type_id = spirv_compiler_get_type_id_for_reg(compiler, reg, write_mask); - if (data_type_is_floating_point(reg->data_type)) - return vkd3d_spirv_build_op_glsl_std450_fabs(builder, type_id, val_id); - - FIXME("Unhandled data type %#x.\n", reg->data_type); - return val_id; -} - -static uint32_t spirv_compiler_emit_neg(struct spirv_compiler *compiler, - const struct vkd3d_shader_register *reg, uint32_t write_mask, uint32_t val_id) -{ - struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; - uint32_t type_id; - - type_id = spirv_compiler_get_type_id_for_reg(compiler, reg, write_mask); - if (data_type_is_floating_point(reg->data_type)) - return vkd3d_spirv_build_op_fnegate(builder, type_id, val_id); - else if (data_type_is_integer(reg->data_type)) - return vkd3d_spirv_build_op_snegate(builder, type_id, val_id); - - FIXME("Unhandled data type %#x.\n", reg->data_type); - return val_id; -} - -static uint32_t spirv_compiler_emit_src_modifier(struct spirv_compiler *compiler, - const struct vkd3d_shader_register *reg, uint32_t write_mask, - enum vkd3d_shader_src_modifier modifier, uint32_t val_id) -{ - switch (modifier) - { - case VKD3DSPSM_NONE: - break; - case VKD3DSPSM_NEG: - return spirv_compiler_emit_neg(compiler, reg, write_mask, val_id); - case VKD3DSPSM_ABS: - return spirv_compiler_emit_abs(compiler, reg, write_mask, val_id); - case VKD3DSPSM_ABSNEG: - val_id = spirv_compiler_emit_abs(compiler, reg, write_mask, val_id); - return spirv_compiler_emit_neg(compiler, reg, write_mask, val_id); - default: - FIXME("Unhandled src modifier %#x.\n", modifier); - break; - } - - return val_id; -} - static uint32_t spirv_compiler_emit_load_src(struct spirv_compiler *compiler, const struct vkd3d_shader_src_param *src, uint32_t write_mask) { - uint32_t val_id; + if (src->modifiers) + spirv_compiler_error(compiler, VKD3D_SHADER_ERROR_SPV_NOT_IMPLEMENTED, + "Unhandled source modifier(s) %#x.", src->modifiers); - val_id = spirv_compiler_emit_load_reg(compiler, &src->reg, src->swizzle, write_mask); - return spirv_compiler_emit_src_modifier(compiler, &src->reg, write_mask, src->modifiers, val_id); + return spirv_compiler_emit_load_reg(compiler, &src->reg, src->swizzle, write_mask); } static uint32_t spirv_compiler_emit_load_src_with_type(struct spirv_compiler *compiler, - const struct vkd3d_shader_src_param *src, uint32_t write_mask, enum vkd3d_shader_component_type component_type) + const struct vkd3d_shader_src_param *src, uint32_t write_mask, enum vsir_data_type data_type) { struct vkd3d_shader_src_param src_param = *src; - src_param.reg.data_type = vsir_data_type_from_component_type(component_type); + src_param.reg.data_type = data_type; + return spirv_compiler_emit_load_src(compiler, &src_param, write_mask); } @@ -5081,10 +5001,8 @@ static void spirv_compiler_emit_store_dst(struct spirv_compiler *compiler, } static void spirv_compiler_emit_store_dst_swizzled(struct spirv_compiler *compiler, - const struct vkd3d_shader_dst_param *dst, uint32_t val_id, - enum vkd3d_shader_component_type component_type, uint32_t swizzle) + const struct vkd3d_shader_dst_param *dst, uint32_t val_id, enum vsir_data_type data_type, uint32_t swizzle) { - enum vsir_data_type data_type = vsir_data_type_from_component_type(component_type); struct vkd3d_shader_dst_param typed_dst = *dst; val_id = spirv_compiler_emit_swizzle(compiler, val_id, @@ -5096,23 +5014,17 @@ static void spirv_compiler_emit_store_dst_swizzled(struct spirv_compiler *compil } static void spirv_compiler_emit_store_dst_components(struct spirv_compiler *compiler, - const struct vkd3d_shader_dst_param *dst, enum vkd3d_shader_component_type component_type, - uint32_t *component_ids) + const struct vkd3d_shader_dst_param *dst, enum vsir_data_type data_type, uint32_t *component_ids) { unsigned int component_count = vsir_write_mask_component_count(dst->write_mask); struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; uint32_t type_id, dst_type_id, val_id; - type_id = spirv_get_type_id_for_component_type(builder, component_type, component_count); + type_id = spirv_get_type_id(builder, data_type, component_count); if (component_count > 1) - { - val_id = vkd3d_spirv_build_op_composite_construct(builder, - type_id, component_ids, component_count); - } + val_id = vkd3d_spirv_build_op_composite_construct(builder, type_id, component_ids, component_count); else - { val_id = *component_ids; - } dst_type_id = spirv_get_type_id(builder, dst->reg.data_type, component_count); if (dst_type_id != type_id) @@ -5122,8 +5034,7 @@ static void spirv_compiler_emit_store_dst_components(struct spirv_compiler *comp } static void spirv_compiler_emit_store_dst_scalar(struct spirv_compiler *compiler, - const struct vkd3d_shader_dst_param *dst, uint32_t val_id, - enum vkd3d_shader_component_type component_type, uint32_t swizzle) + const struct vkd3d_shader_dst_param *dst, uint32_t val_id, enum vsir_data_type data_type, uint32_t swizzle) { unsigned int component_count = vsir_write_mask_component_count(dst->write_mask); uint32_t component_ids[VKD3D_VEC4_SIZE]; @@ -5137,7 +5048,7 @@ static void spirv_compiler_emit_store_dst_scalar(struct spirv_compiler *compiler component_ids[i] = val_id; } - spirv_compiler_emit_store_dst_components(compiler, dst, component_type, component_ids); + spirv_compiler_emit_store_dst_components(compiler, dst, data_type, component_ids); } static void spirv_compiler_decorate_builtin(struct spirv_compiler *compiler, @@ -5229,7 +5140,7 @@ static void spirv_compiler_decorate_builtin(struct spirv_compiler *compiler, } static void spirv_compiler_emit_interpolation_decorations(struct spirv_compiler *compiler, - enum vkd3d_shader_component_type component_type, uint32_t id, enum vkd3d_shader_interpolation_mode mode) + enum vsir_data_type data_type, uint32_t id, enum vkd3d_shader_interpolation_mode mode) { struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; @@ -5238,7 +5149,7 @@ static void spirv_compiler_emit_interpolation_decorations(struct spirv_compiler case VKD3DSIM_NONE: /* VUID-StandaloneSpirv-Flat-04744: integer or double types must be * decorated 'Flat' for fragment shaders. */ - if (compiler->shader_type != VKD3D_SHADER_TYPE_PIXEL || component_type == VKD3D_SHADER_COMPONENT_FLOAT) + if (compiler->shader_type != VKD3D_SHADER_TYPE_PIXEL || data_type == VSIR_DATA_F32) break; /* fall through */ case VKD3DSIM_CONSTANT: @@ -5724,7 +5635,6 @@ static void spirv_compiler_emit_input(struct spirv_compiler *compiler, unsigned int component_idx, input_component_count; const struct signature_element *signature_element; const struct shader_signature *shader_signature; - enum vkd3d_shader_component_type component_type; enum vkd3d_shader_register_type sysval_reg_type; const struct vkd3d_spirv_builtin *builtin; enum vkd3d_shader_sysval_semantic sysval; @@ -5782,13 +5692,11 @@ static void spirv_compiler_emit_input(struct spirv_compiler *compiler, if (builtin) { data_type = builtin->data_type; - component_type = vkd3d_component_type_from_data_type(data_type); input_component_count = builtin->component_count; } else { - component_type = signature_element->component_type; - data_type = vsir_data_type_from_component_type(component_type); + data_type = vsir_data_type_from_component_type(signature_element->component_type); input_component_count = vsir_write_mask_component_count(signature_element->mask); } @@ -5841,8 +5749,8 @@ static void spirv_compiler_emit_input(struct spirv_compiler *compiler, if (component_idx) vkd3d_spirv_build_op_decorate1(builder, input_id, SpvDecorationComponent, component_idx); - spirv_compiler_emit_interpolation_decorations(compiler, component_type, input_id, - signature_element->interpolation_mode); + spirv_compiler_emit_interpolation_decorations(compiler, data_type, + input_id, signature_element->interpolation_mode); } var_id = input_id; @@ -6879,7 +6787,7 @@ static const struct vkd3d_spirv_resource_type *spirv_compiler_enable_resource_ty return resource_type_info; } -static SpvImageFormat image_format_for_image_read(enum vkd3d_shader_component_type data_type) +static SpvImageFormat image_format_for_image_read(enum vsir_data_type data_type) { /* The following formats are supported by Direct3D 11 hardware for UAV * typed loads. A newer hardware may support more formats for UAV typed @@ -6887,11 +6795,11 @@ static SpvImageFormat image_format_for_image_read(enum vkd3d_shader_component_ty */ switch (data_type) { - case VKD3D_SHADER_COMPONENT_FLOAT: + case VSIR_DATA_F32: return SpvImageFormatR32f; - case VKD3D_SHADER_COMPONENT_INT: + case VSIR_DATA_I32: return SpvImageFormatR32i; - case VKD3D_SHADER_COMPONENT_UINT: + case VSIR_DATA_U32: return SpvImageFormatR32ui; default: FIXME("Unhandled type %#x.\n", data_type); @@ -6901,8 +6809,7 @@ static SpvImageFormat image_format_for_image_read(enum vkd3d_shader_component_ty static uint32_t spirv_compiler_get_image_type_id(struct spirv_compiler *compiler, const struct vkd3d_shader_register *reg, const struct vkd3d_shader_register_range *range, - const struct vkd3d_spirv_resource_type *resource_type_info, enum vkd3d_shader_component_type data_type, - bool raw_structured) + const struct vkd3d_spirv_resource_type *resource_type_info, enum vsir_data_type data_type, bool raw_structured) { struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; const struct vkd3d_shader_descriptor_info1 *d; @@ -6923,15 +6830,15 @@ static uint32_t spirv_compiler_get_image_type_id(struct spirv_compiler *compiler vkd3d_spirv_enable_capability(builder, SpvCapabilityStorageImageReadWithoutFormat); } - sampled_type_id = spirv_get_type_id_for_component_type(builder, data_type, 1); - return vkd3d_spirv_get_op_type_image(builder, sampled_type_id, resource_type_info->dim, - 2, resource_type_info->arrayed, resource_type_info->ms, - reg->type == VKD3DSPR_UAV ? 2 : 1, format); + sampled_type_id = spirv_get_type_id(builder, data_type, 1); + + return vkd3d_spirv_get_op_type_image(builder, sampled_type_id, resource_type_info->dim, 2, + resource_type_info->arrayed, resource_type_info->ms, reg->type == VKD3DSPR_UAV ? 2 : 1, format); } static void spirv_compiler_emit_combined_sampler_declarations(struct spirv_compiler *compiler, const struct vkd3d_shader_register *resource, const struct vkd3d_shader_register_range *resource_range, - enum vkd3d_shader_resource_type resource_type, enum vkd3d_shader_component_type sampled_type, + enum vkd3d_shader_resource_type resource_type, enum vsir_data_type sampled_type, unsigned int structure_stride, bool raw, const struct vkd3d_spirv_resource_type *resource_type_info) { const struct vkd3d_shader_interface_info *shader_interface = &compiler->shader_interface; @@ -6992,7 +6899,7 @@ static void spirv_compiler_emit_combined_sampler_declarations(struct spirv_compi symbol.id = var_id; symbol.descriptor_array = NULL; symbol.info.resource.range = *resource_range; - symbol.info.resource.sampled_type = vsir_data_type_from_component_type(sampled_type); + symbol.info.resource.sampled_type = sampled_type; symbol.info.resource.type_id = image_type_id; symbol.info.resource.resource_type_info = resource_type_info; symbol.info.resource.structure_stride = structure_stride; @@ -7017,9 +6924,9 @@ static void spirv_compiler_emit_resource_declaration(struct spirv_compiler *comp uint32_t counter_type_id, type_id, var_id, counter_var_id = 0; const struct vkd3d_spirv_resource_type *resource_type_info; unsigned int sample_count = descriptor->sample_count; - enum vkd3d_shader_component_type sampled_type; struct vkd3d_symbol resource_symbol; struct vkd3d_shader_register reg; + enum vsir_data_type sampled_type; vsir_register_init(®, is_uav ? VKD3DSPR_UAV : VKD3DSPR_RESOURCE, VSIR_DATA_F32, 1); reg.idx[0].offset = descriptor->register_id; @@ -7036,7 +6943,7 @@ static void spirv_compiler_emit_resource_declaration(struct spirv_compiler *comp return; } - sampled_type = vkd3d_component_type_from_data_type(descriptor->resource_data_type); + sampled_type = descriptor->resource_data_type; if (!is_uav && spirv_compiler_has_combined_sampler_for_resource(compiler, range)) { @@ -7049,7 +6956,7 @@ static void spirv_compiler_emit_resource_declaration(struct spirv_compiler *comp { uint32_t array_type_id, struct_id; - type_id = spirv_get_type_id(builder, descriptor->resource_data_type, 1); + type_id = spirv_get_type_id(builder, sampled_type, 1); array_type_id = vkd3d_spirv_get_op_type_runtime_array(builder, type_id); vkd3d_spirv_build_op_decorate1(builder, array_type_id, SpvDecorationArrayStride, 4); @@ -7122,7 +7029,7 @@ static void spirv_compiler_emit_resource_declaration(struct spirv_compiler *comp resource_symbol.id = var_id; resource_symbol.descriptor_array = var_info.array_symbol; resource_symbol.info.resource.range = *range; - resource_symbol.info.resource.sampled_type = descriptor->resource_data_type; + resource_symbol.info.resource.sampled_type = sampled_type; resource_symbol.info.resource.type_id = type_id; resource_symbol.info.resource.resource_type_info = resource_type_info; resource_symbol.info.resource.structure_stride = structure_stride; @@ -7564,6 +7471,7 @@ static SpvOp spirv_compiler_map_alu_instruction(const struct vkd3d_shader_instru {VSIR_OP_ITOF, SpvOpConvertSToF}, {VSIR_OP_ITOI, SpvOpSConvert}, {VSIR_OP_MUL, SpvOpFMul}, + {VSIR_OP_NEG, SpvOpFNegate}, {VSIR_OP_NOT, SpvOpNot}, {VSIR_OP_OR, SpvOpBitwiseOr}, {VSIR_OP_UDIV_SIMPLE, SpvOpUDiv}, @@ -7641,14 +7549,13 @@ static void spirv_compiler_emit_bool_cast(struct spirv_compiler *compiler, static enum vkd3d_result spirv_compiler_emit_alu_instruction(struct spirv_compiler *compiler, const struct vkd3d_shader_instruction *instruction) { - uint32_t src_ids[SPIRV_MAX_SRC_COUNT], condition_id = 0, uint_max_id = 0; struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; const struct vkd3d_shader_dst_param *dst = instruction->dst; const struct vkd3d_shader_src_param *src = instruction->src; - unsigned int i, component_count; + uint32_t src_ids[SPIRV_MAX_SRC_COUNT]; uint32_t type_id, val_id; SpvOp op = SpvOpMax; - bool check_zero; + unsigned int i; if (src->reg.data_type == VSIR_DATA_U64 && instruction->opcode == VSIR_OP_COUNTBITS) { @@ -7688,44 +7595,14 @@ static enum vkd3d_result spirv_compiler_emit_alu_instruction(struct spirv_compil return VKD3D_ERROR_INVALID_SHADER; } - /* SPIR-V doesn't mandate a behaviour when a denominator is zero, - * so we have an explicit check. */ - switch (instruction->opcode) - { - case VSIR_OP_IDIV: - case VSIR_OP_IREM: - case VSIR_OP_UDIV_SIMPLE: - case VSIR_OP_UREM: - check_zero = true; - break; - - default: - check_zero = false; - break; - } - VKD3D_ASSERT(instruction->dst_count == 1); VKD3D_ASSERT(instruction->src_count <= SPIRV_MAX_SRC_COUNT); - if (check_zero) - VKD3D_ASSERT(instruction->src_count == 2); - component_count = vsir_write_mask_component_count(dst[0].write_mask); type_id = spirv_compiler_get_type_id_for_dst(compiler, dst); for (i = 0; i < instruction->src_count; ++i) src_ids[i] = spirv_compiler_emit_load_src(compiler, &src[i], dst->write_mask); - if (check_zero) - { - condition_id = spirv_compiler_emit_int_to_bool(compiler, - VKD3D_SHADER_CONDITIONAL_OP_NZ, src[1].reg.data_type, component_count, src_ids[1]); - - if (data_type_is_64_bit(dst[0].reg.data_type)) - uint_max_id = spirv_compiler_get_constant_uint64_vector(compiler, UINT64_MAX, component_count); - else - uint_max_id = spirv_compiler_get_constant_uint_vector(compiler, UINT_MAX, component_count); - } - /* The SPIR-V specification states, "The resulting value is undefined if * Shift is greater than or equal to the bit width of the components of * Base." Direct3D applies only the lowest 5 bits of the shift. @@ -7746,9 +7623,6 @@ static enum vkd3d_result spirv_compiler_emit_alu_instruction(struct spirv_compil if (instruction->flags & VKD3DSI_PRECISE_XYZW) vkd3d_spirv_build_op_decorate(builder, val_id, SpvDecorationNoContraction, NULL, 0); - if (check_zero) - val_id = vkd3d_spirv_build_op_select(builder, type_id, condition_id, val_id, uint_max_id); - spirv_compiler_emit_store_dst(compiler, dst, val_id); return VKD3D_OK; } @@ -8230,16 +8104,16 @@ static void spirv_compiler_emit_bitfield_instruction(struct spirv_compiler *comp struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; const struct vkd3d_shader_dst_param *dst = instruction->dst; const struct vkd3d_shader_src_param *src = instruction->src; - enum vkd3d_shader_component_type component_type; unsigned int i, j, k, src_count, size; + enum vsir_data_type data_type; uint32_t write_mask; SpvOp op; src_count = instruction->src_count; VKD3D_ASSERT(2 <= src_count && src_count <= ARRAY_SIZE(src_ids)); - component_type = vkd3d_component_type_from_data_type(dst->reg.data_type); - type_id = spirv_get_type_id(builder, dst->reg.data_type, 1); + data_type = dst->reg.data_type; + type_id = spirv_get_type_id(builder, data_type, 1); size = data_type_is_64_bit(src[src_count - 1].reg.data_type) ? 0x40 : 0x20; mask_id = spirv_compiler_get_constant_uint(compiler, size - 1); size_id = spirv_compiler_get_constant_uint(compiler, size); @@ -8265,7 +8139,7 @@ static void spirv_compiler_emit_bitfield_instruction(struct spirv_compiler *comp for (j = 0; j < src_count; ++j) { src_ids[src_count - j - 1] = spirv_compiler_emit_load_src_with_type(compiler, - &src[j], write_mask, component_type); + &src[j], write_mask, data_type); } /* In SPIR-V, the last two operands are Offset and Count. */ @@ -8281,7 +8155,7 @@ static void spirv_compiler_emit_bitfield_instruction(struct spirv_compiler *comp op, type_id, src_ids, src_count); } - spirv_compiler_emit_store_dst_components(compiler, dst, component_type, constituents); + spirv_compiler_emit_store_dst_components(compiler, dst, data_type, constituents); } static void spirv_compiler_emit_f16tof32(struct spirv_compiler *compiler, @@ -8313,8 +8187,7 @@ static void spirv_compiler_emit_f16tof32(struct spirv_compiler *compiler, scalar_type_id, result_id, 0); } - spirv_compiler_emit_store_dst_components(compiler, - dst, vkd3d_component_type_from_data_type(dst->reg.data_type), components); + spirv_compiler_emit_store_dst_components(compiler, dst, dst->reg.data_type, components); } static void spirv_compiler_emit_f32tof16(struct spirv_compiler *compiler, @@ -8349,8 +8222,7 @@ static void spirv_compiler_emit_f32tof16(struct spirv_compiler *compiler, instr_set_id, GLSLstd450PackHalf2x16, &src_id, 1); } - spirv_compiler_emit_store_dst_components(compiler, - dst, vkd3d_component_type_from_data_type(dst->reg.data_type), components); + spirv_compiler_emit_store_dst_components(compiler, dst, dst->reg.data_type, components); } static void spirv_compiler_emit_comparison_instruction(struct spirv_compiler *compiler, @@ -8918,8 +8790,7 @@ static void spirv_compiler_prepare_image(struct spirv_compiler *compiler, } image->image_type_id = spirv_compiler_get_image_type_id(compiler, resource_reg, &symbol->info.resource.range, - image->resource_type_info, vkd3d_component_type_from_data_type(image->sampled_type), - image->structure_stride || image->raw); + image->resource_type_info, image->sampled_type, image->structure_stride || image->raw); if (sampled) { @@ -9014,8 +8885,7 @@ static void spirv_compiler_emit_ld(struct spirv_compiler *compiler, val_id = vkd3d_spirv_build_op_image_fetch(builder, type_id, image.image_id, coordinate_id, operands_mask, image_operands, image_operand_count); - spirv_compiler_emit_store_dst_swizzled(compiler, dst, val_id, - vkd3d_component_type_from_data_type(image.sampled_type), src[1].swizzle); + spirv_compiler_emit_store_dst_swizzled(compiler, dst, val_id, image.sampled_type, src[1].swizzle); } static void spirv_compiler_emit_lod(struct spirv_compiler *compiler, @@ -9040,8 +8910,7 @@ static void spirv_compiler_emit_lod(struct spirv_compiler *compiler, val_id = vkd3d_spirv_build_op_image_query_lod(builder, type_id, image.sampled_image_id, coordinate_id); - spirv_compiler_emit_store_dst_swizzled(compiler, dst, val_id, - vkd3d_component_type_from_data_type(image.sampled_type), resource->swizzle); + spirv_compiler_emit_store_dst_swizzled(compiler, dst, val_id, image.sampled_type, resource->swizzle); } static void spirv_compiler_emit_sample(struct spirv_compiler *compiler, @@ -9111,8 +8980,7 @@ static void spirv_compiler_emit_sample(struct spirv_compiler *compiler, val_id = vkd3d_spirv_build_op_image_sample(builder, op, sampled_type_id, image.sampled_image_id, coordinate_id, operands_mask, image_operands, image_operand_count); - spirv_compiler_emit_store_dst_swizzled(compiler, dst, val_id, - vkd3d_component_type_from_data_type(image.sampled_type), resource->swizzle); + spirv_compiler_emit_store_dst_swizzled(compiler, dst, val_id, image.sampled_type, resource->swizzle); } static void spirv_compiler_emit_sample_c(struct spirv_compiler *compiler, @@ -9157,8 +9025,7 @@ static void spirv_compiler_emit_sample_c(struct spirv_compiler *compiler, image.sampled_image_id, coordinate_id, dref_id, operands_mask, image_operands, image_operand_count); - spirv_compiler_emit_store_dst_scalar(compiler, dst, val_id, - vkd3d_component_type_from_data_type(image.sampled_type), src[1].swizzle); + spirv_compiler_emit_store_dst_scalar(compiler, dst, val_id, image.sampled_type, src[1].swizzle); } static void spirv_compiler_emit_gather4(struct spirv_compiler *compiler, @@ -9230,8 +9097,7 @@ static void spirv_compiler_emit_gather4(struct spirv_compiler *compiler, operands_mask, image_operands, image_operand_count); } - spirv_compiler_emit_store_dst_swizzled(compiler, dst, val_id, - vkd3d_component_type_from_data_type(image.sampled_type), resource->swizzle); + spirv_compiler_emit_store_dst_swizzled(compiler, dst, val_id, image.sampled_type, resource->swizzle); } static uint32_t spirv_compiler_emit_raw_structured_addressing( @@ -9293,7 +9159,7 @@ static void spirv_compiler_emit_ld_raw_structured_srv_uav(struct spirv_compiler texel_type_id = spirv_get_type_id(builder, resource_symbol->info.resource.sampled_type, 1); ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, SpvStorageClassUniform, texel_type_id); - type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_UINT, 1); + type_id = spirv_get_type_id(builder, VSIR_DATA_U32, 1); base_coordinate_id = spirv_compiler_emit_raw_structured_addressing(compiler, type_id, resource_symbol->info.resource.structure_stride, &src[0], VKD3DSP_WRITEMASK_0, &src[1], VKD3DSP_WRITEMASK_0); @@ -9325,7 +9191,7 @@ static void spirv_compiler_emit_ld_raw_structured_srv_uav(struct spirv_compiler spirv_compiler_prepare_image(compiler, &image, &resource->reg, NULL, VKD3D_IMAGE_FLAG_NONE); - type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_UINT, 1); + type_id = spirv_get_type_id(builder, VSIR_DATA_U32, 1); base_coordinate_id = spirv_compiler_emit_raw_structured_addressing(compiler, type_id, image.structure_stride, &src[0], VKD3DSP_WRITEMASK_0, &src[1], VKD3DSP_WRITEMASK_0); @@ -9348,7 +9214,7 @@ static void spirv_compiler_emit_ld_raw_structured_srv_uav(struct spirv_compiler type_id, val_id, 0); } } - spirv_compiler_emit_store_dst_components(compiler, dst, VKD3D_SHADER_COMPONENT_UINT, constituents); + spirv_compiler_emit_store_dst_components(compiler, dst, VSIR_DATA_U32, constituents); } static void spirv_compiler_emit_ld_tgsm(struct spirv_compiler *compiler, @@ -9388,7 +9254,7 @@ static void spirv_compiler_emit_ld_tgsm(struct spirv_compiler *compiler, ptr_id = vkd3d_spirv_build_op_access_chain1(builder, ptr_type_id, reg_info.id, coordinate_id); constituents[j++] = vkd3d_spirv_build_op_load(builder, type_id, ptr_id, SpvMemoryAccessMaskNone); } - spirv_compiler_emit_store_dst_components(compiler, dst, VKD3D_SHADER_COMPONENT_UINT, constituents); + spirv_compiler_emit_store_dst_components(compiler, dst, VSIR_DATA_U32, constituents); } static void spirv_compiler_emit_ld_raw_structured(struct spirv_compiler *compiler, @@ -9430,7 +9296,7 @@ static void spirv_compiler_emit_store_uav_raw_structured(struct spirv_compiler * type_id = spirv_get_type_id(builder, resource_symbol->info.resource.sampled_type, 1); ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, SpvStorageClassUniform, type_id); - type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_UINT, 1); + type_id = spirv_get_type_id(builder, VSIR_DATA_U32, 1); base_coordinate_id = spirv_compiler_emit_raw_structured_addressing(compiler, type_id, resource_symbol->info.resource.structure_stride, &src[0], VKD3DSP_WRITEMASK_0, &src[1], VKD3DSP_WRITEMASK_0); @@ -9458,7 +9324,7 @@ static void spirv_compiler_emit_store_uav_raw_structured(struct spirv_compiler * } else { - type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_UINT, 1); + type_id = spirv_get_type_id(builder, VSIR_DATA_U32, 1); spirv_compiler_prepare_image(compiler, &image, &dst->reg, NULL, VKD3D_IMAGE_FLAG_NONE); base_coordinate_id = spirv_compiler_emit_raw_structured_addressing(compiler, type_id, image.structure_stride, &src[0], VKD3DSP_WRITEMASK_0, &src[1], VKD3DSP_WRITEMASK_0); @@ -9569,7 +9435,7 @@ static void spirv_compiler_emit_ld_uav_typed(struct spirv_compiler *compiler, val_id = vkd3d_spirv_build_op_load(builder, type_id, ptr_id, SpvMemoryAccessMaskNone); spirv_compiler_emit_store_dst_swizzled(compiler, dst, val_id, - vkd3d_component_type_from_data_type(resource_symbol->info.resource.sampled_type), src[1].swizzle); + resource_symbol->info.resource.sampled_type, src[1].swizzle); } else { @@ -9581,8 +9447,7 @@ static void spirv_compiler_emit_ld_uav_typed(struct spirv_compiler *compiler, val_id = vkd3d_spirv_build_op_image_read(builder, type_id, image.image_id, coordinate_id, SpvImageOperandsMaskNone, NULL, 0); - spirv_compiler_emit_store_dst_swizzled(compiler, dst, val_id, - vkd3d_component_type_from_data_type(image.sampled_type), src[1].swizzle); + spirv_compiler_emit_store_dst_swizzled(compiler, dst, val_id, image.sampled_type, src[1].swizzle); } } @@ -9608,8 +9473,8 @@ static void spirv_compiler_emit_store_uav_typed(struct spirv_compiler *compiler, indices[0] = spirv_compiler_get_constant_uint(compiler, 0); indices[1] = coordinate_id; - val_id = spirv_compiler_emit_load_src_with_type(compiler, &src[1], VKD3DSP_WRITEMASK_0, - vkd3d_component_type_from_data_type(resource_symbol->info.resource.sampled_type)); + val_id = spirv_compiler_emit_load_src_with_type(compiler, &src[1], + VKD3DSP_WRITEMASK_0, resource_symbol->info.resource.sampled_type); ptr_id = vkd3d_spirv_build_op_access_chain(builder, ptr_type_id, resource_symbol->id, indices, 2); vkd3d_spirv_build_op_store(builder, ptr_id, val_id, SpvMemoryAccessMaskNone); } @@ -9620,8 +9485,7 @@ static void spirv_compiler_emit_store_uav_typed(struct spirv_compiler *compiler, spirv_compiler_prepare_image(compiler, &image, &dst->reg, NULL, VKD3D_IMAGE_FLAG_NONE); coordinate_mask = (1u << image.resource_type_info->coordinate_component_count) - 1; coordinate_id = spirv_compiler_emit_load_src(compiler, &src[0], coordinate_mask); - texel_id = spirv_compiler_emit_load_src_with_type(compiler, &src[1], - dst->write_mask, vkd3d_component_type_from_data_type(image.sampled_type)); + texel_id = spirv_compiler_emit_load_src_with_type(compiler, &src[1], dst->write_mask, image.sampled_type); vkd3d_spirv_build_op_image_write(builder, image.image_id, coordinate_id, texel_id, SpvImageOperandsMaskNone, NULL, 0); @@ -9756,11 +9620,9 @@ static void spirv_compiler_emit_atomic_instruction(struct spirv_compiler *compil const struct vkd3d_shader_src_param *src = instruction->src; const struct vkd3d_symbol *resource_symbol = NULL; uint32_t ptr_type_id, type_id, val_id, result_id; - enum vkd3d_shader_component_type component_type; const struct vkd3d_shader_dst_param *resource; uint32_t coordinate_id, sample_id, pointer_id; struct vkd3d_shader_register_info reg_info; - SpvMemorySemanticsMask memory_semantic; struct vkd3d_shader_image image; enum vsir_data_type data_type; unsigned int structure_stride; @@ -9811,7 +9673,7 @@ static void spirv_compiler_emit_atomic_instruction(struct spirv_compiler *compil } } - type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_UINT, 1); + type_id = spirv_get_type_id(builder, VSIR_DATA_U32, 1); if (structure_stride || raw) { VKD3D_ASSERT(!raw != !structure_stride); @@ -9853,8 +9715,7 @@ static void spirv_compiler_emit_atomic_instruction(struct spirv_compiler *compil } } - component_type = vkd3d_component_type_from_data_type(data_type); - val_id = spirv_compiler_emit_load_src_with_type(compiler, &src[1], VKD3DSP_WRITEMASK_0, component_type); + val_id = spirv_compiler_emit_load_src_with_type(compiler, &src[1], VKD3DSP_WRITEMASK_0, data_type); if (instruction->flags & VKD3DARF_VOLATILE) { @@ -9863,17 +9724,13 @@ static void spirv_compiler_emit_atomic_instruction(struct spirv_compiler *compil vsir_opcode_get_name(instruction->opcode, ""), instruction->opcode); } - memory_semantic = (instruction->flags & VKD3DARF_SEQ_CST) - ? SpvMemorySemanticsSequentiallyConsistentMask - : SpvMemorySemanticsMaskNone; - operands[i++] = pointer_id; operands[i++] = spirv_compiler_get_constant_uint(compiler, scope); - operands[i++] = spirv_compiler_get_constant_uint(compiler, memory_semantic); + operands[i++] = spirv_compiler_get_constant_uint(compiler, SpvMemorySemanticsMaskNone); if (instruction->src_count >= 3) { - operands[i++] = spirv_compiler_get_constant_uint(compiler, memory_semantic); - operands[i++] = spirv_compiler_emit_load_src_with_type(compiler, &src[2], VKD3DSP_WRITEMASK_0, component_type); + operands[i++] = spirv_compiler_get_constant_uint(compiler, SpvMemorySemanticsMaskNone); + operands[i++] = spirv_compiler_emit_load_src_with_type(compiler, &src[2], VKD3DSP_WRITEMASK_0, data_type); } operands[i++] = val_id; result_id = vkd3d_spirv_build_op_trv(builder, &builder->function_stream, @@ -10648,6 +10505,7 @@ static int spirv_compiler_handle_instruction(struct spirv_compiler *compiler, case VSIR_OP_ITOF: case VSIR_OP_ITOI: case VSIR_OP_MUL: + case VSIR_OP_NEG: case VSIR_OP_NOT: case VSIR_OP_OR: case VSIR_OP_UDIV_SIMPLE: diff --git a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c index 2b5badb8871..821c639ee16 100644 --- a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c +++ b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c @@ -950,6 +950,7 @@ static bool vkd3d_shader_signature_from_shader_signature(struct vkd3d_shader_sig struct vkd3d_shader_scan_context { const struct vkd3d_shader_version *version; + const struct vkd3d_shader_d3dbc_source_info *d3dbc_source_info; struct vkd3d_shader_scan_descriptor_info1 *scan_descriptor_info; size_t descriptors_size; @@ -1017,6 +1018,7 @@ static void vkd3d_shader_scan_context_init(struct vkd3d_shader_scan_context *con context->location.line = 2; /* Line 1 is the version token. */ context->api_version = VKD3D_SHADER_API_VERSION_1_2; context->combined_sampler_info = combined_sampler_info; + context->d3dbc_source_info = vkd3d_find_struct(compile_info->next, D3DBC_SOURCE_INFO); for (i = 0; i < compile_info->option_count; ++i) { @@ -1218,15 +1220,6 @@ static void vkd3d_shader_scan_sampler_declaration(struct vkd3d_shader_scan_conte d->flags |= VKD3D_SHADER_DESCRIPTOR_INFO_FLAG_SAMPLER_COMPARISON_MODE; } -static void vkd3d_shader_scan_combined_sampler_declaration( - struct vkd3d_shader_scan_context *context, const struct vkd3d_shader_semantic *semantic) -{ - vkd3d_shader_scan_add_descriptor(context, VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER, &semantic->resource.reg.reg, - &semantic->resource.range, VKD3D_SHADER_RESOURCE_NONE, VSIR_DATA_UNUSED); - vkd3d_shader_scan_add_descriptor(context, VKD3D_SHADER_DESCRIPTOR_TYPE_SRV, &semantic->resource.reg.reg, - &semantic->resource.range, semantic->resource_type, VSIR_DATA_F32); -} - const struct vkd3d_shader_descriptor_info1 *vkd3d_shader_find_descriptor( const struct vkd3d_shader_scan_descriptor_info1 *info, enum vkd3d_shader_descriptor_type type, unsigned int register_id) @@ -1312,40 +1305,6 @@ static void vkd3d_shader_scan_combined_sampler_usage(struct vkd3d_shader_scan_co s->sampler_index = sampler_idx; } -static void vkd3d_shader_scan_sample_instruction(struct vkd3d_shader_scan_context *context, - const struct vkd3d_shader_register *resource, const struct vkd3d_shader_register *sampler) -{ - unsigned int resource_idx = resource->idx[0].offset; - unsigned int sampler_idx = sampler->idx[0].offset; - - vkd3d_shader_scan_combined_sampler_usage(context, resource, sampler); - - if (!context->scan_descriptor_info) - return; - - /* Sample instructions lowered from 1.x texture instructions have no - * DCL, so we need to add the resource if it didn't already exist. - * Such descriptors have a fixed count, type, etc. */ - - if (!vkd3d_shader_find_descriptor(context->scan_descriptor_info, - VKD3D_SHADER_DESCRIPTOR_TYPE_SRV, resource_idx)) - { - struct vkd3d_shader_register_range range = {.first = resource_idx, .last = resource_idx}; - - vkd3d_shader_scan_add_descriptor(context, VKD3D_SHADER_DESCRIPTOR_TYPE_SRV, resource, - &range, VKD3D_SHADER_RESOURCE_TEXTURE_2D, VSIR_DATA_F32); - } - - if (!vkd3d_shader_find_descriptor(context->scan_descriptor_info, - VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER, sampler_idx)) - { - struct vkd3d_shader_register_range range = {.first = sampler_idx, .last = sampler_idx}; - - vkd3d_shader_scan_add_descriptor(context, VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER, resource, - &range, VKD3D_SHADER_RESOURCE_NONE, VSIR_DATA_UNUSED); - } -} - static void vkd3d_shader_scan_resource_declaration(struct vkd3d_shader_scan_context *context, const struct vkd3d_shader_resource *resource, enum vkd3d_shader_resource_type resource_type, enum vsir_data_type resource_data_type, unsigned int sample_count, @@ -1403,14 +1362,9 @@ static int vkd3d_shader_scan_instruction(struct vkd3d_shader_scan_context *conte vkd3d_shader_scan_sampler_declaration(context, instruction); break; case VSIR_OP_DCL: - if (instruction->declaration.semantic.resource_type == VKD3D_SHADER_RESOURCE_NONE) - break; - - if (instruction->declaration.semantic.resource.reg.reg.type == VKD3DSPR_COMBINED_SAMPLER) - { - vkd3d_shader_scan_combined_sampler_declaration(context, &instruction->declaration.semantic); + if (instruction->declaration.semantic.resource_type == VKD3D_SHADER_RESOURCE_NONE + || instruction->declaration.semantic.resource.reg.reg.type == VKD3DSPR_COMBINED_SAMPLER) break; - } /* fall through */ case VSIR_OP_DCL_UAV_TYPED: vkd3d_shader_scan_typed_resource_declaration(context, instruction); @@ -1564,6 +1518,7 @@ static int vkd3d_shader_scan_instruction(struct vkd3d_shader_scan_context *conte break; case VSIR_OP_GATHER4: case VSIR_OP_GATHER4_C: + case VSIR_OP_SAMPLE: case VSIR_OP_SAMPLE_B: case VSIR_OP_SAMPLE_C: case VSIR_OP_SAMPLE_C_LZ: @@ -1571,9 +1526,6 @@ static int vkd3d_shader_scan_instruction(struct vkd3d_shader_scan_context *conte case VSIR_OP_SAMPLE_LOD: vkd3d_shader_scan_combined_sampler_usage(context, &instruction->src[1].reg, &instruction->src[2].reg); break; - case VSIR_OP_SAMPLE: - vkd3d_shader_scan_sample_instruction(context, &instruction->src[1].reg, &instruction->src[2].reg); - break; case VSIR_OP_GATHER4_PO: case VSIR_OP_GATHER4_PO_C: vkd3d_shader_scan_combined_sampler_usage(context, &instruction->src[2].reg, &instruction->src[3].reg); @@ -1714,7 +1666,6 @@ static int vsir_program_scan(struct vsir_program *program, const struct vkd3d_sh struct vkd3d_shader_scan_context context; struct vkd3d_shader_instruction *ins; int ret = VKD3D_OK; - unsigned int i; descriptor_info = vkd3d_find_struct(compile_info->next, SCAN_DESCRIPTOR_INFO); if (descriptor_info) @@ -1729,6 +1680,9 @@ static int vsir_program_scan(struct vsir_program *program, const struct vkd3d_sh add_descriptor_info = true; } + if (program->has_descriptor_info) + add_descriptor_info = false; + tessellation_info = vkd3d_find_struct(compile_info->next, SCAN_HULL_SHADER_TESSELLATION_INFO); thread_group_size_info = vkd3d_find_struct(compile_info->next, SCAN_THREAD_GROUP_SIZE_INFO); @@ -1747,21 +1701,6 @@ static int vsir_program_scan(struct vsir_program *program, const struct vkd3d_sh break; } - for (i = 0; i < ARRAY_SIZE(program->flat_constant_count); ++i) - { - struct vkd3d_shader_register_range range = {.space = 0, .first = i, .last = i}; - struct vkd3d_shader_register reg = {.idx[0].offset = i, .idx_count = 1}; - unsigned int size = program->flat_constant_count[i]; - struct vkd3d_shader_descriptor_info1 *d; - - if (size) - { - if ((d = vkd3d_shader_scan_add_descriptor(&context, VKD3D_SHADER_DESCRIPTOR_TYPE_CBV, - ®, &range, VKD3D_SHADER_RESOURCE_BUFFER, VSIR_DATA_U32))) - d->buffer_size = size * 16; - } - } - if (!ret && signature_info) { if (!vkd3d_shader_signature_from_shader_signature(&signature_info->input, &program->input_signature) diff --git a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h index df0eb2ff789..c70096f1f75 100644 --- a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h +++ b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h @@ -503,6 +503,7 @@ enum vkd3d_shader_opcode VSIR_OP_MOVC, VSIR_OP_MSAD, VSIR_OP_MUL, + VSIR_OP_NEG, VSIR_OP_NEO, VSIR_OP_NEU, VSIR_OP_NOP, @@ -878,8 +879,7 @@ enum vkd3d_shader_uav_flags enum vkd3d_shader_atomic_rmw_flags { - VKD3DARF_SEQ_CST = 0x1, - VKD3DARF_VOLATILE = 0x2, + VKD3DARF_VOLATILE = 0x1, }; enum vkd3d_tessellator_domain @@ -1590,6 +1590,7 @@ struct vsir_program struct vkd3d_shader_scan_descriptor_info1 descriptors; bool has_descriptor_info; + size_t descriptors_size; unsigned int parameter_count; const struct vkd3d_shader_parameter1 *parameters; @@ -1597,7 +1598,6 @@ struct vsir_program unsigned int input_control_point_count, output_control_point_count; struct vsir_thread_group_size thread_group_size; - unsigned int flat_constant_count[3]; unsigned int block_count; /* maximum block count in any function */ unsigned int temp_count; unsigned int ssa_count; @@ -1636,6 +1636,10 @@ enum vkd3d_result vsir_allocate_temp_registers(struct vsir_program *program, enum vkd3d_result vsir_update_dcl_temps(struct vsir_program *program, struct vkd3d_shader_message_context *message_context); +struct vkd3d_shader_descriptor_info1 *vsir_program_add_descriptor(struct vsir_program *program, + enum vkd3d_shader_descriptor_type type, unsigned int register_id, + const struct vkd3d_shader_register_range *range, + enum vkd3d_shader_resource_type resource_type, enum vsir_data_type resource_data_type); bool vsir_program_add_icb(struct vsir_program *program, struct vkd3d_shader_immediate_constant_buffer *icb); void vsir_program_cleanup(struct vsir_program *program); const struct vkd3d_shader_parameter1 *vsir_program_get_parameter( @@ -1883,42 +1887,6 @@ int hlsl_parse(const struct vkd3d_shader_compile_info *compile_info, struct vkd3d_shader_message_context *message_context, struct vsir_program *program, struct vkd3d_shader_code *reflection_data); -static inline enum vkd3d_shader_component_type vkd3d_component_type_from_data_type( enum vsir_data_type data_type) -{ - switch (data_type) - { - case VSIR_DATA_BOOL: - return VKD3D_SHADER_COMPONENT_BOOL; - case VSIR_DATA_F16: - return VKD3D_SHADER_COMPONENT_FLOAT16; - case VSIR_DATA_F32: - case VSIR_DATA_SNORM: - case VSIR_DATA_UNORM: - return VKD3D_SHADER_COMPONENT_FLOAT; - case VSIR_DATA_F64: - return VKD3D_SHADER_COMPONENT_DOUBLE; - case VSIR_DATA_I16: - return VKD3D_SHADER_COMPONENT_INT16; - case VSIR_DATA_I32: - return VKD3D_SHADER_COMPONENT_INT; - case VSIR_DATA_I64: - return VKD3D_SHADER_COMPONENT_INT64; - case VSIR_DATA_U16: - return VKD3D_SHADER_COMPONENT_UINT16; - case VSIR_DATA_U32: - return VKD3D_SHADER_COMPONENT_UINT; - case VSIR_DATA_U64: - return VKD3D_SHADER_COMPONENT_UINT64; - case VSIR_DATA_UNUSED: - return VKD3D_SHADER_COMPONENT_VOID; - default: - FIXME("Unhandled data type %#x.\n", data_type); - /* fall-through */ - case VSIR_DATA_MIXED: - return VKD3D_SHADER_COMPONENT_UINT; - } -} - static inline enum vsir_data_type vsir_data_type_from_component_type(enum vkd3d_shader_component_type component_type) { switch (component_type) @@ -1954,12 +1922,6 @@ static inline enum vsir_data_type vsir_data_type_from_component_type(enum vkd3d_ return VSIR_DATA_UNUSED; } -static inline bool component_type_is_64_bit(enum vkd3d_shader_component_type component_type) -{ - return component_type == VKD3D_SHADER_COMPONENT_DOUBLE || component_type == VKD3D_SHADER_COMPONENT_INT64 - || component_type == VKD3D_SHADER_COMPONENT_UINT64; -} - static inline unsigned int vsir_write_mask_get_component_idx(uint32_t write_mask) { unsigned int i; -- 2.51.0