[Mesa-dev] [PATCH 2/3] gallium: change pipe_image_view::first_element/last_element -> offset/size

Ilia Mirkin imirkin at alum.mit.edu
Fri Aug 12 17:23:34 UTC 2016


Patches 1 and 2 are

Acked-by: Ilia Mirkin <imirkin at alum.mit.edu>

I skimmed them and your transformations all seemed right, but I'd be
lying if I said I looked at each and every line of the diff...

On Fri, Aug 12, 2016 at 12:46 PM, Marek Olšák <maraeo at gmail.com> wrote:
> From: Marek Olšák <marek.olsak at amd.com>
>
> This is required by OpenGL. Our hardware supports this.
>
> Example: Bind RGBA32F with offset = 4 bytes.
> ---
>  src/gallium/auxiliary/util/u_dump_state.c     |  4 ++--
>  src/gallium/drivers/nouveau/nvc0/nvc0_state.c |  4 ++--
>  src/gallium/drivers/nouveau/nvc0/nvc0_tex.c   | 24 +++++++-----------------
>  src/gallium/drivers/radeonsi/si_descriptors.c | 16 ++++------------
>  src/gallium/drivers/softpipe/sp_image.c       |  6 +++---
>  src/gallium/drivers/trace/tr_dump_state.c     |  4 ++--
>  src/gallium/include/pipe/p_state.h            |  4 ++--
>  src/mesa/state_tracker/st_atom_image.c        | 10 ++--------
>  src/mesa/state_tracker/st_cb_readpixels.c     |  5 +++--
>  9 files changed, 27 insertions(+), 50 deletions(-)
>
> diff --git a/src/gallium/auxiliary/util/u_dump_state.c b/src/gallium/auxiliary/util/u_dump_state.c
> index 4568dc6..6aecee1 100644
> --- a/src/gallium/auxiliary/util/u_dump_state.c
> +++ b/src/gallium/auxiliary/util/u_dump_state.c
> @@ -715,22 +715,22 @@ util_dump_image_view(FILE *stream, const struct pipe_image_view *state)
>        util_dump_null(stream);
>        return;
>     }
>
>     util_dump_struct_begin(stream, "pipe_image_view");
>
>     util_dump_member(stream, ptr, state, resource);
>     util_dump_member(stream, format, state, format);
>
>     if (state->resource->target == PIPE_BUFFER) {
> -      util_dump_member(stream, uint, state, u.buf.first_element);
> -      util_dump_member(stream, uint, state, u.buf.last_element);
> +      util_dump_member(stream, uint, state, u.buf.offset);
> +      util_dump_member(stream, uint, state, u.buf.size);
>     }
>     else {
>        util_dump_member(stream, uint, state, u.tex.first_layer);
>        util_dump_member(stream, uint, state, u.tex.last_layer);
>        util_dump_member(stream, uint, state, u.tex.level);
>     }
>
>     util_dump_struct_end(stream);
>  }
>
> diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_state.c b/src/gallium/drivers/nouveau/nvc0/nvc0_state.c
> index fcb695a..b9ac9f4 100644
> --- a/src/gallium/drivers/nouveau/nvc0/nvc0_state.c
> +++ b/src/gallium/drivers/nouveau/nvc0/nvc0_state.c
> @@ -1264,22 +1264,22 @@ nvc0_bind_images_range(struct nvc0_context *nvc0, const unsigned s,
>        for (i = start; i < end; ++i) {
>           struct pipe_image_view *img = &nvc0->images[s][i];
>           const unsigned p = i - start;
>
>           if (img->resource == pimages[p].resource &&
>               img->format == pimages[p].format &&
>               img->access == pimages[p].access) {
>              if (img->resource == NULL)
>                 continue;
>              if (img->resource->target == PIPE_BUFFER &&
> -                img->u.buf.first_element == pimages[p].u.buf.first_element &&
> -                img->u.buf.last_element == pimages[p].u.buf.last_element)
> +                img->u.buf.offset == pimages[p].u.buf.offset &&
> +                img->u.buf.size == pimages[p].u.buf.size)
>                 continue;
>              if (img->resource->target != PIPE_BUFFER &&
>                  img->u.tex.first_layer == pimages[p].u.tex.first_layer &&
>                  img->u.tex.last_layer == pimages[p].u.tex.last_layer &&
>                  img->u.tex.level == pimages[p].u.tex.level)
>                 continue;
>           }
>
>           mask |= (1 << i);
>           if (pimages[p].resource)
> diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_tex.c b/src/gallium/drivers/nouveau/nvc0/nvc0_tex.c
> index b6e0ba8..4fa2621 100644
> --- a/src/gallium/drivers/nouveau/nvc0/nvc0_tex.c
> +++ b/src/gallium/drivers/nouveau/nvc0/nvc0_tex.c
> @@ -252,25 +252,22 @@ gm107_create_texture_view_from_image(struct pipe_context *pipe,
>     if (target == PIPE_TEXTURE_CUBE || target == PIPE_TEXTURE_CUBE_ARRAY)
>        target = PIPE_TEXTURE_2D_ARRAY;
>
>     templ.format = view->format;
>     templ.swizzle_r = PIPE_SWIZZLE_X;
>     templ.swizzle_g = PIPE_SWIZZLE_Y;
>     templ.swizzle_b = PIPE_SWIZZLE_Z;
>     templ.swizzle_a = PIPE_SWIZZLE_W;
>
>     if (target == PIPE_BUFFER) {
> -      templ.u.buf.offset = view->u.buf.first_element *
> -                           util_format_get_blocksize(view->format);
> -      templ.u.buf.size = (view->u.buf.last_element -
> -                          view->u.buf.first_element + 1) *
> -                         util_format_get_blocksize(view->format);
> +      templ.u.buf.offset = view->u.buf.offset;
> +      templ.u.buf.size = view->u.buf.size;
>     } else {
>        templ.u.tex.first_layer = view->u.tex.first_layer;
>        templ.u.tex.last_layer = view->u.tex.last_layer;
>        templ.u.tex.first_level = templ.u.tex.last_level = view->u.tex.level;
>     }
>
>     flags = NV50_TEXVIEW_SCALED_COORDS;
>
>     return nvc0_create_texture_view(pipe, &res->base, &templ, flags, target);
>  }
> @@ -769,21 +766,21 @@ static const uint16_t nve4_suldp_lib_offset[PIPE_FORMAT_COUNT];
>
>  static void
>  nvc0_get_surface_dims(struct pipe_image_view *view, int *width, int *height,
>                        int *depth)
>  {
>     struct nv04_resource *res = nv04_resource(view->resource);
>     int level;
>
>     *width = *height = *depth = 1;
>     if (res->base.target == PIPE_BUFFER) {
> -      *width = view->u.buf.last_element - view->u.buf.first_element + 1;
> +      *width = view->u.buf.size / util_format_get_blocksize(view->format);
>        return;
>     }
>
>     level = view->u.tex.level;
>     *width = u_minify(view->resource->width0, level);
>     *height = u_minify(view->resource->height0, level);
>     *depth = u_minify(view->resource->depth0, level);
>
>     switch (res->base.target) {
>     case PIPE_TEXTURE_1D_ARRAY:
> @@ -800,31 +797,26 @@ nvc0_get_surface_dims(struct pipe_image_view *view, int *width, int *height,
>     default:
>        assert(!"unexpected texture target");
>        break;
>     }
>  }
>
>  void
>  nvc0_mark_image_range_valid(const struct pipe_image_view *view)
>  {
>     struct nv04_resource *res = (struct nv04_resource *)view->resource;
> -   const struct util_format_description *desc;
> -   unsigned stride;
>
>     assert(view->resource->target == PIPE_BUFFER);
>
> -   desc = util_format_description(view->format);
> -   stride = desc->block.bits / 8;
> -
>     util_range_add(&res->valid_buffer_range,
> -                  stride * (view->u.buf.first_element),
> -                  stride * (view->u.buf.last_element + 1));
> +                  view->u.buf.offset,
> +                  view->u.buf.offset + view->u.buf.size);
>  }
>
>  void
>  nve4_set_surface_info(struct nouveau_pushbuf *push,
>                        struct pipe_image_view *view,
>                        struct nvc0_context *nvc0)
>  {
>     struct nvc0_screen *screen = nvc0->screen;
>     struct nv04_resource *res;
>     uint64_t address;
> @@ -896,23 +888,21 @@ nve4_set_surface_info(struct nouveau_pushbuf *push,
>     default:
>        break;
>     }
>  #else
>     info[1] |= log2cpp << 16;
>     info[1] |=  0x4000;
>     info[1] |= (0x0f00 & nve4_su_format_aux_map[view->format]);
>  #endif
>
>     if (res->base.target == PIPE_BUFFER) {
> -      unsigned blocksize = util_format_get_blocksize(view->format);
> -
> -      address += view->u.buf.first_element * blocksize;
> +      address += view->u.buf.offset;
>
>        info[0]  = address >> 8;
>        info[2]  = width - 1;
>        info[2] |= (0xff & nve4_su_format_aux_map[view->format]) << 22;
>        info[3]  = 0;
>        info[4]  = 0;
>        info[5]  = 0;
>        info[6]  = 0;
>        info[7]  = 0;
>        info[14] = 0;
> @@ -1023,21 +1013,21 @@ nvc0_validate_suf(struct nvc0_context *nvc0, int s)
>           else
>              rt = (rt << 4) | (0x14 << 12);
>
>           /* get surface dimensions based on the target. */
>           nvc0_get_surface_dims(view, &width, &height, &depth);
>
>           address = res->address;
>           if (res->base.target == PIPE_BUFFER) {
>              unsigned blocksize = util_format_get_blocksize(view->format);
>
> -            address += view->u.buf.first_element * blocksize;
> +            address += view->u.buf.offset;
>              assert(!(address & 0xff));
>
>              if (view->access & PIPE_IMAGE_ACCESS_WRITE)
>                 nvc0_mark_image_range_valid(view);
>
>              PUSH_DATAh(push, address);
>              PUSH_DATA (push, address);
>              PUSH_DATA (push, align(width * blocksize, 0x100));
>              PUSH_DATA (push, NVC0_3D_IMAGE_HEIGHT_LINEAR | 1);
>              PUSH_DATA (push, rt);
> diff --git a/src/gallium/drivers/radeonsi/si_descriptors.c b/src/gallium/drivers/radeonsi/si_descriptors.c
> index a3e4564..0e026e9 100644
> --- a/src/gallium/drivers/radeonsi/si_descriptors.c
> +++ b/src/gallium/drivers/radeonsi/si_descriptors.c
> @@ -593,31 +593,26 @@ si_disable_shader_image(struct si_context *ctx, unsigned shader, unsigned slot)
>                 images->enabled_mask &= ~(1u << slot);
>                 descs->dirty_mask |= 1u << slot;
>                 ctx->descriptors_dirty |= 1u << si_image_descriptors_idx(shader);
>         }
>  }
>
>  static void
>  si_mark_image_range_valid(const struct pipe_image_view *view)
>  {
>         struct r600_resource *res = (struct r600_resource *)view->resource;
> -       const struct util_format_description *desc;
> -       unsigned stride;
>
>         assert(res && res->b.b.target == PIPE_BUFFER);
>
> -       desc = util_format_description(view->format);
> -       stride = desc->block.bits / 8;
> -
>         util_range_add(&res->valid_buffer_range,
> -                      stride * (view->u.buf.first_element),
> -                      stride * (view->u.buf.last_element + 1));
> +                      view->u.buf.offset,
> +                      view->u.buf.offset + view->u.buf.size);
>  }
>
>  static void si_set_shader_image(struct si_context *ctx,
>                                 unsigned shader,
>                                 unsigned slot, const struct pipe_image_view *view)
>  {
>         struct si_screen *screen = ctx->screen;
>         struct si_images_info *images = &ctx->images[shader];
>         struct si_descriptors *descs = si_image_descriptors(ctx, shader);
>         struct r600_resource *res;
> @@ -634,25 +629,22 @@ static void si_set_shader_image(struct si_context *ctx,
>
>         si_sampler_view_add_buffer(ctx, &res->b.b,
>                                    RADEON_USAGE_READWRITE, false, true);
>
>         if (res->b.b.target == PIPE_BUFFER) {
>                 if (view->access & PIPE_IMAGE_ACCESS_WRITE)
>                         si_mark_image_range_valid(view);
>
>                 si_make_buffer_descriptor(screen, res,
>                                           view->format,
> -                                         view->u.buf.first_element *
> -                                         util_format_get_blocksize(view->format),
> -                                         (view->u.buf.last_element -
> -                                          view->u.buf.first_element + 1) *
> -                                         util_format_get_blocksize(view->format),
> +                                         view->u.buf.offset,
> +                                         view->u.buf.size,
>                                           descs->list + slot * 8);
>                 images->compressed_colortex_mask &= ~(1 << slot);
>         } else {
>                 static const unsigned char swizzle[4] = { 0, 1, 2, 3 };
>                 struct r600_texture *tex = (struct r600_texture *)res;
>                 unsigned level = view->u.tex.level;
>                 unsigned width, height, depth;
>                 uint32_t *desc = descs->list + slot * 8;
>                 bool uses_dcc = tex->dcc_offset &&
>                                 tex->surface.level[level].dcc_enabled;
> diff --git a/src/gallium/drivers/softpipe/sp_image.c b/src/gallium/drivers/softpipe/sp_image.c
> index 0be11cb..d5547e2 100644
> --- a/src/gallium/drivers/softpipe/sp_image.c
> +++ b/src/gallium/drivers/softpipe/sp_image.c
> @@ -32,21 +32,21 @@
>   * 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);
> +      return iview->u.buf.offset;
>
>     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);
>  }
>
> @@ -146,21 +146,21 @@ has_compat_target(unsigned pipe_target, unsigned tgsi_target)
>  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;
> +      *width = iview->u.buf.size / util_format_get_blocksize(pformat);
>        *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 {
> @@ -745,21 +745,21 @@ sp_tgsi_get_dims(const struct tgsi_image *image,
>     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[0] = iview->u.buf.size / util_format_get_blocksize(iview->format);
>        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 */
> diff --git a/src/gallium/drivers/trace/tr_dump_state.c b/src/gallium/drivers/trace/tr_dump_state.c
> index d80037a..c5740d0 100644
> --- a/src/gallium/drivers/trace/tr_dump_state.c
> +++ b/src/gallium/drivers/trace/tr_dump_state.c
> @@ -753,22 +753,22 @@ void trace_dump_image_view(const struct pipe_image_view *state)
>     trace_dump_struct_begin("pipe_image_view");
>     trace_dump_member(resource_ptr, state, resource);
>     trace_dump_member(uint, state, format);
>     trace_dump_member(uint, state, access);
>
>     trace_dump_member_begin("u");
>     trace_dump_struct_begin(""); /* anonymous */
>     if (state->resource->target == PIPE_BUFFER) {
>        trace_dump_member_begin("buf");
>        trace_dump_struct_begin(""); /* anonymous */
> -      trace_dump_member(uint, &state->u.buf, first_element);
> -      trace_dump_member(uint, &state->u.buf, last_element);
> +      trace_dump_member(uint, &state->u.buf, offset);
> +      trace_dump_member(uint, &state->u.buf, size);
>        trace_dump_struct_end(); /* anonymous */
>        trace_dump_member_end(); /* buf */
>     } else {
>        trace_dump_member_begin("tex");
>        trace_dump_struct_begin(""); /* anonymous */
>        trace_dump_member(uint, &state->u.tex, first_layer);
>        trace_dump_member(uint, &state->u.tex, last_layer);
>        trace_dump_member(uint, &state->u.tex, level);
>        trace_dump_struct_end(); /* anonymous */
>        trace_dump_member_end(); /* tex */
> diff --git a/src/gallium/include/pipe/p_state.h b/src/gallium/include/pipe/p_state.h
> index 1fd6353..ebd0337 100644
> --- a/src/gallium/include/pipe/p_state.h
> +++ b/src/gallium/include/pipe/p_state.h
> @@ -449,22 +449,22 @@ struct pipe_image_view
>     enum pipe_format format;      /**< typed PIPE_FORMAT_x */
>     unsigned access;              /**< PIPE_IMAGE_ACCESS_x */
>
>     union {
>        struct {
>           unsigned first_layer:16;     /**< first layer to use for array textures */
>           unsigned last_layer:16;      /**< last layer to use for array textures */
>           unsigned level:8;            /**< mipmap level to use */
>        } tex;
>        struct {
> -         unsigned first_element;
> -         unsigned last_element;
> +         unsigned offset;   /**< offset in bytes */
> +         unsigned size;     /**< size of the accessible sub-range in bytes */
>        } buf;
>     } u;
>  };
>
>
>  /**
>   * Subregion of 1D/2D/3D image resource.
>   */
>  struct pipe_box
>  {
> diff --git a/src/mesa/state_tracker/st_atom_image.c b/src/mesa/state_tracker/st_atom_image.c
> index e80fc14..4d76ac9 100644
> --- a/src/mesa/state_tracker/st_atom_image.c
> +++ b/src/mesa/state_tracker/st_atom_image.c
> @@ -81,33 +81,27 @@ st_bind_images(struct st_context *st, struct gl_linked_shader *shader,
>           break;
>        case GL_READ_WRITE:
>           img->access = PIPE_IMAGE_ACCESS_READ_WRITE;
>           break;
>        default:
>           unreachable("bad gl_image_unit::Access");
>        }
>
>        if (stObj->pt->target == PIPE_BUFFER) {
>           unsigned base, size;
> -         unsigned f, n;
> -         const struct util_format_description *desc
> -            = util_format_description(img->format);
>
>           base = stObj->base.BufferOffset;
>           assert(base < stObj->pt->width0);
>           size = MIN2(stObj->pt->width0 - base, (unsigned)stObj->base.BufferSize);
>
> -         f = (base / (desc->block.bits / 8)) * desc->block.width;
> -         n = (size / (desc->block.bits / 8)) * desc->block.width;
> -         assert(n > 0);
> -         img->u.buf.first_element = f;
> -         img->u.buf.last_element  = f + (n - 1);
> +         img->u.buf.offset = base;
> +         img->u.buf.size = size;
>        } else {
>           img->u.tex.level = u->Level + stObj->base.MinLevel;
>           if (stObj->pt->target == PIPE_TEXTURE_3D) {
>              if (u->Layered) {
>                 img->u.tex.first_layer = 0;
>                 img->u.tex.last_layer = u_minify(stObj->pt->depth0, img->u.tex.level) - 1;
>              } else {
>                 img->u.tex.first_layer = u->_Layer;
>                 img->u.tex.last_layer = u->_Layer;
>              }
> diff --git a/src/mesa/state_tracker/st_cb_readpixels.c b/src/mesa/state_tracker/st_cb_readpixels.c
> index 8eb839d..3cfdf78 100644
> --- a/src/mesa/state_tracker/st_cb_readpixels.c
> +++ b/src/mesa/state_tracker/st_cb_readpixels.c
> @@ -185,22 +185,23 @@ try_pbo_readpixels(struct st_context *st, struct st_renderbuffer *strb,
>     }
>
>     /* Set up destination image */
>     {
>        struct pipe_image_view image;
>
>        memset(&image, 0, sizeof(image));
>        image.resource = addr.buffer;
>        image.format = dst_format;
>        image.access = PIPE_IMAGE_ACCESS_WRITE;
> -      image.u.buf.first_element = addr.first_element;
> -      image.u.buf.last_element = addr.last_element;
> +      image.u.buf.offset = addr.first_element * addr.bytes_per_pixel;
> +      image.u.buf.size = (addr.last_element - addr.first_element + 1) *
> +                         addr.bytes_per_pixel;
>
>        cso_set_shader_images(cso, PIPE_SHADER_FRAGMENT, 0, 1, &image);
>     }
>
>     /* Set up no-attachment framebuffer */
>     memset(&fb, 0, sizeof(fb));
>     fb.width = surface->width;
>     fb.height = surface->height;
>     fb.samples = 1;
>     fb.layers = 1;
> --
> 2.7.4
>
> _______________________________________________
> mesa-dev mailing list
> mesa-dev at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/mesa-dev


More information about the mesa-dev mailing list