nir: Move intel's half-float image store lowering to to nir_format.h.
[mesa.git] / src / intel / compiler / brw_nir_lower_image_load_store.c
index 4494dccccd2801acfc3deb2faa25069f247966d8..2abebceb2d1a37bf2a487a7a081c274f1b4be617 100644 (file)
@@ -91,9 +91,6 @@ _load_image_param(nir_builder *b, nir_deref_instr *deref, unsigned offset)
    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;
@@ -126,7 +123,7 @@ image_coord_is_in_bounds(nir_builder *b, nir_deref_instr *deref,
    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));
 
@@ -547,38 +544,16 @@ convert_color_for_store(nir_builder *b, const struct gen_device_info *devinfo,
       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:
@@ -617,7 +592,7 @@ lower_image_store_instr(nir_builder *b,
    /* 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 =
@@ -725,6 +700,21 @@ lower_image_size_instr(nir_builder *b,
                        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);
 
@@ -805,9 +795,50 @@ brw_nir_lower_image_load_store(nir_shader *shader,
          }
       }
 
-      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));
+}