Loading libs/vkd3d-shader/dxil.c +177 −6 Original line number Diff line number Diff line Loading @@ -791,6 +791,7 @@ struct sm6_parser size_t global_symbol_count; const char *entry_point; const char *patch_constant_function; struct vkd3d_shader_dst_param *output_params; struct vkd3d_shader_dst_param *input_params; Loading Loading @@ -2790,7 +2791,7 @@ static inline uint64_t decode_rotated_signed_value(uint64_t value) return value << 63; } static inline float bitcast_uint64_to_float(uint64_t value) static float bitcast_uint_to_float(unsigned int value) { union { Loading @@ -2814,6 +2815,23 @@ static inline double bitcast_uint64_to_double(uint64_t value) return u.double_value; } static float register_get_float_value(const struct vkd3d_shader_register *reg) { if (!register_is_constant(reg) || !data_type_is_floating_point(reg->data_type)) return 0.0; if (reg->dimension == VSIR_DIMENSION_VEC4) WARN("Returning vec4.x.\n"); if (reg->type == VKD3DSPR_IMMCONST64) { WARN("Truncating double to float.\n"); return bitcast_uint64_to_double(reg->u.immconst_u64[0]); } return bitcast_uint_to_float(reg->u.immconst_u32[0]); } static enum vkd3d_result value_allocate_constant_array(struct sm6_value *dst, const struct sm6_type *type, const uint64_t *operands, struct sm6_parser *sm6) { Loading Loading @@ -3098,7 +3116,7 @@ static enum vkd3d_result sm6_parser_constants_init(struct sm6_parser *sm6, const if (type->u.width == 16) dst->u.reg.u.immconst_u32[0] = record->operands[0]; else if (type->u.width == 32) dst->u.reg.u.immconst_f32[0] = bitcast_uint64_to_float(record->operands[0]); dst->u.reg.u.immconst_f32[0] = bitcast_uint_to_float(record->operands[0]); else if (type->u.width == 64) dst->u.reg.u.immconst_f64[0] = bitcast_uint64_to_double(record->operands[0]); else Loading Loading @@ -6728,6 +6746,25 @@ static bool sm6_metadata_get_uint64_value(const struct sm6_parser *sm6, return true; } static bool sm6_metadata_get_float_value(const struct sm6_parser *sm6, const struct sm6_metadata_value *m, float *f) { const struct sm6_value *value; if (!m || m->type != VKD3D_METADATA_VALUE) return false; value = m->u.value; if (!sm6_value_is_constant(value)) return false; if (!sm6_type_is_floating_point(value->type)) return false; *f = register_get_float_value(&value->u.reg); return true; } static void sm6_parser_metadata_attachment_block_init(struct sm6_parser *sm6, const struct dxil_block *target_block, const struct dxil_block *block) { Loading Loading @@ -8762,6 +8799,14 @@ static enum vkd3d_result sm6_parser_emit_thread_group(struct sm6_parser *sm6, co return VKD3D_OK; } static void sm6_parser_emit_dcl_count(struct sm6_parser *sm6, enum vkd3d_shader_opcode handler_idx, unsigned int count) { struct vkd3d_shader_instruction *ins; ins = sm6_parser_add_instruction(sm6, handler_idx); ins->declaration.count = count; } static void sm6_parser_emit_dcl_tessellator_domain(struct sm6_parser *sm6, enum vkd3d_tessellator_domain tessellator_domain) { Loading @@ -8778,14 +8823,72 @@ static void sm6_parser_emit_dcl_tessellator_domain(struct sm6_parser *sm6, ins->declaration.tessellator_domain = tessellator_domain; } static void sm6_parser_validate_control_point_count(struct sm6_parser *sm6, unsigned int count) static void sm6_parser_validate_control_point_count(struct sm6_parser *sm6, unsigned int count, const char *type) { if (!count || count > 32) { WARN("Invalid control point count %u.\n", count); WARN("%s control point count %u invalid.\n", type, count); vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_PROPERTIES, "%s control point count %u is invalid.", type, count); } } static void sm6_parser_emit_dcl_tessellator_partitioning(struct sm6_parser *sm6, enum vkd3d_shader_tessellator_partitioning tessellator_partitioning) { struct vkd3d_shader_instruction *ins; if (!tessellator_partitioning || tessellator_partitioning > VKD3D_SHADER_TESSELLATOR_PARTITIONING_FRACTIONAL_EVEN) { WARN("Unhandled partitioning %u.\n", tessellator_partitioning); vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_PROPERTIES, "Hull shader tessellator partitioning %u is unhandled.", tessellator_partitioning); } ins = sm6_parser_add_instruction(sm6, VKD3DSIH_DCL_TESSELLATOR_PARTITIONING); ins->declaration.tessellator_partitioning = tessellator_partitioning; } static void sm6_parser_emit_dcl_tessellator_output_primitive(struct sm6_parser *sm6, enum vkd3d_shader_tessellator_output_primitive primitive) { struct vkd3d_shader_instruction *ins; if (!primitive || primitive > VKD3D_SHADER_TESSELLATOR_OUTPUT_TRIANGLE_CCW) { WARN("Unhandled output primitive %u.\n", primitive); vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_PROPERTIES, "Domain shader input control point count %u is invalid.", count); "Hull shader tessellator output primitive %u is unhandled.", primitive); } ins = sm6_parser_add_instruction(sm6, VKD3DSIH_DCL_TESSELLATOR_OUTPUT_PRIMITIVE); ins->declaration.tessellator_output_primitive = primitive; } static void sm6_parser_emit_dcl_max_tessellation_factor(struct sm6_parser *sm6, struct sm6_metadata_value *m) { struct vkd3d_shader_instruction *ins; float max_tessellation_factor; if (!sm6_metadata_get_float_value(sm6, m, &max_tessellation_factor)) { WARN("Max tess factor property is not a float value.\n"); vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_PROPERTIES, "Hull shader max tessellation factor property operand is not a float."); return; } /* Exclude non-finite values. */ if (!(max_tessellation_factor >= 1.0f && max_tessellation_factor <= 64.0f)) { WARN("Invalid max tess factor %f.\n", max_tessellation_factor); vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_PROPERTIES, "Hull shader max tessellation factor %f is invalid.", max_tessellation_factor); } ins = sm6_parser_add_instruction(sm6, VKD3DSIH_DCL_HS_MAX_TESSFACTOR); ins->declaration.max_tessellation_factor = max_tessellation_factor; } static enum vkd3d_tessellator_domain sm6_parser_ds_properties_init(struct sm6_parser *sm6, Loading Loading @@ -8830,12 +8933,77 @@ static enum vkd3d_tessellator_domain sm6_parser_ds_properties_init(struct sm6_pa } sm6_parser_emit_dcl_tessellator_domain(sm6, operands[0]); sm6_parser_validate_control_point_count(sm6, operands[1]); sm6_parser_validate_control_point_count(sm6, operands[1], "Domain shader input"); sm6->p.program.input_control_point_count = operands[1]; return operands[0]; } static enum vkd3d_tessellator_domain sm6_parser_hs_properties_init(struct sm6_parser *sm6, const struct sm6_metadata_value *m) { const struct sm6_metadata_node *node; unsigned int operands[6] = {0}; unsigned int i; if (!m || !sm6_metadata_value_is_node(m)) { WARN("Missing or invalid HS properties.\n"); vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_PROPERTIES, "Hull shader properties node is missing or invalid."); return 0; } node = m->u.node; if (node->operand_count < 7) { WARN("Invalid operand count %u.\n", node->operand_count); vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND_COUNT, "Hull shader properties operand count %u is invalid.", node->operand_count); return 0; } if (node->operand_count > 7) { WARN("Ignoring %u extra operands.\n", node->operand_count - 7); vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_WARNING_DXIL_IGNORING_OPERANDS, "Ignoring %u extra operands for hull shader properties.", node->operand_count - 7); } m = node->operands[0]; if (!sm6_metadata_value_is_value(m) || !sm6_value_is_function_dcl(m->u.value)) { WARN("Patch constant function node is not a function value.\n"); vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_PROPERTIES, "Hull shader patch constant function node is not a function value."); } else { sm6->patch_constant_function = m->u.value->u.function.name; } for (i = 1; i < min(node->operand_count, ARRAY_SIZE(operands)); ++i) { if (!sm6_metadata_get_uint_value(sm6, node->operands[i], &operands[i])) { WARN("HS property at index %u is not a uint value.\n", i); vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_PROPERTIES, "Hull shader properties operand at index %u is not an integer.", i); } } sm6_parser_validate_control_point_count(sm6, operands[1], "Hull shader input"); sm6->p.program.input_control_point_count = operands[1]; sm6_parser_validate_control_point_count(sm6, operands[2], "Hull shader output"); sm6_parser_emit_dcl_count(sm6, VKD3DSIH_DCL_OUTPUT_CONTROL_POINT_COUNT, operands[2]); sm6->p.program.output_control_point_count = operands[2]; sm6_parser_emit_dcl_tessellator_domain(sm6, operands[3]); sm6_parser_emit_dcl_tessellator_partitioning(sm6, operands[4]); sm6_parser_emit_dcl_tessellator_output_primitive(sm6, operands[5]); sm6_parser_emit_dcl_max_tessellation_factor(sm6, node->operands[6]); return operands[3]; } static enum vkd3d_result sm6_parser_entry_point_init(struct sm6_parser *sm6) { const struct sm6_metadata_value *m = sm6_parser_find_named_metadata(sm6, "dx.entryPoints"); Loading Loading @@ -8916,6 +9084,9 @@ static enum vkd3d_result sm6_parser_entry_point_init(struct sm6_parser *sm6) case SHADER_PROPERTIES_DOMAIN: tessellator_domain = sm6_parser_ds_properties_init(sm6, node->operands[i + 1]); break; case SHADER_PROPERTIES_HULL: tessellator_domain = sm6_parser_hs_properties_init(sm6, node->operands[i + 1]); break; case SHADER_PROPERTIES_COMPUTE: if ((ret = sm6_parser_emit_thread_group(sm6, node->operands[i + 1])) < 0) return ret; Loading libs/vkd3d-shader/spirv.c +0 −5 Original line number Diff line number Diff line Loading @@ -223,11 +223,6 @@ enum vkd3d_shader_input_sysval_semantic vkd3d_siv_from_sysval_indexed(enum vkd3d } } static bool data_type_is_floating_point(enum vkd3d_data_type data_type) { return data_type == VKD3D_DATA_HALF || data_type == VKD3D_DATA_FLOAT || data_type == VKD3D_DATA_DOUBLE; } #define VKD3D_SPIRV_VERSION 0x00010000 #define VKD3D_SPIRV_GENERATOR_ID 18 #define VKD3D_SPIRV_GENERATOR_VERSION 11 Loading libs/vkd3d-shader/vkd3d_shader_private.h +5 −0 Original line number Diff line number Diff line Loading @@ -641,6 +641,11 @@ static inline bool data_type_is_bool(enum vkd3d_data_type data_type) return data_type == VKD3D_DATA_BOOL; } static inline bool data_type_is_floating_point(enum vkd3d_data_type data_type) { return data_type == VKD3D_DATA_HALF || data_type == VKD3D_DATA_FLOAT || data_type == VKD3D_DATA_DOUBLE; } static inline bool data_type_is_64_bit(enum vkd3d_data_type data_type) { return data_type == VKD3D_DATA_DOUBLE || data_type == VKD3D_DATA_UINT64; Loading Loading
libs/vkd3d-shader/dxil.c +177 −6 Original line number Diff line number Diff line Loading @@ -791,6 +791,7 @@ struct sm6_parser size_t global_symbol_count; const char *entry_point; const char *patch_constant_function; struct vkd3d_shader_dst_param *output_params; struct vkd3d_shader_dst_param *input_params; Loading Loading @@ -2790,7 +2791,7 @@ static inline uint64_t decode_rotated_signed_value(uint64_t value) return value << 63; } static inline float bitcast_uint64_to_float(uint64_t value) static float bitcast_uint_to_float(unsigned int value) { union { Loading @@ -2814,6 +2815,23 @@ static inline double bitcast_uint64_to_double(uint64_t value) return u.double_value; } static float register_get_float_value(const struct vkd3d_shader_register *reg) { if (!register_is_constant(reg) || !data_type_is_floating_point(reg->data_type)) return 0.0; if (reg->dimension == VSIR_DIMENSION_VEC4) WARN("Returning vec4.x.\n"); if (reg->type == VKD3DSPR_IMMCONST64) { WARN("Truncating double to float.\n"); return bitcast_uint64_to_double(reg->u.immconst_u64[0]); } return bitcast_uint_to_float(reg->u.immconst_u32[0]); } static enum vkd3d_result value_allocate_constant_array(struct sm6_value *dst, const struct sm6_type *type, const uint64_t *operands, struct sm6_parser *sm6) { Loading Loading @@ -3098,7 +3116,7 @@ static enum vkd3d_result sm6_parser_constants_init(struct sm6_parser *sm6, const if (type->u.width == 16) dst->u.reg.u.immconst_u32[0] = record->operands[0]; else if (type->u.width == 32) dst->u.reg.u.immconst_f32[0] = bitcast_uint64_to_float(record->operands[0]); dst->u.reg.u.immconst_f32[0] = bitcast_uint_to_float(record->operands[0]); else if (type->u.width == 64) dst->u.reg.u.immconst_f64[0] = bitcast_uint64_to_double(record->operands[0]); else Loading Loading @@ -6728,6 +6746,25 @@ static bool sm6_metadata_get_uint64_value(const struct sm6_parser *sm6, return true; } static bool sm6_metadata_get_float_value(const struct sm6_parser *sm6, const struct sm6_metadata_value *m, float *f) { const struct sm6_value *value; if (!m || m->type != VKD3D_METADATA_VALUE) return false; value = m->u.value; if (!sm6_value_is_constant(value)) return false; if (!sm6_type_is_floating_point(value->type)) return false; *f = register_get_float_value(&value->u.reg); return true; } static void sm6_parser_metadata_attachment_block_init(struct sm6_parser *sm6, const struct dxil_block *target_block, const struct dxil_block *block) { Loading Loading @@ -8762,6 +8799,14 @@ static enum vkd3d_result sm6_parser_emit_thread_group(struct sm6_parser *sm6, co return VKD3D_OK; } static void sm6_parser_emit_dcl_count(struct sm6_parser *sm6, enum vkd3d_shader_opcode handler_idx, unsigned int count) { struct vkd3d_shader_instruction *ins; ins = sm6_parser_add_instruction(sm6, handler_idx); ins->declaration.count = count; } static void sm6_parser_emit_dcl_tessellator_domain(struct sm6_parser *sm6, enum vkd3d_tessellator_domain tessellator_domain) { Loading @@ -8778,14 +8823,72 @@ static void sm6_parser_emit_dcl_tessellator_domain(struct sm6_parser *sm6, ins->declaration.tessellator_domain = tessellator_domain; } static void sm6_parser_validate_control_point_count(struct sm6_parser *sm6, unsigned int count) static void sm6_parser_validate_control_point_count(struct sm6_parser *sm6, unsigned int count, const char *type) { if (!count || count > 32) { WARN("Invalid control point count %u.\n", count); WARN("%s control point count %u invalid.\n", type, count); vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_PROPERTIES, "%s control point count %u is invalid.", type, count); } } static void sm6_parser_emit_dcl_tessellator_partitioning(struct sm6_parser *sm6, enum vkd3d_shader_tessellator_partitioning tessellator_partitioning) { struct vkd3d_shader_instruction *ins; if (!tessellator_partitioning || tessellator_partitioning > VKD3D_SHADER_TESSELLATOR_PARTITIONING_FRACTIONAL_EVEN) { WARN("Unhandled partitioning %u.\n", tessellator_partitioning); vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_PROPERTIES, "Hull shader tessellator partitioning %u is unhandled.", tessellator_partitioning); } ins = sm6_parser_add_instruction(sm6, VKD3DSIH_DCL_TESSELLATOR_PARTITIONING); ins->declaration.tessellator_partitioning = tessellator_partitioning; } static void sm6_parser_emit_dcl_tessellator_output_primitive(struct sm6_parser *sm6, enum vkd3d_shader_tessellator_output_primitive primitive) { struct vkd3d_shader_instruction *ins; if (!primitive || primitive > VKD3D_SHADER_TESSELLATOR_OUTPUT_TRIANGLE_CCW) { WARN("Unhandled output primitive %u.\n", primitive); vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_PROPERTIES, "Domain shader input control point count %u is invalid.", count); "Hull shader tessellator output primitive %u is unhandled.", primitive); } ins = sm6_parser_add_instruction(sm6, VKD3DSIH_DCL_TESSELLATOR_OUTPUT_PRIMITIVE); ins->declaration.tessellator_output_primitive = primitive; } static void sm6_parser_emit_dcl_max_tessellation_factor(struct sm6_parser *sm6, struct sm6_metadata_value *m) { struct vkd3d_shader_instruction *ins; float max_tessellation_factor; if (!sm6_metadata_get_float_value(sm6, m, &max_tessellation_factor)) { WARN("Max tess factor property is not a float value.\n"); vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_PROPERTIES, "Hull shader max tessellation factor property operand is not a float."); return; } /* Exclude non-finite values. */ if (!(max_tessellation_factor >= 1.0f && max_tessellation_factor <= 64.0f)) { WARN("Invalid max tess factor %f.\n", max_tessellation_factor); vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_PROPERTIES, "Hull shader max tessellation factor %f is invalid.", max_tessellation_factor); } ins = sm6_parser_add_instruction(sm6, VKD3DSIH_DCL_HS_MAX_TESSFACTOR); ins->declaration.max_tessellation_factor = max_tessellation_factor; } static enum vkd3d_tessellator_domain sm6_parser_ds_properties_init(struct sm6_parser *sm6, Loading Loading @@ -8830,12 +8933,77 @@ static enum vkd3d_tessellator_domain sm6_parser_ds_properties_init(struct sm6_pa } sm6_parser_emit_dcl_tessellator_domain(sm6, operands[0]); sm6_parser_validate_control_point_count(sm6, operands[1]); sm6_parser_validate_control_point_count(sm6, operands[1], "Domain shader input"); sm6->p.program.input_control_point_count = operands[1]; return operands[0]; } static enum vkd3d_tessellator_domain sm6_parser_hs_properties_init(struct sm6_parser *sm6, const struct sm6_metadata_value *m) { const struct sm6_metadata_node *node; unsigned int operands[6] = {0}; unsigned int i; if (!m || !sm6_metadata_value_is_node(m)) { WARN("Missing or invalid HS properties.\n"); vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_PROPERTIES, "Hull shader properties node is missing or invalid."); return 0; } node = m->u.node; if (node->operand_count < 7) { WARN("Invalid operand count %u.\n", node->operand_count); vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND_COUNT, "Hull shader properties operand count %u is invalid.", node->operand_count); return 0; } if (node->operand_count > 7) { WARN("Ignoring %u extra operands.\n", node->operand_count - 7); vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_WARNING_DXIL_IGNORING_OPERANDS, "Ignoring %u extra operands for hull shader properties.", node->operand_count - 7); } m = node->operands[0]; if (!sm6_metadata_value_is_value(m) || !sm6_value_is_function_dcl(m->u.value)) { WARN("Patch constant function node is not a function value.\n"); vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_PROPERTIES, "Hull shader patch constant function node is not a function value."); } else { sm6->patch_constant_function = m->u.value->u.function.name; } for (i = 1; i < min(node->operand_count, ARRAY_SIZE(operands)); ++i) { if (!sm6_metadata_get_uint_value(sm6, node->operands[i], &operands[i])) { WARN("HS property at index %u is not a uint value.\n", i); vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_PROPERTIES, "Hull shader properties operand at index %u is not an integer.", i); } } sm6_parser_validate_control_point_count(sm6, operands[1], "Hull shader input"); sm6->p.program.input_control_point_count = operands[1]; sm6_parser_validate_control_point_count(sm6, operands[2], "Hull shader output"); sm6_parser_emit_dcl_count(sm6, VKD3DSIH_DCL_OUTPUT_CONTROL_POINT_COUNT, operands[2]); sm6->p.program.output_control_point_count = operands[2]; sm6_parser_emit_dcl_tessellator_domain(sm6, operands[3]); sm6_parser_emit_dcl_tessellator_partitioning(sm6, operands[4]); sm6_parser_emit_dcl_tessellator_output_primitive(sm6, operands[5]); sm6_parser_emit_dcl_max_tessellation_factor(sm6, node->operands[6]); return operands[3]; } static enum vkd3d_result sm6_parser_entry_point_init(struct sm6_parser *sm6) { const struct sm6_metadata_value *m = sm6_parser_find_named_metadata(sm6, "dx.entryPoints"); Loading Loading @@ -8916,6 +9084,9 @@ static enum vkd3d_result sm6_parser_entry_point_init(struct sm6_parser *sm6) case SHADER_PROPERTIES_DOMAIN: tessellator_domain = sm6_parser_ds_properties_init(sm6, node->operands[i + 1]); break; case SHADER_PROPERTIES_HULL: tessellator_domain = sm6_parser_hs_properties_init(sm6, node->operands[i + 1]); break; case SHADER_PROPERTIES_COMPUTE: if ((ret = sm6_parser_emit_thread_group(sm6, node->operands[i + 1])) < 0) return ret; Loading
libs/vkd3d-shader/spirv.c +0 −5 Original line number Diff line number Diff line Loading @@ -223,11 +223,6 @@ enum vkd3d_shader_input_sysval_semantic vkd3d_siv_from_sysval_indexed(enum vkd3d } } static bool data_type_is_floating_point(enum vkd3d_data_type data_type) { return data_type == VKD3D_DATA_HALF || data_type == VKD3D_DATA_FLOAT || data_type == VKD3D_DATA_DOUBLE; } #define VKD3D_SPIRV_VERSION 0x00010000 #define VKD3D_SPIRV_GENERATOR_ID 18 #define VKD3D_SPIRV_GENERATOR_VERSION 11 Loading
libs/vkd3d-shader/vkd3d_shader_private.h +5 −0 Original line number Diff line number Diff line Loading @@ -641,6 +641,11 @@ static inline bool data_type_is_bool(enum vkd3d_data_type data_type) return data_type == VKD3D_DATA_BOOL; } static inline bool data_type_is_floating_point(enum vkd3d_data_type data_type) { return data_type == VKD3D_DATA_HALF || data_type == VKD3D_DATA_FLOAT || data_type == VKD3D_DATA_DOUBLE; } static inline bool data_type_is_64_bit(enum vkd3d_data_type data_type) { return data_type == VKD3D_DATA_DOUBLE || data_type == VKD3D_DATA_UINT64; Loading