/*
 * Copyright 2016 Red Hat.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * on the rights to use, copy, modify, merge, publish, distribute, sub
 * license, and/or sell copies of the Software, and to permit persons to whom
 * the Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice (including the next
 * paragraph) shall be included in all copies or substantial portions of the
 * Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
 * USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

#include "sp_context.h"
#include "sp_image.h"
#include "sp_texture.h"

#include "util/u_format.h"

/*
 * Get the offset into the base image
 * first element for a buffer or layer/level for texture.
 */
static uint32_t
get_image_offset(const struct softpipe_resource *spr,
                 const struct pipe_image_view *iview,
                 enum pipe_format format, unsigned r_coord)
{
   int base_layer = 0;

   if (spr->base.target == PIPE_BUFFER)
      return iview->u.buf.first_element * util_format_get_blocksize(format);

   if (spr->base.target == PIPE_TEXTURE_1D_ARRAY ||
       spr->base.target == PIPE_TEXTURE_2D_ARRAY ||
       spr->base.target == PIPE_TEXTURE_CUBE_ARRAY ||
       spr->base.target == PIPE_TEXTURE_CUBE ||
       spr->base.target == PIPE_TEXTURE_3D)
      base_layer = r_coord + iview->u.tex.first_layer;
   return softpipe_get_tex_image_offset(spr, iview->u.tex.level, base_layer);
}

/*
 * Does this texture instruction have a layer or depth parameter.
 */
static inline bool
has_layer_or_depth(unsigned tgsi_tex_instr)
{
   return (tgsi_tex_instr == TGSI_TEXTURE_3D ||
           tgsi_tex_instr == TGSI_TEXTURE_CUBE ||
           tgsi_tex_instr == TGSI_TEXTURE_1D_ARRAY ||
           tgsi_tex_instr == TGSI_TEXTURE_2D_ARRAY ||
           tgsi_tex_instr == TGSI_TEXTURE_CUBE_ARRAY ||
           tgsi_tex_instr == TGSI_TEXTURE_2D_ARRAY_MSAA);
}

/*
 * Is this texture instruction a single non-array coordinate.
 */
static inline bool
has_1coord(unsigned tgsi_tex_instr)
{
   return (tgsi_tex_instr == TGSI_TEXTURE_BUFFER ||
           tgsi_tex_instr == TGSI_TEXTURE_1D ||
           tgsi_tex_instr == TGSI_TEXTURE_1D_ARRAY);
}

/*
 * check the bounds vs w/h/d
 */
static inline bool
bounds_check(int width, int height, int depth,
             int s, int t, int r)
{
   if (s < 0 || s >= width)
      return false;
   if (t < 0 || t >= height)
      return false;
   if (r < 0 || r >= depth)
      return false;
   return true;
}

/*
 * Checks if the texture target compatible with the image resource
 * pipe target.
 */
static inline bool
has_compat_target(unsigned pipe_target, unsigned tgsi_target)
{
   switch (pipe_target) {
   case PIPE_TEXTURE_1D:
      if (tgsi_target == TGSI_TEXTURE_1D)
         return true;
      break;
   case PIPE_TEXTURE_2D:
      if (tgsi_target == TGSI_TEXTURE_2D)
         return true;
      break;
   case PIPE_TEXTURE_RECT:
      if (tgsi_target == TGSI_TEXTURE_RECT)
         return true;
      break;
   case PIPE_TEXTURE_3D:
      if (tgsi_target == TGSI_TEXTURE_3D ||
          tgsi_target == TGSI_TEXTURE_2D)
         return true;
      break;
   case PIPE_TEXTURE_CUBE:
      if (tgsi_target == TGSI_TEXTURE_CUBE ||
          tgsi_target == TGSI_TEXTURE_2D)
         return true;
      break;
   case PIPE_TEXTURE_1D_ARRAY:
      if (tgsi_target == TGSI_TEXTURE_1D ||
          tgsi_target == TGSI_TEXTURE_1D_ARRAY)
         return true;
      break;
   case PIPE_TEXTURE_2D_ARRAY:
      if (tgsi_target == TGSI_TEXTURE_2D ||
          tgsi_target == TGSI_TEXTURE_2D_ARRAY)
         return true;
      break;
   case PIPE_TEXTURE_CUBE_ARRAY:
      if (tgsi_target == TGSI_TEXTURE_CUBE ||
          tgsi_target == TGSI_TEXTURE_CUBE_ARRAY ||
          tgsi_target == TGSI_TEXTURE_2D)
         return true;
      break;
   case PIPE_BUFFER:
      return (tgsi_target == TGSI_TEXTURE_BUFFER);
   }
   return false;
}

