mirror of
https://gitlab.winehq.org/wine/vkd3d.git
synced 2025-12-15 08:03:30 -08:00
vkd3d-shader/dxil: Parse the f32 denormalization mode.
This commit is contained in:
committed by
Henri Verbeet
parent
e99b29d203
commit
1e4764d555
Notes:
Henri Verbeet
2025-12-02 14:37:50 +01:00
Approved-by: Henri Verbeet (@hverbeet) Merge-Request: https://gitlab.winehq.org/wine/vkd3d/-/merge_requests/1842
@@ -1522,6 +1522,8 @@ static enum vkd3d_result shader_sm1_init(struct vkd3d_shader_sm1_parser *sm1, st
|
||||
code_size != ~(size_t)0 ? token_count / 4u + 4 : 16, VSIR_CF_STRUCTURED, normalisation_level))
|
||||
return VKD3D_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
program->f32_denorm_mode = VSIR_DENORM_FLUSH_TO_ZERO;
|
||||
|
||||
vkd3d_shader_parser_init(&sm1->p, message_context, compile_info->source_name);
|
||||
sm1->program = program;
|
||||
sm1->ptr = sm1->start;
|
||||
|
||||
@@ -3360,8 +3360,7 @@ static bool sm6_parser_declare_function(struct sm6_parser *sm6, const struct dxi
|
||||
if (record->operands[4] > UINT_MAX)
|
||||
WARN("Invalid attributes id %#"PRIx64".\n", record->operands[4]);
|
||||
/* 1-based index. */
|
||||
if ((fn->u.function.attribs_id = record->operands[4]))
|
||||
TRACE("Ignoring function attributes.\n");
|
||||
fn->u.function.attribs_id = record->operands[4];
|
||||
|
||||
/* These always seem to be zero. */
|
||||
for (i = 5, j = 0; i < min(record->operand_count, max_count); ++i)
|
||||
@@ -10929,6 +10928,62 @@ static void sm6_parser_cleanup(struct sm6_parser *sm6)
|
||||
vkd3d_free(sm6->values);
|
||||
}
|
||||
|
||||
static enum vsir_denorm_mode sm6_function_get_denorm_mode(const struct sm6_function *function,
|
||||
struct sm6_parser *dxil)
|
||||
{
|
||||
unsigned int attribs_id = function->declaration->u.function.attribs_id;
|
||||
const struct dxil_parameter_attribute *parameter_attribute;
|
||||
size_t i, j, k;
|
||||
|
||||
if (!attribs_id)
|
||||
return VSIR_DENORM_FLUSH_TO_ZERO;
|
||||
|
||||
if (attribs_id > dxil->parameter_attribute_count)
|
||||
{
|
||||
vkd3d_shader_parser_error(&dxil->p, VKD3D_SHADER_ERROR_DXIL_INVALID_ATTRIBUTE,
|
||||
"Invalid attribute id %u.", attribs_id);
|
||||
return VSIR_DENORM_FLUSH_TO_ZERO;
|
||||
}
|
||||
|
||||
parameter_attribute = &dxil->parameter_attributes[attribs_id - 1];
|
||||
|
||||
for (i = 0; i < parameter_attribute->group_count; ++i)
|
||||
{
|
||||
for (j = 0; j < dxil->attribute_group_count; ++j)
|
||||
{
|
||||
struct dxil_attribute_group *attribute_group = &dxil->attribute_groups[j];
|
||||
|
||||
if (attribute_group->group_id != parameter_attribute->groups[i]
|
||||
|| attribute_group->parameter_idx != ~0u)
|
||||
continue;
|
||||
|
||||
for (k = 0; k < attribute_group->attribute_count; ++k)
|
||||
{
|
||||
struct dxil_attribute *attribute = &attribute_group->attributes[k];
|
||||
|
||||
if (attribute->kind != ATTRIBUTE_STRING_WITH_STRING_VALUE
|
||||
|| strcmp(attribute->key.string, "fp32-denorm-mode"))
|
||||
continue;
|
||||
|
||||
if (!strcmp(attribute->value.string, "preserve"))
|
||||
return VSIR_DENORM_PRESERVE;
|
||||
|
||||
if (!strcmp(attribute->value.string, "ftz"))
|
||||
return VSIR_DENORM_FLUSH_TO_ZERO;
|
||||
|
||||
if (!strcmp(attribute->value.string, "any"))
|
||||
return VSIR_DENORM_ANY;
|
||||
|
||||
vkd3d_shader_parser_error(&dxil->p, VKD3D_SHADER_ERROR_DXIL_INVALID_ATTRIBUTE,
|
||||
"Invalid value for attribute `fp32-denorm-mode'.");
|
||||
return VSIR_DENORM_FLUSH_TO_ZERO;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return VSIR_DENORM_FLUSH_TO_ZERO;
|
||||
}
|
||||
|
||||
static struct sm6_function *sm6_parser_get_function(const struct sm6_parser *sm6, const char *name)
|
||||
{
|
||||
size_t i;
|
||||
@@ -11209,8 +11264,12 @@ static enum vkd3d_result sm6_parser_init(struct sm6_parser *sm6, struct vsir_pro
|
||||
goto fail;
|
||||
}
|
||||
|
||||
program->f32_denorm_mode = sm6_function_get_denorm_mode(fn, sm6);
|
||||
|
||||
if (version.type == VKD3D_SHADER_TYPE_HULL)
|
||||
{
|
||||
enum vsir_denorm_mode cp_denorm_mode;
|
||||
|
||||
sm6_parser_add_instruction(sm6, VSIR_OP_HS_CONTROL_POINT_PHASE);
|
||||
|
||||
if ((ret = sm6_function_emit_instructions(fn, sm6)) < 0)
|
||||
@@ -11226,6 +11285,15 @@ static enum vkd3d_result sm6_parser_init(struct sm6_parser *sm6, struct vsir_pro
|
||||
goto fail;
|
||||
}
|
||||
|
||||
cp_denorm_mode = sm6_function_get_denorm_mode(fn, sm6);
|
||||
|
||||
if (sm6->p.status >= 0 && program->f32_denorm_mode != cp_denorm_mode)
|
||||
{
|
||||
vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_ATTRIBUTE,
|
||||
"Patch constant denorm mode %u doesn't match control point denorm mode %u.",
|
||||
program->f32_denorm_mode, cp_denorm_mode);
|
||||
}
|
||||
|
||||
sm6_parser_add_instruction(sm6, VSIR_OP_HS_FORK_PHASE);
|
||||
if ((ret = sm6_function_emit_instructions(fn, sm6)) < 0)
|
||||
goto fail;
|
||||
|
||||
@@ -5296,6 +5296,8 @@ int hlsl_parse(const struct vkd3d_shader_compile_info *compile_info,
|
||||
if (!vsir_program_init(program, compile_info, &version, 0, VSIR_CF_STRUCTURED, normalisation_level))
|
||||
return VKD3D_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
program->f32_denorm_mode = VSIR_DENORM_FLUSH_TO_ZERO;
|
||||
|
||||
if ((ret = hlsl_ctx_parse(&ctx, &program->source_files, compile_info, profile, message_context)) < 0)
|
||||
{
|
||||
vsir_program_cleanup(program);
|
||||
|
||||
@@ -2811,6 +2811,9 @@ static bool shader_sm4_init(struct vkd3d_shader_sm4_parser *sm4, struct vsir_pro
|
||||
if (!vsir_program_init(program, compile_info,
|
||||
&version, token_count / 7u + 20, VSIR_CF_STRUCTURED, VSIR_NORMALISED_SM4))
|
||||
return false;
|
||||
|
||||
program->f32_denorm_mode = VSIR_DENORM_FLUSH_TO_ZERO;
|
||||
|
||||
vkd3d_shader_parser_init(&sm4->p, message_context, compile_info->source_name);
|
||||
sm4->ptr = sm4->start;
|
||||
sm4->program = program;
|
||||
|
||||
@@ -232,6 +232,7 @@ enum vkd3d_shader_error
|
||||
VKD3D_SHADER_ERROR_DXIL_DUPLICATED_BLOCK = 8022,
|
||||
VKD3D_SHADER_ERROR_DXIL_INVALID_STRING = 8023,
|
||||
VKD3D_SHADER_ERROR_DXIL_INVALID_ATTRIBUTE_KIND = 8024,
|
||||
VKD3D_SHADER_ERROR_DXIL_INVALID_ATTRIBUTE = 8025,
|
||||
|
||||
VKD3D_SHADER_WARNING_DXIL_UNKNOWN_MAGIC_NUMBER = 8300,
|
||||
VKD3D_SHADER_WARNING_DXIL_UNKNOWN_SHADER_TYPE = 8301,
|
||||
@@ -1609,6 +1610,13 @@ enum vsir_normalisation_level
|
||||
VSIR_NORMALISED_SM6,
|
||||
};
|
||||
|
||||
enum vsir_denorm_mode
|
||||
{
|
||||
VSIR_DENORM_ANY = 0,
|
||||
VSIR_DENORM_PRESERVE,
|
||||
VSIR_DENORM_FLUSH_TO_ZERO,
|
||||
};
|
||||
|
||||
struct vkd3d_shader_descriptor_info1
|
||||
{
|
||||
enum vkd3d_shader_descriptor_type type;
|
||||
@@ -1687,6 +1695,8 @@ struct vsir_program
|
||||
|
||||
struct vkd3d_shader_param_allocator src_params;
|
||||
struct vkd3d_shader_param_allocator dst_params;
|
||||
|
||||
enum vsir_denorm_mode f32_denorm_mode;
|
||||
};
|
||||
|
||||
enum vkd3d_result vsir_allocate_temp_registers(struct vsir_program *program,
|
||||
|
||||
Reference in New Issue
Block a user