nir: add nir_tex_instr::can_speculate

Set to true everywhere except:
- spirv_to_nir used by Vulkan
- bindless handles in GLSL
- some internal shaders and driver-specific code

Acked-by: Job Noorman <job@noorman.info>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/36099>
This commit is contained in:
Marek Olšák 2025-04-01 16:07:18 -04:00 committed by Marge Bot
parent b4afe848a1
commit 688a639117
32 changed files with 109 additions and 37 deletions

View file

@ -428,6 +428,7 @@ static bool lower_image_opcodes(nir_builder *b, nir_instr *instr, void *data)
new_tex->is_array = tex->is_array; new_tex->is_array = tex->is_array;
new_tex->texture_index = tex->texture_index; new_tex->texture_index = tex->texture_index;
new_tex->sampler_index = tex->sampler_index; new_tex->sampler_index = tex->sampler_index;
new_tex->can_speculate = tex->can_speculate;
new_tex->dest_type = nir_type_int32; new_tex->dest_type = nir_type_int32;
new_tex->src[0].src = nir_src_for_ssa(tex->src[i].src.ssa); new_tex->src[0].src = nir_src_for_ssa(tex->src[i].src.ssa);
new_tex->src[0].src_type = tex->src[i].src_type; new_tex->src[0].src_type = tex->src[i].src_type;
@ -447,6 +448,7 @@ static bool lower_image_opcodes(nir_builder *b, nir_instr *instr, void *data)
new_tex->is_array = tex->is_array; new_tex->is_array = tex->is_array;
new_tex->texture_index = tex->texture_index; new_tex->texture_index = tex->texture_index;
new_tex->sampler_index = tex->sampler_index; new_tex->sampler_index = tex->sampler_index;
new_tex->can_speculate = tex->can_speculate;
new_tex->dest_type = nir_type_int32; new_tex->dest_type = nir_type_int32;
new_tex->src[0].src = nir_src_for_ssa(tex->src[i].src.ssa); new_tex->src[0].src = nir_src_for_ssa(tex->src[i].src.ssa);
new_tex->src[0].src_type = tex->src[i].src_type; new_tex->src[0].src_type = tex->src[i].src_type;

View file

@ -322,6 +322,7 @@ static bool lower_resinfo(nir_builder *b, nir_instr *instr, void *data)
new_tex->is_array = tex->is_array; new_tex->is_array = tex->is_array;
new_tex->texture_index = tex->texture_index; new_tex->texture_index = tex->texture_index;
new_tex->sampler_index = tex->sampler_index; new_tex->sampler_index = tex->sampler_index;
new_tex->can_speculate = tex->can_speculate;
new_tex->dest_type = nir_type_int32; new_tex->dest_type = nir_type_int32;
new_tex->src[0].src = nir_src_for_ssa(tex->src[i].src.ssa); new_tex->src[0].src = nir_src_for_ssa(tex->src[i].src.ssa);
new_tex->src[0].src_type = tex->src[i].src_type; new_tex->src[0].src_type = tex->src[i].src_type;

View file

@ -2931,14 +2931,22 @@ agx_mem_vectorize_cb(unsigned align_mul, unsigned align_offset,
} }
static bool static bool
set_speculate(nir_builder *b, nir_intrinsic_instr *intr, UNUSED void *_) set_speculate(nir_builder *b, nir_instr *instr, UNUSED void *_)
{ {
if (!nir_intrinsic_has_access(intr)) if (instr->type == nir_instr_type_intrinsic &&
return false; nir_intrinsic_has_access(nir_instr_as_intrinsic(instr))) {
nir_intrinsic_instr *intr = nir_instr_as_intrinsic(instr);
nir_intrinsic_set_access(intr,
ACCESS_CAN_SPECULATE | nir_intrinsic_access(intr));
return true;
}
nir_intrinsic_set_access(intr, if (instr->type == nir_instr_type_tex) {
ACCESS_CAN_SPECULATE | nir_intrinsic_access(intr)); nir_instr_as_tex(instr)->can_speculate = true;
return true; return true;
}
return false;
} }
static bool static bool
@ -3067,7 +3075,7 @@ agx_optimize_nir(nir_shader *nir, bool soft_fault, uint16_t *preamble_size,
* peephole select and form preambles more aggressively. * peephole select and form preambles more aggressively.
*/ */
if (soft_fault) { if (soft_fault) {
NIR_PASS(_, nir, nir_shader_intrinsics_pass, set_speculate, NIR_PASS(_, nir, nir_shader_instructions_pass, set_speculate,
nir_metadata_control_flow, NULL); nir_metadata_control_flow, NULL);
} }

View file

@ -404,7 +404,8 @@ txs_for_image(nir_builder *b, nir_intrinsic_instr *intr,
nir_def *res = nir_def *res =
nir_build_tex(b, op, .texture_handle = intr->src[0].ssa, .lod = lod, nir_build_tex(b, op, .texture_handle = intr->src[0].ssa, .lod = lod,
.dim = dim, .is_array = nir_intrinsic_image_array(intr)); .dim = dim, .is_array = nir_intrinsic_image_array(intr),
.can_speculate = nir_instr_can_speculate(&intr->instr));
/* Cube images are implemented as 2D arrays, so we need to divide here. */ /* Cube images are implemented as 2D arrays, so we need to divide here. */
if (dim == GLSL_SAMPLER_DIM_CUBE && res->num_components > 2 && if (dim == GLSL_SAMPLER_DIM_CUBE && res->num_components > 2 &&

View file

@ -206,6 +206,7 @@ gl_nir_inline_functions(nir_shader *shader)
&deref->def, instr); &deref->def, instr);
replace_tex_src(&intr->src[1], nir_tex_src_sampler_deref, replace_tex_src(&intr->src[1], nir_tex_src_sampler_deref,
&deref->def, instr); &deref->def, instr);
intr->can_speculate = true;
} }
nir_instr_remove(&intrin->instr); nir_instr_remove(&intrin->instr);
} }