static bool
get_dimensions(const struct pipe_image_view *iview,
               const struct softpipe_resource *spr,
               unsigned tgsi_tex_instr,
               enum pipe_format pformat,
               unsigned *width,
               unsigned *height,
               unsigned *depth)
{
   if (tgsi_tex_instr == TGSI_TEXTURE_BUFFER) {
      *width = iview->u.buf.last_element - iview->u.buf.first_element + 1;
      *height = 1;
      *depth = 1;
      /*
       * Bounds check the buffer size from the view
       * and the buffer size from the underlying buffer.
       */
      if (util_format_get_stride(pformat, *width) >
          util_format_get_stride(spr->base.format, spr->base.width0))
         return false;
   } else {
      unsigned level;

      level = spr->base.target == PIPE_BUFFER ? 0 : iview->u.tex.level;
      *width = u_minify(spr->base.width0, level);
      *height = u_minify(spr->base.height0, level);

      if (spr->base.target == TGSI_TEXTURE_3D)
         *depth = u_minify(spr->base.depth0, level);
      else
         *depth = spr->base.array_size;

      /* Make sure the resource and view have compatiable formats */
      if (util_format_get_blocksize(pformat) >
          util_format_get_blocksize(spr->base.format))
         return false;
   }
   return true;
}

static void
fill_coords(const struct tgsi_image_params *params,
            unsigned index,
            const int s[TGSI_QUAD_SIZE],
            const int t[TGSI_QUAD_SIZE],
            const int r[TGSI_QUAD_SIZE],
            int *s_coord, int *t_coord, int *r_coord)
{
   *s_coord = s[index];
   *t_coord = has_1coord(params->tgsi_tex_instr) ? 0 : t[index];
   *r_coord = has_layer_or_depth(params->tgsi_tex_instr) ?
      (params->tgsi_tex_instr == TGSI_TEXTURE_1D_ARRAY ? t[index] : r[index]) : 0;
}
/*
 * Implement the image LOAD operation.
 */
static void
sp_tgsi_load(const struct tgsi_image *image,
             const struct tgsi_image_params *params,
             const int s[TGSI_QUAD_SIZE],
             const int t[TGSI_QUAD_SIZE],
             const int r[TGSI_QUAD_SIZE],
             const int sample[TGSI_QUAD_SIZE],
             float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE])
{
   struct sp_tgsi_image *sp_img = (struct sp_tgsi_image *)image;
   struct pipe_image_view *iview;
   struct softpipe_resource *spr;
   unsigned width, height, depth;
   unsigned stride;
   int c, j;
   char *data_ptr;
   unsigned offset = 0;

   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;
   if (!spr)
      goto fail_write_all_zero;

   if (!has_compat_target(spr->base.target, params->tgsi_tex_instr))
      goto fail_write_all_zero;

   if (!get_dimensions(iview, spr, params->tgsi_tex_instr,
                       params->format, &width, &height, &depth))
      return;

   stride = util_format_get_stride(params->format, width);

   for (j = 0; j < TGSI_QUAD_SIZE; j++) {
      int s_coord, t_coord, r_coord;
      bool fill_zero = false;

      if (!(params->execmask & (1 << j)))
         fill_zero = true;

      fill_coords(params, j, s, t, r, &s_coord, &t_coord, &r_coord);
      if (!bounds_check(width, height, depth,
                        s_coord, t_coord, r_coord))
         fill_zero = true;

      if (fill_zero) {
         int nc = util_format_get_nr_components(params->format);
         int ival = util_format_is_pure_integer(params->format);
         for (c = 0; c < 4; c++) {
            rgba[c][j] = 0;
            if (c == 3 && nc < 4) {
               if (ival)
                  ((int32_t *)rgba[c])[j] = 1;
               else
                  rgba[c][j] = 1.0;
            }
         }
         continue;
      }
      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];
      }
   }
   return;
