mirror of
https://gitlab.winehq.org/wine/vkd3d.git
synced 2025-01-28 13:05:02 -08:00
vkd3d-shader: Write uninitialized components of COLOR0 as 1.
This commit is contained in:
parent
cc9fcee676
commit
e781abc3fb
Notes:
Henri Verbeet
2024-11-04 17:11:05 +01:00
Approved-by: Henri Verbeet (@hverbeet) Merge-Request: https://gitlab.winehq.org/wine/vkd3d/-/merge_requests/1236
@ -129,6 +129,19 @@ const struct vkd3d_shader_parameter1 *vsir_program_get_parameter(
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static struct signature_element *vsir_signature_find_element_by_name(
|
||||
const struct shader_signature *signature, const char *semantic_name, unsigned int semantic_index)
|
||||
{
|
||||
for (unsigned int i = 0; i < signature->element_count; ++i)
|
||||
{
|
||||
if (!ascii_strcasecmp(signature->elements[i].semantic_name, semantic_name)
|
||||
&& signature->elements[i].semantic_index == semantic_index)
|
||||
return &signature->elements[i];
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void vsir_register_init(struct vkd3d_shader_register *reg, enum vkd3d_shader_register_type reg_type,
|
||||
enum vkd3d_data_type data_type, unsigned int idx_count)
|
||||
{
|
||||
@ -806,6 +819,81 @@ static enum vkd3d_result vsir_program_ensure_ret(struct vsir_program *program,
|
||||
return VKD3D_OK;
|
||||
}
|
||||
|
||||
static enum vkd3d_result vsir_program_add_diffuse_output(struct vsir_program *program,
|
||||
struct vsir_transformation_context *ctx)
|
||||
{
|
||||
struct shader_signature *signature = &program->output_signature;
|
||||
struct signature_element *new_elements, *e;
|
||||
|
||||
if (program->shader_version.type != VKD3D_SHADER_TYPE_VERTEX)
|
||||
return VKD3D_OK;
|
||||
|
||||
if ((e = vsir_signature_find_element_by_name(signature, "COLOR", 0)))
|
||||
{
|
||||
program->diffuse_written_mask = e->mask;
|
||||
e->mask = VKD3DSP_WRITEMASK_ALL;
|
||||
|
||||
return VKD3D_OK;
|
||||
}
|
||||
|
||||
if (!(new_elements = vkd3d_realloc(signature->elements,
|
||||
(signature->element_count + 1) * sizeof(*signature->elements))))
|
||||
return VKD3D_ERROR_OUT_OF_MEMORY;
|
||||
signature->elements = new_elements;
|
||||
e = &signature->elements[signature->element_count++];
|
||||
memset(e, 0, sizeof(*e));
|
||||
e->semantic_name = vkd3d_strdup("COLOR");
|
||||
e->sysval_semantic = VKD3D_SHADER_SV_NONE;
|
||||
e->component_type = VKD3D_SHADER_COMPONENT_FLOAT;
|
||||
e->register_count = 1;
|
||||
e->mask = VKD3DSP_WRITEMASK_ALL;
|
||||
e->used_mask = VKD3DSP_WRITEMASK_ALL;
|
||||
e->register_index = SM1_COLOR_REGISTER_OFFSET;
|
||||
e->target_location = SM1_COLOR_REGISTER_OFFSET;
|
||||
e->interpolation_mode = VKD3DSIM_NONE;
|
||||
|
||||
return VKD3D_OK;
|
||||
}
|
||||
|
||||
/* Uninitialized components of diffuse yield 1.0 in SM1-2. Implement this by
|
||||
* always writing diffuse in those versions, even if the PS doesn't read it. */
|
||||
static enum vkd3d_result vsir_program_ensure_diffuse(struct vsir_program *program,
|
||||
struct vsir_transformation_context *ctx)
|
||||
{
|
||||
static const struct vkd3d_shader_location no_loc;
|
||||
struct vkd3d_shader_instruction *ins;
|
||||
unsigned int i;
|
||||
|
||||
if (program->shader_version.type != VKD3D_SHADER_TYPE_VERTEX
|
||||
|| program->diffuse_written_mask == VKD3DSP_WRITEMASK_ALL)
|
||||
return VKD3D_OK;
|
||||
|
||||
/* Write the instruction after all LABEL, DCL, and NOP instructions.
|
||||
* We need to skip NOP instructions because they might result from removed
|
||||
* DCLs, and there could still be DCLs after NOPs. */
|
||||
for (i = 0; i < program->instructions.count; ++i)
|
||||
{
|
||||
ins = &program->instructions.elements[i];
|
||||
|
||||
if (!vsir_instruction_is_dcl(ins) && ins->opcode != VKD3DSIH_LABEL && ins->opcode != VKD3DSIH_NOP)
|
||||
break;
|
||||
}
|
||||
|
||||
if (!shader_instruction_array_insert_at(&program->instructions, i, 1))
|
||||
return VKD3D_ERROR_OUT_OF_MEMORY;
|
||||
ins = &program->instructions.elements[i];
|
||||
vsir_instruction_init_with_params(program, ins, &no_loc, VKD3DSIH_MOV, 1, 1);
|
||||
vsir_dst_param_init(&ins->dst[0], VKD3DSPR_ATTROUT, VKD3D_DATA_FLOAT, 1);
|
||||
ins->dst[0].reg.idx[0].offset = 0;
|
||||
ins->dst[0].reg.dimension = VSIR_DIMENSION_VEC4;
|
||||
ins->dst[0].write_mask = VKD3DSP_WRITEMASK_ALL & ~program->diffuse_written_mask;
|
||||
vsir_src_param_init(&ins->src[0], VKD3DSPR_IMMCONST, VKD3D_DATA_FLOAT, 0);
|
||||
ins->src[0].reg.dimension = VSIR_DIMENSION_VEC4;
|
||||
for (i = 0; i < 4; ++i)
|
||||
ins->src[0].reg.u.immconst_f32[i] = 1.0f;
|
||||
return VKD3D_OK;
|
||||
}
|
||||
|
||||
static const struct vkd3d_shader_varying_map *find_varying_map(
|
||||
const struct vkd3d_shader_varying_map_info *varying_map, unsigned int signature_idx)
|
||||
{
|
||||
@ -8087,6 +8175,31 @@ static void vsir_transform_(
|
||||
}
|
||||
}
|
||||
|
||||
/* Transformations which should happen at parse time, i.e. before scan
|
||||
* information is returned to the user.
|
||||
*
|
||||
* In particular, some passes need to modify the signature, and
|
||||
* vkd3d_shader_scan() should report the modified signature for the given
|
||||
* target. */
|
||||
enum vkd3d_result vsir_program_transform_early(struct vsir_program *program, uint64_t config_flags,
|
||||
const struct vkd3d_shader_compile_info *compile_info, struct vkd3d_shader_message_context *message_context)
|
||||
{
|
||||
struct vsir_transformation_context ctx =
|
||||
{
|
||||
.result = VKD3D_OK,
|
||||
.program = program,
|
||||
.config_flags = config_flags,
|
||||
.compile_info = compile_info,
|
||||
.message_context = message_context,
|
||||
};
|
||||
|
||||
/* For vsir_program_ensure_diffuse(). */
|
||||
if (program->shader_version.major <= 2)
|
||||
vsir_transform(&ctx, vsir_program_add_diffuse_output);
|
||||
|
||||
return ctx.result;
|
||||
}
|
||||
|
||||
enum vkd3d_result vsir_program_transform(struct vsir_program *program, uint64_t config_flags,
|
||||
const struct vkd3d_shader_compile_info *compile_info, struct vkd3d_shader_message_context *message_context)
|
||||
{
|
||||
@ -8113,6 +8226,9 @@ enum vkd3d_result vsir_program_transform(struct vsir_program *program, uint64_t
|
||||
{
|
||||
vsir_transform(&ctx, vsir_program_ensure_ret);
|
||||
|
||||
if (program->shader_version.major <= 2)
|
||||
vsir_transform(&ctx, vsir_program_ensure_diffuse);
|
||||
|
||||
if (program->shader_version.type != VKD3D_SHADER_TYPE_PIXEL)
|
||||
vsir_transform(&ctx, vsir_program_remap_output_signature);
|
||||
|
||||
|
@ -719,8 +719,11 @@ static enum vkd3d_result vsir_parse(const struct vkd3d_shader_compile_info *comp
|
||||
vsir_program_trace(program);
|
||||
|
||||
vsir_program_cleanup(program);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (compile_info->target_type != VKD3D_SHADER_TARGET_NONE)
|
||||
ret = vsir_program_transform_early(program, config_flags, compile_info, message_context);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -1424,6 +1424,7 @@ struct vsir_program
|
||||
bool use_vocp;
|
||||
bool has_point_size;
|
||||
bool has_point_coord;
|
||||
uint8_t diffuse_written_mask;
|
||||
enum vsir_control_flow_type cf_type;
|
||||
enum vsir_normalisation_level normalisation_level;
|
||||
|
||||
@ -1442,6 +1443,8 @@ bool vsir_program_init(struct vsir_program *program, const struct vkd3d_shader_c
|
||||
enum vsir_normalisation_level normalisation_level);
|
||||
enum vkd3d_result vsir_program_transform(struct vsir_program *program, uint64_t config_flags,
|
||||
const struct vkd3d_shader_compile_info *compile_info, struct vkd3d_shader_message_context *message_context);
|
||||
enum vkd3d_result vsir_program_transform_early(struct vsir_program *program, uint64_t config_flags,
|
||||
const struct vkd3d_shader_compile_info *compile_info, struct vkd3d_shader_message_context *message_context);
|
||||
enum vkd3d_result vsir_program_validate(struct vsir_program *program, uint64_t config_flags,
|
||||
const char *source_name, struct vkd3d_shader_message_context *message_context);
|
||||
struct vkd3d_shader_src_param *vsir_program_create_outpointid_param(
|
||||
|
@ -42,5 +42,5 @@ float4 main(float4 v : color0) : sv_target
|
||||
|
||||
[test]
|
||||
clear rtv 0 1 0 0 1
|
||||
todo draw quad
|
||||
draw quad
|
||||
probe (0, 0) rgba (1, 1, 1, 1)
|
||||
|
Loading…
x
Reference in New Issue
Block a user