View file

@ -816,6 +816,7 @@ nir_tex_instr_create(nir_shader *shader, unsigned num_srcs)
instr->texture_index = 0; instr->texture_index = 0;
instr->sampler_index = 0; instr->sampler_index = 0;
memcpy(instr->tg4_offsets, default_tg4_offsets, sizeof(instr->tg4_offsets)); memcpy(instr->tg4_offsets, default_tg4_offsets, sizeof(instr->tg4_offsets));
instr->can_speculate = false;
return instr; return instr;
} }
@ -2745,7 +2746,7 @@ nir_instr_can_speculate(nir_instr *instr)
return true; return true;
case nir_instr_type_tex: case nir_instr_type_tex:
return false; return nir_instr_as_tex(instr)->can_speculate;
case nir_instr_type_intrinsic: case nir_instr_type_intrinsic:
intr = nir_instr_as_intrinsic(instr); intr = nir_instr_as_intrinsic(instr);

View file

@ -2474,6 +2474,11 @@ typedef struct nir_tex_instr {
/** True if the offset is not dynamically uniform */ /** True if the offset is not dynamically uniform */
bool offset_non_uniform; bool offset_non_uniform;
/** True whether this returns the same result anywhere in the shader and
* doesn't cause page faults.
*/
bool can_speculate;
/** The texture index /** The texture index
* *
* If this texture instruction has a nir_tex_src_texture_offset source, * If this texture instruction has a nir_tex_src_texture_offset source,

View file

@ -284,6 +284,7 @@ nir_build_tex_struct(nir_builder *build, nir_texop op, struct nir_tex_builder f)
tex->backend_flags = f.backend_flags; tex->backend_flags = f.backend_flags;
tex->texture_index = f.texture_index; tex->texture_index = f.texture_index;
tex->sampler_index = f.sampler_index; tex->sampler_index = f.sampler_index;
tex->can_speculate = f.can_speculate;
switch (op) { switch (op) {
case nir_texop_txs: case nir_texop_txs:

View file

@ -2189,6 +2189,7 @@ struct nir_tex_builder {
enum glsl_sampler_dim dim; enum glsl_sampler_dim dim;
nir_alu_type dest_type; nir_alu_type dest_type;
bool is_array; bool is_array;
bool can_speculate;
uint32_t backend_flags; uint32_t backend_flags;
}; };

View file

@ -319,6 +319,7 @@ nir_build_texture_query(nir_builder *b, nir_tex_instr *tex, nir_texop texop,
query->is_new_style_shadow = tex->is_new_style_shadow; query->is_new_style_shadow = tex->is_new_style_shadow;
query->texture_index = tex->texture_index; query->texture_index = tex->texture_index;
query->sampler_index = tex->sampler_index; query->sampler_index = tex->sampler_index;
query->can_speculate = tex->can_speculate;
query->dest_type = dest_type; query->dest_type = dest_type;
if (include_coord) { if (include_coord) {

View file

@ -414,6 +414,7 @@ clone_tex(clone_state *state, const nir_tex_instr *tex)
ntex->texture_index = tex->texture_index; ntex->texture_index = tex->texture_index;
ntex->sampler_index = tex->sampler_index; ntex->sampler_index = tex->sampler_index;
ntex->can_speculate = tex->can_speculate;
ntex->texture_non_uniform = tex->texture_non_uniform; ntex->texture_non_uniform = tex->texture_non_uniform;
ntex->sampler_non_uniform = tex->sampler_non_uniform; ntex->sampler_non_uniform = tex->sampler_non_uniform;

View file

@ -78,7 +78,8 @@ nir_lower_bitmap(nir_shader *shader, const nir_lower_bitmap_options *options)
nir_deref_instr *tex_deref = nir_build_deref_var(b, tex_var); nir_deref_instr *tex_deref = nir_build_deref_var(b, tex_var);
nir_def *tex = nir_tex(b, texcoord, .texture_deref = tex_deref, nir_def *tex = nir_tex(b, texcoord, .texture_deref = tex_deref,
.sampler_deref = tex_deref); .sampler_deref = tex_deref,
.can_speculate = true);
/* kill if tex != 0.0.. take .x or .w channel according to format: */ /* kill if tex != 0.0.. take .x or .w channel according to format: */
nir_def *channel = nir_channel(b, tex, options->swizzle_xxxx ? 0 : 3); nir_def *channel = nir_channel(b, tex, options->swizzle_xxxx ? 0 : 3);

View file

@ -102,7 +102,7 @@ lower_color(nir_builder *b, lower_drawpixels_state *state, nir_intrinsic_instr *
* TEX def, texcoord, drawpix_sampler, 2D * TEX def, texcoord, drawpix_sampler, 2D
*/ */
def = nir_tex(b, nir_trim_vector(b, texcoord, 2), .texture_deref = tex_deref, def = nir_tex(b, nir_trim_vector(b, texcoord, 2), .texture_deref = tex_deref,
.sampler_deref = tex_deref); .sampler_deref = tex_deref, .can_speculate = true);
/* Apply the scale and bias. */ /* Apply the scale and bias. */
if (state->options->scale_and_bias) { if (state->options->scale_and_bias) {
@ -132,6 +132,7 @@ lower_color(nir_builder *b, lower_drawpixels_state *state, nir_intrinsic_instr *
tex->coord_components = 2; tex->coord_components = 2;
tex->sampler_index = state->options->pixelmap_sampler; tex->sampler_index = state->options->pixelmap_sampler;
tex->texture_index = state->options->pixelmap_sampler; tex->texture_index = state->options->pixelmap_sampler;
tex->can_speculate = true;
tex->dest_type = nir_type_float32; tex->dest_type = nir_type_float32;
tex->src[0] = nir_tex_src_for_ssa(nir_tex_src_texture_deref, tex->src[0] = nir_tex_src_for_ssa(nir_tex_src_texture_deref,
&pixelmap_deref->def); &pixelmap_deref->def);
@ -150,6 +151,7 @@ lower_color(nir_builder *b, lower_drawpixels_state *state, nir_intrinsic_instr *
tex->sampler_dim = GLSL_SAMPLER_DIM_2D; tex->sampler_dim = GLSL_SAMPLER_DIM_2D;
tex->coord_components = 2; tex->coord_components = 2;
tex->sampler_index = state->options->pixelmap_sampler; tex->sampler_index = state->options->pixelmap_sampler;
tex->can_speculate = true;
tex->dest_type = nir_type_float32; tex->dest_type = nir_type_float32;
tex->src[0] = nir_tex_src_for_ssa(nir_tex_src_coord, tex->src[0] = nir_tex_src_for_ssa(nir_tex_src_coord,
nir_channels(b, def, 0xc)); nir_channels(b, def, 0xc));

View file

@ -66,6 +66,7 @@ nir_lower_fb_read_instr(nir_builder *b, nir_intrinsic_instr *intr,
tex->coord_components = 3; tex->coord_components = 3;
tex->dest_type = nir_type_float32; tex->dest_type = nir_type_float32;
tex->is_array = true; tex->is_array = true;
tex->can_speculate = true;
tex->src[0] = nir_tex_src_for_ssa(nir_tex_src_coord, tex->src[0] = nir_tex_src_for_ssa(nir_tex_src_coord,
nir_vec3(b, nir_channel(b, fragcoord, 0), nir_channel(b, fragcoord, 1), layer)); nir_vec3(b, nir_channel(b, fragcoord, 0), nir_channel(b, fragcoord, 1), layer));
tex->src[1] = nir_tex_src_for_ssa(nir_tex_src_ms_index, sampid); tex->src[1] = nir_tex_src_for_ssa(nir_tex_src_ms_index, sampid);

View file

@ -140,6 +140,7 @@ try_lower_input_load(nir_builder *b, nir_intrinsic_instr *load,
tex->texture_index = 0; tex->texture_index = 0;
tex->sampler_index = 0; tex->sampler_index = 0;
tex->can_speculate = true;
tex->src[0] = nir_tex_src_for_ssa(nir_tex_src_texture_deref, tex->src[0] = nir_tex_src_for_ssa(nir_tex_src_texture_deref,
&deref->def); &deref->def);

View file

@ -136,6 +136,7 @@ lower_readonly_image_instr_intrinsic(nir_builder *b, nir_intrinsic_instr *intrin
tex->sampler_dim = glsl_get_sampler_dim(deref->type); tex->sampler_dim = glsl_get_sampler_dim(deref->type);
tex->is_array = glsl_sampler_type_is_array(deref->type); tex->is_array = glsl_sampler_type_is_array(deref->type);
tex->is_shadow = false; tex->is_shadow = false;
tex->can_speculate = nir_instr_can_speculate(&intrin->instr);
unsigned coord_components = unsigned coord_components =
glsl_get_sampler_dim_coordinate_components(tex->sampler_dim); glsl_get_sampler_dim_coordinate_components(tex->sampler_dim);

View file

@ -377,6 +377,7 @@ sample_plane(nir_builder *b, nir_tex_instr *tex, int plane,
plane_tex->texture_index = tex->texture_index; plane_tex->texture_index = tex->texture_index;
plane_tex->sampler_index = tex->sampler_index; plane_tex->sampler_index = tex->sampler_index;
plane_tex->can_speculate = tex->can_speculate;
nir_def_init(&plane_tex->instr, &plane_tex->def, 4, nir_def_init(&plane_tex->instr, &plane_tex->def, 4,
tex->def.bit_size); tex->def.bit_size);
@ -940,6 +941,7 @@ lower_tex_to_txd(nir_builder *b, nir_tex_instr *tex)
txd->is_array = tex->is_array; txd->is_array = tex->is_array;
txd->is_shadow = tex->is_shadow; txd->is_shadow = tex->is_shadow;
txd->is_new_style_shadow = tex->is_new_style_shadow; txd->is_new_style_shadow = tex->is_new_style_shadow;
txd->can_speculate = tex->can_speculate;
/* reuse existing srcs */ /* reuse existing srcs */
for (unsigned i = 0; i < tex->num_srcs; i++) { for (unsigned i = 0; i < tex->num_srcs; i++) {
@ -981,6 +983,7 @@ lower_txb_to_txl(nir_builder *b, nir_tex_instr *tex)
txl->is_array = tex->is_array; txl->is_array = tex->is_array;
txl->is_shadow = tex->is_shadow; txl->is_shadow = tex->is_shadow;
txl->is_new_style_shadow = tex->is_new_style_shadow; txl->is_new_style_shadow = tex->is_new_style_shadow;
txl->can_speculate = tex->can_speculate;
/* reuse all but bias src */ /* reuse all but bias src */
for (int i = 0; i < tex->num_srcs; i++) { for (int i = 0; i < tex->num_srcs; i++) {
@ -1275,6 +1278,7 @@ lower_tg4_offsets(nir_builder *b, nir_tex_instr *tex)
tex_copy->texture_index = tex->texture_index; tex_copy->texture_index = tex->texture_index;
tex_copy->sampler_index = tex->sampler_index; tex_copy->sampler_index = tex->sampler_index;
tex_copy->backend_flags = tex->backend_flags; tex_copy->backend_flags = tex->backend_flags;
tex_copy->can_speculate = tex->can_speculate;
for (unsigned j = 0; j < tex->num_srcs; ++j) { for (unsigned j = 0; j < tex->num_srcs; ++j) {
tex_copy->src[j].src = nir_src_for_ssa(tex->src[j].src.ssa); tex_copy->src[j].src = nir_src_for_ssa(tex->src[j].src.ssa);
@ -1407,6 +1411,7 @@ nir_lower_ms_txf_to_fragment_fetch(nir_builder *b, nir_tex_instr *tex)
fmask_fetch->texture_non_uniform = tex->texture_non_uniform; fmask_fetch->texture_non_uniform = tex->texture_non_uniform;
fmask_fetch->offset_non_uniform = tex->offset_non_uniform; fmask_fetch->offset_non_uniform = tex->offset_non_uniform;
fmask_fetch->dest_type = nir_type_uint32; fmask_fetch->dest_type = nir_type_uint32;
fmask_fetch->can_speculate = tex->can_speculate;
nir_def_init(&fmask_fetch->instr, &fmask_fetch->def, 1, 32); nir_def_init(&fmask_fetch->instr, &fmask_fetch->def, 1, 32);
fmask_fetch->num_srcs = 0; fmask_fetch->num_srcs = 0;

View file

@ -1366,7 +1366,8 @@ union packed_tex_data {
unsigned offset_non_uniform : 1; unsigned offset_non_uniform : 1;
unsigned array_is_lowered_cube : 1; unsigned array_is_lowered_cube : 1;
unsigned is_gather_implicit_lod : 1; unsigned is_gather_implicit_lod : 1;
unsigned unused : 4; /* Mark unused for valgrind. */ unsigned can_speculate : 1;
unsigned unused : 3; /* Mark unused for valgrind. */
} u; } u;
}; };
@ -1406,6 +1407,7 @@ write_tex(write_ctx *ctx, const nir_tex_instr *tex)
.u.offset_non_uniform = tex->offset_non_uniform, .u.offset_non_uniform = tex->offset_non_uniform,
.u.array_is_lowered_cube = tex->array_is_lowered_cube, .u.array_is_lowered_cube = tex->array_is_lowered_cube,
.u.is_gather_implicit_lod = tex->is_gather_implicit_lod, .u.is_gather_implicit_lod = tex->is_gather_implicit_lod,
.u.can_speculate = tex->can_speculate,
}; };
blob_write_uint32(ctx->blob, packed.u32); blob_write_uint32(ctx->blob, packed.u32);
@ -1446,6 +1448,7 @@ read_tex(read_ctx *ctx, union packed_instr header)
tex->offset_non_uniform = packed.u.offset_non_uniform; tex->offset_non_uniform = packed.u.offset_non_uniform;
tex->array_is_lowered_cube = packed.u.array_is_lowered_cube; tex->array_is_lowered_cube = packed.u.array_is_lowered_cube;
tex->is_gather_implicit_lod = packed.u.is_gather_implicit_lod; tex->is_gather_implicit_lod = packed.u.is_gather_implicit_lod;
tex->can_speculate = packed.u.can_speculate;
for (unsigned i = 0; i < tex->num_srcs; i++) { for (unsigned i = 0; i < tex->num_srcs; i++) {
union packed_src src = read_src(ctx, &tex->src[i].src); union packed_src src = read_src(ctx, &tex->src[i].src);

View file

@ -3749,6 +3749,8 @@ vtn_handle_texture(struct vtn_builder *b, SpvOp opcode,
instr->is_new_style_shadow = instr->is_new_style_shadow =
is_shadow && glsl_get_components(ret_type->type) == 1; is_shadow && glsl_get_components(ret_type->type) == 1;
instr->component = gather_component; instr->component = gather_component;
/* spirv_to_nir doesn't support OpenGL bindless textures. */
instr->can_speculate = b->options->environment == NIR_SPIRV_OPENGL;
/* If SpvCapabilityImageGatherBiasLodAMD is enabled, texture gather without an explicit LOD /* If SpvCapabilityImageGatherBiasLodAMD is enabled, texture gather without an explicit LOD
* has an implicit one (instead of using level 0). * has an implicit one (instead of using level 0).

View file

@ -269,8 +269,18 @@ avoid_instr(const nir_instr *instr, const void *data)
} }
static bool static bool
set_speculate(nir_builder *b, nir_intrinsic_instr *intr, UNUSED void *_) set_speculate(nir_builder *b, nir_instr *instr, UNUSED void *_)
{ {
if (instr->type == nir_instr_type_tex) {
nir_instr_as_tex(instr)->can_speculate = true;
return true;
}
if (instr->type != nir_instr_type_intrinsic)
return false;
nir_intrinsic_instr *intr = nir_instr_as_intrinsic(instr);
switch (intr->intrinsic) { switch (intr->intrinsic) {
/* These instructions go through bounds-checked hardware descriptors so /* These instructions go through bounds-checked hardware descriptors so
* should be safe to speculate. * should be safe to speculate.
@ -313,8 +323,8 @@ ir3_nir_opt_preamble(nir_shader *nir, struct ir3_shader_variant *v)
if (max_size == 0) if (max_size == 0)
return false; return false;
bool progress = nir_shader_intrinsics_pass(nir, set_speculate, bool progress = nir_shader_instructions_pass(nir, set_speculate,
nir_metadata_control_flow, NULL); nir_metadata_control_flow, NULL);
nir_opt_preamble_options options = { nir_opt_preamble_options options = {
.drawid_uniform = true, .drawid_uniform = true,

View file

@ -77,6 +77,7 @@ nir_lower_pstipple_block(nir_block *block,
tex->dest_type = nir_type_float32; tex->dest_type = nir_type_float32;
tex->texture_index = state->stip_tex->data.binding; tex->texture_index = state->stip_tex->data.binding;
tex->sampler_index = state->stip_tex->data.binding; tex->sampler_index = state->stip_tex->data.binding;
tex->can_speculate = true;
tex->src[0] = nir_tex_src_for_ssa(nir_tex_src_coord, texcoord); tex->src[0] = nir_tex_src_for_ssa(nir_tex_src_coord, texcoord);
nir_def_init(&tex->instr, &tex->def, 4, 32); nir_def_init(&tex->instr, &tex->def, 4, 32);

View file

@ -1259,6 +1259,7 @@ ttn_tex(struct ttn_compile *c, nir_def **src)
instr = nir_tex_instr_create(b->shader, num_srcs); instr = nir_tex_instr_create(b->shader, num_srcs);
instr->op = op; instr->op = op;
instr->can_speculate = true; /* No shaders come from SPIR-V or GLSL. */
get_texture_info(tgsi_inst->Texture.Texture, get_texture_info(tgsi_inst->Texture.Texture,
&instr->sampler_dim, &instr->is_shadow, &instr->is_array); &instr->sampler_dim, &instr->is_shadow, &instr->is_array);
@ -1441,12 +1442,14 @@ ttn_txq(struct ttn_compile *c, nir_def **src)
txs = nir_tex_instr_create(b->shader, 2); txs = nir_tex_instr_create(b->shader, 2);
txs->op = nir_texop_txs; txs->op = nir_texop_txs;
txs->dest_type = nir_type_uint32; txs->dest_type = nir_type_uint32;
txs->can_speculate = true;
get_texture_info(tgsi_inst->Texture.Texture, get_texture_info(tgsi_inst->Texture.Texture,
&txs->sampler_dim, &txs->is_shadow, &txs->is_array); &txs->sampler_dim, &txs->is_shadow, &txs->is_array);
qlv = nir_tex_instr_create(b->shader, 1); qlv = nir_tex_instr_create(b->shader, 1);
qlv->op = nir_texop_query_levels; qlv->op = nir_texop_query_levels;
qlv->dest_type = nir_type_uint32; qlv->dest_type = nir_type_uint32;
qlv->can_speculate = true;
get_texture_info(tgsi_inst->Texture.Texture, get_texture_info(tgsi_inst->Texture.Texture,
&qlv->sampler_dim, &qlv->is_shadow, &qlv->is_array); &qlv->sampler_dim, &qlv->is_shadow, &qlv->is_array);

View file

@ -158,6 +158,7 @@ create_array_tex_from_cube_tex(nir_builder *b, nir_tex_instr *tex, nir_def *coor
array_tex->sampler_index = tex->sampler_index; array_tex->sampler_index = tex->sampler_index;
array_tex->dest_type = tex->dest_type; array_tex->dest_type = tex->dest_type;
array_tex->coord_components = 3; array_tex->coord_components = 3;
array_tex->can_speculate = tex->can_speculate;
nir_src coord_src = nir_src_for_ssa(coord); nir_src coord_src = nir_src_for_ssa(coord);
unsigned s = 0; unsigned s = 0;
@ -415,6 +416,7 @@ lower_tex_to_txl(nir_builder *b, nir_tex_instr *tex)
txl->is_shadow = tex->is_shadow; txl->is_shadow = tex->is_shadow;
txl->is_sparse = tex->is_sparse; txl->is_sparse = tex->is_sparse;
txl->is_new_style_shadow = tex->is_new_style_shadow; txl->is_new_style_shadow = tex->is_new_style_shadow;
txl->can_speculate = tex->can_speculate;
unsigned s = 0; unsigned s = 0;
for (int i = 0; i < tex->num_srcs; i++) { for (int i = 0; i < tex->num_srcs; i++) {

View file

@ -771,6 +771,7 @@ load_texture(struct texenv_fragment_program *p, GLuint unit)
tex->dest_type = nir_type_float32; tex->dest_type = nir_type_float32;
tex->texture_index = unit; tex->texture_index = unit;
tex->sampler_index = unit; tex->sampler_index = unit;
tex->can_speculate = true;
tex->sampler_dim = tex->sampler_dim =
_mesa_texture_index_to_sampler_dim(texTarget, _mesa_texture_index_to_sampler_dim(texTarget,

View file

@ -422,6 +422,7 @@ ptn_tex(struct ptn_compile *c, nir_def **src,
instr->op = op; instr->op = op;
instr->dest_type = nir_type_float32; instr->dest_type = nir_type_float32;
instr->is_shadow = prog_inst->TexShadow; instr->is_shadow = prog_inst->TexShadow;
instr->can_speculate = true;
bool is_array; bool is_array;
instr->sampler_dim = _mesa_texture_index_to_sampler_dim(prog_inst->TexSrcTarget, &is_array); instr->sampler_dim = _mesa_texture_index_to_sampler_dim(prog_inst->TexSrcTarget, &is_array);

View file

@ -355,6 +355,7 @@ compile_setupinst(struct st_translate *t,
tex->dest_type = nir_type_float32; tex->dest_type = nir_type_float32;
tex->coord_components = tex->coord_components =
glsl_get_sampler_dim_coordinate_components(tex->sampler_dim); glsl_get_sampler_dim_coordinate_components(tex->sampler_dim);
tex->can_speculate = true;
tex->src[0] = nir_tex_src_for_ssa(nir_tex_src_texture_deref, tex->src[0] = nir_tex_src_for_ssa(nir_tex_src_texture_deref,
&tex_deref->def); &tex_deref->def);

View file

@ -129,6 +129,7 @@ sample_via_nir(nir_builder *b, const char *name, int sampler,
tex->op = nir_texop_tex; tex->op = nir_texop_tex;
tex->sampler_dim = GLSL_SAMPLER_DIM_2D; tex->sampler_dim = GLSL_SAMPLER_DIM_2D;
tex->coord_components = 2; tex->coord_components = 2;
tex->can_speculate = true;
tex->dest_type = alu_type; tex->dest_type = alu_type;
tex->src[0] = nir_tex_src_for_ssa(nir_tex_src_texture_deref, tex->src[0] = nir_tex_src_for_ssa(nir_tex_src_texture_deref,
&deref->def); &deref->def);

View file

@ -513,6 +513,7 @@ create_fs(struct st_context *st, bool download,
tex->coord_components = tex->coord_components =
glsl_get_sampler_coordinate_components(tex_var->type); glsl_get_sampler_coordinate_components(tex_var->type);
tex->is_array = target >= PIPE_TEXTURE_1D_ARRAY; tex->is_array = target >= PIPE_TEXTURE_1D_ARRAY;
tex->can_speculate = true;
tex->dest_type = nir_get_nir_type_for_glsl_base_type(glsl_get_sampler_result_type(tex_var->type)); tex->dest_type = nir_get_nir_type_for_glsl_base_type(glsl_get_sampler_result_type(tex_var->type));
tex->src[0].src_type = nir_tex_src_texture_deref; tex->src[0].src_type = nir_tex_src_texture_deref;

View file

@ -683,6 +683,7 @@ create_conversion_shader(struct st_context *st, enum pipe_texture_target target,
txf->coord_components = coord_components; txf->coord_components = coord_components;
txf->texture_index = 0; txf->texture_index = 0;
txf->sampler_index = 0; txf->sampler_index = 0;
txf->can_speculate = true;
txf->src[0] = nir_tex_src_for_ssa(nir_tex_src_coord, coord); txf->src[0] = nir_tex_src_for_ssa(nir_tex_src_coord, coord);
txf->src[1] = nir_tex_src_for_ssa(nir_tex_src_lod, nir_imm_int(&b, 0)); txf->src[1] = nir_tex_src_for_ssa(nir_tex_src_lod, nir_imm_int(&b, 0));
txf->src[2].src_type = nir_tex_src_texture_deref; txf->src[2].src_type = nir_tex_src_texture_deref;

View file

@ -178,6 +178,7 @@ create_array_tex_from_cube_tex(nir_builder *b, nir_tex_instr *tex, nir_def *coor
array_tex->sampler_index = tex->sampler_index; array_tex->sampler_index = tex->sampler_index;
array_tex->dest_type = tex->dest_type; array_tex->dest_type = tex->dest_type;
array_tex->coord_components = 3; array_tex->coord_components = 3;
array_tex->can_speculate = tex->can_speculate;
nir_src coord_src = nir_src_for_ssa(coord); nir_src coord_src = nir_src_for_ssa(coord);
for (unsigned i = 0; i < tex->num_srcs; i++) { for (unsigned i = 0; i < tex->num_srcs; i++) {

View file

@ -78,6 +78,7 @@ dx_get_texture_lod(nir_builder *b, nir_tex_instr *tex)
tql->is_new_style_shadow = tex->is_new_style_shadow; tql->is_new_style_shadow = tex->is_new_style_shadow;
tql->texture_index = tex->texture_index; tql->texture_index = tex->texture_index;
tql->sampler_index = tex->sampler_index; tql->sampler_index = tex->sampler_index;
tql->can_speculate = tex->can_speculate;
tql->dest_type = nir_type_float32; tql->dest_type = nir_type_float32;
/* The coordinate needs special handling because we might have /* The coordinate needs special handling because we might have
@ -282,6 +283,7 @@ create_txf_from_tex(nir_builder *b, nir_tex_instr *tex)
txf->is_new_style_shadow = tex->is_new_style_shadow; txf->is_new_style_shadow = tex->is_new_style_shadow;
txf->texture_index = tex->texture_index; txf->texture_index = tex->texture_index;
txf->sampler_index = tex->sampler_index; txf->sampler_index = tex->sampler_index;
txf->can_speculate = tex->can_speculate;
txf->dest_type = tex->dest_type; txf->dest_type = tex->dest_type;
unsigned idx = 0; unsigned idx = 0;

View file

@ -43,7 +43,7 @@ tex_handle_as_cbuf(nir_def *tex_h, uint32_t *cbuf_out)
} }
static nir_def * static nir_def *
build_txq(nir_builder *b, nir_texop op, nir_def *img_h, build_txq(nir_builder *b, nir_texop op, bool can_speculate, nir_def *img_h,
nir_def *lod_idx, const struct nak_compiler *nak) nir_def *lod_idx, const struct nak_compiler *nak)
{ {
uint32_t texture_index = 0; uint32_t texture_index = 0;
@ -63,6 +63,7 @@ build_txq(nir_builder *b, nir_texop op, nir_def *img_h,
txq->sampler_dim = GLSL_SAMPLER_DIM_2D, txq->sampler_dim = GLSL_SAMPLER_DIM_2D,
txq->is_array = false, txq->is_array = false,
txq->dest_type = nir_type_int32; txq->dest_type = nir_type_int32;
txq->can_speculate = can_speculate;
nir_def *src[2] = { NULL, }; nir_def *src[2] = { NULL, };
unsigned src_comps = 0; unsigned src_comps = 0;
@ -94,23 +95,23 @@ build_txq(nir_builder *b, nir_texop op, nir_def *img_h,
} }
static nir_def * static nir_def *
build_txq_levels(nir_builder *b, nir_def *img_h, build_txq_levels(nir_builder *b, bool can_speculate, nir_def *img_h,
const struct nak_compiler *nak) const struct nak_compiler *nak)
{ {
nir_def *res = build_txq(b, nir_texop_hdr_dim_nv, img_h, nir_def *res = build_txq(b, nir_texop_hdr_dim_nv, can_speculate, img_h,
nir_imm_int(b, 0), nak); nir_imm_int(b, 0), nak);
return nir_channel(b, res, 3); return nir_channel(b, res, 3);
} }
static nir_def * static nir_def *
build_img_is_null(nir_builder *b, nir_def *img_h, build_img_is_null(nir_builder *b, bool can_speculate, nir_def *img_h,
const struct nak_compiler *nak) const struct nak_compiler *nak)
{ {
/* Prior to Volta, we don't have real NULL descriptors but we can figure /* Prior to Volta, we don't have real NULL descriptors but we can figure
* out if it's null based on the number of levels returned by * out if it's null based on the number of levels returned by
* txq.dimension. * txq.dimension.
*/ */
return nir_ieq_imm(b, build_txq_levels(b, img_h, nak), 0); return nir_ieq_imm(b, build_txq_levels(b, can_speculate, img_h, nak), 0);
} }
static enum glsl_sampler_dim static enum glsl_sampler_dim
@ -413,7 +414,7 @@ lower_tex(nir_builder *b, nir_tex_instr *tex, const struct nak_compiler *nak)
nir_def *res = nir_vec2(b, abs, rel); nir_def *res = nir_vec2(b, abs, rel);
if (!has_null_descriptors(nak)) { if (!has_null_descriptors(nak)) {
res = nir_bcsel(b, build_img_is_null(b, tex_h, nak), res = nir_bcsel(b, build_img_is_null(b, tex->can_speculate, tex_h, nak),
nir_imm_int(b, 0), res); nir_imm_int(b, 0), res);
} }
@ -424,21 +425,22 @@ lower_tex(nir_builder *b, nir_tex_instr *tex, const struct nak_compiler *nak)
} }
static nir_def * static nir_def *
build_txq_samples_raw(nir_builder *b, nir_def *img_h, build_txq_samples_raw(nir_builder *b, bool can_speculate, nir_def *img_h,
const struct nak_compiler *nak) const struct nak_compiler *nak)
{ {
nir_def *res = build_txq(b, nir_texop_tex_type_nv, img_h, NULL, nak); nir_def *res = build_txq(b, nir_texop_tex_type_nv, can_speculate, img_h,
NULL, nak);
return nir_channel(b, res, 2); return nir_channel(b, res, 2);
} }
static nir_def * static nir_def *
build_txq_samples(nir_builder *b, nir_def *img_h, build_txq_samples(nir_builder *b, bool can_speculate, nir_def *img_h,
const struct nak_compiler *nak) const struct nak_compiler *nak)
{ {
nir_def *res = build_txq_samples_raw(b, img_h, nak); nir_def *res = build_txq_samples_raw(b, can_speculate, img_h, nak);
if (!has_null_descriptors(nak)) { if (!has_null_descriptors(nak)) {
res = nir_bcsel(b, build_img_is_null(b, img_h, nak), res = nir_bcsel(b, build_img_is_null(b, can_speculate, img_h, nak),
nir_imm_int(b, 0), res); nir_imm_int(b, 0), res);
} }
@ -446,18 +448,19 @@ build_txq_samples(nir_builder *b, nir_def *img_h,
} }
static nir_def * static nir_def *
build_txq_size(nir_builder *b, unsigned num_components, build_txq_size(nir_builder *b, unsigned num_components, bool can_speculate,
nir_def *img_h, nir_def *lod, nir_def *img_h, nir_def *lod,
const struct nak_compiler *nak) const struct nak_compiler *nak)
{ {
if (lod == NULL) if (lod == NULL)
lod = nir_imm_int(b, 0); lod = nir_imm_int(b, 0);
nir_def *res = build_txq(b, nir_texop_hdr_dim_nv, img_h, lod, nak); nir_def *res = build_txq(b, nir_texop_hdr_dim_nv, can_speculate, img_h,
lod, nak);
res = nir_trim_vector(b, res, num_components); res = nir_trim_vector(b, res, num_components);
if (!has_null_descriptors(nak)) { if (!has_null_descriptors(nak)) {
res = nir_bcsel(b, build_img_is_null(b, img_h, nak), res = nir_bcsel(b, build_img_is_null(b, can_speculate, img_h, nak),
nir_imm_int(b, 0), res); nir_imm_int(b, 0), res);
} }
@ -485,13 +488,14 @@ lower_txq(nir_builder *b, nir_tex_instr *tex, const struct nak_compiler *nak)
nir_def *res; nir_def *res;
switch (tex->op) { switch (tex->op) {
case nir_texop_txs: case nir_texop_txs:
res = build_txq_size(b, tex->def.num_components, tex_h, lod, nak); res = build_txq_size(b, tex->can_speculate, tex->def.num_components,
tex_h, lod, nak);
break; break;
case nir_texop_query_levels: case nir_texop_query_levels:
res = build_txq_levels(b, tex_h, nak); res = build_txq_levels(b, tex->can_speculate, tex_h, nak);
break; break;
case nir_texop_texture_samples: case nir_texop_texture_samples:
res = build_txq_samples(b, tex_h, nak); res = build_txq_samples(b, tex->can_speculate, tex_h, nak);
break; break;
default: default:
unreachable("Invalid texture query op"); unreachable("Invalid texture query op");
@ -696,6 +700,7 @@ lower_msaa_image_access(nir_builder *b, nir_intrinsic_instr *intrin,
b->cursor = nir_before_instr(&intrin->instr); b->cursor = nir_before_instr(&intrin->instr);
bool can_speculate = nir_instr_can_speculate(&intrin->instr);
nir_def *img_h = intrin->src[0].ssa; nir_def *img_h = intrin->src[0].ssa;
nir_def *x = nir_channel(b, intrin->src[1].ssa, 0); nir_def *x = nir_channel(b, intrin->src[1].ssa, 0);
nir_def *y = nir_channel(b, intrin->src[1].ssa, 1); nir_def *y = nir_channel(b, intrin->src[1].ssa, 1);
@ -703,7 +708,7 @@ lower_msaa_image_access(nir_builder *b, nir_intrinsic_instr *intrin,
nir_def *w = nir_channel(b, intrin->src[1].ssa, 3); nir_def *w = nir_channel(b, intrin->src[1].ssa, 3);
nir_def *s = intrin->src[2].ssa; nir_def *s = intrin->src[2].ssa;
nir_def *samples = build_txq_samples_raw(b, img_h, nak); nir_def *samples = build_txq_samples_raw(b, can_speculate, img_h, nak);
nir_def *px_size_sa_log2 = build_px_size_sa_log2(b, samples); nir_def *px_size_sa_log2 = build_px_size_sa_log2(b, samples);
nir_def *px_w_log2 = nir_channel(b, px_size_sa_log2, 0); nir_def *px_w_log2 = nir_channel(b, px_size_sa_log2, 0);
@ -714,7 +719,8 @@ lower_msaa_image_access(nir_builder *b, nir_intrinsic_instr *intrin,
* txq.sampler_pos gives us the sample coordinates as a signed 4.12 fixed * txq.sampler_pos gives us the sample coordinates as a signed 4.12 fixed
* point with x in the bottom 16 bits and y in the top 16 bits. * point with x in the bottom 16 bits and y in the top 16 bits.
*/ */
nir_def *spos_sf = build_txq(b, nir_texop_sample_pos_nv, img_h, s, nak); nir_def *spos_sf = build_txq(b, nir_texop_sample_pos_nv, can_speculate,
img_h, s, nak);
spos_sf = nir_trim_vector(b, spos_sf, 2); spos_sf = nir_trim_vector(b, spos_sf, 2);
/* Fortunately, the samples are laid out in the supersampled image the same /* Fortunately, the samples are laid out in the supersampled image the same
@ -755,10 +761,12 @@ lower_image_txq(nir_builder *b, nir_intrinsic_instr *intrin,
nir_def *img_h = intrin->src[0].ssa; nir_def *img_h = intrin->src[0].ssa;
bool can_speculate = nir_instr_can_speculate(&intrin->instr);
nir_def *res; nir_def *res;
switch (intrin->intrinsic) { switch (intrin->intrinsic) {
case nir_intrinsic_bindless_image_size: case nir_intrinsic_bindless_image_size:
res = build_txq_size(b, intrin->def.num_components, img_h, res = build_txq_size(b, intrin->def.num_components, can_speculate, img_h,
intrin->src[1].ssa /* lod */, nak); intrin->src[1].ssa /* lod */, nak);
if (nir_intrinsic_image_dim(intrin) == GLSL_SAMPLER_DIM_MS) { if (nir_intrinsic_image_dim(intrin) == GLSL_SAMPLER_DIM_MS) {
@ -768,13 +776,13 @@ lower_image_txq(nir_builder *b, nir_intrinsic_instr *intrin,
* they're given. This means we need to divide back out the pixel * they're given. This means we need to divide back out the pixel
* size in order to get the size in pixels. * size in order to get the size in pixels.
*/ */
nir_def *samples = build_txq_samples_raw(b, img_h, nak); nir_def *samples = build_txq_samples_raw(b, can_speculate, img_h, nak);
nir_def *px_size_sa_log2 = build_px_size_sa_log2(b, samples); nir_def *px_size_sa_log2 = build_px_size_sa_log2(b, samples);
res = nir_ushr(b, res, px_size_sa_log2); res = nir_ushr(b, res, px_size_sa_log2);
} }
break; break;
case nir_intrinsic_bindless_image_samples: case nir_intrinsic_bindless_image_samples:
res = build_txq_samples(b, img_h, nak); res = build_txq_samples(b, can_speculate, img_h, nak);
break; break;
default: default:
unreachable("Invalid image query op"); unreachable("Invalid image query op");