fail_write_all_zero:
   for (j = 0; j < TGSI_QUAD_SIZE; j++) {
      for (c = 0; c < 4; c++)
         rgba[c][j] = 0;
   }
   return;
}

/*
 * Implement the image STORE operation.
 */
static void
sp_tgsi_store(const struct tgsi_image *image,
              const struct tgsi_image_params *params,
              const int s[TGSI_QUAD_SIZE],
              const int t[TGSI_QUAD_SIZE],
              const int r[TGSI_QUAD_SIZE],
              const int sample[TGSI_QUAD_SIZE],
              float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE])
{
   struct sp_tgsi_image *sp_img = (struct sp_tgsi_image *)image;
   struct pipe_image_view *iview;
   struct softpipe_resource *spr;
   unsigned width, height, depth;
   unsigned stride;
   char *data_ptr;
   int j, c;
   unsigned offset = 0;
   unsigned pformat = params->format;

   if (params->unit > PIPE_MAX_SHADER_IMAGES)
      return;
   iview = &sp_img->sp_iview[params->unit];
   spr = (struct softpipe_resource *)iview->resource;
   if (!spr)
      return;
   if (!has_compat_target(spr->base.target, params->tgsi_tex_instr))
      return;

   if (params->format == PIPE_FORMAT_NONE)
      pformat = spr->base.format;

   if (!get_dimensions(iview, spr, params->tgsi_tex_instr,
                       pformat, &width, &height, &depth))
      return;

   stride = util_format_get_stride(pformat, width);

   for (j = 0; j < TGSI_QUAD_SIZE; j++) {
      int s_coord, t_coord, r_coord;

      if (!(params->execmask & (1 << j)))
         continue;

      fill_coords(params, j, s, t, r, &s_coord, &t_coord, &r_coord);
      if (!bounds_check(width, height, depth,
                        s_coord, t_coord, r_coord))
         continue;

      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);
      }
   }
}

/*
 * Implement atomic operations on unsigned integers.
 */
