nir_intrinsic_set_base(load, offset / 4);
switch (offset) {
- case BRW_IMAGE_PARAM_SURFACE_IDX_OFFSET:
- load->num_components = 1;
- break;
case BRW_IMAGE_PARAM_OFFSET_OFFSET:
case BRW_IMAGE_PARAM_SWIZZLING_OFFSET:
load->num_components = 2;
nir_ssa_def *cmp = nir_ilt(b, coord, size);
unsigned coord_comps = glsl_get_sampler_coordinate_components(deref->type);
- nir_ssa_def *in_bounds = nir_imm_int(b, NIR_TRUE);
+ nir_ssa_def *in_bounds = nir_imm_true(b);
for (unsigned i = 0; i < coord_comps; i++)
in_bounds = nir_iand(b, in_bounds, nir_channel(b, cmp, i));
break;
case ISL_SFLOAT:
- if (image.bits[0] == 16) {
- nir_ssa_def *f16comps[4];
- for (unsigned i = 0; i < image.chans; i++) {
- f16comps[i] = nir_pack_half_2x16_split(b, nir_channel(b, color, i),
- nir_imm_float(b, 0));
- }
- color = nir_vec(b, f16comps, image.chans);
- }
+ if (image.bits[0] == 16)
+ color = nir_format_float_to_half(b, color);
break;
case ISL_UINT:
- if (image.bits[0] < 32) {
- nir_const_value max;
- for (unsigned i = 0; i < image.chans; i++) {
- assert(image.bits[i] < 32);
- max.u32[i] = (1u << image.bits[i]) - 1;
- }
- color = nir_umin(b, color, nir_build_imm(b, image.chans, 32, max));
- }
+ color = nir_format_clamp_uint(b, color, image.bits);
break;
case ISL_SINT:
- if (image.bits[0] < 32) {
- nir_const_value min, max;
- for (unsigned i = 0; i < image.chans; i++) {
- assert(image.bits[i] < 32);
- max.i32[i] = (1 << (image.bits[i] - 1)) - 1;
- min.i32[i] = -(1 << (image.bits[i] - 1));
- }
- color = nir_imin(b, color, nir_build_imm(b, image.chans, 32, max));
- color = nir_imax(b, color, nir_build_imm(b, image.chans, 32, min));
- }
+ color = nir_format_clamp_sint(b, color, image.bits);
break;
default:
/* For write-only surfaces, we trust that the hardware can just do the
* conversion for us.
*/
- if (var->data.image.write_only)
+ if (var->data.image.access & ACCESS_NON_READABLE)
return false;
const enum isl_format image_fmt =
nir_intrinsic_instr *intrin)
{
nir_deref_instr *deref = nir_src_as_deref(intrin->src[0]);
+ nir_variable *var = nir_deref_instr_get_variable(deref);
+
+ /* For write-only images, we have an actual image surface so we fall back
+ * and let the back-end emit a TXS for this.
+ */
+ if (var->data.image.access & ACCESS_NON_READABLE)
+ return false;
+
+ /* If we have a matching typed format, then we have an actual image surface
+ * so we fall back and let the back-end emit a TXS for this.
+ */
+ const enum isl_format image_fmt =
+ isl_format_for_gl_format(var->data.image.format);
+ if (isl_has_matching_typed_storage_image_format(devinfo, image_fmt))
+ return false;
b->cursor = nir_instr_remove(&intrin->instr);
}
}
- nir_metadata_preserve(function->impl, nir_metadata_block_index |
- nir_metadata_dominance);
+ if (progress)
+ nir_metadata_preserve(function->impl, nir_metadata_none);
}
return progress;
}
+
+void
+brw_nir_rewrite_image_intrinsic(nir_intrinsic_instr *intrin,
+ nir_ssa_def *index)
+{
+ nir_deref_instr *deref = nir_src_as_deref(intrin->src[0]);
+ nir_variable *var = nir_deref_instr_get_variable(deref);
+
+ switch (intrin->intrinsic) {
+#define CASE(op) \
+ case nir_intrinsic_image_deref_##op: \
+ intrin->intrinsic = nir_intrinsic_image_##op; \
+ break;
+ CASE(load)
+ CASE(store)
+ CASE(atomic_add)
+ CASE(atomic_min)
+ CASE(atomic_max)
+ CASE(atomic_and)
+ CASE(atomic_or)
+ CASE(atomic_xor)
+ CASE(atomic_exchange)
+ CASE(atomic_comp_swap)
+ CASE(atomic_fadd)
+ CASE(size)
+ CASE(samples)
+ CASE(load_raw_intel)
+ CASE(store_raw_intel)
+#undef CASE
+ default:
+ unreachable("Unhanded image intrinsic");
+ }
+
+ nir_intrinsic_set_image_dim(intrin, glsl_get_sampler_dim(deref->type));
+ nir_intrinsic_set_image_array(intrin, glsl_sampler_type_is_array(deref->type));
+ nir_intrinsic_set_access(intrin, var->data.image.access);
+ nir_intrinsic_set_format(intrin, var->data.image.format);
+
+ nir_instr_rewrite_src(&intrin->instr, &intrin->src[0],
+ nir_src_for_ssa(index));
+}