mirror of
https://gitlab.winehq.org/wine/vkd3d.git
synced 2025-12-15 08:03:30 -08:00
vkd3d-shader/d3dbc: Lower TEXTURE to TEMP registers when written.
This commit is contained in:
committed by
Henri Verbeet
parent
2cf883d1dd
commit
b09a17ddde
Notes:
Henri Verbeet
2025-09-17 12:56:28 +02:00
Approved-by: Henri Verbeet (@hverbeet) Merge-Request: https://gitlab.winehq.org/wine/vkd3d/-/merge_requests/1688
@@ -2049,6 +2049,61 @@ static enum vkd3d_result vsir_program_lower_instructions(struct vsir_program *pr
|
||||
return VKD3D_OK;
|
||||
}
|
||||
|
||||
/* 1.0-1.3 pixel shaders allow writing t# registers, at which point they
|
||||
* effectively behave like normal r# temps. Convert them to r# registers.
|
||||
* t# registers which are read before being written contain TEXCOORD varyings,
|
||||
* just as in 1.4 and 2.x, and will later be lowered to v# registers.
|
||||
*
|
||||
* Registers which are partially written are rejected by the native validator,
|
||||
* but with a "read of uninitialized component" message that suggests that once
|
||||
* any component of a t# register is written, none of the components contain
|
||||
* texcoord data. */
|
||||
static enum vkd3d_result vsir_program_lower_texture_writes(struct vsir_program *program,
|
||||
struct vsir_transformation_context *ctx)
|
||||
{
|
||||
struct vsir_program_iterator it = vsir_program_iterator(&program->instructions);
|
||||
struct vkd3d_shader_instruction *ins;
|
||||
unsigned int texture_temp_idx = ~0u;
|
||||
uint32_t texture_written_mask = 0;
|
||||
|
||||
/* We run before I/O normalization. */
|
||||
VKD3D_ASSERT(program->normalisation_level < VSIR_NORMALISED_SM6);
|
||||
|
||||
for (ins = vsir_program_iterator_head(&it); ins; ins = vsir_program_iterator_next(&it))
|
||||
{
|
||||
for (unsigned int i = 0; i < ins->src_count; ++i)
|
||||
{
|
||||
struct vkd3d_shader_src_param *src = &ins->src[i];
|
||||
|
||||
if (src->reg.type == VKD3DSPR_TEXTURE && bitmap_is_set(&texture_written_mask, src->reg.idx[0].offset))
|
||||
{
|
||||
src->reg.type = VKD3DSPR_TEMP;
|
||||
src->reg.idx[0].offset += texture_temp_idx;
|
||||
}
|
||||
}
|
||||
|
||||
for (unsigned int i = 0; i < ins->dst_count; ++i)
|
||||
{
|
||||
struct vkd3d_shader_dst_param *dst = &ins->dst[i];
|
||||
|
||||
if (dst->reg.type == VKD3DSPR_TEXTURE)
|
||||
{
|
||||
bitmap_set(&texture_written_mask, dst->reg.idx[0].offset);
|
||||
if (texture_temp_idx == ~0u)
|
||||
{
|
||||
texture_temp_idx = program->temp_count;
|
||||
/* These versions have 4 texture registers. */
|
||||
program->temp_count += 4;
|
||||
}
|
||||
dst->reg.type = VKD3DSPR_TEMP;
|
||||
dst->reg.idx[0].offset += texture_temp_idx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return VKD3D_OK;
|
||||
}
|
||||
|
||||
/* Ensure that the program closes with a ret. sm1 programs do not, by default.
|
||||
* Many of our IR passes rely on this in order to insert instructions at the
|
||||
* end of execution. */
|
||||
@@ -12569,8 +12624,14 @@ enum vkd3d_result vsir_program_lower_d3dbc(struct vsir_program *program, uint64_
|
||||
|
||||
vsir_transformation_context_init(&ctx, program, config_flags, compile_info, message_context);
|
||||
vsir_transform(&ctx, vsir_program_lower_d3dbc_instructions);
|
||||
|
||||
if (program->shader_version.major == 1 && program->shader_version.type == VKD3D_SHADER_TYPE_PIXEL)
|
||||
{
|
||||
if (program->shader_version.minor < 4)
|
||||
vsir_transform(&ctx, vsir_program_lower_texture_writes);
|
||||
|
||||
vsir_transform(&ctx, vsir_program_normalise_ps1_output);
|
||||
}
|
||||
|
||||
if (TRACE_ON())
|
||||
vsir_program_trace(program);
|
||||
|
||||
Reference in New Issue
Block a user