nir: Add option to preserve double immediates in tgsi shader.

The nir to tgsi translator flattens all constants in the nir shader into uint32
immediates. In the svga driver, the vgpu10 shader translator then packs all
these immediates into a constant buffer, and also optimizes it to prevent
repetitions by only emitting a 32-bit constant once.
This can cause problems with double sized constants, since either the lower or
higher 32-bits of different 64-bit constant can be identical, and in the constant
buffer that repeating 32-bit value will be emitted only once, so a 64-bit
constant gets split into two non-contiguous 32-bit values.
When this 64-bit constant is then invoked by a double instruction live ddiv or
dmul, the source register can now have invalid swizzles like .xz or .xw since
its 32-bit components are not contiguous.
We have seen this happen in the piglit test -
spec@arb_gpu_shader_fp64@execution@glsl-fs-loop-unroll-mul-fp64
which emits invalid swizzle values for double instructions.

To fix this, introduce a new option in nir to tgsi shader translator that
preserves uint64 constants. When a 64-bit immediate is translated into svga
shader code, its 32-bit components are contiguous and aligned in the constant
buffer, so accessing them only emits valid swizzles .xy and .zw.

Other drivers using the nir to tgsi shader translater should not see any change
in the tgsi shader emitted unless they too explicitly invoke the
keep_double_immediates option like svga.

Signed-off-by: Maaz Mombasawala <maaz.mombasawala@broadcom.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/33749>
This commit is contained in:
Maaz Mombasawala 2025-01-27 18:50:44 -08:00 committed by Marge Bot
parent 882ad3fa3e
commit 3da0774be1
3 changed files with 19 additions and 6 deletions

View file

@ -1176,21 +1176,28 @@ ntt_get_load_const_src(struct ntt_compile *c, nir_load_const_instr *instr)
return ureg_DECL_immediate(c->ureg, values, num_components);
} else {
uint32_t values[4];
if (instr->def.bit_size == 32) {
uint32_t values[4];
for (int i = 0; i < num_components; i++)
values[i] = instr->value[i].u32;
return ureg_DECL_immediate_uint(c->ureg, values, num_components);
} else if (c->options->keep_double_immediates && instr->def.bit_size == 64) {
uint64_t values[2];
assert(num_components <= 2);
for (int i = 0; i < num_components; i++)
values[i] = instr->value[i].u64;
num_components *= 2;
return ureg_DECL_immediate_uint64(c->ureg, values, num_components);
} else {
uint32_t values[4];
assert(num_components <= 2);
for (int i = 0; i < num_components; i++) {
values[i * 2 + 0] = instr->value[i].u64 & 0xffffffff;
values[i * 2 + 1] = instr->value[i].u64 >> 32;
}
num_components *= 2;
return ureg_DECL_immediate_uint(c->ureg, values, num_components);
}
return ureg_DECL_immediate_uint(c->ureg, values, num_components);
}
}

View file

@ -38,6 +38,7 @@ struct nir_to_tgsi_options {
bool unoptimized_ra;
bool lower_ssbo_bindings;
bool non_compute_membar_needs_all_modes;
bool keep_double_immediates;
uint32_t ubo_vec4_max;
};

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2008-2024 Broadcom. All Rights Reserved.
* Copyright (c) 2008-2025 Broadcom. All Rights Reserved.
* The term Broadcom refers to Broadcom Inc.
* and/or its subsidiaries.
* SPDX-License-Identifier: MIT
@ -929,10 +929,15 @@ svga_create_shader(struct pipe_context *pipe,
shader->stage = stage;
if (templ->type == PIPE_SHADER_IR_NIR) {
const struct nir_to_tgsi_options ntt_options = {
.keep_double_immediates = true,
};
/* nir_to_tgsi requires lowered images */
NIR_PASS_V(nir, gl_nir_lower_images, false);
shader->tokens = nir_to_tgsi_options(nir, pipe->screen, &ntt_options);
} else {
shader->tokens = pipe_shader_state_to_tgsi_tokens(pipe->screen, templ);
}
shader->tokens = pipe_shader_state_to_tgsi_tokens(pipe->screen, templ);
shader->type = PIPE_SHADER_IR_TGSI;
/* Collect basic info of the shader */