static void
handle_op_uint(const struct pipe_image_view *iview,
               const struct tgsi_image_params *params,
               bool just_read,
               char *data_ptr,
               uint qi,
               unsigned stride,
               unsigned opcode,
               int s,
               int t,
               float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE],
               float rgba2[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE])
{
   uint c;
   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);

   if (just_read) {
      for (c = 0; c < nc; c++) {
         ((uint32_t *)rgba[c])[qi] = sdata[c];
      }
      return;
   }
   switch (opcode) {
   case TGSI_OPCODE_ATOMUADD:
      for (c = 0; c < nc; c++) {
         unsigned temp = sdata[c];
         sdata[c] += ((uint32_t *)rgba[c])[qi];
         ((uint32_t *)rgba[c])[qi] = temp;
      }
      break;
   case TGSI_OPCODE_ATOMXCHG:
      for (c = 0; c < nc; c++) {
         unsigned temp = sdata[c];
         sdata[c] = ((uint32_t *)rgba[c])[qi];
         ((uint32_t *)rgba[c])[qi] = temp;
      }
      break;
   case TGSI_OPCODE_ATOMCAS:
      for (c = 0; c < nc; c++) {
         unsigned dst_x = sdata[c];
         unsigned cmp_x = ((uint32_t *)rgba[c])[qi];
         unsigned src_x = ((uint32_t *)rgba2[c])[qi];
         unsigned temp = sdata[c];
         sdata[c] = (dst_x == cmp_x) ? src_x : dst_x;
         ((uint32_t *)rgba[c])[qi] = temp;
      }
      break;
   case TGSI_OPCODE_ATOMAND:
      for (c = 0; c < nc; c++) {
         unsigned temp = sdata[c];
         sdata[c] &= ((uint32_t *)rgba[c])[qi];
         ((uint32_t *)rgba[c])[qi] = temp;
      }
      break;
   case TGSI_OPCODE_ATOMOR:
      for (c = 0; c < nc; c++) {
         unsigned temp = sdata[c];
         sdata[c] |= ((uint32_t *)rgba[c])[qi];
         ((uint32_t *)rgba[c])[qi] = temp;
      }
      break;
   case TGSI_OPCODE_ATOMXOR:
      for (c = 0; c < nc; c++) {
         unsigned temp = sdata[c];
         sdata[c] ^= ((uint32_t *)rgba[c])[qi];
         ((uint32_t *)rgba[c])[qi] = temp;
      }
      break;
   case TGSI_OPCODE_ATOMUMIN:
      for (c = 0; c < nc; c++) {
         unsigned dst_x = sdata[c];
         unsigned src_x = ((uint32_t *)rgba[c])[qi];
         sdata[c] = MIN2(dst_x, src_x);
         ((uint32_t *)rgba[c])[qi] = dst_x;
      }
      break;
   case TGSI_OPCODE_ATOMUMAX:
      for (c = 0; c < nc; c++) {
         unsigned dst_x = sdata[c];
         unsigned src_x = ((uint32_t *)rgba[c])[qi];
         sdata[c] = MAX2(dst_x, src_x);
         ((uint32_t *)rgba[c])[qi] = dst_x;
      }
      break;
   case TGSI_OPCODE_ATOMIMIN:
      for (c = 0; c < nc; c++) {
         int dst_x = sdata[c];
         int src_x = ((uint32_t *)rgba[c])[qi];
         sdata[c] = MIN2(dst_x, src_x);
         ((uint32_t *)rgba[c])[qi] = dst_x;
      }
      break;
   case TGSI_OPCODE_ATOMIMAX:
      for (c = 0; c < nc; c++) {
         int dst_x = sdata[c];
         int src_x = ((uint32_t *)rgba[c])[qi];
         sdata[c] = MAX2(dst_x, src_x);
         ((uint32_t *)rgba[c])[qi] = dst_x;
      }
      break;
   default:
      assert(!"Unexpected TGSI opcode in sp_tgsi_op");
      break;
   }
   util_format_write_4ui(params->format, sdata, 0, data_ptr, stride,
                         s, t, 1, 1);
}

/*
 * Implement atomic operations on signed integers.
 */
