From 669dcd4183544055c8b512d6a60df7536e82b453 Mon Sep 17 00:00:00 2001 From: Alistair Leslie-Hughes Date: Mon, 13 May 2024 09:29:08 +1000 Subject: [PATCH] Updated vkd3d to 4b3a948edcb5e83074b63aad25ecf450dcae4130. --- libs/vkd3d/libs/vkd3d-shader/d3d_asm.c | 23 + libs/vkd3d/libs/vkd3d-shader/d3dbc.c | 31 +- libs/vkd3d/libs/vkd3d-shader/dxil.c | 321 +++++++++++ libs/vkd3d/libs/vkd3d-shader/fx.c | 506 ++++++++++++++---- libs/vkd3d/libs/vkd3d-shader/hlsl.c | 168 +++--- libs/vkd3d/libs/vkd3d-shader/hlsl.h | 19 +- libs/vkd3d/libs/vkd3d-shader/hlsl.y | 66 +-- libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c | 84 ++- .../libs/vkd3d-shader/hlsl_constant_ops.c | 170 +++--- libs/vkd3d/libs/vkd3d-shader/ir.c | 26 + libs/vkd3d/libs/vkd3d-shader/spirv.c | 94 ++++ libs/vkd3d/libs/vkd3d-shader/tpf.c | 79 +-- .../libs/vkd3d-shader/vkd3d_shader_private.h | 16 + libs/vkd3d/libs/vkd3d/device.c | 177 +++--- libs/vkd3d/libs/vkd3d/utils.c | 24 + 15 files changed, 1335 insertions(+), 469 deletions(-) diff --git a/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c b/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c index b2f329cd199..f2ad39f2f07 100644 --- a/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c +++ b/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c @@ -328,8 +328,20 @@ static const char * const shader_opcode_names[] = [VKD3DSIH_UTOF ] = "utof", [VKD3DSIH_UTOU ] = "utou", [VKD3DSIH_WAVE_ACTIVE_ALL_EQUAL ] = "wave_active_all_equal", + [VKD3DSIH_WAVE_ACTIVE_BALLOT ] = "wave_active_ballot", + [VKD3DSIH_WAVE_ACTIVE_BIT_AND ] = "wave_active_bit_and", + [VKD3DSIH_WAVE_ACTIVE_BIT_OR ] = "wave_active_bit_or", + [VKD3DSIH_WAVE_ACTIVE_BIT_XOR ] = "wave_active_bit_xor", [VKD3DSIH_WAVE_ALL_TRUE ] = "wave_all_true", [VKD3DSIH_WAVE_ANY_TRUE ] = "wave_any_true", + [VKD3DSIH_WAVE_OP_ADD ] = "wave_op_add", + [VKD3DSIH_WAVE_OP_IMAX ] = "wave_op_imax", + [VKD3DSIH_WAVE_OP_IMIN ] = "wave_op_imin", + [VKD3DSIH_WAVE_OP_MAX ] = "wave_op_max", + [VKD3DSIH_WAVE_OP_MIN ] = "wave_op_min", + [VKD3DSIH_WAVE_OP_MUL ] = "wave_op_mul", + [VKD3DSIH_WAVE_OP_UMAX ] = "wave_op_umax", + [VKD3DSIH_WAVE_OP_UMIN ] = "wave_op_umin", [VKD3DSIH_XOR ] = "xor", }; @@ -1840,6 +1852,17 @@ static void shader_dump_instruction_flags(struct vkd3d_d3d_asm_compiler *compile vkd3d_string_buffer_printf(buffer, "p"); break; + case VKD3DSIH_WAVE_OP_ADD: + case VKD3DSIH_WAVE_OP_IMAX: + case VKD3DSIH_WAVE_OP_IMIN: + case VKD3DSIH_WAVE_OP_MAX: + case VKD3DSIH_WAVE_OP_MIN: + case VKD3DSIH_WAVE_OP_MUL: + case VKD3DSIH_WAVE_OP_UMAX: + case VKD3DSIH_WAVE_OP_UMIN: + vkd3d_string_buffer_printf(&compiler->buffer, (ins->flags & VKD3DSI_WAVE_PREFIX) ? "_prefix" : "_active"); + break; + case VKD3DSIH_ISHL: case VKD3DSIH_ISHR: case VKD3DSIH_USHR: diff --git a/libs/vkd3d/libs/vkd3d-shader/d3dbc.c b/libs/vkd3d/libs/vkd3d-shader/d3dbc.c index aa2358440e5..24a95224349 100644 --- a/libs/vkd3d/libs/vkd3d-shader/d3dbc.c +++ b/libs/vkd3d/libs/vkd3d-shader/d3dbc.c @@ -1514,10 +1514,11 @@ D3DXPARAMETER_CLASS hlsl_sm1_class(const struct hlsl_type *type) return D3DXPC_STRUCT; case HLSL_CLASS_VECTOR: return D3DXPC_VECTOR; - case HLSL_CLASS_OBJECT: + case HLSL_CLASS_PIXEL_SHADER: case HLSL_CLASS_SAMPLER: case HLSL_CLASS_STRING: case HLSL_CLASS_TEXTURE: + case HLSL_CLASS_VERTEX_SHADER: return D3DXPC_OBJECT; case HLSL_CLASS_DEPTH_STENCIL_VIEW: case HLSL_CLASS_EFFECT_GROUP: @@ -1539,7 +1540,7 @@ D3DXPARAMETER_TYPE hlsl_sm1_base_type(const struct hlsl_type *type) case HLSL_CLASS_SCALAR: case HLSL_CLASS_VECTOR: case HLSL_CLASS_MATRIX: - switch (type->base_type) + switch (type->e.numeric.type) { case HLSL_TYPE_BOOL: return D3DXPT_BOOL; @@ -1600,18 +1601,6 @@ D3DXPARAMETER_TYPE hlsl_sm1_base_type(const struct hlsl_type *type) } break; - case HLSL_CLASS_OBJECT: - switch (type->base_type) - { - case HLSL_TYPE_PIXELSHADER: - return D3DXPT_PIXELSHADER; - case HLSL_TYPE_VERTEXSHADER: - return D3DXPT_VERTEXSHADER; - default: - vkd3d_unreachable(); - } - vkd3d_unreachable(); - case HLSL_CLASS_ARRAY: return hlsl_sm1_base_type(type->e.array.type); @@ -1621,6 +1610,12 @@ D3DXPARAMETER_TYPE hlsl_sm1_base_type(const struct hlsl_type *type) case HLSL_CLASS_STRING: return D3DXPT_STRING; + case HLSL_CLASS_PIXEL_SHADER: + return D3DXPT_PIXELSHADER; + + case HLSL_CLASS_VERTEX_SHADER: + return D3DXPT_VERTEXSHADER; + case HLSL_CLASS_DEPTH_STENCIL_VIEW: case HLSL_CLASS_EFFECT_GROUP: case HLSL_CLASS_PASS: @@ -2020,11 +2015,11 @@ static void write_sm1_cast(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *b /* Narrowing casts were already lowered. */ assert(src_type->dimx == dst_type->dimx); - switch (dst_type->base_type) + switch (dst_type->e.numeric.type) { case HLSL_TYPE_HALF: case HLSL_TYPE_FLOAT: - switch (src_type->base_type) + switch (src_type->e.numeric.type) { case HLSL_TYPE_INT: case HLSL_TYPE_UINT: @@ -2046,7 +2041,7 @@ static void write_sm1_cast(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *b case HLSL_TYPE_INT: case HLSL_TYPE_UINT: - switch(src_type->base_type) + switch(src_type->e.numeric.type) { case HLSL_TYPE_HALF: case HLSL_TYPE_FLOAT: @@ -2308,7 +2303,7 @@ static void write_sm1_expr(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *b return; } - if (instr->data_type->base_type != HLSL_TYPE_FLOAT) + if (instr->data_type->e.numeric.type != HLSL_TYPE_FLOAT) { /* These need to be lowered. */ hlsl_fixme(ctx, &instr->loc, "SM1 non-float expression."); diff --git a/libs/vkd3d/libs/vkd3d-shader/dxil.c b/libs/vkd3d/libs/vkd3d-shader/dxil.c index e636ad917db..29f736364dc 100644 --- a/libs/vkd3d/libs/vkd3d-shader/dxil.c +++ b/libs/vkd3d/libs/vkd3d-shader/dxil.c @@ -37,6 +37,10 @@ static const size_t MAX_IR_INSTRUCTIONS_PER_DXIL_INSTRUCTION = 11; static const unsigned int dx_max_thread_group_size[3] = {1024, 1024, 64}; +static const unsigned int MAX_GS_INSTANCE_COUNT = 32; /* kMaxGSInstanceCount */ +static const unsigned int MAX_GS_OUTPUT_TOTAL_SCALARS = 1024; /* kMaxGSOutputTotalScalars */ +static const unsigned int MAX_GS_OUTPUT_STREAMS = 4; + #define VKD3D_SHADER_SWIZZLE_64_MASK \ (VKD3D_SHADER_SWIZZLE_MASK << VKD3D_SHADER_SWIZZLE_SHIFT(0) \ | VKD3D_SHADER_SWIZZLE_MASK << VKD3D_SHADER_SWIZZLE_SHIFT(1)) @@ -283,6 +287,18 @@ enum dxil_element_additional_tag ADDITIONAL_TAG_USED_MASK = 3, }; +enum dxil_input_primitive +{ + INPUT_PRIMITIVE_UNDEFINED = 0, + INPUT_PRIMITIVE_POINT = 1, + INPUT_PRIMITIVE_LINE = 2, + INPUT_PRIMITIVE_TRIANGLE = 3, + INPUT_PRIMITIVE_LINEWITHADJACENCY = 6, + INPUT_PRIMITIVE_TRIANGLEWITHADJACENY = 7, + INPUT_PRIMITIVE_PATCH1 = 8, + INPUT_PRIMITIVE_PATCH32 = 39, +}; + enum dxil_shader_properties_tag { SHADER_PROPERTIES_FLAGS = 0, @@ -419,6 +435,9 @@ enum dx_intrinsic_opcode DX_GROUP_ID = 94, DX_THREAD_ID_IN_GROUP = 95, DX_FLATTENED_THREAD_ID_IN_GROUP = 96, + DX_EMIT_STREAM = 97, + DX_CUT_STREAM = 98, + DX_EMIT_THEN_CUT_STREAM = 99, DX_MAKE_DOUBLE = 101, DX_SPLIT_DOUBLE = 102, DX_LOAD_OUTPUT_CONTROL_POINT = 103, @@ -432,6 +451,10 @@ enum dx_intrinsic_opcode DX_WAVE_ANY_TRUE = 113, DX_WAVE_ALL_TRUE = 114, DX_WAVE_ACTIVE_ALL_EQUAL = 115, + DX_WAVE_ACTIVE_BALLOT = 116, + DX_WAVE_ACTIVE_OP = 119, + DX_WAVE_ACTIVE_BIT = 120, + DX_WAVE_PREFIX_OP = 121, DX_LEGACY_F32TOF16 = 130, DX_LEGACY_F16TOF32 = 131, DX_RAW_BUFFER_LOAD = 139, @@ -533,6 +556,21 @@ enum dxil_sync_flags SYNC_GROUP_SHARED_MEMORY = 0x8, }; +enum dxil_wave_bit_op_kind +{ + WAVE_BIT_OP_AND = 0, + WAVE_BIT_OP_OR = 1, + WAVE_BIT_OP_XOR = 2, +}; + +enum dxil_wave_op_kind +{ + WAVE_OP_ADD = 0, + WAVE_OP_MUL = 1, + WAVE_OP_MIN = 2, + WAVE_OP_MAX = 3, +}; + struct sm6_pointer_info { const struct sm6_type *type; @@ -4896,6 +4934,38 @@ static void sm6_parser_emit_dx_create_handle(struct sm6_parser *sm6, enum dx_int ins->handler_idx = VKD3DSIH_NOP; } +static void sm6_parser_emit_dx_stream(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, + const struct sm6_value **operands, struct function_emission_state *state) +{ + struct vkd3d_shader_instruction *ins = state->ins; + struct vkd3d_shader_src_param *src_param; + unsigned int i; + + vsir_instruction_init(ins, &sm6->p.location, (op == DX_CUT_STREAM) ? VKD3DSIH_CUT_STREAM : VKD3DSIH_EMIT_STREAM); + + if (!(src_param = instruction_src_params_alloc(ins, 1, sm6))) + return; + + i = sm6_value_get_constant_uint(operands[0]); + if (i >= MAX_GS_OUTPUT_STREAMS) + { + WARN("Invalid stream index %u.\n", i); + vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, + "Output stream index %u is invalid.", i); + } + + /* VKD3D_DATA_UNUSED would be more reasonable, but TPF uses data type 0 here. */ + register_init_with_id(&src_param->reg, VKD3DSPR_STREAM, 0, i); + src_param_init(src_param); + + if (op == DX_EMIT_THEN_CUT_STREAM) + { + ++state->ins; + ++state->code_block->instruction_count; + sm6_parser_emit_dx_stream(sm6, DX_CUT_STREAM, operands, state); + } +} + static void sm6_parser_emit_dx_discard(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, const struct sm6_value **operands, struct function_emission_state *state) { @@ -5910,6 +5980,111 @@ static void sm6_parser_emit_dx_texture_store(struct sm6_parser *sm6, enum dx_int dst_param_init_with_mask(dst_param, write_mask); } +static void sm6_parser_emit_dx_wave_active_ballot(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, + const struct sm6_value **operands, struct function_emission_state *state) +{ + struct vkd3d_shader_instruction *ins = state->ins; + struct vkd3d_shader_src_param *src_param; + + vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_WAVE_ACTIVE_BALLOT); + if (!(src_param = instruction_src_params_alloc(ins, 1, sm6))) + return; + src_param_init_from_value(src_param, operands[0]); + + instruction_dst_param_init_ssa_vector(ins, VKD3D_VEC4_SIZE, sm6); +} + +static enum vkd3d_shader_opcode sm6_dx_map_wave_bit_op(enum dxil_wave_bit_op_kind op, + struct sm6_parser *sm6) +{ + switch (op) + { + case WAVE_BIT_OP_AND: + return VKD3DSIH_WAVE_ACTIVE_BIT_AND; + case WAVE_BIT_OP_OR: + return VKD3DSIH_WAVE_ACTIVE_BIT_OR; + case WAVE_BIT_OP_XOR: + return VKD3DSIH_WAVE_ACTIVE_BIT_XOR; + default: + FIXME("Unhandled wave bit op %u.\n", op); + vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_UNHANDLED_INTRINSIC, + "Wave bit operation %u is unhandled.\n", op); + return VKD3DSIH_INVALID; + } +} + +static void sm6_parser_emit_dx_wave_active_bit(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, + const struct sm6_value **operands, struct function_emission_state *state) +{ + struct vkd3d_shader_instruction *ins = state->ins; + struct vkd3d_shader_src_param *src_param; + enum dxil_wave_bit_op_kind wave_op; + enum vkd3d_shader_opcode opcode; + + wave_op = sm6_value_get_constant_uint(operands[1]); + + if ((opcode = sm6_dx_map_wave_bit_op(wave_op, sm6)) == VKD3DSIH_INVALID) + return; + vsir_instruction_init(ins, &sm6->p.location, opcode); + + if (!(src_param = instruction_src_params_alloc(ins, 1, sm6))) + return; + src_param_init_from_value(src_param, operands[0]); + + instruction_dst_param_init_ssa_scalar(ins, sm6); +} + +static enum vkd3d_shader_opcode sm6_dx_map_wave_op(enum dxil_wave_op_kind op, bool is_signed, bool is_float, + struct sm6_parser *sm6) +{ + switch (op) + { + case WAVE_OP_ADD: + return VKD3DSIH_WAVE_OP_ADD; + case WAVE_OP_MUL: + return VKD3DSIH_WAVE_OP_MUL; + case WAVE_OP_MIN: + if (is_float) + return VKD3DSIH_WAVE_OP_MIN; + return is_signed ? VKD3DSIH_WAVE_OP_IMIN : VKD3DSIH_WAVE_OP_UMIN; + case WAVE_OP_MAX: + if (is_float) + return VKD3DSIH_WAVE_OP_MAX; + return is_signed ? VKD3DSIH_WAVE_OP_IMAX : VKD3DSIH_WAVE_OP_UMAX; + default: + FIXME("Unhandled wave op %u.\n", op); + vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_UNHANDLED_INTRINSIC, + "Wave operation %u is unhandled.\n", op); + return VKD3DSIH_INVALID; + } +} + +static void sm6_parser_emit_dx_wave_op(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, + const struct sm6_value **operands, struct function_emission_state *state) +{ + struct vkd3d_shader_instruction *ins = state->ins; + struct vkd3d_shader_src_param *src_param; + enum vkd3d_shader_opcode opcode; + enum dxil_wave_op_kind wave_op; + bool is_signed; + + wave_op = sm6_value_get_constant_uint(operands[1]); + is_signed = !sm6_value_get_constant_uint(operands[2]); + opcode = sm6_dx_map_wave_op(wave_op, is_signed, sm6_type_is_floating_point(operands[0]->type), sm6); + + if (opcode == VKD3DSIH_INVALID) + return; + + vsir_instruction_init(ins, &sm6->p.location, opcode); + ins->flags = (op == DX_WAVE_PREFIX_OP) ? VKD3DSI_WAVE_PREFIX : 0; + + if (!(src_param = instruction_src_params_alloc(ins, 1, sm6))) + return; + src_param_init_from_value(src_param, operands[0]); + + instruction_dst_param_init_ssa_scalar(ins, sm6); +} + static void sm6_parser_emit_dx_wave_builtin(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, const struct sm6_value **operands, struct function_emission_state *state) { @@ -5954,6 +6129,7 @@ struct sm6_dx_opcode_info H -> handle D -> Dimensions S -> splitdouble + V -> 4 x i32 v -> void o -> overloaded R -> matches the return type @@ -5976,6 +6152,7 @@ static const struct sm6_dx_opcode_info sm6_dx_op_table[] = [DX_COUNT_BITS ] = {"i", "m", sm6_parser_emit_dx_unary}, [DX_COVERAGE ] = {"i", "", sm6_parser_emit_dx_coverage}, [DX_CREATE_HANDLE ] = {"H", "ccib", sm6_parser_emit_dx_create_handle}, + [DX_CUT_STREAM ] = {"v", "c", sm6_parser_emit_dx_stream}, [DX_DERIV_COARSEX ] = {"e", "R", sm6_parser_emit_dx_unary}, [DX_DERIV_COARSEY ] = {"e", "R", sm6_parser_emit_dx_unary}, [DX_DERIV_FINEX ] = {"e", "R", sm6_parser_emit_dx_unary}, @@ -5985,6 +6162,8 @@ static const struct sm6_dx_opcode_info sm6_dx_op_table[] = [DX_DOT2 ] = {"g", "RRRR", sm6_parser_emit_dx_dot}, [DX_DOT3 ] = {"g", "RRRRRR", sm6_parser_emit_dx_dot}, [DX_DOT4 ] = {"g", "RRRRRRRR", sm6_parser_emit_dx_dot}, + [DX_EMIT_STREAM ] = {"v", "c", sm6_parser_emit_dx_stream}, + [DX_EMIT_THEN_CUT_STREAM ] = {"v", "c", sm6_parser_emit_dx_stream}, [DX_EXP ] = {"g", "R", sm6_parser_emit_dx_unary}, [DX_FABS ] = {"g", "R", sm6_parser_emit_dx_fabs}, [DX_FIRST_BIT_HI ] = {"i", "m", sm6_parser_emit_dx_unary}, @@ -6051,10 +6230,14 @@ static const struct sm6_dx_opcode_info sm6_dx_op_table[] = [DX_UMAX ] = {"m", "RR", sm6_parser_emit_dx_binary}, [DX_UMIN ] = {"m", "RR", sm6_parser_emit_dx_binary}, [DX_WAVE_ACTIVE_ALL_EQUAL ] = {"1", "n", sm6_parser_emit_dx_unary}, + [DX_WAVE_ACTIVE_BALLOT ] = {"V", "1", sm6_parser_emit_dx_wave_active_ballot}, + [DX_WAVE_ACTIVE_BIT ] = {"m", "Rc", sm6_parser_emit_dx_wave_active_bit}, + [DX_WAVE_ACTIVE_OP ] = {"n", "Rcc", sm6_parser_emit_dx_wave_op}, [DX_WAVE_ALL_TRUE ] = {"1", "1", sm6_parser_emit_dx_unary}, [DX_WAVE_ANY_TRUE ] = {"1", "1", sm6_parser_emit_dx_unary}, [DX_WAVE_GET_LANE_COUNT ] = {"i", "", sm6_parser_emit_dx_wave_builtin}, [DX_WAVE_GET_LANE_INDEX ] = {"i", "", sm6_parser_emit_dx_wave_builtin}, + [DX_WAVE_PREFIX_OP ] = {"n", "Rcc", sm6_parser_emit_dx_wave_op}, }; static bool sm6_parser_validate_operand_type(struct sm6_parser *sm6, const struct sm6_value *value, char info_type, @@ -6102,6 +6285,8 @@ static bool sm6_parser_validate_operand_type(struct sm6_parser *sm6, const struc return sm6_type_is_struct(type) && !strcmp(type->u.struc->name, "dx.types.Dimensions"); case 'S': return sm6_type_is_struct(type) && !strcmp(type->u.struc->name, "dx.types.splitdouble"); + case 'V': + return sm6_type_is_struct(type) && !strcmp(type->u.struc->name, "dx.types.fouri32"); case 'v': return !type; case 'o': @@ -9336,6 +9521,17 @@ static void sm6_parser_emit_dcl_count(struct sm6_parser *sm6, enum vkd3d_shader_ 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, + unsigned int patch_vertex_count) +{ + struct vkd3d_shader_instruction *ins; + + ins = sm6_parser_add_instruction(sm6, handler_idx); + ins->declaration.primitive_type.type = primitive_type; + ins->declaration.primitive_type.patch_vertex_count = patch_vertex_count; +} + static void sm6_parser_emit_dcl_tessellator_domain(struct sm6_parser *sm6, enum vkd3d_tessellator_domain tessellator_domain) { @@ -9420,6 +9616,128 @@ static void sm6_parser_emit_dcl_max_tessellation_factor(struct sm6_parser *sm6, ins->declaration.max_tessellation_factor = max_tessellation_factor; } +static void sm6_parser_gs_properties_init(struct sm6_parser *sm6, const struct sm6_metadata_value *m) +{ + enum vkd3d_primitive_type input_primitive = VKD3D_PT_TRIANGLELIST, output_primitive; + unsigned int i, input_control_point_count = 1, patch_vertex_count = 0; + const struct sm6_metadata_node *node; + unsigned int operands[5] = {0}; + + if (!m || !sm6_metadata_value_is_node(m)) + { + WARN("Missing or invalid GS properties.\n"); + vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_PROPERTIES, + "Geometry shader properties node is missing or invalid."); + return; + } + + node = m->u.node; + if (node->operand_count < ARRAY_SIZE(operands)) + { + WARN("Invalid operand count %u.\n", node->operand_count); + vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND_COUNT, + "Geometry shader properties operand count %u is invalid.", node->operand_count); + return; + } + if (node->operand_count > ARRAY_SIZE(operands)) + { + WARN("Ignoring %zu extra operands.\n", node->operand_count - ARRAY_SIZE(operands)); + vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_WARNING_DXIL_IGNORING_OPERANDS, + "Ignoring %zu extra operands for geometry shader properties.", + node->operand_count - ARRAY_SIZE(operands)); + } + + for (i = 0; i < node->operand_count; ++i) + { + if (!sm6_metadata_get_uint_value(sm6, node->operands[i], &operands[i])) + { + WARN("GS property at index %u is not a uint value.\n", i); + vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_PROPERTIES, + "Geometry shader properties operand at index %u is not an integer.", i); + } + } + + switch (i = operands[0]) + { + case INPUT_PRIMITIVE_POINT: + input_primitive = VKD3D_PT_POINTLIST; + input_control_point_count = 1; + break; + + case INPUT_PRIMITIVE_LINE: + input_primitive = VKD3D_PT_LINELIST; + input_control_point_count = 2; + break; + + case INPUT_PRIMITIVE_TRIANGLE: + input_primitive = VKD3D_PT_TRIANGLELIST; + input_control_point_count = 3; + break; + + case INPUT_PRIMITIVE_LINEWITHADJACENCY: + input_primitive = VKD3D_PT_LINELIST_ADJ; + input_control_point_count = 4; + break; + + case INPUT_PRIMITIVE_TRIANGLEWITHADJACENY: + input_primitive = VKD3D_PT_TRIANGLELIST_ADJ; + input_control_point_count = 6; + break; + + default: + if (i >= INPUT_PRIMITIVE_PATCH1 && i <= INPUT_PRIMITIVE_PATCH32) + { + input_primitive = VKD3D_PT_PATCH; + patch_vertex_count = i - INPUT_PRIMITIVE_PATCH1 + 1; + break; + } + + WARN("Unhandled input primitive %u.\n", i); + vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_PROPERTIES, + "Geometry shader input primitive %u is unhandled.", i); + break; + } + + sm6_parser_emit_dcl_primitive_topology(sm6, VKD3DSIH_DCL_INPUT_PRIMITIVE, input_primitive, patch_vertex_count); + sm6->p.program.input_control_point_count = input_control_point_count; + + i = operands[1]; + /* Max total scalar count sets an upper limit. We would need to scan outputs to be more precise. */ + if (i > MAX_GS_OUTPUT_TOTAL_SCALARS) + { + WARN("GS output vertex count %u invalid.\n", i); + vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_PROPERTIES, + "Geometry shader output vertex count %u is invalid.", i); + } + sm6_parser_emit_dcl_count(sm6, VKD3DSIH_DCL_VERTICES_OUT, i); + + if (operands[2] > 1) + { + FIXME("Unhandled stream mask %#x.\n", operands[2]); + vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_PROPERTIES, + "Geometry shader stream mask %#x is unhandled.", operands[2]); + } + + output_primitive = operands[3]; + if (output_primitive == VKD3D_PT_UNDEFINED || output_primitive >= VKD3D_PT_COUNT) + { + WARN("Unhandled output primitive %u.\n", output_primitive); + vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_PROPERTIES, + "Geometry shader output primitive %u is unhandled.", output_primitive); + output_primitive = VKD3D_PT_TRIANGLELIST; + } + sm6_parser_emit_dcl_primitive_topology(sm6, VKD3DSIH_DCL_OUTPUT_TOPOLOGY, output_primitive, 0); + + i = operands[4]; + if (!i || i > MAX_GS_INSTANCE_COUNT) + { + WARN("GS instance count %u invalid.\n", i); + vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_PROPERTIES, + "Geometry shader instance count %u is invalid.", i); + } + sm6_parser_emit_dcl_count(sm6, VKD3DSIH_DCL_GS_INSTANCES, i); +} + static enum vkd3d_tessellator_domain sm6_parser_ds_properties_init(struct sm6_parser *sm6, const struct sm6_metadata_value *m) { @@ -9610,6 +9928,9 @@ static enum vkd3d_result sm6_parser_entry_point_init(struct sm6_parser *sm6) case SHADER_PROPERTIES_FLAGS: sm6_parser_emit_global_flags(sm6, node->operands[i + 1]); break; + case SHADER_PROPERTIES_GEOMETRY: + sm6_parser_gs_properties_init(sm6, node->operands[i + 1]); + break; case SHADER_PROPERTIES_DOMAIN: tessellator_domain = sm6_parser_ds_properties_init(sm6, node->operands[i + 1]); break; diff --git a/libs/vkd3d/libs/vkd3d-shader/fx.c b/libs/vkd3d/libs/vkd3d-shader/fx.c index 168378e6b42..6fb2e8a0f0b 100644 --- a/libs/vkd3d/libs/vkd3d-shader/fx.c +++ b/libs/vkd3d/libs/vkd3d-shader/fx.c @@ -85,8 +85,13 @@ struct fx_write_context uint32_t numeric_variable_count; uint32_t object_variable_count; uint32_t shared_object_count; - uint32_t shader_variable_count; + uint32_t shader_count; uint32_t parameter_count; + uint32_t dsv_count; + uint32_t rtv_count; + uint32_t texture_count; + uint32_t uav_count; + uint32_t sampler_state_count; int status; bool child_effect; @@ -169,7 +174,7 @@ static void fx_write_context_init(struct hlsl_ctx *ctx, const struct fx_write_co struct fx_write_context *fx) { unsigned int version = ctx->profile->major_version; - struct hlsl_block block; + struct hlsl_ir_var *var; memset(fx, 0, sizeof(*fx)); @@ -197,9 +202,15 @@ static void fx_write_context_init(struct hlsl_ctx *ctx, const struct fx_write_co fx->child_effect = fx->ops->are_child_effects_supported && ctx->child_effect; fx->include_empty_buffers = version == 4 && ctx->include_empty_buffers; - hlsl_block_init(&block); - hlsl_prepend_global_uniform_copy(fx->ctx, &block); - hlsl_block_cleanup(&block); + LIST_FOR_EACH_ENTRY(var, &ctx->globals->vars, struct hlsl_ir_var, scope_entry) + { + if (var->storage_modifiers & HLSL_STORAGE_UNIFORM) + { + list_add_tail(&ctx->extern_vars, &var->extern_entry); + var->is_uniform = 1; + } + } + hlsl_calculate_buffer_offsets(fx->ctx); } @@ -292,6 +303,14 @@ static uint32_t get_fx_4_type_size(const struct hlsl_type *type) return type->reg_size[HLSL_REGSET_NUMERIC] * sizeof(float) * elements_count; } +static const uint32_t fx_4_numeric_base_type[] = +{ + [HLSL_TYPE_FLOAT] = 1, + [HLSL_TYPE_INT ] = 2, + [HLSL_TYPE_UINT ] = 3, + [HLSL_TYPE_BOOL ] = 4, +}; + static uint32_t get_fx_4_numeric_type_description(const struct hlsl_type *type, struct fx_write_context *fx) { static const unsigned int NUMERIC_BASE_TYPE_SHIFT = 3; @@ -304,13 +323,6 @@ static uint32_t get_fx_4_numeric_type_description(const struct hlsl_type *type, [HLSL_CLASS_VECTOR] = 2, [HLSL_CLASS_MATRIX] = 3, }; - static const uint32_t numeric_base_type[] = - { - [HLSL_TYPE_FLOAT] = 1, - [HLSL_TYPE_INT ] = 2, - [HLSL_TYPE_UINT ] = 3, - [HLSL_TYPE_BOOL ] = 4, - }; struct hlsl_ctx *ctx = fx->ctx; uint32_t value = 0; @@ -326,16 +338,16 @@ static uint32_t get_fx_4_numeric_type_description(const struct hlsl_type *type, return 0; } - switch (type->base_type) + switch (type->e.numeric.type) { case HLSL_TYPE_FLOAT: case HLSL_TYPE_INT: case HLSL_TYPE_UINT: case HLSL_TYPE_BOOL: - value |= (numeric_base_type[type->base_type] << NUMERIC_BASE_TYPE_SHIFT); + value |= (fx_4_numeric_base_type[type->e.numeric.type] << NUMERIC_BASE_TYPE_SHIFT); break; default: - hlsl_fixme(ctx, &ctx->location, "Not implemented for base type %u.", type->base_type); + hlsl_fixme(ctx, &ctx->location, "Not implemented for base type %u.", type->e.numeric.type); return 0; } @@ -349,11 +361,6 @@ static uint32_t get_fx_4_numeric_type_description(const struct hlsl_type *type, static const char * get_fx_4_type_name(const struct hlsl_type *type) { - static const char * const object_type_names[] = - { - [HLSL_TYPE_PIXELSHADER] = "PixelShader", - [HLSL_TYPE_VERTEXSHADER] = "VertexShader", - }; static const char * const texture_type_names[] = { [HLSL_SAMPLER_DIM_GENERIC] = "texture", @@ -380,6 +387,9 @@ static const char * get_fx_4_type_name(const struct hlsl_type *type) switch (type->class) { + case HLSL_CLASS_SAMPLER: + return "SamplerState"; + case HLSL_CLASS_TEXTURE: return texture_type_names[type->sampler_dim]; @@ -392,15 +402,11 @@ static const char * get_fx_4_type_name(const struct hlsl_type *type) case HLSL_CLASS_RENDER_TARGET_VIEW: return "RenderTargetView"; - case HLSL_CLASS_OBJECT: - switch (type->base_type) - { - case HLSL_TYPE_PIXELSHADER: - case HLSL_TYPE_VERTEXSHADER: - return object_type_names[type->base_type]; - default: - return type->name; - } + case HLSL_CLASS_VERTEX_SHADER: + return "VertexShader"; + + case HLSL_CLASS_PIXEL_SHADER: + return "PixelShader"; default: return type->name; @@ -413,7 +419,6 @@ static uint32_t write_fx_4_type(const struct hlsl_type *type, struct fx_write_co uint32_t name_offset, offset, size, stride, numeric_desc; uint32_t elements_count = 0; const char *name; - struct hlsl_ctx *ctx = fx->ctx; /* Resolve arrays to element type and number of elements. */ if (type->class == HLSL_CLASS_ARRAY) @@ -436,10 +441,12 @@ static uint32_t write_fx_4_type(const struct hlsl_type *type, struct fx_write_co break; case HLSL_CLASS_DEPTH_STENCIL_VIEW: - case HLSL_CLASS_OBJECT: + case HLSL_CLASS_PIXEL_SHADER: case HLSL_CLASS_RENDER_TARGET_VIEW: + case HLSL_CLASS_SAMPLER: case HLSL_CLASS_TEXTURE: case HLSL_CLASS_UAV: + case HLSL_CLASS_VERTEX_SHADER: put_u32_unaligned(buffer, 2); break; @@ -453,7 +460,6 @@ static uint32_t write_fx_4_type(const struct hlsl_type *type, struct fx_write_co case HLSL_CLASS_TECHNIQUE: vkd3d_unreachable(); - case HLSL_CLASS_SAMPLER: case HLSL_CLASS_STRING: case HLSL_CLASS_VOID: FIXME("Writing type class %u is not implemented.\n", type->class); @@ -509,6 +515,10 @@ static uint32_t write_fx_4_type(const struct hlsl_type *type, struct fx_write_co put_u32_unaligned(buffer, texture_type[type->sampler_dim]); } + else if (type->class == HLSL_CLASS_SAMPLER) + { + put_u32_unaligned(buffer, 21); + } else if (type->class == HLSL_CLASS_UAV) { static const uint32_t uav_type[] = @@ -532,24 +542,13 @@ static uint32_t write_fx_4_type(const struct hlsl_type *type, struct fx_write_co { put_u32_unaligned(buffer, 19); } - else if (type->class == HLSL_CLASS_OBJECT) + else if (type->class == HLSL_CLASS_PIXEL_SHADER) { - static const uint32_t object_type[] = - { - [HLSL_TYPE_PIXELSHADER] = 5, - [HLSL_TYPE_VERTEXSHADER] = 6, - }; - - switch (type->base_type) - { - case HLSL_TYPE_PIXELSHADER: - case HLSL_TYPE_VERTEXSHADER: - put_u32_unaligned(buffer, object_type[type->base_type]); - break; - default: - hlsl_fixme(ctx, &ctx->location, "Object type %u is not supported.", type->base_type); - return 0; - } + put_u32_unaligned(buffer, 5); + } + else if (type->class == HLSL_CLASS_VERTEX_SHADER) + { + put_u32_unaligned(buffer, 6); } else if (hlsl_is_numeric_type(type)) { @@ -838,20 +837,10 @@ static bool is_type_supported_fx_2(struct hlsl_ctx *ctx, const struct hlsl_type } break; - case HLSL_CLASS_OBJECT: - switch (type->base_type) - { - case HLSL_TYPE_PIXELSHADER: - case HLSL_TYPE_VERTEXSHADER: - hlsl_fixme(ctx, loc, "Write fx 2.0 parameter object type %#x.", type->base_type); - return false; - - default: - return false; - } - + case HLSL_CLASS_PIXEL_SHADER: case HLSL_CLASS_SAMPLER: case HLSL_CLASS_STRING: + case HLSL_CLASS_VERTEX_SHADER: hlsl_fixme(ctx, loc, "Write fx 2.0 parameter class %#x.", type->class); return false; @@ -1012,6 +1001,317 @@ static void write_fx_4_numeric_variable(struct hlsl_ir_var *var, struct fx_write hlsl_fixme(ctx, &ctx->location, "Writing annotations for numeric variables is not implemented."); } +struct rhs_named_value +{ + const char *name; + unsigned int value; +}; + +static bool get_fx_4_state_enum_value(const struct rhs_named_value *pairs, + const char *name, unsigned int *value) +{ + while (pairs->name) + { + if (!ascii_strcasecmp(pairs->name, name)) + { + *value = pairs->value; + return true; + } + + pairs++; + } + + return false; +} + +static uint32_t write_fx_4_state_numeric_value(struct hlsl_ir_constant *value, struct fx_write_context *fx) +{ + struct vkd3d_bytecode_buffer *buffer = &fx->unstructured; + struct hlsl_type *data_type = value->node.data_type; + struct hlsl_ctx *ctx = fx->ctx; + uint32_t i, type, offset; + unsigned int count = hlsl_type_component_count(data_type); + + offset = put_u32_unaligned(buffer, count); + + for (i = 0; i < count; ++i) + { + if (hlsl_is_numeric_type(data_type)) + { + switch (data_type->e.numeric.type) + { + case HLSL_TYPE_FLOAT: + case HLSL_TYPE_INT: + case HLSL_TYPE_UINT: + case HLSL_TYPE_BOOL: + type = fx_4_numeric_base_type[data_type->e.numeric.type]; + break; + default: + type = 0; + hlsl_fixme(ctx, &ctx->location, "Unsupported numeric state value type %u.", data_type->e.numeric.type); + } + } + + put_u32_unaligned(buffer, type); + put_u32_unaligned(buffer, value->value.u[i].u); + } + + return offset; +} + +static void write_fx_4_state_assignment(const struct hlsl_ir_var *var, struct hlsl_state_block_entry *entry, + struct fx_write_context *fx) +{ + uint32_t value_offset = 0, assignment_type = 0, rhs_offset; + uint32_t type_offset; + struct vkd3d_bytecode_buffer *buffer = &fx->structured; + struct hlsl_ctx *ctx = fx->ctx; + struct hlsl_ir_node *value = entry->args->node; + + if (entry->lhs_has_index) + hlsl_fixme(ctx, &var->loc, "Unsupported assignment to array element."); + + put_u32(buffer, entry->name_id); + put_u32(buffer, 0); /* TODO: destination index */ + type_offset = put_u32(buffer, 0); + rhs_offset = put_u32(buffer, 0); + + switch (value->type) + { + case HLSL_IR_CONSTANT: + { + struct hlsl_ir_constant *c = hlsl_ir_constant(value); + + value_offset = write_fx_4_state_numeric_value(c, fx); + assignment_type = 1; + break; + } + default: + hlsl_fixme(ctx, &var->loc, "Unsupported assignment type for state %s.", entry->name); + } + + set_u32(buffer, type_offset, assignment_type); + set_u32(buffer, rhs_offset, value_offset); +} + +static bool state_block_contains_state(const char *name, unsigned int start, struct hlsl_state_block *block) +{ + unsigned int i; + + for (i = start; i < block->count; ++i) + { + if (!ascii_strcasecmp(block->entries[i]->name, name)) + return true; + } + + return false; +} + +struct replace_state_context +{ + const struct rhs_named_value *values; + struct hlsl_ir_var *var; +}; + +static bool replace_state_block_constant(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) +{ + struct replace_state_context *replace_context = context; + struct hlsl_ir_stateblock_constant *state_constant; + struct hlsl_ir_node *c; + unsigned int value; + + if (!replace_context->values) + return false; + if (instr->type != HLSL_IR_STATEBLOCK_CONSTANT) + return false; + + state_constant = hlsl_ir_stateblock_constant(instr); + if (!get_fx_4_state_enum_value(replace_context->values, state_constant->name, &value)) + { + hlsl_error(ctx, &replace_context->var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_SYNTAX, + "Unrecognized state constant %s.", state_constant->name); + return false; + } + + if (!(c = hlsl_new_uint_constant(ctx, value, &replace_context->var->loc))) + return false; + + list_add_before(&state_constant->node.entry, &c->entry); + hlsl_replace_node(&state_constant->node, c); + + return true; +} + +static void resolve_fx_4_state_block_values(struct hlsl_ir_var *var, struct hlsl_state_block_entry *entry, + struct fx_write_context *fx) +{ + static const struct rhs_named_value filter_values[] = + { + { "MIN_MAG_MIP_POINT", 0x00 }, + { "MIN_MAG_POINT_MIP_LINEAR", 0x01 }, + { "MIN_POINT_MAG_LINEAR_MIP_POINT", 0x04 }, + { "MIN_POINT_MAG_MIP_LINEAR", 0x05 }, + { "MIN_LINEAR_MAG_MIP_POINT", 0x10 }, + { "MIN_LINEAR_MAG_POINT_MIP_LINEAR", 0x11 }, + { "MIN_MAG_LINEAR_MIP_POINT", 0x14 }, + { "MIN_MAG_MIP_LINEAR", 0x15 }, + { "ANISOTROPIC", 0x55 }, + { "COMPARISON_MIN_MAG_MIP_POINT", 0x80 }, + { "COMPARISON_MIN_MAG_POINT_MIP_LINEAR", 0x81 }, + { "COMPARISON_MIN_POINT_MAG_LINEAR_MIP_POINT", 0x84 }, + { "COMPARISON_MIN_POINT_MAG_MIP_LINEAR", 0x85 }, + { "COMPARISON_MIN_LINEAR_MAG_MIP_POINT", 0x90 }, + { "COMPARISON_MIN_LINEAR_MAG_POINT_MIP_LINEAR", 0x91 }, + { "COMPARISON_MIN_MAG_LINEAR_MIP_POINT", 0x94 }, + { "COMPARISON_MIN_MAG_MIP_LINEAR", 0x95 }, + { "COMPARISON_ANISOTROPIC", 0xd5 }, + { NULL }, + }; + + static const struct rhs_named_value address_values[] = + { + { "WRAP", 1 }, + { "MIRROR", 2 }, + { "CLAMP", 3 }, + { "BORDER", 4 }, + { "MIRROR_ONCE", 5 }, + { NULL }, + }; + + static const struct rhs_named_value compare_func_values[] = + { + { "NEVER", 1 }, + { "LESS", 2 }, + { "EQUAL", 3 }, + { "LESS_EQUAL", 4 }, + { "GREATER", 5 }, + { "NOT_EQUAL", 6 }, + { "GREATER_EQUAL", 7 }, + { "ALWAYS", 8 }, + { NULL } + }; + + static const struct state + { + const char *name; + enum hlsl_type_class container; + enum hlsl_base_type type; + unsigned int dimx; + uint32_t id; + const struct rhs_named_value *values; + } + states[] = + { + { "Filter", HLSL_CLASS_SAMPLER, HLSL_TYPE_UINT, 1, 45, filter_values }, + { "AddressU", HLSL_CLASS_SAMPLER, HLSL_TYPE_UINT, 1, 46, address_values }, + { "AddressV", HLSL_CLASS_SAMPLER, HLSL_TYPE_UINT, 1, 47, address_values }, + { "AddressW", HLSL_CLASS_SAMPLER, HLSL_TYPE_UINT, 1, 48, address_values }, + { "MipLODBias", HLSL_CLASS_SAMPLER, HLSL_TYPE_FLOAT, 1, 49 }, + { "MaxAnisotropy", HLSL_CLASS_SAMPLER, HLSL_TYPE_UINT, 1, 50 }, + { "ComparisonFunc", HLSL_CLASS_SAMPLER, HLSL_TYPE_UINT, 1, 51, compare_func_values }, + { "BorderColor", HLSL_CLASS_SAMPLER, HLSL_TYPE_FLOAT, 4, 52 }, + { "MinLOD", HLSL_CLASS_SAMPLER, HLSL_TYPE_FLOAT, 1, 53 }, + { "MaxLOD", HLSL_CLASS_SAMPLER, HLSL_TYPE_FLOAT, 1, 54 }, + /* TODO: "Texture" field */ + }; + const struct hlsl_type *type = hlsl_get_multiarray_element_type(var->data_type); + struct replace_state_context replace_context; + struct hlsl_ir_node *node, *cast; + const struct state *state = NULL; + struct hlsl_ctx *ctx = fx->ctx; + struct hlsl_type *state_type; + unsigned int i; + bool progress; + + for (i = 0; i < ARRAY_SIZE(states); ++i) + { + if (type->class == states[i].container + && !ascii_strcasecmp(entry->name, states[i].name)) + { + state = &states[i]; + break; + } + } + + if (!state) + { + hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_SYNTAX, "Unrecognized state name %s.", entry->name); + return; + } + + if (entry->args_count != 1) + { + hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_SYNTAX, "Unrecognized initializer for the state %s.", + entry->name); + return; + } + + entry->name_id = state->id; + + replace_context.values = state->values; + replace_context.var = var; + + /* Turned named constants to actual constants. */ + hlsl_transform_ir(ctx, replace_state_block_constant, entry->instrs, &replace_context); + + if (state->dimx) + state_type = hlsl_get_vector_type(ctx, state->type, state->dimx); + else + state_type = hlsl_get_scalar_type(ctx, state->type); + + /* Cast to expected property type. */ + node = entry->args->node; + if (!(cast = hlsl_new_cast(ctx, node, state_type, &var->loc))) + return; + list_add_after(&node->entry, &cast->entry); + + hlsl_src_remove(entry->args); + hlsl_src_from_node(entry->args, cast); + + do + { + progress = hlsl_transform_ir(ctx, hlsl_fold_constant_exprs, entry->instrs, NULL); + progress |= hlsl_copy_propagation_execute(ctx, entry->instrs); + } while (progress); +} + +static void write_fx_4_state_object_initializer(struct hlsl_ir_var *var, struct fx_write_context *fx) +{ + uint32_t elements_count = hlsl_get_multiarray_size(var->data_type), i, j; + struct vkd3d_bytecode_buffer *buffer = &fx->structured; + uint32_t count_offset, count; + + for (i = 0; i < elements_count; ++i) + { + struct hlsl_state_block *block; + + count_offset = put_u32(buffer, 0); + + count = 0; + if (var->state_blocks) + { + block = var->state_blocks[i]; + + for (j = 0; j < block->count; ++j) + { + struct hlsl_state_block_entry *entry = block->entries[j]; + + /* Skip if property is reassigned later. This will use the last assignment. */ + if (state_block_contains_state(entry->name, j + 1, block)) + continue; + + /* Resolve special constant names and property names. */ + resolve_fx_4_state_block_values(var, entry, fx); + + write_fx_4_state_assignment(var, entry, fx); + ++count; + } + } + + set_u32(buffer, count_offset, count); + } +} + static void write_fx_4_object_variable(struct hlsl_ir_var *var, struct fx_write_context *fx) { const struct hlsl_type *type = hlsl_get_multiarray_element_type(var->data_type); @@ -1044,29 +1344,35 @@ static void write_fx_4_object_variable(struct hlsl_ir_var *var, struct fx_write_ switch (type->class) { case HLSL_CLASS_RENDER_TARGET_VIEW: + fx->rtv_count += elements_count; + break; case HLSL_CLASS_TEXTURE: + fx->texture_count += elements_count; + break; case HLSL_CLASS_UAV: + fx->uav_count += elements_count; break; - case HLSL_CLASS_OBJECT: - switch (type->base_type) - { - case HLSL_TYPE_PIXELSHADER: - case HLSL_TYPE_VERTEXSHADER: - /* FIXME: write shader blobs, once parser support works. */ - for (i = 0; i < elements_count; ++i) - put_u32(buffer, 0); - ++fx->shader_variable_count; - break; - default: - hlsl_fixme(ctx, &ctx->location, "Writing initializer for object type %u is not implemented.", - type->base_type); - } + case HLSL_CLASS_PIXEL_SHADER: + case HLSL_CLASS_VERTEX_SHADER: + /* FIXME: write shader blobs, once parser support works. */ + for (i = 0; i < elements_count; ++i) + put_u32(buffer, 0); + fx->shader_count += elements_count; + break; + + case HLSL_CLASS_DEPTH_STENCIL_VIEW: + fx->dsv_count += elements_count; + break; + + case HLSL_CLASS_SAMPLER: + write_fx_4_state_object_initializer(var, fx); + fx->sampler_state_count += elements_count; break; default: hlsl_fixme(ctx, &ctx->location, "Writing initializer for object type %u is not implemented.", - type->base_type); + type->e.numeric.type); } put_u32(buffer, 0); /* Annotations count */ @@ -1143,27 +1449,26 @@ static void write_buffers(struct fx_write_context *fx) } } -static bool is_object_variable(const struct hlsl_ir_var *var) +static bool is_supported_object_variable(const struct hlsl_ctx *ctx, const struct hlsl_ir_var *var) { const struct hlsl_type *type = hlsl_get_multiarray_element_type(var->data_type); switch (type->class) { + case HLSL_CLASS_DEPTH_STENCIL_VIEW: + case HLSL_CLASS_PIXEL_SHADER: case HLSL_CLASS_RENDER_TARGET_VIEW: case HLSL_CLASS_SAMPLER: case HLSL_CLASS_TEXTURE: + return true; case HLSL_CLASS_UAV: + if (ctx->profile->major_version < 5) + return false; + if (type->e.resource.rasteriser_ordered) + return false; + return true; + case HLSL_CLASS_VERTEX_SHADER: return true; - - case HLSL_CLASS_OBJECT: - switch (type->base_type) - { - case HLSL_TYPE_PIXELSHADER: - case HLSL_TYPE_VERTEXSHADER: - return true; - default: - return false; - } default: return false; @@ -1172,14 +1477,15 @@ static bool is_object_variable(const struct hlsl_ir_var *var) static void write_objects(struct fx_write_context *fx, bool shared) { + struct hlsl_ctx *ctx = fx->ctx; struct hlsl_ir_var *var; if (shared && !fx->child_effect) return; - LIST_FOR_EACH_ENTRY(var, &fx->ctx->extern_vars, struct hlsl_ir_var, extern_entry) + LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry) { - if (!is_object_variable(var)) + if (!is_supported_object_variable(ctx, var)) continue; if (fx->child_effect && (shared != !!(var->storage_modifiers & HLSL_STORAGE_SHARED))) @@ -1216,14 +1522,14 @@ static int hlsl_fx_4_write(struct hlsl_ctx *ctx, struct vkd3d_shader_code *out) put_u32(&buffer, fx.technique_count); size_offset = put_u32(&buffer, 0); /* Unstructured size. */ put_u32(&buffer, 0); /* String count. */ - put_u32(&buffer, 0); /* Texture object count. */ + put_u32(&buffer, fx.texture_count); put_u32(&buffer, 0); /* Depth stencil state count. */ put_u32(&buffer, 0); /* Blend state count. */ put_u32(&buffer, 0); /* Rasterizer state count. */ - put_u32(&buffer, 0); /* Sampler state count. */ - put_u32(&buffer, 0); /* Rendertarget view count. */ - put_u32(&buffer, 0); /* Depth stencil view count. */ - put_u32(&buffer, fx.shader_variable_count); /* Shader count. */ + put_u32(&buffer, fx.sampler_state_count); + put_u32(&buffer, fx.rtv_count); + put_u32(&buffer, fx.dsv_count); + put_u32(&buffer, fx.shader_count); put_u32(&buffer, 0); /* Inline shader count. */ set_u32(&buffer, size_offset, fx.unstructured.size); @@ -1274,17 +1580,17 @@ static int hlsl_fx_5_write(struct hlsl_ctx *ctx, struct vkd3d_shader_code *out) put_u32(&buffer, fx.technique_count); size_offset = put_u32(&buffer, 0); /* Unstructured size. */ put_u32(&buffer, 0); /* String count. */ - put_u32(&buffer, 0); /* Texture object count. */ + put_u32(&buffer, fx.texture_count); put_u32(&buffer, 0); /* Depth stencil state count. */ put_u32(&buffer, 0); /* Blend state count. */ put_u32(&buffer, 0); /* Rasterizer state count. */ - put_u32(&buffer, 0); /* Sampler state count. */ - put_u32(&buffer, 0); /* Rendertarget view count. */ - put_u32(&buffer, 0); /* Depth stencil view count. */ - put_u32(&buffer, fx.shader_variable_count); /* Shader count. */ + put_u32(&buffer, fx.sampler_state_count); + put_u32(&buffer, fx.rtv_count); + put_u32(&buffer, fx.dsv_count); + put_u32(&buffer, fx.shader_count); put_u32(&buffer, 0); /* Inline shader count. */ put_u32(&buffer, fx.group_count); /* Group count. */ - put_u32(&buffer, 0); /* UAV count. */ + put_u32(&buffer, fx.uav_count); put_u32(&buffer, 0); /* Interface variables count. */ put_u32(&buffer, 0); /* Interface variable element count. */ put_u32(&buffer, 0); /* Class instance elements count. */ diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.c b/libs/vkd3d/libs/vkd3d-shader/hlsl.c index 0b48b17d21c..96e73d23d72 100644 --- a/libs/vkd3d/libs/vkd3d-shader/hlsl.c +++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.c @@ -136,7 +136,11 @@ struct hlsl_ir_var *hlsl_get_var(struct hlsl_scope *scope, const char *name) static void free_state_block_entry(struct hlsl_state_block_entry *entry) { + unsigned int i; + vkd3d_free(entry->name); + for (i = 0; i < entry->args_count; ++i) + hlsl_src_remove(&entry->args[i]); vkd3d_free(entry->args); hlsl_block_cleanup(entry->instrs); vkd3d_free(entry->instrs); @@ -365,11 +369,12 @@ static void hlsl_type_calculate_reg_size(struct hlsl_ctx *ctx, struct hlsl_type case HLSL_CLASS_DEPTH_STENCIL_VIEW: case HLSL_CLASS_EFFECT_GROUP: - case HLSL_CLASS_OBJECT: case HLSL_CLASS_PASS: + case HLSL_CLASS_PIXEL_SHADER: case HLSL_CLASS_RENDER_TARGET_VIEW: case HLSL_CLASS_STRING: case HLSL_CLASS_TECHNIQUE: + case HLSL_CLASS_VERTEX_SHADER: case HLSL_CLASS_VOID: break; } @@ -416,7 +421,7 @@ static struct hlsl_type *hlsl_new_type(struct hlsl_ctx *ctx, const char *name, e return NULL; } type->class = type_class; - type->base_type = base_type; + type->e.numeric.type = base_type; type->dimx = dimx; type->dimy = dimy; hlsl_type_calculate_reg_size(ctx, type); @@ -431,13 +436,14 @@ static bool type_is_single_component(const struct hlsl_type *type) switch (type->class) { case HLSL_CLASS_DEPTH_STENCIL_VIEW: + case HLSL_CLASS_PIXEL_SHADER: case HLSL_CLASS_SCALAR: - case HLSL_CLASS_OBJECT: case HLSL_CLASS_SAMPLER: case HLSL_CLASS_STRING: case HLSL_CLASS_RENDER_TARGET_VIEW: case HLSL_CLASS_TEXTURE: case HLSL_CLASS_UAV: + case HLSL_CLASS_VERTEX_SHADER: return true; case HLSL_CLASS_VECTOR: @@ -475,7 +481,7 @@ static unsigned int traverse_path_from_component_index(struct hlsl_ctx *ctx, { case HLSL_CLASS_VECTOR: assert(index < type->dimx); - *type_ptr = hlsl_get_scalar_type(ctx, type->base_type); + *type_ptr = hlsl_get_scalar_type(ctx, type->e.numeric.type); *index_ptr = 0; return index; @@ -485,7 +491,7 @@ static unsigned int traverse_path_from_component_index(struct hlsl_ctx *ctx, bool row_major = hlsl_type_is_row_major(type); assert(index < type->dimx * type->dimy); - *type_ptr = hlsl_get_vector_type(ctx, type->base_type, row_major ? type->dimx : type->dimy); + *type_ptr = hlsl_get_vector_type(ctx, type->e.numeric.type, row_major ? type->dimx : type->dimy); *index_ptr = row_major ? x : y; return row_major ? y : x; } @@ -572,12 +578,13 @@ unsigned int hlsl_type_get_component_offset(struct hlsl_ctx *ctx, struct hlsl_ty break; case HLSL_CLASS_DEPTH_STENCIL_VIEW: - case HLSL_CLASS_OBJECT: + case HLSL_CLASS_PIXEL_SHADER: case HLSL_CLASS_RENDER_TARGET_VIEW: case HLSL_CLASS_SAMPLER: case HLSL_CLASS_STRING: case HLSL_CLASS_TEXTURE: case HLSL_CLASS_UAV: + case HLSL_CLASS_VERTEX_SHADER: assert(idx == 0); break; @@ -758,13 +765,13 @@ struct hlsl_type *hlsl_get_element_type_from_path_index(struct hlsl_ctx *ctx, co switch (type->class) { case HLSL_CLASS_VECTOR: - return hlsl_get_scalar_type(ctx, type->base_type); + return hlsl_get_scalar_type(ctx, type->e.numeric.type); case HLSL_CLASS_MATRIX: if (hlsl_type_is_row_major(type)) - return hlsl_get_vector_type(ctx, type->base_type, type->dimx); + return hlsl_get_vector_type(ctx, type->e.numeric.type, type->dimx); else - return hlsl_get_vector_type(ctx, type->base_type, type->dimy); + return hlsl_get_vector_type(ctx, type->e.numeric.type, type->dimy); case HLSL_CLASS_ARRAY: return type->e.array.type; @@ -950,12 +957,13 @@ unsigned int hlsl_type_component_count(const struct hlsl_type *type) return hlsl_type_component_count(type->e.array.type) * type->e.array.elements_count; case HLSL_CLASS_DEPTH_STENCIL_VIEW: - case HLSL_CLASS_OBJECT: + case HLSL_CLASS_PIXEL_SHADER: case HLSL_CLASS_RENDER_TARGET_VIEW: case HLSL_CLASS_SAMPLER: case HLSL_CLASS_STRING: case HLSL_CLASS_TEXTURE: case HLSL_CLASS_UAV: + case HLSL_CLASS_VERTEX_SHADER: return 1; case HLSL_CLASS_EFFECT_GROUP: @@ -975,55 +983,73 @@ bool hlsl_types_are_equal(const struct hlsl_type *t1, const struct hlsl_type *t2 if (t1->class != t2->class) return false; - if (t1->base_type != t2->base_type) - return false; - if (t1->class == HLSL_CLASS_SAMPLER || t1->class == HLSL_CLASS_TEXTURE || t1->class == HLSL_CLASS_UAV) - { - if (t1->sampler_dim != t2->sampler_dim) - return false; - if ((t1->class == HLSL_CLASS_TEXTURE || t1->class == HLSL_CLASS_UAV) - && t1->sampler_dim != HLSL_SAMPLER_DIM_GENERIC - && !hlsl_types_are_equal(t1->e.resource.format, t2->e.resource.format)) - return false; - if (t1->class == HLSL_CLASS_UAV && t1->e.resource.rasteriser_ordered != t2->e.resource.rasteriser_ordered) - return false; - } - if ((t1->modifiers & HLSL_MODIFIER_ROW_MAJOR) - != (t2->modifiers & HLSL_MODIFIER_ROW_MAJOR)) - return false; - if (t1->dimx != t2->dimx) - return false; - if (t1->dimy != t2->dimy) - return false; - if (t1->class == HLSL_CLASS_STRUCT) - { - size_t i; - if (t1->e.record.field_count != t2->e.record.field_count) - return false; - - for (i = 0; i < t1->e.record.field_count; ++i) - { - const struct hlsl_struct_field *field1 = &t1->e.record.fields[i]; - const struct hlsl_struct_field *field2 = &t2->e.record.fields[i]; + switch (t1->class) + { + case HLSL_CLASS_SCALAR: + case HLSL_CLASS_VECTOR: + case HLSL_CLASS_MATRIX: + if (t1->e.numeric.type != t2->e.numeric.type) + return false; + if ((t1->modifiers & HLSL_MODIFIER_ROW_MAJOR) + != (t2->modifiers & HLSL_MODIFIER_ROW_MAJOR)) + return false; + if (t1->dimx != t2->dimx) + return false; + if (t1->dimy != t2->dimy) + return false; + return true; - if (!hlsl_types_are_equal(field1->type, field2->type)) + case HLSL_CLASS_UAV: + if (t1->e.resource.rasteriser_ordered != t2->e.resource.rasteriser_ordered) + return false; + /* fall through */ + case HLSL_CLASS_TEXTURE: + if (t1->sampler_dim != HLSL_SAMPLER_DIM_GENERIC + && !hlsl_types_are_equal(t1->e.resource.format, t2->e.resource.format)) return false; + /* fall through */ + case HLSL_CLASS_SAMPLER: + if (t1->sampler_dim != t2->sampler_dim) + return false; + return true; - if (strcmp(field1->name, field2->name)) + case HLSL_CLASS_STRUCT: + if (t1->e.record.field_count != t2->e.record.field_count) return false; - } - } - if (t1->class == HLSL_CLASS_ARRAY) - return t1->e.array.elements_count == t2->e.array.elements_count - && hlsl_types_are_equal(t1->e.array.type, t2->e.array.type); - if (t1->class == HLSL_CLASS_TECHNIQUE) - { - if (t1->e.version != t2->e.version) - return false; + + for (size_t i = 0; i < t1->e.record.field_count; ++i) + { + const struct hlsl_struct_field *field1 = &t1->e.record.fields[i]; + const struct hlsl_struct_field *field2 = &t2->e.record.fields[i]; + + if (!hlsl_types_are_equal(field1->type, field2->type)) + return false; + + if (strcmp(field1->name, field2->name)) + return false; + } + return true; + + case HLSL_CLASS_ARRAY: + return t1->e.array.elements_count == t2->e.array.elements_count + && hlsl_types_are_equal(t1->e.array.type, t2->e.array.type); + + case HLSL_CLASS_TECHNIQUE: + return t1->e.version == t2->e.version; + + case HLSL_CLASS_DEPTH_STENCIL_VIEW: + case HLSL_CLASS_EFFECT_GROUP: + case HLSL_CLASS_PASS: + case HLSL_CLASS_PIXEL_SHADER: + case HLSL_CLASS_RENDER_TARGET_VIEW: + case HLSL_CLASS_STRING: + case HLSL_CLASS_VERTEX_SHADER: + case HLSL_CLASS_VOID: + return true; } - return true; + vkd3d_unreachable(); } struct hlsl_type *hlsl_type_clone(struct hlsl_ctx *ctx, struct hlsl_type *old, @@ -1044,7 +1070,6 @@ struct hlsl_type *hlsl_type_clone(struct hlsl_ctx *ctx, struct hlsl_type *old, } } type->class = old->class; - type->base_type = old->base_type; type->dimx = old->dimx; type->dimy = old->dimy; type->modifiers = old->modifiers | modifiers; @@ -1056,6 +1081,12 @@ struct hlsl_type *hlsl_type_clone(struct hlsl_ctx *ctx, struct hlsl_type *old, switch (old->class) { + case HLSL_CLASS_SCALAR: + case HLSL_CLASS_VECTOR: + case HLSL_CLASS_MATRIX: + type->e.numeric.type = old->e.numeric.type; + break; + case HLSL_CLASS_ARRAY: if (!(type->e.array.type = hlsl_type_clone(ctx, old->e.array.type, default_majority, modifiers))) { @@ -1643,10 +1674,11 @@ struct hlsl_ir_node *hlsl_new_swizzle(struct hlsl_ctx *ctx, uint32_t s, unsigned if (!(swizzle = hlsl_alloc(ctx, sizeof(*swizzle)))) return NULL; + assert(hlsl_is_numeric_type(val->data_type)); if (components == 1) - type = hlsl_get_scalar_type(ctx, val->data_type->base_type); + type = hlsl_get_scalar_type(ctx, val->data_type->e.numeric.type); else - type = hlsl_get_vector_type(ctx, val->data_type->base_type, components); + type = hlsl_get_vector_type(ctx, val->data_type->e.numeric.type, components); init_node(&swizzle->node, HLSL_IR_SWIZZLE, type, loc); hlsl_src_from_node(&swizzle->val, val); swizzle->swizzle = s; @@ -1709,7 +1741,7 @@ struct hlsl_ir_node *hlsl_new_index(struct hlsl_ctx *ctx, struct hlsl_ir_node *v if (type->class == HLSL_CLASS_TEXTURE || type->class == HLSL_CLASS_UAV) type = type->e.resource.format; else if (type->class == HLSL_CLASS_MATRIX) - type = hlsl_get_vector_type(ctx, type->base_type, type->dimx); + type = hlsl_get_vector_type(ctx, type->e.numeric.type, type->dimx); else type = hlsl_get_element_type_from_path_index(ctx, type, idx); @@ -2295,18 +2327,18 @@ struct vkd3d_string_buffer *hlsl_type_to_string(struct hlsl_ctx *ctx, const stru switch (type->class) { case HLSL_CLASS_SCALAR: - assert(type->base_type < ARRAY_SIZE(base_types)); - vkd3d_string_buffer_printf(string, "%s", base_types[type->base_type]); + assert(type->e.numeric.type < ARRAY_SIZE(base_types)); + vkd3d_string_buffer_printf(string, "%s", base_types[type->e.numeric.type]); return string; case HLSL_CLASS_VECTOR: - assert(type->base_type < ARRAY_SIZE(base_types)); - vkd3d_string_buffer_printf(string, "%s%u", base_types[type->base_type], type->dimx); + assert(type->e.numeric.type < ARRAY_SIZE(base_types)); + vkd3d_string_buffer_printf(string, "%s%u", base_types[type->e.numeric.type], type->dimx); return string; case HLSL_CLASS_MATRIX: - assert(type->base_type < ARRAY_SIZE(base_types)); - vkd3d_string_buffer_printf(string, "%s%ux%u", base_types[type->base_type], type->dimy, type->dimx); + assert(type->e.numeric.type < ARRAY_SIZE(base_types)); + vkd3d_string_buffer_printf(string, "%s%ux%u", base_types[type->e.numeric.type], type->dimy, type->dimx); return string; case HLSL_CLASS_ARRAY: @@ -2343,7 +2375,8 @@ struct vkd3d_string_buffer *hlsl_type_to_string(struct hlsl_ctx *ctx, const stru return string; } - assert(type->e.resource.format->base_type < ARRAY_SIZE(base_types)); + assert(hlsl_is_numeric_type(type->e.resource.format)); + assert(type->e.resource.format->e.numeric.type < ARRAY_SIZE(base_types)); if (type->sampler_dim == HLSL_SAMPLER_DIM_BUFFER) { vkd3d_string_buffer_printf(string, "Buffer"); @@ -2376,12 +2409,13 @@ struct vkd3d_string_buffer *hlsl_type_to_string(struct hlsl_ctx *ctx, const stru case HLSL_CLASS_DEPTH_STENCIL_VIEW: case HLSL_CLASS_EFFECT_GROUP: - case HLSL_CLASS_OBJECT: case HLSL_CLASS_PASS: + case HLSL_CLASS_PIXEL_SHADER: case HLSL_CLASS_RENDER_TARGET_VIEW: case HLSL_CLASS_SAMPLER: case HLSL_CLASS_STRING: case HLSL_CLASS_TECHNIQUE: + case HLSL_CLASS_VERTEX_SHADER: case HLSL_CLASS_VOID: break; } @@ -2665,7 +2699,7 @@ static void dump_ir_constant(struct vkd3d_string_buffer *buffer, const struct hl { const union hlsl_constant_value_component *value = &constant->value.u[x]; - switch (type->base_type) + switch (type->e.numeric.type) { case HLSL_TYPE_BOOL: vkd3d_string_buffer_printf(buffer, "%s ", value->u ? "true" : "false"); @@ -3557,8 +3591,6 @@ static void declare_predefined_types(struct hlsl_ctx *ctx) {"dword", HLSL_CLASS_SCALAR, HLSL_TYPE_UINT, 1, 1}, {"vector", HLSL_CLASS_VECTOR, HLSL_TYPE_FLOAT, 4, 1}, {"matrix", HLSL_CLASS_MATRIX, HLSL_TYPE_FLOAT, 4, 4}, - {"pixelshader", HLSL_CLASS_OBJECT, HLSL_TYPE_PIXELSHADER, 1, 1}, - {"vertexshader", HLSL_CLASS_OBJECT, HLSL_TYPE_VERTEXSHADER, 1, 1}, }; static const struct @@ -3682,9 +3714,11 @@ static void declare_predefined_types(struct hlsl_ctx *ctx) hlsl_scope_add_type(ctx->globals, hlsl_new_simple_type(ctx, "DepthStencilView", HLSL_CLASS_DEPTH_STENCIL_VIEW)); hlsl_scope_add_type(ctx->globals, hlsl_new_simple_type(ctx, "fxgroup", HLSL_CLASS_EFFECT_GROUP)); hlsl_scope_add_type(ctx->globals, hlsl_new_simple_type(ctx, "pass", HLSL_CLASS_PASS)); + hlsl_scope_add_type(ctx->globals, hlsl_new_simple_type(ctx, "pixelshader", HLSL_CLASS_PIXEL_SHADER)); hlsl_scope_add_type(ctx->globals, hlsl_new_simple_type(ctx, "RenderTargetView", HLSL_CLASS_RENDER_TARGET_VIEW)); hlsl_scope_add_type(ctx->globals, hlsl_new_simple_type(ctx, "STRING", HLSL_CLASS_STRING)); hlsl_scope_add_type(ctx->globals, hlsl_new_simple_type(ctx, "texture", HLSL_CLASS_TEXTURE)); + hlsl_scope_add_type(ctx->globals, hlsl_new_simple_type(ctx, "vertexshader", HLSL_CLASS_VERTEX_SHADER)); for (i = 0; i < ARRAY_SIZE(effect_types); ++i) { diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.h b/libs/vkd3d/libs/vkd3d-shader/hlsl.h index c3a4c6bd291..a89e43f9bf2 100644 --- a/libs/vkd3d/libs/vkd3d-shader/hlsl.h +++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.h @@ -78,16 +78,17 @@ enum hlsl_type_class HLSL_CLASS_LAST_NUMERIC = HLSL_CLASS_MATRIX, HLSL_CLASS_STRUCT, HLSL_CLASS_ARRAY, - HLSL_CLASS_OBJECT, HLSL_CLASS_DEPTH_STENCIL_VIEW, HLSL_CLASS_EFFECT_GROUP, HLSL_CLASS_PASS, + HLSL_CLASS_PIXEL_SHADER, HLSL_CLASS_RENDER_TARGET_VIEW, HLSL_CLASS_SAMPLER, HLSL_CLASS_STRING, HLSL_CLASS_TECHNIQUE, HLSL_CLASS_TEXTURE, HLSL_CLASS_UAV, + HLSL_CLASS_VERTEX_SHADER, HLSL_CLASS_VOID, }; @@ -100,8 +101,6 @@ enum hlsl_base_type HLSL_TYPE_UINT, HLSL_TYPE_BOOL, HLSL_TYPE_LAST_SCALAR = HLSL_TYPE_BOOL, - HLSL_TYPE_PIXELSHADER, - HLSL_TYPE_VERTEXSHADER, }; enum hlsl_sampler_dim @@ -143,10 +142,6 @@ struct hlsl_type struct rb_entry scope_entry; enum hlsl_type_class class; - /* If class is <= HLSL_CLASS_LAST_NUMERIC, then base_type is <= HLSL_TYPE_LAST_SCALAR. - * If class is HLSL_CLASS_OBJECT, then base_type is > HLSL_TYPE_LAST_SCALAR. - * Otherwise, base_type is not used. */ - enum hlsl_base_type base_type; /* If class is HLSL_CLASS_SAMPLER, then sampler_dim is <= HLSL_SAMPLER_DIM_LAST_SAMPLER. * If class is HLSL_CLASS_TEXTURE, then sampler_dim can be any value of the enum except @@ -177,6 +172,11 @@ struct hlsl_type union { + /* Additional information if type is numeric. */ + struct + { + enum hlsl_base_type type; + } numeric; /* Additional information if type is HLSL_CLASS_STRUCT. */ struct { @@ -474,6 +474,8 @@ struct hlsl_state_block_entry { /* For assignments, the name in the lhs. */ char *name; + /* Resolved format-specific property identifier. */ + unsigned int name_id; /* Whether the lhs in the assignment is indexed and, in that case, its index. */ bool lhs_has_index; @@ -483,7 +485,7 @@ struct hlsl_state_block_entry struct hlsl_block *instrs; /* For assignments, arguments of the rhs initializer. */ - struct hlsl_ir_node **args; + struct hlsl_src *args; unsigned int args_count; }; @@ -1400,7 +1402,6 @@ unsigned int hlsl_type_get_sm4_offset(const struct hlsl_type *type, unsigned int bool hlsl_types_are_equal(const struct hlsl_type *t1, const struct hlsl_type *t2); void hlsl_calculate_buffer_offsets(struct hlsl_ctx *ctx); -void hlsl_prepend_global_uniform_copy(struct hlsl_ctx *ctx, struct hlsl_block *block); const struct hlsl_type *hlsl_get_multiarray_element_type(const struct hlsl_type *type); unsigned int hlsl_get_multiarray_size(const struct hlsl_type *type); diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.y b/libs/vkd3d/libs/vkd3d-shader/hlsl.y index 0eed15c5a91..79317bb0545 100644 --- a/libs/vkd3d/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.y @@ -1352,9 +1352,6 @@ static unsigned int evaluate_static_expression_as_uint(struct hlsl_ctx *ctx, str static bool expr_compatible_data_types(struct hlsl_type *t1, struct hlsl_type *t2) { - if (t1->base_type > HLSL_TYPE_LAST_SCALAR || t2->base_type > HLSL_TYPE_LAST_SCALAR) - return false; - /* Scalar vars can be converted to pretty much everything */ if ((t1->dimx == 1 && t1->dimy == 1) || (t2->dimx == 1 && t2->dimy == 1)) return true; @@ -1386,10 +1383,6 @@ static bool expr_compatible_data_types(struct hlsl_type *t1, struct hlsl_type *t static enum hlsl_base_type expr_common_base_type(enum hlsl_base_type t1, enum hlsl_base_type t2) { - if (t1 > HLSL_TYPE_LAST_SCALAR || t2 > HLSL_TYPE_LAST_SCALAR) { - FIXME("Unexpected base type.\n"); - return HLSL_TYPE_FLOAT; - } if (t1 == t2) return t1 == HLSL_TYPE_BOOL ? HLSL_TYPE_INT : t1; if (t1 == HLSL_TYPE_DOUBLE || t2 == HLSL_TYPE_DOUBLE) @@ -1493,7 +1486,7 @@ static struct hlsl_ir_node *add_expr(struct hlsl_ctx *ctx, struct hlsl_block *bl struct hlsl_ir_node *load; struct hlsl_ir_var *var; - scalar_type = hlsl_get_scalar_type(ctx, type->base_type); + scalar_type = hlsl_get_scalar_type(ctx, type->e.numeric.type); if (!(var = hlsl_new_synthetic_var(ctx, "split_op", type, loc))) return NULL; @@ -1543,7 +1536,7 @@ static void check_integer_type(struct hlsl_ctx *ctx, const struct hlsl_ir_node * const struct hlsl_type *type = instr->data_type; struct vkd3d_string_buffer *string; - switch (type->base_type) + switch (type->e.numeric.type) { case HLSL_TYPE_BOOL: case HLSL_TYPE_INT: @@ -1593,13 +1586,13 @@ static struct hlsl_ir_node *add_unary_logical_expr(struct hlsl_ctx *ctx, struct static struct hlsl_type *get_common_numeric_type(struct hlsl_ctx *ctx, const struct hlsl_ir_node *arg1, const struct hlsl_ir_node *arg2, const struct vkd3d_shader_location *loc) { - enum hlsl_base_type base = expr_common_base_type(arg1->data_type->base_type, arg2->data_type->base_type); enum hlsl_type_class type; + enum hlsl_base_type base; unsigned int dimx, dimy; if (!expr_common_shape(ctx, arg1->data_type, arg2->data_type, loc, &type, &dimx, &dimy)) return NULL; - + base = expr_common_base_type(arg1->data_type->e.numeric.type, arg2->data_type->e.numeric.type); return hlsl_get_numeric_type(ctx, type, base, dimx, dimy); } @@ -1636,14 +1629,15 @@ static struct hlsl_ir_node *add_binary_comparison_expr(struct hlsl_ctx *ctx, str const struct vkd3d_shader_location *loc) { struct hlsl_type *common_type, *return_type; - enum hlsl_base_type base = expr_common_base_type(arg1->data_type->base_type, arg2->data_type->base_type); enum hlsl_type_class type; + enum hlsl_base_type base; unsigned int dimx, dimy; struct hlsl_ir_node *args[HLSL_MAX_OPERANDS] = {0}; if (!expr_common_shape(ctx, arg1->data_type, arg2->data_type, loc, &type, &dimx, &dimy)) return NULL; + base = expr_common_base_type(arg1->data_type->e.numeric.type, arg2->data_type->e.numeric.type); common_type = hlsl_get_numeric_type(ctx, type, base, dimx, dimy); return_type = hlsl_get_numeric_type(ctx, type, HLSL_TYPE_BOOL, dimx, dimy); @@ -1683,7 +1677,7 @@ static struct hlsl_ir_node *add_binary_shift_expr(struct hlsl_ctx *ctx, struct h enum hlsl_ir_expr_op op, struct hlsl_ir_node *arg1, struct hlsl_ir_node *arg2, const struct vkd3d_shader_location *loc) { - enum hlsl_base_type base = arg1->data_type->base_type; + enum hlsl_base_type base = arg1->data_type->e.numeric.type; struct hlsl_ir_node *args[HLSL_MAX_OPERANDS] = {0}; struct hlsl_type *return_type, *integer_type; enum hlsl_type_class type; @@ -1713,7 +1707,7 @@ static struct hlsl_ir_node *add_binary_shift_expr(struct hlsl_ctx *ctx, struct h static struct hlsl_ir_node *add_binary_dot_expr(struct hlsl_ctx *ctx, struct hlsl_block *instrs, struct hlsl_ir_node *arg1, struct hlsl_ir_node *arg2, const struct vkd3d_shader_location *loc) { - enum hlsl_base_type base = expr_common_base_type(arg1->data_type->base_type, arg2->data_type->base_type); + enum hlsl_base_type base = expr_common_base_type(arg1->data_type->e.numeric.type, arg2->data_type->e.numeric.type); struct hlsl_ir_node *args[HLSL_MAX_OPERANDS] = {0}; struct hlsl_type *common_type, *ret_type; enum hlsl_ir_expr_op op; @@ -1964,7 +1958,7 @@ static struct hlsl_ir_node *add_assignment(struct hlsl_ctx *ctx, struct hlsl_blo "Resource store expressions must write to all components."); assert(coords->data_type->class == HLSL_CLASS_VECTOR); - assert(coords->data_type->base_type == HLSL_TYPE_UINT); + assert(coords->data_type->e.numeric.type == HLSL_TYPE_UINT); assert(coords->data_type->dimx == dim_count); if (!(store = hlsl_new_resource_store(ctx, &resource_deref, coords, rhs, &lhs->loc))) @@ -2603,7 +2597,7 @@ static struct hlsl_ir_node *intrinsic_float_convert_arg(struct hlsl_ctx *ctx, { struct hlsl_type *type = arg->data_type; - if (type->base_type == HLSL_TYPE_FLOAT || type->base_type == HLSL_TYPE_HALF) + if (type->e.numeric.type == HLSL_TYPE_FLOAT || type->e.numeric.type == HLSL_TYPE_HALF) return arg; type = hlsl_get_numeric_type(ctx, type->class, HLSL_TYPE_FLOAT, type->dimx, type->dimy); @@ -2630,7 +2624,7 @@ static bool convert_args(struct hlsl_ctx *ctx, const struct parse_initializer *p static struct hlsl_type *elementwise_intrinsic_get_common_type(struct hlsl_ctx *ctx, const struct parse_initializer *params, const struct vkd3d_shader_location *loc) { - enum hlsl_base_type base = params->args[0]->data_type->base_type; + enum hlsl_base_type base = params->args[0]->data_type->e.numeric.type; bool vectors = false, matrices = false; unsigned int dimx = 4, dimy = 4; struct hlsl_type *common_type; @@ -2640,7 +2634,7 @@ static struct hlsl_type *elementwise_intrinsic_get_common_type(struct hlsl_ctx * { struct hlsl_type *arg_type = params->args[i]->data_type; - base = expr_common_base_type(base, arg_type->base_type); + base = expr_common_base_type(base, arg_type->e.numeric.type); if (arg_type->class == HLSL_CLASS_VECTOR) { @@ -2697,7 +2691,7 @@ static bool elementwise_intrinsic_float_convert_args(struct hlsl_ctx *ctx, if (!(type = elementwise_intrinsic_get_common_type(ctx, params, loc))) return false; - base_type = type->base_type == HLSL_TYPE_HALF ? HLSL_TYPE_HALF : HLSL_TYPE_FLOAT; + base_type = type->e.numeric.type == HLSL_TYPE_HALF ? HLSL_TYPE_HALF : HLSL_TYPE_FLOAT; type = hlsl_get_numeric_type(ctx, type->class, base_type, type->dimx, type->dimy); return convert_args(ctx, params, type, loc); @@ -2921,7 +2915,7 @@ static bool intrinsic_asfloat(struct hlsl_ctx *ctx, struct hlsl_type *data_type; data_type = params->args[0]->data_type; - if (data_type->base_type == HLSL_TYPE_BOOL || data_type->base_type == HLSL_TYPE_DOUBLE) + if (data_type->e.numeric.type == HLSL_TYPE_BOOL || data_type->e.numeric.type == HLSL_TYPE_DOUBLE) { struct vkd3d_string_buffer *string; @@ -2957,7 +2951,7 @@ static bool intrinsic_asuint(struct hlsl_ctx *ctx, } data_type = params->args[0]->data_type; - if (data_type->base_type == HLSL_TYPE_BOOL || data_type->base_type == HLSL_TYPE_DOUBLE) + if (data_type->e.numeric.type == HLSL_TYPE_BOOL || data_type->e.numeric.type == HLSL_TYPE_DOUBLE) { struct vkd3d_string_buffer *string; @@ -3086,7 +3080,7 @@ static bool intrinsic_cross(struct hlsl_ctx *ctx, struct hlsl_type *cast_type; enum hlsl_base_type base; - if (arg1->data_type->base_type == HLSL_TYPE_HALF && arg2->data_type->base_type == HLSL_TYPE_HALF) + if (arg1->data_type->e.numeric.type == HLSL_TYPE_HALF && arg2->data_type->e.numeric.type == HLSL_TYPE_HALF) base = HLSL_TYPE_HALF; else base = HLSL_TYPE_FLOAT; @@ -3267,7 +3261,7 @@ static bool intrinsic_determinant(struct hlsl_ctx *ctx, return hlsl_add_load_component(ctx, params->instrs, arg, 0, loc); } - typename = type->base_type == HLSL_TYPE_HALF ? "half" : "float"; + typename = type->e.numeric.type == HLSL_TYPE_HALF ? "half" : "float"; template = templates[dim]; switch (dim) @@ -3621,7 +3615,7 @@ static bool intrinsic_mul(struct hlsl_ctx *ctx, const struct parse_initializer *params, const struct vkd3d_shader_location *loc) { struct hlsl_ir_node *arg1 = params->args[0], *arg2 = params->args[1], *cast1, *cast2; - enum hlsl_base_type base = expr_common_base_type(arg1->data_type->base_type, arg2->data_type->base_type); + enum hlsl_base_type base = expr_common_base_type(arg1->data_type->e.numeric.type, arg2->data_type->e.numeric.type); struct hlsl_type *cast_type1 = arg1->data_type, *cast_type2 = arg2->data_type, *matrix_type, *ret_type; unsigned int i, j, k, vect_count = 0; struct hlsl_deref var_deref; @@ -3824,7 +3818,7 @@ static bool intrinsic_refract(struct hlsl_ctx *ctx, if (!(res_type = elementwise_intrinsic_get_common_type(ctx, &mut_params, loc))) return false; - base = expr_common_base_type(res_type->base_type, i_type->base_type); + base = expr_common_base_type(res_type->e.numeric.type, i_type->e.numeric.type); base = base == HLSL_TYPE_HALF ? HLSL_TYPE_HALF : HLSL_TYPE_FLOAT; res_type = convert_numeric_type(ctx, res_type, base); idx_type = convert_numeric_type(ctx, i_type, base); @@ -3884,7 +3878,7 @@ static bool intrinsic_sign(struct hlsl_ctx *ctx, struct hlsl_type *int_type = hlsl_get_numeric_type(ctx, arg->data_type->class, HLSL_TYPE_INT, arg->data_type->dimx, arg->data_type->dimy); - if (!(zero = hlsl_new_constant(ctx, hlsl_get_scalar_type(ctx, arg->data_type->base_type), &zero_value, loc))) + if (!(zero = hlsl_new_constant(ctx, hlsl_get_scalar_type(ctx, arg->data_type->e.numeric.type), &zero_value, loc))) return false; hlsl_block_add_instr(params->instrs, zero); @@ -4257,7 +4251,7 @@ static bool intrinsic_transpose(struct hlsl_ctx *ctx, return true; } - mat_type = hlsl_get_matrix_type(ctx, arg_type->base_type, arg_type->dimy, arg_type->dimx); + mat_type = hlsl_get_matrix_type(ctx, arg_type->e.numeric.type, arg_type->dimy, arg_type->dimx); if (!(var = hlsl_new_synthetic_var(ctx, "transpose", mat_type, loc))) return false; @@ -4553,7 +4547,7 @@ static bool add_ternary(struct hlsl_ctx *ctx, struct hlsl_block *block, if (common_type->dimx == 1 && common_type->dimy == 1) { common_type = hlsl_get_numeric_type(ctx, cond_type->class, - common_type->base_type, cond_type->dimx, cond_type->dimy); + common_type->e.numeric.type, cond_type->dimx, cond_type->dimy); } else if (cond_type->dimx != common_type->dimx || cond_type->dimy != common_type->dimy) { @@ -4603,7 +4597,7 @@ static bool add_ternary(struct hlsl_ctx *ctx, struct hlsl_block *block, common_type = first->data_type; } - assert(cond->data_type->base_type == HLSL_TYPE_BOOL); + assert(cond->data_type->e.numeric.type == HLSL_TYPE_BOOL); args[0] = cond; args[1] = first; @@ -4926,7 +4920,7 @@ static bool add_gather_method_call(struct hlsl_ctx *ctx, struct hlsl_block *bloc hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, sampler_dim), loc))) return false; - load_params.format = hlsl_get_vector_type(ctx, object_type->e.resource.format->base_type, 4); + load_params.format = hlsl_get_vector_type(ctx, object_type->e.resource.format->e.numeric.type, 4); load_params.resource = object; load_params.sampler = params->args[0]; @@ -6585,7 +6579,7 @@ type_no_void: YYABORT; } - $$ = hlsl_type_clone(ctx, hlsl_get_vector_type(ctx, $3->base_type, $5), 0, 0); + $$ = hlsl_type_clone(ctx, hlsl_get_vector_type(ctx, $3->e.numeric.type, $5), 0, 0); $$->is_minimum_precision = $3->is_minimum_precision; } | KW_VECTOR @@ -6618,7 +6612,7 @@ type_no_void: YYABORT; } - $$ = hlsl_type_clone(ctx, hlsl_get_matrix_type(ctx, $3->base_type, $7, $5), 0, 0); + $$ = hlsl_type_clone(ctx, hlsl_get_matrix_type(ctx, $3->e.numeric.type, $7, $5), 0, 0); $$->is_minimum_precision = $3->is_minimum_precision; } | KW_MATRIX @@ -6918,6 +6912,7 @@ state_block: | state_block stateblock_lhs_identifier state_block_index_opt '=' complex_initializer ';' { struct hlsl_state_block_entry *entry; + unsigned int i; if (!(entry = hlsl_alloc(ctx, sizeof(*entry)))) YYABORT; @@ -6927,8 +6922,13 @@ state_block: entry->lhs_index = $3.index; entry->instrs = $5.instrs; - entry->args = $5.args; + entry->args_count = $5.args_count; + if (!(entry->args = hlsl_alloc(ctx, sizeof(*entry->args) * entry->args_count))) + YYABORT; + for (i = 0; i < entry->args_count; ++i) + hlsl_src_from_node(&entry->args[i], $5.args[i]); + vkd3d_free($5.args); $$ = $1; state_block_add_entry($$, entry); diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c index 94acb70fff9..8882deaf6cd 100644 --- a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c +++ b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c @@ -263,8 +263,8 @@ static bool types_are_semantic_equivalent(struct hlsl_ctx *ctx, const struct hls if (type1->dimx != type2->dimx) return false; - return base_type_get_semantic_equivalent(type1->base_type) - == base_type_get_semantic_equivalent(type2->base_type); + return base_type_get_semantic_equivalent(type1->e.numeric.type) + == base_type_get_semantic_equivalent(type2->e.numeric.type); } static struct hlsl_ir_var *add_semantic_var(struct hlsl_ctx *ctx, struct hlsl_ir_var *var, @@ -355,10 +355,10 @@ static void prepend_input_copy(struct hlsl_ctx *ctx, struct hlsl_block *block, s if (!semantic->name) return; - vector_type_dst = hlsl_get_vector_type(ctx, type->base_type, hlsl_type_minor_size(type)); + vector_type_dst = hlsl_get_vector_type(ctx, type->e.numeric.type, hlsl_type_minor_size(type)); vector_type_src = vector_type_dst; if (ctx->profile->major_version < 4 && ctx->profile->type == VKD3D_SHADER_TYPE_VERTEX) - vector_type_src = hlsl_get_vector_type(ctx, type->base_type, 4); + vector_type_src = hlsl_get_vector_type(ctx, type->e.numeric.type, 4); for (i = 0; i < hlsl_type_major_size(type); ++i) { @@ -500,7 +500,7 @@ static void append_output_copy(struct hlsl_ctx *ctx, struct hlsl_block *block, s if (!semantic->name) return; - vector_type = hlsl_get_vector_type(ctx, type->base_type, hlsl_type_minor_size(type)); + vector_type = hlsl_get_vector_type(ctx, type->e.numeric.type, hlsl_type_minor_size(type)); for (i = 0; i < hlsl_type_major_size(type); ++i) { @@ -1101,7 +1101,7 @@ static bool lower_index_loads(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_ir_node *resource_load; assert(coords->data_type->class == HLSL_CLASS_VECTOR); - assert(coords->data_type->base_type == HLSL_TYPE_UINT); + assert(coords->data_type->e.numeric.type == HLSL_TYPE_UINT); assert(coords->data_type->dimx == dim_count); if (!(coords = add_zero_mipmap_level(ctx, coords, &instr->loc))) @@ -1191,7 +1191,7 @@ static bool lower_broadcasts(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, s { struct hlsl_ir_node *new_cast, *swizzle; - dst_scalar_type = hlsl_get_scalar_type(ctx, dst_type->base_type); + dst_scalar_type = hlsl_get_scalar_type(ctx, dst_type->e.numeric.type); /* We need to preserve the cast since it might be doing more than just * turning the scalar into a vector. */ if (!(new_cast = hlsl_new_cast(ctx, cast->operands[0].node, dst_scalar_type, &cast->node.loc))) @@ -1625,10 +1625,11 @@ static bool copy_propagation_transform_load(struct hlsl_ctx *ctx, { case HLSL_CLASS_SCALAR: case HLSL_CLASS_VECTOR: + case HLSL_CLASS_PIXEL_SHADER: case HLSL_CLASS_SAMPLER: case HLSL_CLASS_TEXTURE: case HLSL_CLASS_UAV: - case HLSL_CLASS_OBJECT: + case HLSL_CLASS_VERTEX_SHADER: break; case HLSL_CLASS_MATRIX: @@ -2064,7 +2065,7 @@ static bool fold_redundant_casts(struct hlsl_ctx *ctx, struct hlsl_ir_node *inst src_type = expr->operands[0].node->data_type; if (hlsl_types_are_equal(src_type, dst_type) - || (src_type->base_type == dst_type->base_type && is_vec1(src_type) && is_vec1(dst_type))) + || (src_type->e.numeric.type == dst_type->e.numeric.type && is_vec1(src_type) && is_vec1(dst_type))) { hlsl_replace_node(&expr->node, expr->operands[0].node); return true; @@ -2191,7 +2192,7 @@ static bool split_matrix_copies(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr type = rhs->data_type; if (type->class != HLSL_CLASS_MATRIX) return false; - element_type = hlsl_get_vector_type(ctx, type->base_type, hlsl_type_minor_size(type)); + element_type = hlsl_get_vector_type(ctx, type->e.numeric.type, hlsl_type_minor_size(type)); if (rhs->type != HLSL_IR_LOAD) { @@ -2228,7 +2229,7 @@ static bool lower_narrowing_casts(struct hlsl_ctx *ctx, struct hlsl_ir_node *ins { struct hlsl_ir_node *new_cast, *swizzle; - dst_vector_type = hlsl_get_vector_type(ctx, dst_type->base_type, src_type->dimx); + dst_vector_type = hlsl_get_vector_type(ctx, dst_type->e.numeric.type, src_type->dimx); /* We need to preserve the cast since it might be doing more than just * narrowing the vector. */ if (!(new_cast = hlsl_new_cast(ctx, cast->operands[0].node, dst_vector_type, &cast->node.loc))) @@ -2482,7 +2483,7 @@ static bool lower_nonconstant_vector_derefs(struct hlsl_ctx *ctx, struct hlsl_ir op = HLSL_OP2_DOT; if (type->dimx == 1) - op = type->base_type == HLSL_TYPE_BOOL ? HLSL_OP2_LOGIC_AND : HLSL_OP2_MUL; + op = type->e.numeric.type == HLSL_TYPE_BOOL ? HLSL_OP2_LOGIC_AND : HLSL_OP2_MUL; /* Note: We may be creating a DOT for bool vectors here, which we need to lower to * LOGIC_OR + LOGIC_AND. */ @@ -2676,9 +2677,9 @@ static bool lower_casts_to_int(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, return false; arg = expr->operands[0].node; - if (instr->data_type->base_type != HLSL_TYPE_INT && instr->data_type->base_type != HLSL_TYPE_UINT) + if (instr->data_type->e.numeric.type != HLSL_TYPE_INT && instr->data_type->e.numeric.type != HLSL_TYPE_UINT) return false; - if (arg->data_type->base_type != HLSL_TYPE_FLOAT && arg->data_type->base_type != HLSL_TYPE_HALF) + if (arg->data_type->e.numeric.type != HLSL_TYPE_FLOAT && arg->data_type->e.numeric.type != HLSL_TYPE_HALF) return false; if (!(floor = hlsl_new_unary_expr(ctx, HLSL_OP1_FLOOR, arg, &instr->loc))) @@ -2935,7 +2936,7 @@ static bool lower_logic_not(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, st float_type = hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, arg->data_type->dimx); /* If this is happens, it means we failed to cast the argument to boolean somewhere. */ - assert(arg->data_type->base_type == HLSL_TYPE_BOOL); + assert(arg->data_type->e.numeric.type == HLSL_TYPE_BOOL); if (!(arg_cast = hlsl_new_cast(ctx, arg, float_type, &arg->loc))) return false; @@ -2991,7 +2992,7 @@ static bool lower_ternary(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, stru return false; } - assert(cond->data_type->base_type == HLSL_TYPE_BOOL); + assert(cond->data_type->e.numeric.type == HLSL_TYPE_BOOL); type = hlsl_get_numeric_type(ctx, instr->data_type->class, HLSL_TYPE_FLOAT, instr->data_type->dimx, instr->data_type->dimy); @@ -3285,7 +3286,7 @@ static bool lower_casts_to_bool(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr arg_type = expr->operands[0].node->data_type; if (type->class > HLSL_CLASS_VECTOR || arg_type->class > HLSL_CLASS_VECTOR) return false; - if (type->base_type != HLSL_TYPE_BOOL) + if (type->e.numeric.type != HLSL_TYPE_BOOL) return false; /* Narrowing casts should have already been lowered. */ @@ -3313,7 +3314,7 @@ struct hlsl_ir_node *hlsl_add_conditional(struct hlsl_ctx *ctx, struct hlsl_bloc assert(hlsl_types_are_equal(if_true->data_type, if_false->data_type)); - if (cond_type->base_type != HLSL_TYPE_BOOL) + if (cond_type->e.numeric.type != HLSL_TYPE_BOOL) { cond_type = hlsl_get_numeric_type(ctx, cond_type->class, HLSL_TYPE_BOOL, cond_type->dimx, cond_type->dimy); @@ -3349,7 +3350,7 @@ static bool lower_int_division(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, return false; if (type->class != HLSL_CLASS_SCALAR && type->class != HLSL_CLASS_VECTOR) return false; - if (type->base_type != HLSL_TYPE_INT) + if (type->e.numeric.type != HLSL_TYPE_INT) return false; utype = hlsl_get_numeric_type(ctx, type->class, HLSL_TYPE_UINT, type->dimx, type->dimy); @@ -3415,7 +3416,7 @@ static bool lower_int_modulus(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, return false; if (type->class != HLSL_CLASS_SCALAR && type->class != HLSL_CLASS_VECTOR) return false; - if (type->base_type != HLSL_TYPE_INT) + if (type->e.numeric.type != HLSL_TYPE_INT) return false; utype = hlsl_get_numeric_type(ctx, type->class, HLSL_TYPE_UINT, type->dimx, type->dimy); @@ -3474,7 +3475,7 @@ static bool lower_int_abs(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, stru return false; if (type->class != HLSL_CLASS_SCALAR && type->class != HLSL_CLASS_VECTOR) return false; - if (type->base_type != HLSL_TYPE_INT) + if (type->e.numeric.type != HLSL_TYPE_INT) return false; arg = expr->operands[0].node; @@ -3505,14 +3506,14 @@ static bool lower_int_dot(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, stru if (expr->op != HLSL_OP2_DOT) return false; - if (type->base_type == HLSL_TYPE_INT || type->base_type == HLSL_TYPE_UINT - || type->base_type == HLSL_TYPE_BOOL) + if (type->e.numeric.type == HLSL_TYPE_INT || type->e.numeric.type == HLSL_TYPE_UINT + || type->e.numeric.type == HLSL_TYPE_BOOL) { arg1 = expr->operands[0].node; arg2 = expr->operands[1].node; assert(arg1->data_type->dimx == arg2->data_type->dimx); dimx = arg1->data_type->dimx; - is_bool = type->base_type == HLSL_TYPE_BOOL; + is_bool = type->e.numeric.type == HLSL_TYPE_BOOL; if (!(mult = hlsl_new_binary_expr(ctx, is_bool ? HLSL_OP2_LOGIC_AND : HLSL_OP2_MUL, arg1, arg2))) return false; @@ -3558,7 +3559,7 @@ static bool lower_float_modulus(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr return false; if (type->class != HLSL_CLASS_SCALAR && type->class != HLSL_CLASS_VECTOR) return false; - if (type->base_type != HLSL_TYPE_FLOAT) + if (type->e.numeric.type != HLSL_TYPE_FLOAT) return false; btype = hlsl_get_numeric_type(ctx, type->class, HLSL_TYPE_BOOL, type->dimx, type->dimy); @@ -3614,7 +3615,7 @@ static bool lower_nonfloat_exprs(struct hlsl_ctx *ctx, struct hlsl_ir_node *inst if (instr->type != HLSL_IR_EXPR) return false; expr = hlsl_ir_expr(instr); - if (expr->op == HLSL_OP1_CAST || instr->data_type->base_type == HLSL_TYPE_FLOAT) + if (expr->op == HLSL_OP1_CAST || instr->data_type->e.numeric.type == HLSL_TYPE_FLOAT) return false; switch (expr->op) @@ -4453,7 +4454,7 @@ static void allocate_const_registers_recurse(struct hlsl_ctx *ctx, continue; value = &constant->value.u[i++]; - switch (type->base_type) + switch (type->e.numeric.type) { case HLSL_TYPE_BOOL: f = !!value->u; @@ -5046,7 +5047,7 @@ bool hlsl_component_index_range_from_deref(struct hlsl_ctx *ctx, const struct hl /* We should always have generated a cast to UINT. */ assert(path_node->data_type->class == HLSL_CLASS_SCALAR - && path_node->data_type->base_type == HLSL_TYPE_UINT); + && path_node->data_type->e.numeric.type == HLSL_TYPE_UINT); idx = hlsl_ir_constant(path_node)->value.u[0].u; @@ -5122,7 +5123,7 @@ bool hlsl_regset_index_from_deref(struct hlsl_ctx *ctx, const struct hlsl_deref /* We should always have generated a cast to UINT. */ assert(path_node->data_type->class == HLSL_CLASS_SCALAR - && path_node->data_type->base_type == HLSL_TYPE_UINT); + && path_node->data_type->e.numeric.type == HLSL_TYPE_UINT); idx = hlsl_ir_constant(path_node)->value.u[0].u; @@ -5162,7 +5163,7 @@ bool hlsl_offset_from_deref(struct hlsl_ctx *ctx, const struct hlsl_deref *deref { /* We should always have generated a cast to UINT. */ assert(offset_node->data_type->class == HLSL_CLASS_SCALAR - && offset_node->data_type->base_type == HLSL_TYPE_UINT); + && offset_node->data_type->e.numeric.type == HLSL_TYPE_UINT); assert(offset_node->type != HLSL_IR_CONSTANT); return false; } @@ -5229,7 +5230,7 @@ static void parse_numthreads_attribute(struct hlsl_ctx *ctx, const struct hlsl_a const struct hlsl_ir_constant *constant; if (type->class != HLSL_CLASS_SCALAR - || (type->base_type != HLSL_TYPE_INT && type->base_type != HLSL_TYPE_UINT)) + || (type->e.numeric.type != HLSL_TYPE_INT && type->e.numeric.type != HLSL_TYPE_UINT)) { struct vkd3d_string_buffer *string; @@ -5248,8 +5249,8 @@ static void parse_numthreads_attribute(struct hlsl_ctx *ctx, const struct hlsl_a } constant = hlsl_ir_constant(instr); - if ((type->base_type == HLSL_TYPE_INT && constant->value.u[0].i <= 0) - || (type->base_type == HLSL_TYPE_UINT && !constant->value.u[0].u)) + if ((type->e.numeric.type == HLSL_TYPE_INT && constant->value.u[0].i <= 0) + || (type->e.numeric.type == HLSL_TYPE_UINT && !constant->value.u[0].u)) hlsl_error(ctx, &instr->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_THREAD_COUNT, "Thread count must be a positive integer."); @@ -5313,17 +5314,6 @@ static void remove_unreachable_code(struct hlsl_ctx *ctx, struct hlsl_block *bod } } -void hlsl_prepend_global_uniform_copy(struct hlsl_ctx *ctx, struct hlsl_block *body) -{ - struct hlsl_ir_var *var; - - LIST_FOR_EACH_ENTRY(var, &ctx->globals->vars, struct hlsl_ir_var, scope_entry) - { - if (var->storage_modifiers & HLSL_STORAGE_UNIFORM) - prepend_uniform_copy(ctx, body, var); - } -} - int hlsl_emit_bytecode(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_func, enum vkd3d_shader_target_type target_type, struct vkd3d_shader_code *out) { @@ -5352,7 +5342,11 @@ int hlsl_emit_bytecode(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry lower_ir(ctx, lower_matrix_swizzles, body); lower_ir(ctx, lower_index_loads, body); - hlsl_prepend_global_uniform_copy(ctx, body); + LIST_FOR_EACH_ENTRY(var, &ctx->globals->vars, struct hlsl_ir_var, scope_entry) + { + if (var->storage_modifiers & HLSL_STORAGE_UNIFORM) + prepend_uniform_copy(ctx, body, var); + } for (i = 0; i < entry_func->parameters.count; ++i) { diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl_constant_ops.c b/libs/vkd3d/libs/vkd3d-shader/hlsl_constant_ops.c index 51f2f9cc050..16015fa8a81 100644 --- a/libs/vkd3d/libs/vkd3d-shader/hlsl_constant_ops.c +++ b/libs/vkd3d/libs/vkd3d-shader/hlsl_constant_ops.c @@ -25,10 +25,10 @@ static bool fold_abs(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, const struct hlsl_type *dst_type, const struct hlsl_ir_constant *src) { - enum hlsl_base_type type = dst_type->base_type; + enum hlsl_base_type type = dst_type->e.numeric.type; unsigned int k; - assert(type == src->node.data_type->base_type); + assert(type == src->node.data_type->e.numeric.type); for (k = 0; k < dst_type->dimx; ++k) { @@ -116,10 +116,10 @@ static int32_t double_to_int(double x) static bool fold_bit_not(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, const struct hlsl_type *dst_type, const struct hlsl_ir_constant *src) { - enum hlsl_base_type type = dst_type->base_type; + enum hlsl_base_type type = dst_type->e.numeric.type; unsigned int k; - assert(type == src->node.data_type->base_type); + assert(type == src->node.data_type->e.numeric.type); for (k = 0; k < dst_type->dimx; ++k) { @@ -158,7 +158,7 @@ static bool fold_cast(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, for (k = 0; k < dst_type->dimx; ++k) { - switch (src->node.data_type->base_type) + switch (src->node.data_type->e.numeric.type) { case HLSL_TYPE_FLOAT: case HLSL_TYPE_HALF: @@ -200,7 +200,7 @@ static bool fold_cast(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, vkd3d_unreachable(); } - switch (dst_type->base_type) + switch (dst_type->e.numeric.type) { case HLSL_TYPE_FLOAT: case HLSL_TYPE_HALF: @@ -231,10 +231,10 @@ static bool fold_cast(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, static bool fold_ceil(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, const struct hlsl_type *dst_type, const struct hlsl_ir_constant *src) { - enum hlsl_base_type type = dst_type->base_type; + enum hlsl_base_type type = dst_type->e.numeric.type; unsigned int k; - assert(type == src->node.data_type->base_type); + assert(type == src->node.data_type->e.numeric.type); for (k = 0; k < dst_type->dimx; ++k) { @@ -257,10 +257,10 @@ static bool fold_ceil(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, static bool fold_exp2(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, const struct hlsl_type *dst_type, const struct hlsl_ir_constant *src) { - enum hlsl_base_type type = dst_type->base_type; + enum hlsl_base_type type = dst_type->e.numeric.type; unsigned int k; - assert(type == src->node.data_type->base_type); + assert(type == src->node.data_type->e.numeric.type); for (k = 0; k < dst_type->dimx; ++k) { @@ -283,10 +283,10 @@ static bool fold_exp2(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, static bool fold_floor(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, const struct hlsl_type *dst_type, const struct hlsl_ir_constant *src) { - enum hlsl_base_type type = dst_type->base_type; + enum hlsl_base_type type = dst_type->e.numeric.type; unsigned int k; - assert(type == src->node.data_type->base_type); + assert(type == src->node.data_type->e.numeric.type); for (k = 0; k < dst_type->dimx; ++k) { @@ -309,11 +309,11 @@ static bool fold_floor(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, static bool fold_fract(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, const struct hlsl_type *dst_type, const struct hlsl_ir_constant *src) { - enum hlsl_base_type type = dst_type->base_type; + enum hlsl_base_type type = dst_type->e.numeric.type; unsigned int k; float i; - assert(type == src->node.data_type->base_type); + assert(type == src->node.data_type->e.numeric.type); for (k = 0; k < dst_type->dimx; ++k) { @@ -336,10 +336,10 @@ static bool fold_fract(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, static bool fold_log2(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, const struct hlsl_type *dst_type, const struct hlsl_ir_constant *src, const struct vkd3d_shader_location *loc) { - enum hlsl_base_type type = dst_type->base_type; + enum hlsl_base_type type = dst_type->e.numeric.type; unsigned int k; - assert(type == src->node.data_type->base_type); + assert(type == src->node.data_type->e.numeric.type); for (k = 0; k < dst_type->dimx; ++k) { @@ -381,10 +381,10 @@ static bool fold_log2(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, con static bool fold_neg(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, const struct hlsl_type *dst_type, const struct hlsl_ir_constant *src) { - enum hlsl_base_type type = dst_type->base_type; + enum hlsl_base_type type = dst_type->e.numeric.type; unsigned int k; - assert(type == src->node.data_type->base_type); + assert(type == src->node.data_type->e.numeric.type); for (k = 0; k < dst_type->dimx; ++k) { @@ -415,10 +415,10 @@ static bool fold_neg(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, static bool fold_not(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, const struct hlsl_type *dst_type, const struct hlsl_ir_constant *src) { - enum hlsl_base_type type = dst_type->base_type; + enum hlsl_base_type type = dst_type->e.numeric.type; unsigned int k; - assert(type == src->node.data_type->base_type); + assert(type == src->node.data_type->e.numeric.type); for (k = 0; k < dst_type->dimx; ++k) { @@ -439,10 +439,10 @@ static bool fold_not(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, static bool fold_rcp(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, const struct hlsl_type *dst_type, const struct hlsl_ir_constant *src, const struct vkd3d_shader_location *loc) { - enum hlsl_base_type type = dst_type->base_type; + enum hlsl_base_type type = dst_type->e.numeric.type; unsigned int k; - assert(type == src->node.data_type->base_type); + assert(type == src->node.data_type->e.numeric.type); for (k = 0; k < dst_type->dimx; ++k) { @@ -484,10 +484,10 @@ static bool fold_rcp(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, cons static bool fold_rsq(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, const struct hlsl_type *dst_type, const struct hlsl_ir_constant *src, const struct vkd3d_shader_location *loc) { - enum hlsl_base_type type = dst_type->base_type; + enum hlsl_base_type type = dst_type->e.numeric.type; unsigned int k; - assert(type == src->node.data_type->base_type); + assert(type == src->node.data_type->e.numeric.type); for (k = 0; k < dst_type->dimx; ++k) { @@ -524,10 +524,10 @@ static bool fold_rsq(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, cons static bool fold_sat(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, const struct hlsl_type *dst_type, const struct hlsl_ir_constant *src) { - enum hlsl_base_type type = dst_type->base_type; + enum hlsl_base_type type = dst_type->e.numeric.type; unsigned int k; - assert(type == src->node.data_type->base_type); + assert(type == src->node.data_type->e.numeric.type); for (k = 0; k < dst_type->dimx; ++k) { @@ -550,10 +550,10 @@ static bool fold_sat(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, cons static bool fold_sqrt(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, const struct hlsl_type *dst_type, const struct hlsl_ir_constant *src, const struct vkd3d_shader_location *loc) { - enum hlsl_base_type type = dst_type->base_type; + enum hlsl_base_type type = dst_type->e.numeric.type; unsigned int k; - assert(type == src->node.data_type->base_type); + assert(type == src->node.data_type->e.numeric.type); for (k = 0; k < dst_type->dimx; ++k) { @@ -595,11 +595,11 @@ static bool fold_sqrt(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, con static bool fold_add(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, const struct hlsl_type *dst_type, const struct hlsl_ir_constant *src1, const struct hlsl_ir_constant *src2) { - enum hlsl_base_type type = dst_type->base_type; + enum hlsl_base_type type = dst_type->e.numeric.type; unsigned int k; - assert(type == src1->node.data_type->base_type); - assert(type == src2->node.data_type->base_type); + assert(type == src1->node.data_type->e.numeric.type); + assert(type == src2->node.data_type->e.numeric.type); for (k = 0; k < dst_type->dimx; ++k) { @@ -632,11 +632,11 @@ static bool fold_add(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, cons static bool fold_and(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, const struct hlsl_type *dst_type, const struct hlsl_ir_constant *src1, const struct hlsl_ir_constant *src2) { - enum hlsl_base_type type = dst_type->base_type; + enum hlsl_base_type type = dst_type->e.numeric.type; unsigned int k; - assert(type == src1->node.data_type->base_type); - assert(type == src2->node.data_type->base_type); + assert(type == src1->node.data_type->e.numeric.type); + assert(type == src2->node.data_type->e.numeric.type); for (k = 0; k < dst_type->dimx; ++k) { @@ -659,11 +659,11 @@ static bool fold_and(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, cons static bool fold_or(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, const struct hlsl_type *dst_type, const struct hlsl_ir_constant *src1, const struct hlsl_ir_constant *src2) { - enum hlsl_base_type type = dst_type->base_type; + enum hlsl_base_type type = dst_type->e.numeric.type; unsigned int k; - assert(type == src1->node.data_type->base_type); - assert(type == src2->node.data_type->base_type); + assert(type == src1->node.data_type->e.numeric.type); + assert(type == src2->node.data_type->e.numeric.type); for (k = 0; k < dst_type->dimx; ++k) { @@ -686,11 +686,11 @@ static bool fold_or(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, const static bool fold_bit_xor(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, const struct hlsl_type *dst_type, const struct hlsl_ir_constant *src1, const struct hlsl_ir_constant *src2) { - enum hlsl_base_type type = dst_type->base_type; + enum hlsl_base_type type = dst_type->e.numeric.type; unsigned int k; - assert(type == src1->node.data_type->base_type); - assert(type == src2->node.data_type->base_type); + assert(type == src1->node.data_type->e.numeric.type); + assert(type == src2->node.data_type->e.numeric.type); for (k = 0; k < dst_type->dimx; ++k) { @@ -712,11 +712,11 @@ static bool fold_bit_xor(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, static bool fold_dot(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, const struct hlsl_type *dst_type, const struct hlsl_ir_constant *src1, const struct hlsl_ir_constant *src2) { - enum hlsl_base_type type = dst_type->base_type; + enum hlsl_base_type type = dst_type->e.numeric.type; unsigned int k; - assert(type == src1->node.data_type->base_type); - assert(type == src2->node.data_type->base_type); + assert(type == src1->node.data_type->e.numeric.type); + assert(type == src2->node.data_type->e.numeric.type); assert(src1->node.data_type->dimx == src2->node.data_type->dimx); dst->u[0].f = 0.0f; @@ -740,12 +740,12 @@ static bool fold_dot(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, cons static bool fold_dp2add(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, const struct hlsl_type *dst_type, const struct hlsl_ir_constant *src1, const struct hlsl_ir_constant *src2, const struct hlsl_ir_constant *src3) { - enum hlsl_base_type type = dst_type->base_type; + enum hlsl_base_type type = dst_type->e.numeric.type; unsigned int k; - assert(type == src1->node.data_type->base_type); - assert(type == src2->node.data_type->base_type); - assert(type == src3->node.data_type->base_type); + assert(type == src1->node.data_type->e.numeric.type); + assert(type == src2->node.data_type->e.numeric.type); + assert(type == src3->node.data_type->e.numeric.type); assert(src1->node.data_type->dimx == src2->node.data_type->dimx); assert(src3->node.data_type->dimx == 1); @@ -771,11 +771,11 @@ static bool fold_div(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, cons const struct hlsl_ir_constant *src1, const struct hlsl_ir_constant *src2, const struct vkd3d_shader_location *loc) { - enum hlsl_base_type type = dst_type->base_type; + enum hlsl_base_type type = dst_type->e.numeric.type; unsigned int k; - assert(type == src1->node.data_type->base_type); - assert(type == src2->node.data_type->base_type); + assert(type == src1->node.data_type->e.numeric.type); + assert(type == src2->node.data_type->e.numeric.type); for (k = 0; k < dst_type->dimx; ++k) { @@ -841,12 +841,12 @@ static bool fold_equal(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, co { unsigned int k; - assert(dst_type->base_type == HLSL_TYPE_BOOL); - assert(src1->node.data_type->base_type == src2->node.data_type->base_type); + assert(dst_type->e.numeric.type == HLSL_TYPE_BOOL); + assert(src1->node.data_type->e.numeric.type == src2->node.data_type->e.numeric.type); for (k = 0; k < dst_type->dimx; ++k) { - switch (src1->node.data_type->base_type) + switch (src1->node.data_type->e.numeric.type) { case HLSL_TYPE_FLOAT: case HLSL_TYPE_HALF: @@ -877,12 +877,12 @@ static bool fold_gequal(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, c { unsigned int k; - assert(dst_type->base_type == HLSL_TYPE_BOOL); - assert(src1->node.data_type->base_type == src2->node.data_type->base_type); + assert(dst_type->e.numeric.type == HLSL_TYPE_BOOL); + assert(src1->node.data_type->e.numeric.type == src2->node.data_type->e.numeric.type); for (k = 0; k < dst_type->dimx; ++k) { - switch (src1->node.data_type->base_type) + switch (src1->node.data_type->e.numeric.type) { case HLSL_TYPE_FLOAT: case HLSL_TYPE_HALF: @@ -916,12 +916,12 @@ static bool fold_less(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, con { unsigned int k; - assert(dst_type->base_type == HLSL_TYPE_BOOL); - assert(src1->node.data_type->base_type == src2->node.data_type->base_type); + assert(dst_type->e.numeric.type == HLSL_TYPE_BOOL); + assert(src1->node.data_type->e.numeric.type == src2->node.data_type->e.numeric.type); for (k = 0; k < dst_type->dimx; ++k) { - switch (src1->node.data_type->base_type) + switch (src1->node.data_type->e.numeric.type) { case HLSL_TYPE_FLOAT: case HLSL_TYPE_HALF: @@ -955,14 +955,14 @@ static bool fold_lshift(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, c { unsigned int k; - assert(dst_type->base_type == src1->node.data_type->base_type); - assert(src2->node.data_type->base_type == HLSL_TYPE_INT); + assert(dst_type->e.numeric.type == src1->node.data_type->e.numeric.type); + assert(src2->node.data_type->e.numeric.type == HLSL_TYPE_INT); for (k = 0; k < dst_type->dimx; ++k) { unsigned int shift = src2->value.u[k].u % 32; - switch (src1->node.data_type->base_type) + switch (src1->node.data_type->e.numeric.type) { case HLSL_TYPE_INT: dst->u[k].i = src1->value.u[k].i << shift; @@ -983,11 +983,11 @@ static bool fold_lshift(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, c static bool fold_max(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, const struct hlsl_type *dst_type, const struct hlsl_ir_constant *src1, const struct hlsl_ir_constant *src2) { - enum hlsl_base_type type = dst_type->base_type; + enum hlsl_base_type type = dst_type->e.numeric.type; unsigned int k; - assert(type == src1->node.data_type->base_type); - assert(type == src2->node.data_type->base_type); + assert(type == src1->node.data_type->e.numeric.type); + assert(type == src2->node.data_type->e.numeric.type); for (k = 0; k < dst_type->dimx; ++k) { @@ -1021,11 +1021,11 @@ static bool fold_max(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, cons static bool fold_min(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, const struct hlsl_type *dst_type, const struct hlsl_ir_constant *src1, const struct hlsl_ir_constant *src2) { - enum hlsl_base_type type = dst_type->base_type; + enum hlsl_base_type type = dst_type->e.numeric.type; unsigned int k; - assert(type == src1->node.data_type->base_type); - assert(type == src2->node.data_type->base_type); + assert(type == src1->node.data_type->e.numeric.type); + assert(type == src2->node.data_type->e.numeric.type); for (k = 0; k < dst_type->dimx; ++k) { @@ -1060,11 +1060,11 @@ static bool fold_mod(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, cons const struct hlsl_ir_constant *src1, const struct hlsl_ir_constant *src2, const struct vkd3d_shader_location *loc) { - enum hlsl_base_type type = dst_type->base_type; + enum hlsl_base_type type = dst_type->e.numeric.type; unsigned int k; - assert(type == src1->node.data_type->base_type); - assert(type == src2->node.data_type->base_type); + assert(type == src1->node.data_type->e.numeric.type); + assert(type == src2->node.data_type->e.numeric.type); for (k = 0; k < dst_type->dimx; ++k) { @@ -1102,11 +1102,11 @@ static bool fold_mod(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, cons static bool fold_mul(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, const struct hlsl_type *dst_type, const struct hlsl_ir_constant *src1, const struct hlsl_ir_constant *src2) { - enum hlsl_base_type type = dst_type->base_type; + enum hlsl_base_type type = dst_type->e.numeric.type; unsigned int k; - assert(type == src1->node.data_type->base_type); - assert(type == src2->node.data_type->base_type); + assert(type == src1->node.data_type->e.numeric.type); + assert(type == src2->node.data_type->e.numeric.type); for (k = 0; k < dst_type->dimx; ++k) { @@ -1139,12 +1139,12 @@ static bool fold_nequal(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, c { unsigned int k; - assert(dst_type->base_type == HLSL_TYPE_BOOL); - assert(src1->node.data_type->base_type == src2->node.data_type->base_type); + assert(dst_type->e.numeric.type == HLSL_TYPE_BOOL); + assert(src1->node.data_type->e.numeric.type == src2->node.data_type->e.numeric.type); for (k = 0; k < dst_type->dimx; ++k) { - switch (src1->node.data_type->base_type) + switch (src1->node.data_type->e.numeric.type) { case HLSL_TYPE_FLOAT: case HLSL_TYPE_HALF: @@ -1175,9 +1175,9 @@ static bool fold_ternary(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, { unsigned int k; - assert(dst_type->base_type == src2->node.data_type->base_type); - assert(dst_type->base_type == src3->node.data_type->base_type); - assert(src1->node.data_type->base_type == HLSL_TYPE_BOOL); + assert(dst_type->e.numeric.type == src2->node.data_type->e.numeric.type); + assert(dst_type->e.numeric.type == src3->node.data_type->e.numeric.type); + assert(src1->node.data_type->e.numeric.type == HLSL_TYPE_BOOL); for (k = 0; k < dst_type->dimx; ++k) dst->u[k] = src1->value.u[k].u ? src2->value.u[k] : src3->value.u[k]; @@ -1190,14 +1190,14 @@ static bool fold_rshift(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, c { unsigned int k; - assert(dst_type->base_type == src1->node.data_type->base_type); - assert(src2->node.data_type->base_type == HLSL_TYPE_INT); + assert(dst_type->e.numeric.type == src1->node.data_type->e.numeric.type); + assert(src2->node.data_type->e.numeric.type == HLSL_TYPE_INT); for (k = 0; k < dst_type->dimx; ++k) { unsigned int shift = src2->value.u[k].u % 32; - switch (src1->node.data_type->base_type) + switch (src1->node.data_type->e.numeric.type) { case HLSL_TYPE_INT: dst->u[k].i = src1->value.u[k].i >> shift; @@ -1403,7 +1403,7 @@ static bool constant_is_zero(struct hlsl_ir_constant *const_arg) for (k = 0; k < data_type->dimx; ++k) { - switch (data_type->base_type) + switch (data_type->e.numeric.type) { case HLSL_TYPE_FLOAT: case HLSL_TYPE_HALF: @@ -1437,7 +1437,7 @@ static bool constant_is_one(struct hlsl_ir_constant *const_arg) for (k = 0; k < data_type->dimx; ++k) { - switch (data_type->base_type) + switch (data_type->e.numeric.type) { case HLSL_TYPE_FLOAT: case HLSL_TYPE_HALF: diff --git a/libs/vkd3d/libs/vkd3d-shader/ir.c b/libs/vkd3d/libs/vkd3d-shader/ir.c index 121b0fe3a6c..c6ecbdd9e46 100644 --- a/libs/vkd3d/libs/vkd3d-shader/ir.c +++ b/libs/vkd3d/libs/vkd3d-shader/ir.c @@ -5753,6 +5753,32 @@ static void vsir_validate_instruction(struct validation_context *ctx) case VKD3DSIH_DCL_OUTPUT: return; + case VKD3DSIH_DCL_INPUT_PRIMITIVE: + if (instruction->declaration.primitive_type.type == VKD3D_PT_UNDEFINED + || instruction->declaration.primitive_type.type >= VKD3D_PT_COUNT) + validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_GS, "GS input primitive %u is invalid.", + instruction->declaration.primitive_type.type); + return; + + case VKD3DSIH_DCL_VERTICES_OUT: + if (instruction->declaration.count > 1024) + validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_GS, "GS output vertex count %u is invalid.", + instruction->declaration.count); + return; + + case VKD3DSIH_DCL_OUTPUT_TOPOLOGY: + if (instruction->declaration.primitive_type.type == VKD3D_PT_UNDEFINED + || instruction->declaration.primitive_type.type >= VKD3D_PT_COUNT) + validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_GS, "GS output primitive %u is invalid.", + instruction->declaration.primitive_type.type); + return; + + case VKD3DSIH_DCL_GS_INSTANCES: + if (!instruction->declaration.count || instruction->declaration.count > 32) + validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_GS, "GS instance count %u is invalid.", + instruction->declaration.count); + return; + case VKD3DSIH_DCL_OUTPUT_CONTROL_POINT_COUNT: if (!instruction->declaration.count || instruction->declaration.count > 32) validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_TESSELLATION, "Output control point count %u is invalid.", diff --git a/libs/vkd3d/libs/vkd3d-shader/spirv.c b/libs/vkd3d/libs/vkd3d-shader/spirv.c index dc9e8c06a5e..813e20fdcd7 100644 --- a/libs/vkd3d/libs/vkd3d-shader/spirv.c +++ b/libs/vkd3d/libs/vkd3d-shader/spirv.c @@ -1752,6 +1752,14 @@ static uint32_t vkd3d_spirv_get_op_scope_subgroup(struct vkd3d_spirv_builder *bu return vkd3d_spirv_build_once(builder, &builder->scope_subgroup_id, vkd3d_spirv_build_op_scope_subgroup); } +static uint32_t vkd3d_spirv_build_op_group_nonuniform_ballot(struct vkd3d_spirv_builder *builder, + uint32_t result_type, uint32_t val_id) +{ + vkd3d_spirv_enable_capability(builder, SpvCapabilityGroupNonUniformBallot); + return vkd3d_spirv_build_op_tr2(builder, &builder->function_stream, SpvOpGroupNonUniformBallot, + 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) { @@ -9793,6 +9801,76 @@ static void spirv_compiler_emit_wave_bool_op(struct spirv_compiler *compiler, spirv_compiler_emit_store_dst(compiler, dst, val_id); } +static void spirv_compiler_emit_wave_active_ballot(struct spirv_compiler *compiler, + const struct vkd3d_shader_instruction *instruction) +{ + 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; + uint32_t type_id, val_id; + + type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, VKD3D_VEC4_SIZE); + val_id = spirv_compiler_emit_load_src(compiler, src, VKD3DSP_WRITEMASK_0); + val_id = vkd3d_spirv_build_op_group_nonuniform_ballot(builder, type_id, val_id); + + spirv_compiler_emit_store_dst(compiler, dst, val_id); +} + +static SpvOp map_wave_alu_op(enum vkd3d_shader_opcode handler_idx, bool is_float) +{ + switch (handler_idx) + { + case VKD3DSIH_WAVE_ACTIVE_BIT_AND: + return SpvOpGroupNonUniformBitwiseAnd; + case VKD3DSIH_WAVE_ACTIVE_BIT_OR: + return SpvOpGroupNonUniformBitwiseOr; + case VKD3DSIH_WAVE_ACTIVE_BIT_XOR: + return SpvOpGroupNonUniformBitwiseXor; + case VKD3DSIH_WAVE_OP_ADD: + return is_float ? SpvOpGroupNonUniformFAdd : SpvOpGroupNonUniformIAdd; + case VKD3DSIH_WAVE_OP_IMAX: + return SpvOpGroupNonUniformSMax; + case VKD3DSIH_WAVE_OP_IMIN: + return SpvOpGroupNonUniformSMin; + case VKD3DSIH_WAVE_OP_MAX: + return SpvOpGroupNonUniformFMax; + case VKD3DSIH_WAVE_OP_MIN: + return SpvOpGroupNonUniformFMin; + case VKD3DSIH_WAVE_OP_MUL: + return is_float ? SpvOpGroupNonUniformFMul : SpvOpGroupNonUniformIMul; + case VKD3DSIH_WAVE_OP_UMAX: + return SpvOpGroupNonUniformUMax; + case VKD3DSIH_WAVE_OP_UMIN: + return SpvOpGroupNonUniformUMin; + default: + vkd3d_unreachable(); + } +} + +static void spirv_compiler_emit_wave_alu_op(struct spirv_compiler *compiler, + const struct vkd3d_shader_instruction *instruction) +{ + 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; + uint32_t type_id, val_id; + SpvOp op; + + op = map_wave_alu_op(instruction->handler_idx, data_type_is_floating_point(src->reg.data_type)); + + type_id = vkd3d_spirv_get_type_id_for_data_type(builder, dst->reg.data_type, + vsir_write_mask_component_count(dst->write_mask)); + val_id = spirv_compiler_emit_load_src(compiler, &src[0], dst->write_mask); + + vkd3d_spirv_enable_capability(builder, SpvCapabilityGroupNonUniformArithmetic); + val_id = vkd3d_spirv_build_op_tr3(builder, &builder->function_stream, op, type_id, + vkd3d_spirv_get_op_scope_subgroup(builder), + (instruction->flags & VKD3DSI_WAVE_PREFIX) ? SpvGroupOperationExclusiveScan : SpvGroupOperationReduce, + val_id); + + spirv_compiler_emit_store_dst(compiler, dst, val_id); +} + /* This function is called after declarations are processed. */ static void spirv_compiler_emit_main_prolog(struct spirv_compiler *compiler) { @@ -10142,6 +10220,22 @@ static int spirv_compiler_handle_instruction(struct spirv_compiler *compiler, case VKD3DSIH_WAVE_ANY_TRUE: spirv_compiler_emit_wave_bool_op(compiler, instruction); break; + case VKD3DSIH_WAVE_ACTIVE_BALLOT: + spirv_compiler_emit_wave_active_ballot(compiler, instruction); + break; + case VKD3DSIH_WAVE_ACTIVE_BIT_AND: + case VKD3DSIH_WAVE_ACTIVE_BIT_OR: + case VKD3DSIH_WAVE_ACTIVE_BIT_XOR: + case VKD3DSIH_WAVE_OP_ADD: + case VKD3DSIH_WAVE_OP_IMAX: + case VKD3DSIH_WAVE_OP_IMIN: + case VKD3DSIH_WAVE_OP_MAX: + case VKD3DSIH_WAVE_OP_MIN: + case VKD3DSIH_WAVE_OP_MUL: + case VKD3DSIH_WAVE_OP_UMAX: + case VKD3DSIH_WAVE_OP_UMIN: + spirv_compiler_emit_wave_alu_op(compiler, instruction); + break; case VKD3DSIH_DCL: case VKD3DSIH_DCL_HS_MAX_TESSFACTOR: case VKD3DSIH_DCL_INPUT_CONTROL_POINT_COUNT: diff --git a/libs/vkd3d/libs/vkd3d-shader/tpf.c b/libs/vkd3d/libs/vkd3d-shader/tpf.c index 708ab6268a7..4e3bef9640c 100644 --- a/libs/vkd3d/libs/vkd3d-shader/tpf.c +++ b/libs/vkd3d/libs/vkd3d-shader/tpf.c @@ -2744,7 +2744,7 @@ static void write_sm4_block(const struct tpf_writer *tpf, const struct hlsl_bloc static bool type_is_integer(const struct hlsl_type *type) { - switch (type->base_type) + switch (type->e.numeric.type) { case HLSL_TYPE_BOOL: case HLSL_TYPE_INT: @@ -2933,7 +2933,7 @@ static void write_sm4_signature(struct hlsl_ctx *ctx, struct dxbc_writer *dxbc, put_u32(&buffer, 0); /* name */ put_u32(&buffer, usage_idx); put_u32(&buffer, usage); - switch (var->data_type->base_type) + switch (var->data_type->e.numeric.type) { case HLSL_TYPE_FLOAT: case HLSL_TYPE_HALF: @@ -3009,14 +3009,15 @@ static D3D_SHADER_VARIABLE_CLASS sm4_class(const struct hlsl_type *type) case HLSL_CLASS_DEPTH_STENCIL_VIEW: case HLSL_CLASS_EFFECT_GROUP: case HLSL_CLASS_STRUCT: - case HLSL_CLASS_OBJECT: case HLSL_CLASS_PASS: + case HLSL_CLASS_PIXEL_SHADER: case HLSL_CLASS_RENDER_TARGET_VIEW: case HLSL_CLASS_SAMPLER: case HLSL_CLASS_STRING: case HLSL_CLASS_TECHNIQUE: case HLSL_CLASS_TEXTURE: case HLSL_CLASS_UAV: + case HLSL_CLASS_VERTEX_SHADER: case HLSL_CLASS_VOID: break; } @@ -3025,7 +3026,7 @@ static D3D_SHADER_VARIABLE_CLASS sm4_class(const struct hlsl_type *type) static D3D_SHADER_VARIABLE_TYPE sm4_base_type(const struct hlsl_type *type) { - switch (type->base_type) + switch (type->e.numeric.type) { case HLSL_TYPE_BOOL: return D3D_SVT_BOOL; @@ -3089,7 +3090,7 @@ static void write_sm4_type(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *b put_u32(buffer, field->name_bytecode_offset); put_u32(buffer, field->type->bytecode_offset); - put_u32(buffer, field->reg_offset[HLSL_REGSET_NUMERIC]); + put_u32(buffer, field->reg_offset[HLSL_REGSET_NUMERIC] * sizeof(float)); } type->bytecode_offset = put_u32(buffer, vkd3d_make_u32(D3D_SVC_STRUCT, D3D_SVT_VOID)); put_u32(buffer, vkd3d_make_u32(1, hlsl_type_component_count(array_type))); @@ -3139,7 +3140,7 @@ static D3D_RESOURCE_RETURN_TYPE sm4_resource_format(const struct hlsl_type *type if (type->class == HLSL_CLASS_ARRAY) return sm4_resource_format(type->e.array.type); - switch (type->e.resource.format->base_type) + switch (type->e.resource.format->e.numeric.type) { case HLSL_TYPE_DOUBLE: return D3D_RETURN_TYPE_DOUBLE; @@ -4727,11 +4728,11 @@ static void write_sm4_sampleinfo(const struct tpf_writer *tpf, const struct hlsl const struct hlsl_ir_node *dst = &load->node; struct sm4_instruction instr; - assert(dst->data_type->base_type == HLSL_TYPE_UINT || dst->data_type->base_type == HLSL_TYPE_FLOAT); + assert(dst->data_type->e.numeric.type == HLSL_TYPE_UINT || dst->data_type->e.numeric.type == HLSL_TYPE_FLOAT); memset(&instr, 0, sizeof(instr)); instr.opcode = VKD3D_SM4_OP_SAMPLE_INFO; - if (dst->data_type->base_type == HLSL_TYPE_UINT) + if (dst->data_type->e.numeric.type == HLSL_TYPE_UINT) instr.extra_bits |= VKD3DSI_SAMPLE_INFO_UINT << VKD3D_SM4_INSTRUCTION_FLAGS_SHIFT; sm4_dst_from_node(&instr.dsts[0], dst); @@ -4756,11 +4757,11 @@ static void write_sm4_resinfo(const struct tpf_writer *tpf, const struct hlsl_ir return; } - assert(dst->data_type->base_type == HLSL_TYPE_UINT || dst->data_type->base_type == HLSL_TYPE_FLOAT); + assert(dst->data_type->e.numeric.type == HLSL_TYPE_UINT || dst->data_type->e.numeric.type == HLSL_TYPE_FLOAT); memset(&instr, 0, sizeof(instr)); instr.opcode = VKD3D_SM4_OP_RESINFO; - if (dst->data_type->base_type == HLSL_TYPE_UINT) + if (dst->data_type->e.numeric.type == HLSL_TYPE_UINT) instr.extra_bits |= VKD3DSI_RESINFO_UINT << VKD3D_SM4_INSTRUCTION_FLAGS_SHIFT; sm4_dst_from_node(&instr.dsts[0], dst); @@ -4775,7 +4776,7 @@ static void write_sm4_resinfo(const struct tpf_writer *tpf, const struct hlsl_ir static bool type_is_float(const struct hlsl_type *type) { - return type->base_type == HLSL_TYPE_FLOAT || type->base_type == HLSL_TYPE_HALF; + return type->e.numeric.type == HLSL_TYPE_FLOAT || type->e.numeric.type == HLSL_TYPE_HALF; } static void write_sm4_cast_from_bool(const struct tpf_writer *tpf, const struct hlsl_ir_expr *expr, @@ -4812,11 +4813,11 @@ static void write_sm4_cast(const struct tpf_writer *tpf, const struct hlsl_ir_ex /* Narrowing casts were already lowered. */ assert(src_type->dimx == dst_type->dimx); - switch (dst_type->base_type) + switch (dst_type->e.numeric.type) { case HLSL_TYPE_HALF: case HLSL_TYPE_FLOAT: - switch (src_type->base_type) + switch (src_type->e.numeric.type) { case HLSL_TYPE_HALF: case HLSL_TYPE_FLOAT: @@ -4845,7 +4846,7 @@ static void write_sm4_cast(const struct tpf_writer *tpf, const struct hlsl_ir_ex break; case HLSL_TYPE_INT: - switch (src_type->base_type) + switch (src_type->e.numeric.type) { case HLSL_TYPE_HALF: case HLSL_TYPE_FLOAT: @@ -4871,7 +4872,7 @@ static void write_sm4_cast(const struct tpf_writer *tpf, const struct hlsl_ir_ex break; case HLSL_TYPE_UINT: - switch (src_type->base_type) + switch (src_type->e.numeric.type) { case HLSL_TYPE_HALF: case HLSL_TYPE_FLOAT: @@ -4941,7 +4942,7 @@ static void write_sm4_expr(const struct tpf_writer *tpf, const struct hlsl_ir_ex switch (expr->op) { case HLSL_OP1_ABS: - switch (dst_type->base_type) + switch (dst_type->e.numeric.type) { case HLSL_TYPE_FLOAT: write_sm4_unary_op(tpf, VKD3D_SM4_OP_MOV, &expr->node, arg1, VKD3DSPSM_ABS); @@ -5022,12 +5023,12 @@ static void write_sm4_expr(const struct tpf_writer *tpf, const struct hlsl_ir_ex break; case HLSL_OP1_LOGIC_NOT: - assert(dst_type->base_type == HLSL_TYPE_BOOL); + assert(dst_type->e.numeric.type == HLSL_TYPE_BOOL); write_sm4_unary_op(tpf, VKD3D_SM4_OP_NOT, &expr->node, arg1, 0); break; case HLSL_OP1_NEG: - switch (dst_type->base_type) + switch (dst_type->e.numeric.type) { case HLSL_TYPE_FLOAT: write_sm4_unary_op(tpf, VKD3D_SM4_OP_MOV, &expr->node, arg1, VKD3DSPSM_NEG); @@ -5080,7 +5081,7 @@ static void write_sm4_expr(const struct tpf_writer *tpf, const struct hlsl_ir_ex break; case HLSL_OP2_ADD: - switch (dst_type->base_type) + switch (dst_type->e.numeric.type) { case HLSL_TYPE_FLOAT: write_sm4_binary_op(tpf, VKD3D_SM4_OP_ADD, &expr->node, arg1, arg2); @@ -5112,7 +5113,7 @@ static void write_sm4_expr(const struct tpf_writer *tpf, const struct hlsl_ir_ex break; case HLSL_OP2_DIV: - switch (dst_type->base_type) + switch (dst_type->e.numeric.type) { case HLSL_TYPE_FLOAT: write_sm4_binary_op(tpf, VKD3D_SM4_OP_DIV, &expr->node, arg1, arg2); @@ -5128,7 +5129,7 @@ static void write_sm4_expr(const struct tpf_writer *tpf, const struct hlsl_ir_ex break; case HLSL_OP2_DOT: - switch (dst_type->base_type) + switch (dst_type->e.numeric.type) { case HLSL_TYPE_FLOAT: switch (arg1->data_type->dimx) @@ -5160,9 +5161,9 @@ static void write_sm4_expr(const struct tpf_writer *tpf, const struct hlsl_ir_ex { const struct hlsl_type *src_type = arg1->data_type; - assert(dst_type->base_type == HLSL_TYPE_BOOL); + assert(dst_type->e.numeric.type == HLSL_TYPE_BOOL); - switch (src_type->base_type) + switch (src_type->e.numeric.type) { case HLSL_TYPE_FLOAT: write_sm4_binary_op(tpf, VKD3D_SM4_OP_EQ, &expr->node, arg1, arg2); @@ -5186,9 +5187,9 @@ static void write_sm4_expr(const struct tpf_writer *tpf, const struct hlsl_ir_ex { const struct hlsl_type *src_type = arg1->data_type; - assert(dst_type->base_type == HLSL_TYPE_BOOL); + assert(dst_type->e.numeric.type == HLSL_TYPE_BOOL); - switch (src_type->base_type) + switch (src_type->e.numeric.type) { case HLSL_TYPE_FLOAT: write_sm4_binary_op(tpf, VKD3D_SM4_OP_GE, &expr->node, arg1, arg2); @@ -5215,9 +5216,9 @@ static void write_sm4_expr(const struct tpf_writer *tpf, const struct hlsl_ir_ex { const struct hlsl_type *src_type = arg1->data_type; - assert(dst_type->base_type == HLSL_TYPE_BOOL); + assert(dst_type->e.numeric.type == HLSL_TYPE_BOOL); - switch (src_type->base_type) + switch (src_type->e.numeric.type) { case HLSL_TYPE_FLOAT: write_sm4_binary_op(tpf, VKD3D_SM4_OP_LT, &expr->node, arg1, arg2); @@ -5241,23 +5242,23 @@ static void write_sm4_expr(const struct tpf_writer *tpf, const struct hlsl_ir_ex } case HLSL_OP2_LOGIC_AND: - assert(dst_type->base_type == HLSL_TYPE_BOOL); + assert(dst_type->e.numeric.type == HLSL_TYPE_BOOL); write_sm4_binary_op(tpf, VKD3D_SM4_OP_AND, &expr->node, arg1, arg2); break; case HLSL_OP2_LOGIC_OR: - assert(dst_type->base_type == HLSL_TYPE_BOOL); + assert(dst_type->e.numeric.type == HLSL_TYPE_BOOL); write_sm4_binary_op(tpf, VKD3D_SM4_OP_OR, &expr->node, arg1, arg2); break; case HLSL_OP2_LSHIFT: assert(type_is_integer(dst_type)); - assert(dst_type->base_type != HLSL_TYPE_BOOL); + assert(dst_type->e.numeric.type != HLSL_TYPE_BOOL); write_sm4_binary_op(tpf, VKD3D_SM4_OP_ISHL, &expr->node, arg1, arg2); break; case HLSL_OP2_MAX: - switch (dst_type->base_type) + switch (dst_type->e.numeric.type) { case HLSL_TYPE_FLOAT: write_sm4_binary_op(tpf, VKD3D_SM4_OP_MAX, &expr->node, arg1, arg2); @@ -5277,7 +5278,7 @@ static void write_sm4_expr(const struct tpf_writer *tpf, const struct hlsl_ir_ex break; case HLSL_OP2_MIN: - switch (dst_type->base_type) + switch (dst_type->e.numeric.type) { case HLSL_TYPE_FLOAT: write_sm4_binary_op(tpf, VKD3D_SM4_OP_MIN, &expr->node, arg1, arg2); @@ -5297,7 +5298,7 @@ static void write_sm4_expr(const struct tpf_writer *tpf, const struct hlsl_ir_ex break; case HLSL_OP2_MOD: - switch (dst_type->base_type) + switch (dst_type->e.numeric.type) { case HLSL_TYPE_UINT: write_sm4_binary_op_with_two_destinations(tpf, VKD3D_SM4_OP_UDIV, &expr->node, 1, arg1, arg2); @@ -5309,7 +5310,7 @@ static void write_sm4_expr(const struct tpf_writer *tpf, const struct hlsl_ir_ex break; case HLSL_OP2_MUL: - switch (dst_type->base_type) + switch (dst_type->e.numeric.type) { case HLSL_TYPE_FLOAT: write_sm4_binary_op(tpf, VKD3D_SM4_OP_MUL, &expr->node, arg1, arg2); @@ -5331,9 +5332,9 @@ static void write_sm4_expr(const struct tpf_writer *tpf, const struct hlsl_ir_ex { const struct hlsl_type *src_type = arg1->data_type; - assert(dst_type->base_type == HLSL_TYPE_BOOL); + assert(dst_type->e.numeric.type == HLSL_TYPE_BOOL); - switch (src_type->base_type) + switch (src_type->e.numeric.type) { case HLSL_TYPE_FLOAT: write_sm4_binary_op(tpf, VKD3D_SM4_OP_NE, &expr->node, arg1, arg2); @@ -5355,8 +5356,8 @@ static void write_sm4_expr(const struct tpf_writer *tpf, const struct hlsl_ir_ex case HLSL_OP2_RSHIFT: assert(type_is_integer(dst_type)); - assert(dst_type->base_type != HLSL_TYPE_BOOL); - write_sm4_binary_op(tpf, dst_type->base_type == HLSL_TYPE_INT ? VKD3D_SM4_OP_ISHR : VKD3D_SM4_OP_USHR, + assert(dst_type->e.numeric.type != HLSL_TYPE_BOOL); + write_sm4_binary_op(tpf, dst_type->e.numeric.type == HLSL_TYPE_INT ? VKD3D_SM4_OP_ISHR : VKD3D_SM4_OP_USHR, &expr->node, arg1, arg2); break; @@ -5458,7 +5459,7 @@ static void write_sm4_load(const struct tpf_writer *tpf, const struct hlsl_ir_lo instr.dst_count = 1; assert(hlsl_is_numeric_type(type)); - if (type->base_type == HLSL_TYPE_BOOL && var_is_user_input(tpf->ctx, load->src.var)) + if (type->e.numeric.type == HLSL_TYPE_BOOL && var_is_user_input(tpf->ctx, load->src.var)) { struct hlsl_constant_value value; diff --git a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h index 07b5818cba9..bf9d3038f08 100644 --- a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h +++ b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h @@ -223,6 +223,7 @@ enum vkd3d_shader_error VKD3D_SHADER_ERROR_VSIR_INVALID_CONTROL_FLOW = 9016, VKD3D_SHADER_ERROR_VSIR_INVALID_SSA_USAGE = 9017, VKD3D_SHADER_ERROR_VSIR_INVALID_TESSELLATION = 9018, + VKD3D_SHADER_ERROR_VSIR_INVALID_GS = 9019, VKD3D_SHADER_WARNING_VSIR_DYNAMIC_DESCRIPTOR_ARRAY = 9300, }; @@ -528,8 +529,20 @@ enum vkd3d_shader_opcode VKD3DSIH_UTOF, VKD3DSIH_UTOU, VKD3DSIH_WAVE_ACTIVE_ALL_EQUAL, + VKD3DSIH_WAVE_ACTIVE_BALLOT, + VKD3DSIH_WAVE_ACTIVE_BIT_AND, + VKD3DSIH_WAVE_ACTIVE_BIT_OR, + VKD3DSIH_WAVE_ACTIVE_BIT_XOR, VKD3DSIH_WAVE_ALL_TRUE, VKD3DSIH_WAVE_ANY_TRUE, + VKD3DSIH_WAVE_OP_ADD, + VKD3DSIH_WAVE_OP_IMAX, + VKD3DSIH_WAVE_OP_IMIN, + VKD3DSIH_WAVE_OP_MAX, + VKD3DSIH_WAVE_OP_MIN, + VKD3DSIH_WAVE_OP_MUL, + VKD3DSIH_WAVE_OP_UMAX, + VKD3DSIH_WAVE_OP_UMIN, VKD3DSIH_XOR, VKD3DSIH_INVALID, @@ -793,6 +806,7 @@ enum vkd3d_tessellator_domain #define VKD3DSI_SAMPLE_INFO_UINT 0x1 #define VKD3DSI_SAMPLER_COMPARISON_MODE 0x1 #define VKD3DSI_SHIFT_UNMASKED 0x1 +#define VKD3DSI_WAVE_PREFIX 0x1 #define VKD3DSI_PRECISE_X 0x100 #define VKD3DSI_PRECISE_Y 0x200 @@ -1151,6 +1165,8 @@ enum vkd3d_primitive_type VKD3D_PT_TRIANGLELIST_ADJ = 12, VKD3D_PT_TRIANGLESTRIP_ADJ = 13, VKD3D_PT_PATCH = 14, + + VKD3D_PT_COUNT = 15, }; struct vkd3d_shader_primitive_type diff --git a/libs/vkd3d/libs/vkd3d/device.c b/libs/vkd3d/libs/vkd3d/device.c index 3f3332dd3e3..36d8433939a 100644 --- a/libs/vkd3d/libs/vkd3d/device.c +++ b/libs/vkd3d/libs/vkd3d/device.c @@ -272,13 +272,15 @@ static bool has_extension(const VkExtensionProperties *extensions, for (i = 0; i < count; ++i) { - if (is_extension_disabled(extension_name)) - { - WARN("Extension %s is disabled.\n", debugstr_a(extension_name)); - continue; - } if (!strcmp(extensions[i].extensionName, extension_name)) + { + if (is_extension_disabled(extension_name)) + { + WARN("Extension %s is disabled.\n", debugstr_a(extension_name)); + return false; + } return true; + } } return false; } @@ -422,8 +424,6 @@ static HRESULT vkd3d_init_instance_caps(struct vkd3d_instance *instance, ERR("Failed to enumerate instance extensions, vr %d.\n", vr); return hresult_from_vk_result(vr); } - if (!count) - return S_OK; if (!(vk_extensions = vkd3d_calloc(count, sizeof(*vk_extensions)))) return E_OUTOFMEMORY; @@ -869,29 +869,41 @@ static void vkd3d_physical_device_info_init(struct vkd3d_physical_device_info *i info->features2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2; conditional_rendering_features->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CONDITIONAL_RENDERING_FEATURES_EXT; - vk_prepend_struct(&info->features2, conditional_rendering_features); + if (vulkan_info->EXT_conditional_rendering) + vk_prepend_struct(&info->features2, conditional_rendering_features); depth_clip_features->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_CLIP_ENABLE_FEATURES_EXT; - vk_prepend_struct(&info->features2, depth_clip_features); + if (vulkan_info->EXT_depth_clip_enable) + vk_prepend_struct(&info->features2, depth_clip_features); descriptor_indexing_features->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES_EXT; - vk_prepend_struct(&info->features2, descriptor_indexing_features); + if (vulkan_info->EXT_descriptor_indexing) + vk_prepend_struct(&info->features2, descriptor_indexing_features); fragment_shader_interlock_features->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADER_INTERLOCK_FEATURES_EXT; - vk_prepend_struct(&info->features2, fragment_shader_interlock_features); + if (vulkan_info->EXT_fragment_shader_interlock) + vk_prepend_struct(&info->features2, fragment_shader_interlock_features); robustness2_features->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ROBUSTNESS_2_FEATURES_EXT; - vk_prepend_struct(&info->features2, robustness2_features); + if (vulkan_info->EXT_robustness2) + vk_prepend_struct(&info->features2, robustness2_features); demote_features->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DEMOTE_TO_HELPER_INVOCATION_FEATURES_EXT; - vk_prepend_struct(&info->features2, demote_features); + if (vulkan_info->EXT_shader_demote_to_helper_invocation) + vk_prepend_struct(&info->features2, demote_features); buffer_alignment_features->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TEXEL_BUFFER_ALIGNMENT_FEATURES_EXT; - vk_prepend_struct(&info->features2, buffer_alignment_features); + if (vulkan_info->EXT_texel_buffer_alignment) + vk_prepend_struct(&info->features2, buffer_alignment_features); xfb_features->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TRANSFORM_FEEDBACK_FEATURES_EXT; - vk_prepend_struct(&info->features2, xfb_features); + if (vulkan_info->EXT_transform_feedback) + vk_prepend_struct(&info->features2, xfb_features); vertex_divisor_features->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_FEATURES_EXT; - vk_prepend_struct(&info->features2, vertex_divisor_features); + if (vulkan_info->EXT_vertex_attribute_divisor) + vk_prepend_struct(&info->features2, vertex_divisor_features); timeline_semaphore_features->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_FEATURES_KHR; - vk_prepend_struct(&info->features2, timeline_semaphore_features); + if (vulkan_info->KHR_timeline_semaphore) + vk_prepend_struct(&info->features2, timeline_semaphore_features); mutable_features->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MUTABLE_DESCRIPTOR_TYPE_FEATURES_EXT; - vk_prepend_struct(&info->features2, mutable_features); + if (vulkan_info->EXT_mutable_descriptor_type) + vk_prepend_struct(&info->features2, mutable_features); formats4444_features->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_4444_FORMATS_FEATURES_EXT; - vk_prepend_struct(&info->features2, formats4444_features); + if (vulkan_info->EXT_4444_formats) + vk_prepend_struct(&info->features2, formats4444_features); if (vulkan_info->KHR_get_physical_device_properties2) VK_CALL(vkGetPhysicalDeviceFeatures2KHR(physical_device, &info->features2)); @@ -901,15 +913,20 @@ static void vkd3d_physical_device_info_init(struct vkd3d_physical_device_info *i info->properties2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2; maintenance3_properties->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_3_PROPERTIES; - vk_prepend_struct(&info->properties2, maintenance3_properties); + if (vulkan_info->KHR_maintenance3) + vk_prepend_struct(&info->properties2, maintenance3_properties); descriptor_indexing_properties->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_PROPERTIES_EXT; - vk_prepend_struct(&info->properties2, descriptor_indexing_properties); + if (vulkan_info->EXT_descriptor_indexing) + vk_prepend_struct(&info->properties2, descriptor_indexing_properties); buffer_alignment_properties->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TEXEL_BUFFER_ALIGNMENT_PROPERTIES_EXT; - vk_prepend_struct(&info->properties2, buffer_alignment_properties); + if (vulkan_info->EXT_texel_buffer_alignment) + vk_prepend_struct(&info->properties2, buffer_alignment_properties); xfb_properties->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TRANSFORM_FEEDBACK_PROPERTIES_EXT; - vk_prepend_struct(&info->properties2, xfb_properties); + if (vulkan_info->EXT_transform_feedback) + vk_prepend_struct(&info->properties2, xfb_properties); vertex_divisor_properties->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_PROPERTIES_EXT; - vk_prepend_struct(&info->properties2, vertex_divisor_properties); + if (vulkan_info->EXT_vertex_attribute_divisor) + vk_prepend_struct(&info->properties2, vertex_divisor_properties); subgroup_properties->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_PROPERTIES; if (d3d12_device_environment_is_vulkan_min_1_1(device)) vk_prepend_struct(&info->properties2, subgroup_properties); @@ -1515,6 +1532,61 @@ static bool d3d12_device_supports_typed_uav_load_additional_formats(const struct return true; } +static HRESULT vkd3d_check_device_extensions(struct d3d12_device *device, + const struct vkd3d_device_create_info *create_info, VkExtensionProperties **vk_extensions, + uint32_t *vk_extension_count, uint32_t *device_extension_count, bool **user_extension_supported) +{ + const struct vkd3d_vk_instance_procs *vk_procs = &device->vkd3d_instance->vk_procs; + const struct vkd3d_optional_device_extensions_info *optional_extensions; + VkPhysicalDevice physical_device = device->vk_physical_device; + struct vkd3d_vulkan_info *vulkan_info = &device->vk_info; + VkResult vr; + + *device_extension_count = 0; + + if ((vr = VK_CALL(vkEnumerateDeviceExtensionProperties(physical_device, NULL, vk_extension_count, NULL))) < 0) + { + ERR("Failed to enumerate device extensions, vr %d.\n", vr); + return hresult_from_vk_result(vr); + } + + if (!(*vk_extensions = vkd3d_calloc(*vk_extension_count, sizeof(**vk_extensions)))) + return E_OUTOFMEMORY; + + TRACE("Enumerating %u device extensions.\n", *vk_extension_count); + if ((vr = VK_CALL(vkEnumerateDeviceExtensionProperties(physical_device, NULL, vk_extension_count, *vk_extensions))) < 0) + { + ERR("Failed to enumerate device extensions, vr %d.\n", vr); + vkd3d_free(*vk_extensions); + return hresult_from_vk_result(vr); + } + + optional_extensions = vkd3d_find_struct(create_info->next, OPTIONAL_DEVICE_EXTENSIONS_INFO); + if (optional_extensions && optional_extensions->extension_count) + { + if (!(*user_extension_supported = vkd3d_calloc(optional_extensions->extension_count, sizeof(bool)))) + { + vkd3d_free(*vk_extensions); + return E_OUTOFMEMORY; + } + } + else + { + *user_extension_supported = NULL; + } + + *device_extension_count = vkd3d_check_extensions(*vk_extensions, *vk_extension_count, + required_device_extensions, ARRAY_SIZE(required_device_extensions), + optional_device_extensions, ARRAY_SIZE(optional_device_extensions), + create_info->device_extensions, create_info->device_extension_count, + optional_extensions ? optional_extensions->extensions : NULL, + optional_extensions ? optional_extensions->extension_count : 0, + *user_extension_supported, vulkan_info, "device", + device->vkd3d_instance->config_flags & VKD3D_CONFIG_FLAG_VULKAN_DEBUG); + + return S_OK; +} + static HRESULT vkd3d_init_device_caps(struct d3d12_device *device, const struct vkd3d_device_create_info *create_info, struct vkd3d_physical_device_info *physical_device_info, @@ -1523,14 +1595,13 @@ static HRESULT vkd3d_init_device_caps(struct d3d12_device *device, const VkPhysicalDeviceSubgroupProperties *subgroup_properties = &physical_device_info->subgroup_properties; const struct vkd3d_vk_instance_procs *vk_procs = &device->vkd3d_instance->vk_procs; VkPhysicalDeviceFragmentShaderInterlockFeaturesEXT *fragment_shader_interlock; - const struct vkd3d_optional_device_extensions_info *optional_extensions; VkPhysicalDeviceDescriptorIndexingFeaturesEXT *descriptor_indexing; VkPhysicalDevice physical_device = device->vk_physical_device; struct vkd3d_vulkan_info *vulkan_info = &device->vk_info; VkExtensionProperties *vk_extensions; VkPhysicalDeviceFeatures *features; - uint32_t count; - VkResult vr; + uint32_t vk_extension_count; + HRESULT hr; /* SHUFFLE is required to implement WaveReadLaneAt with dynamically uniform index before SPIR-V 1.5 / Vulkan 1.2. */ static const VkSubgroupFeatureFlags required_subgroup_features = VK_SUBGROUP_FEATURE_ARITHMETIC_BIT @@ -1542,7 +1613,11 @@ static HRESULT vkd3d_init_device_caps(struct d3d12_device *device, static const VkSubgroupFeatureFlags required_stages = VK_SHADER_STAGE_COMPUTE_BIT | VK_SHADER_STAGE_FRAGMENT_BIT; - *device_extension_count = 0; + if (FAILED(hr = vkd3d_check_device_extensions(device, create_info, &vk_extensions, &vk_extension_count, + device_extension_count, user_extension_supported))) + return hr; + + vkd3d_physical_device_info_init(physical_device_info, device); vkd3d_trace_physical_device(physical_device, physical_device_info, vk_procs); vkd3d_trace_physical_device_features(physical_device_info); @@ -1634,48 +1709,6 @@ static HRESULT vkd3d_init_device_caps(struct d3d12_device *device, device->feature_options5.RenderPassesTier = D3D12_RENDER_PASS_TIER_0; device->feature_options5.RaytracingTier = D3D12_RAYTRACING_TIER_NOT_SUPPORTED; - if ((vr = VK_CALL(vkEnumerateDeviceExtensionProperties(physical_device, NULL, &count, NULL))) < 0) - { - ERR("Failed to enumerate device extensions, vr %d.\n", vr); - return hresult_from_vk_result(vr); - } - if (!count) - return S_OK; - - if (!(vk_extensions = vkd3d_calloc(count, sizeof(*vk_extensions)))) - return E_OUTOFMEMORY; - - TRACE("Enumerating %u device extensions.\n", count); - if ((vr = VK_CALL(vkEnumerateDeviceExtensionProperties(physical_device, NULL, &count, vk_extensions))) < 0) - { - ERR("Failed to enumerate device extensions, vr %d.\n", vr); - vkd3d_free(vk_extensions); - return hresult_from_vk_result(vr); - } - - optional_extensions = vkd3d_find_struct(create_info->next, OPTIONAL_DEVICE_EXTENSIONS_INFO); - if (optional_extensions && optional_extensions->extension_count) - { - if (!(*user_extension_supported = vkd3d_calloc(optional_extensions->extension_count, sizeof(bool)))) - { - vkd3d_free(vk_extensions); - return E_OUTOFMEMORY; - } - } - else - { - *user_extension_supported = NULL; - } - - *device_extension_count = vkd3d_check_extensions(vk_extensions, count, - required_device_extensions, ARRAY_SIZE(required_device_extensions), - optional_device_extensions, ARRAY_SIZE(optional_device_extensions), - create_info->device_extensions, create_info->device_extension_count, - optional_extensions ? optional_extensions->extensions : NULL, - optional_extensions ? optional_extensions->extension_count : 0, - *user_extension_supported, vulkan_info, "device", - device->vkd3d_instance->config_flags & VKD3D_CONFIG_FLAG_VULKAN_DEBUG); - fragment_shader_interlock = &physical_device_info->fragment_shader_interlock_features; if (!fragment_shader_interlock->fragmentShaderSampleInterlock || !fragment_shader_interlock->fragmentShaderPixelInterlock) @@ -1701,7 +1734,7 @@ static HRESULT vkd3d_init_device_caps(struct d3d12_device *device, vulkan_info->texel_buffer_alignment_properties = physical_device_info->texel_buffer_alignment_properties; - if (get_spec_version(vk_extensions, count, VK_EXT_VERTEX_ATTRIBUTE_DIVISOR_EXTENSION_NAME) >= 3) + if (get_spec_version(vk_extensions, vk_extension_count, VK_EXT_VERTEX_ATTRIBUTE_DIVISOR_EXTENSION_NAME) >= 3) { const VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT *divisor_features; divisor_features = &physical_device_info->vertex_divisor_features; @@ -2098,8 +2131,6 @@ static HRESULT vkd3d_create_vk_device(struct d3d12_device *device, VK_CALL(vkGetPhysicalDeviceMemoryProperties(physical_device, &device->memory_properties)); - vkd3d_physical_device_info_init(&physical_device_info, device); - if (FAILED(hr = vkd3d_init_device_caps(device, create_info, &physical_device_info, &extension_count, &user_extension_supported))) return hr; diff --git a/libs/vkd3d/libs/vkd3d/utils.c b/libs/vkd3d/libs/vkd3d/utils.c index 58747342b5c..11029c9f5f9 100644 --- a/libs/vkd3d/libs/vkd3d/utils.c +++ b/libs/vkd3d/libs/vkd3d/utils.c @@ -901,6 +901,30 @@ bool vkd3d_get_program_name(char program_name[PATH_MAX]) return true; } +#elif defined(WIN32) + +bool vkd3d_get_program_name(char program_name[PATH_MAX]) +{ + char buffer[MAX_PATH]; + char *p, *name; + size_t len; + + *program_name = '\0'; + len = GetModuleFileNameA(NULL, buffer, ARRAY_SIZE(buffer)); + if (!(len && len < MAX_PATH)) + return false; + + name = buffer; + if ((p = strrchr(name, '/'))) + name = p + 1; + if ((p = strrchr(name, '\\'))) + name = p + 1; + + len = strlen(name) + 1; + memcpy(program_name, name, len); + return true; +} + #else bool vkd3d_get_program_name(char program_name[PATH_MAX]) -- 2.43.0