util: Merge util_format_read_4* functions.
[mesa.git] / src / gallium / drivers / softpipe / sp_image.c
index 3488fa831858cd0cda769e1dde2855e1a15007ab..b0240c952652c9142c36b68200ea3713a98c1da6 100644 (file)
@@ -25,7 +25,7 @@
 #include "sp_image.h"
 #include "sp_texture.h"
 
-#include "util/u_format.h"
+#include "util/format/u_format.h"
 
 /*
  * Get the offset into the base image
@@ -39,7 +39,7 @@ get_image_offset(const struct softpipe_resource *spr,
    int base_layer = 0;
 
    if (spr->base.target == PIPE_BUFFER)
-      return iview->u.buf.first_element * util_format_get_blocksize(format);
+      return iview->u.buf.offset;
 
    if (spr->base.target == PIPE_TEXTURE_1D_ARRAY ||
        spr->base.target == PIPE_TEXTURE_2D_ARRAY ||
@@ -153,7 +153,7 @@ get_dimensions(const struct pipe_image_view *iview,
                unsigned *depth)
 {
    if (tgsi_tex_instr == TGSI_TEXTURE_BUFFER) {
-      *width = iview->u.buf.last_element - iview->u.buf.first_element + 1;
+      *width = iview->u.buf.size / util_format_get_blocksize(pformat);
       *height = 1;
       *depth = 1;
       /*
@@ -170,7 +170,7 @@ get_dimensions(const struct pipe_image_view *iview,
       *width = u_minify(spr->base.width0, level);
       *height = u_minify(spr->base.height0, level);
 
-      if (spr->base.target == TGSI_TEXTURE_3D)
+      if (spr->base.target == PIPE_TEXTURE_3D)
          *depth = u_minify(spr->base.depth0, level);
       else
          *depth = spr->base.array_size;
@@ -217,7 +217,7 @@ sp_tgsi_load(const struct tgsi_image *image,
    char *data_ptr;
    unsigned offset = 0;
 
-   if (params->unit > PIPE_MAX_SHADER_IMAGES)
+   if (params->unit >= PIPE_MAX_SHADER_IMAGES)
       goto fail_write_all_zero;
    iview = &sp_img->sp_iview[params->unit];
    spr = (struct softpipe_resource *)iview->resource;
@@ -262,32 +262,13 @@ sp_tgsi_load(const struct tgsi_image *image,
       offset = get_image_offset(spr, iview, params->format, r_coord);
       data_ptr = (char *)spr->data + offset;
 
-      if (util_format_is_pure_sint(params->format)) {
-         int32_t sdata[4];
-
-         util_format_read_4i(params->format,
-                             sdata, 0,
-                             data_ptr, stride,
-                             s_coord, t_coord, 1, 1);
-         for (c = 0; c < 4; c++)
-            ((int32_t *)rgba[c])[j] = sdata[c];
-      } else if (util_format_is_pure_uint(params->format)) {
-         uint32_t sdata[4];
-         util_format_read_4ui(params->format,
-                             sdata, 0,
-                             data_ptr, stride,
-                             s_coord, t_coord, 1, 1);
-         for (c = 0; c < 4; c++)
-            ((uint32_t *)rgba[c])[j] = sdata[c];
-      } else {
-         float sdata[4];
-         util_format_read_4f(params->format,
-                             sdata, 0,
-                             data_ptr, stride,
-                             s_coord, t_coord, 1, 1);
-         for (c = 0; c < 4; c++)
-            rgba[c][j] = sdata[c];
-      }
+      uint32_t sdata[4];
+      util_format_read_4(params->format,
+                         sdata, 0,
+                         data_ptr, stride,
+                         s_coord, t_coord, 1, 1);
+      for (c = 0; c < 4; c++)
+         ((uint32_t *)rgba[c])[j] = sdata[c];
    }
    return;
 fail_write_all_zero:
@@ -320,7 +301,7 @@ sp_tgsi_store(const struct tgsi_image *image,
    unsigned offset = 0;
    unsigned pformat = params->format;
 
-   if (params->unit > PIPE_MAX_SHADER_IMAGES)
+   if (params->unit >= PIPE_MAX_SHADER_IMAGES)
       return;
    iview = &sp_img->sp_iview[params->unit];
    spr = (struct softpipe_resource *)iview->resource;
@@ -352,25 +333,11 @@ sp_tgsi_store(const struct tgsi_image *image,
       offset = get_image_offset(spr, iview, pformat, r_coord);
       data_ptr = (char *)spr->data + offset;
 
-      if (util_format_is_pure_sint(pformat)) {
-         int32_t sdata[4];
-         for (c = 0; c < 4; c++)
-            sdata[c] = ((int32_t *)rgba[c])[j];
-         util_format_write_4i(pformat, sdata, 0, data_ptr, stride,
-                              s_coord, t_coord, 1, 1);
-      } else if (util_format_is_pure_uint(pformat)) {
-         uint32_t sdata[4];
-         for (c = 0; c < 4; c++)
-            sdata[c] = ((uint32_t *)rgba[c])[j];
-         util_format_write_4ui(pformat, sdata, 0, data_ptr, stride,
-                               s_coord, t_coord, 1, 1);
-      } else {
-         float sdata[4];
-         for (c = 0; c < 4; c++)
-            sdata[c] = rgba[c][j];
-         util_format_write_4f(pformat, sdata, 0, data_ptr, stride,
-                              s_coord, t_coord, 1, 1);
-      }
+      uint32_t sdata[4];
+      for (c = 0; c < 4; c++)
+         sdata[c] = ((uint32_t *)rgba[c])[j];
+      util_format_write_4(pformat, sdata, 0, data_ptr, stride,
+                          s_coord, t_coord, 1, 1);
    }
 }
 
@@ -384,7 +351,7 @@ handle_op_uint(const struct pipe_image_view *iview,
                char *data_ptr,
                uint qi,
                unsigned stride,
-               unsigned opcode,
+               enum tgsi_opcode opcode,
                int s,
                int t,
                float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE],
@@ -394,10 +361,10 @@ handle_op_uint(const struct pipe_image_view *iview,
    int nc = util_format_get_nr_components(params->format);
    unsigned sdata[4];
 
-   util_format_read_4ui(params->format,
-                        sdata, 0,
-                        data_ptr, stride,
-                        s, t, 1, 1);
+   util_format_read_4(params->format,
+                      sdata, 0,
+                      data_ptr, stride,
+                      s, t, 1, 1);
 
    if (just_read) {
       for (c = 0; c < nc; c++) {
@@ -487,8 +454,8 @@ handle_op_uint(const struct pipe_image_view *iview,
       assert(!"Unexpected TGSI opcode in sp_tgsi_op");
       break;
    }
-   util_format_write_4ui(params->format, sdata, 0, data_ptr, stride,
-                         s, t, 1, 1);
+   util_format_write_4(params->format, sdata, 0, data_ptr, stride,
+                       s, t, 1, 1);
 }
 
 /*
@@ -501,7 +468,7 @@ handle_op_int(const struct pipe_image_view *iview,
               char *data_ptr,
               uint qi,
               unsigned stride,
-              unsigned opcode,
+              enum tgsi_opcode opcode,
               int s,
               int t,
               float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE],
@@ -510,10 +477,10 @@ handle_op_int(const struct pipe_image_view *iview,
    uint c;
    int nc = util_format_get_nr_components(params->format);
    int sdata[4];
-   util_format_read_4i(params->format,
-                       sdata, 0,
-                       data_ptr, stride,
-                       s, t, 1, 1);
+   util_format_read_4(params->format,
+                      sdata, 0,
+                      data_ptr, stride,
+                      s, t, 1, 1);
 
    if (just_read) {
       for (c = 0; c < nc; c++) {
@@ -603,8 +570,44 @@ handle_op_int(const struct pipe_image_view *iview,
       assert(!"Unexpected TGSI opcode in sp_tgsi_op");
       break;
    }
-   util_format_write_4i(params->format, sdata, 0, data_ptr, stride,
-                        s, t, 1, 1);
+   util_format_write_4(params->format, sdata, 0, data_ptr, stride,
+                       s, t, 1, 1);
+}
+
+/* GLES OES_shader_image_atomic.txt allows XCHG on R32F */
+static void
+handle_op_r32f_xchg(const struct pipe_image_view *iview,
+                    const struct tgsi_image_params *params,
+                    bool just_read,
+                    char *data_ptr,
+                    uint qi,
+                    unsigned stride,
+                    enum tgsi_opcode opcode,
+                    int s,
+                    int t,
+                    float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE])
+{
+   float sdata[4];
+   uint c;
+   int nc = 1;
+   util_format_read_4(params->format,
+                      sdata, 0,
+                      data_ptr, stride,
+                      s, t, 1, 1);
+   if (just_read) {
+      for (c = 0; c < nc; c++) {
+         ((int32_t *)rgba[c])[qi] = sdata[c];
+      }
+      return;
+   }
+
+   for (c = 0; c < nc; c++) {
+      int temp = sdata[c];
+      sdata[c] = ((float *)rgba[c])[qi];
+      ((float *)rgba[c])[qi] = temp;
+   }
+   util_format_write_4(params->format, sdata, 0, data_ptr, stride,
+                       s, t, 1, 1);
 }
 
 /*
@@ -613,7 +616,7 @@ handle_op_int(const struct pipe_image_view *iview,
 static void
 sp_tgsi_op(const struct tgsi_image *image,
            const struct tgsi_image_params *params,
-           unsigned opcode,
+           enum tgsi_opcode opcode,
            const int s[TGSI_QUAD_SIZE],
            const int t[TGSI_QUAD_SIZE],
            const int r[TGSI_QUAD_SIZE],
@@ -630,7 +633,7 @@ sp_tgsi_op(const struct tgsi_image *image,
    unsigned offset;
    char *data_ptr;
 
-   if (params->unit > PIPE_MAX_SHADER_IMAGES)
+   if (params->unit >= PIPE_MAX_SHADER_IMAGES)
       return;
    iview = &sp_img->sp_iview[params->unit];
    spr = (struct softpipe_resource *)iview->resource;
@@ -682,6 +685,10 @@ sp_tgsi_op(const struct tgsi_image *image,
       else if (util_format_is_pure_sint(params->format))
          handle_op_int(iview, params, just_read, data_ptr, j, stride,
                        opcode, s_coord, t_coord, rgba, rgba2);
+      else if (params->format == PIPE_FORMAT_R32_FLOAT &&
+               opcode == TGSI_OPCODE_ATOMXCHG)
+         handle_op_r32f_xchg(iview, params, just_read, data_ptr, j, stride,
+                             opcode, s_coord, t_coord, rgba);
       else
          assert(0);
    }
@@ -704,7 +711,7 @@ sp_tgsi_get_dims(const struct tgsi_image *image,
    struct softpipe_resource *spr;
    int level;
 
-   if (params->unit > PIPE_MAX_SHADER_IMAGES)
+   if (params->unit >= PIPE_MAX_SHADER_IMAGES)
       return;
    iview = &sp_img->sp_iview[params->unit];
    spr = (struct softpipe_resource *)iview->resource;
@@ -712,7 +719,7 @@ sp_tgsi_get_dims(const struct tgsi_image *image,
       return;
 
    if (params->tgsi_tex_instr == TGSI_TEXTURE_BUFFER) {
-      dims[0] = iview->u.buf.last_element - iview->u.buf.first_element + 1;
+      dims[0] = iview->u.buf.size / util_format_get_blocksize(iview->format);
       dims[1] = dims[2] = dims[3] = 0;
       return;
    }