static void
handle_op_int(const struct pipe_image_view *iview,
              const struct tgsi_image_params *params,
              bool just_read,
              char *data_ptr,
              uint qi,
              unsigned stride,
              unsigned opcode,
              int s,
              int t,
              float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE],
              float rgba2[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE])
{
   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);

   if (just_read) {
      for (c = 0; c < nc; c++) {
         ((int32_t *)rgba[c])[qi] = sdata[c];
      }
      return;
   }
   switch (opcode) {
   case TGSI_OPCODE_ATOMUADD:
      for (c = 0; c < nc; c++) {
         int temp = sdata[c];
         sdata[c] += ((int32_t *)rgba[c])[qi];
         ((int32_t *)rgba[c])[qi] = temp;
      }
      break;
   case TGSI_OPCODE_ATOMXCHG:
      for (c = 0; c < nc; c++) {
         int temp = sdata[c];
         sdata[c] = ((int32_t *)rgba[c])[qi];
         ((int32_t *)rgba[c])[qi] = temp;
      }
      break;
   case TGSI_OPCODE_ATOMCAS:
      for (c = 0; c < nc; c++) {
         int dst_x = sdata[c];
         int cmp_x = ((int32_t *)rgba[c])[qi];
         int src_x = ((int32_t *)rgba2[c])[qi];
         int temp = sdata[c];
         sdata[c] = (dst_x == cmp_x) ? src_x : dst_x;
         ((int32_t *)rgba[c])[qi] = temp;
      }
      break;
   case TGSI_OPCODE_ATOMAND:
      for (c = 0; c < nc; c++) {
         int temp = sdata[c];
         sdata[c] &= ((int32_t *)rgba[c])[qi];
         ((int32_t *)rgba[c])[qi] = temp;
      }
      break;
   case TGSI_OPCODE_ATOMOR:
      for (c = 0; c < nc; c++) {
         int temp = sdata[c];
         sdata[c] |= ((int32_t *)rgba[c])[qi];
         ((int32_t *)rgba[c])[qi] = temp;
      }
      break;
   case TGSI_OPCODE_ATOMXOR:
      for (c = 0; c < nc; c++) {
         int temp = sdata[c];
         sdata[c] ^= ((int32_t *)rgba[c])[qi];
         ((int32_t *)rgba[c])[qi] = temp;
      }
      break;
   case TGSI_OPCODE_ATOMUMIN:
      for (c = 0; c < nc; c++) {
         int dst_x = sdata[c];
         int src_x = ((int32_t *)rgba[c])[qi];
         sdata[c] = MIN2(dst_x, src_x);
         ((int32_t *)rgba[c])[qi] = dst_x;
      }
      break;
   case TGSI_OPCODE_ATOMUMAX:
      for (c = 0; c < nc; c++) {
         int dst_x = sdata[c];
         int src_x = ((int32_t *)rgba[c])[qi];
         sdata[c] = MAX2(dst_x, src_x);
         ((int32_t *)rgba[c])[qi] = dst_x;
      }
      break;
   case TGSI_OPCODE_ATOMIMIN:
      for (c = 0; c < nc; c++) {
         int dst_x = sdata[c];
         int src_x = ((int32_t *)rgba[c])[qi];
         sdata[c] = MIN2(dst_x, src_x);
         ((int32_t *)rgba[c])[qi] = dst_x;
      }
      break;
   case TGSI_OPCODE_ATOMIMAX:
      for (c = 0; c < nc; c++) {
         int dst_x = sdata[c];
         int src_x = ((int32_t *)rgba[c])[qi];
         sdata[c] = MAX2(dst_x, src_x);
         ((int32_t *)rgba[c])[qi] = dst_x;
      }
      break;
   default:
      assert(!"Unexpected TGSI opcode in sp_tgsi_op");
      break;
   }
   util_format_write_4i(params->format, sdata, 0, data_ptr, stride,
                        s, t, 1, 1);
}

/*
 * Implement atomic image operations.
 */
static void
sp_tgsi_op(const struct tgsi_image *image,
           const struct tgsi_image_params *params,
           unsigned opcode,
           const int s[TGSI_QUAD_SIZE],
           const int t[TGSI_QUAD_SIZE],
           const int r[TGSI_QUAD_SIZE],
           const int sample[TGSI_QUAD_SIZE],
           float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE],
           float rgba2[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE])
{
   struct sp_tgsi_image *sp_img = (struct sp_tgsi_image *)image;
   struct pipe_image_view *iview;
   struct softpipe_resource *spr;
   unsigned width, height, depth;
   unsigned stride;
   int j, c;
   unsigned offset;
   char *data_ptr;

   if (params->unit > PIPE_MAX_SHADER_IMAGES)
      return;
   iview = &sp_img->sp_iview[params->unit];
   spr = (struct softpipe_resource *)iview->resource;
   if (!spr)
      goto fail_write_all_zero;
   if (!has_compat_target(spr->base.target, params->tgsi_tex_instr))
      goto fail_write_all_zero;

   if (!get_dimensions(iview, spr, params->tgsi_tex_instr,
                       params->format, &width, &height, &depth))
      goto fail_write_all_zero;

   stride = util_format_get_stride(spr->base.format, width);

   for (j = 0; j < TGSI_QUAD_SIZE; j++) {
      int s_coord, t_coord, r_coord;
      bool just_read = false;

      fill_coords(params, j, s, t, r, &s_coord, &t_coord, &r_coord);
      if (!bounds_check(width, height, depth,
                        s_coord, t_coord, r_coord)) {
         int nc = util_format_get_nr_components(params->format);
         int ival = util_format_is_pure_integer(params->format);
         int c;
         for (c = 0; c < 4; c++) {
            rgba[c][j] = 0;
            if (c == 3 && nc < 4) {
               if (ival)
                  ((int32_t *)rgba[c])[j] = 1;
               else
                  rgba[c][j] = 1.0;
            }
         }
         continue;
      }

      /* just readback the value for atomic if execmask isn't set */
      if (!(params->execmask & (1 << j))) {
         just_read = true;
      }

      offset = get_image_offset(spr, iview, params->format, r_coord);
      data_ptr = (char *)spr->data + offset;

      /* we should see atomic operations on r32 formats */
      if (util_format_is_pure_uint(params->format))
         handle_op_uint(iview, params, just_read, data_ptr, j, stride,
                        opcode, s_coord, t_coord, rgba, rgba2);
      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
         assert(0);
   }
   return;
fail_write_all_zero:
   for (j = 0; j < TGSI_QUAD_SIZE; j++) {
      for (c = 0; c < 4; c++)
         rgba[c][j] = 0;
   }
   return;
}

static void
sp_tgsi_get_dims(const struct tgsi_image *image,
                 const struct tgsi_image_params *params,
                 int dims[4])
{
   struct sp_tgsi_image *sp_img = (struct sp_tgsi_image *)image;
   struct pipe_image_view *iview;
   struct softpipe_resource *spr;
   int level;

   if (params->unit > PIPE_MAX_SHADER_IMAGES)
      return;
   iview = &sp_img->sp_iview[params->unit];
   spr = (struct softpipe_resource *)iview->resource;
   if (!spr)
      return;

   if (params->tgsi_tex_instr == TGSI_TEXTURE_BUFFER) {
      dims[0] = iview->u.buf.last_element - iview->u.buf.first_element + 1;
      dims[1] = dims[2] = dims[3] = 0;
      return;
   }

   level = iview->u.tex.level;
   dims[0] = u_minify(spr->base.width0, level);
   switch (params->tgsi_tex_instr) {
   case TGSI_TEXTURE_1D_ARRAY:
      dims[1] = iview->u.tex.last_layer - iview->u.tex.first_layer + 1;
      /* fallthrough */
   case TGSI_TEXTURE_1D:
      return;
   case TGSI_TEXTURE_2D_ARRAY:
      dims[2] = iview->u.tex.last_layer - iview->u.tex.first_layer + 1;
      /* fallthrough */
   case TGSI_TEXTURE_2D:
   case TGSI_TEXTURE_CUBE:
   case TGSI_TEXTURE_RECT:
      dims[1] = u_minify(spr->base.height0, level);
      return;
   case TGSI_TEXTURE_3D:
      dims[1] = u_minify(spr->base.height0, level);
      dims[2] = u_minify(spr->base.depth0, level);
      return;
   case TGSI_TEXTURE_CUBE_ARRAY:
      dims[1] = u_minify(spr->base.height0, level);
      dims[2] = (iview->u.tex.last_layer - iview->u.tex.first_layer + 1) / 6;
      break;
   default:
      assert(!"unexpected texture target in sp_get_dims()");
      return;
   }
}

struct sp_tgsi_image *
sp_create_tgsi_image(void)
{
   struct sp_tgsi_image *img = CALLOC_STRUCT(sp_tgsi_image);
   if (!img)
      return NULL;

   img->base.load = sp_tgsi_load;
   img->base.store = sp_tgsi_store;
   img->base.op = sp_tgsi_op;
   img->base.get_dims = sp_tgsi_get_dims;
   return img;
};
