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

Roland Scheidegger sroland at vmware.com
Fri Aug 12 18:48:43 UTC 2016


I can't say I'm a big fan of this.
>From an "api cleanness" point of view, defining things in elements makes
more sense imho.
This is due to the GL api though which uses generic buffer api to turn
buffers into textures which can be sampled (somewhat different to what
d3d10 does).
Can't you just say you require 16 bytes alignment and call it a day? I
don't think all hw can do 4 bytes anyway (actually though to satisfy
d3d10 requirements, your hw would still need to be able to even support
1-byte alignment, if the format is r8).

It also makes things asymmetric wrt pipe_surface (granted that's
something gl can't do IIRC).

But I guess we could live with this if necessary... Maybe hw does work
more like that and not what d3d10 wants anyway...

Roland



Am 12.08.2016 um 18:46 schrieb Marek Olšák:
> 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.
> 
> Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=97305
> ---
>  src/gallium/auxiliary/util/u_dump_state.c        |  4 ++--
>  src/gallium/docs/source/screen.rst               |  4 ++--
>  src/gallium/drivers/freedreno/a3xx/fd3_emit.c    |  3 +--
>  src/gallium/drivers/freedreno/a3xx/fd3_texture.c |  3 +--
>  src/gallium/drivers/freedreno/a4xx/fd4_texture.c |  7 +++----
>  src/gallium/drivers/ilo/ilo_state.c              |  5 ++---
>  src/gallium/drivers/llvmpipe/lp_setup.c          | 12 +++++-------
>  src/gallium/drivers/llvmpipe/lp_state_sampler.c  |  8 +++-----
>  src/gallium/drivers/nouveau/nv50/nv50_tex.c      |  7 +++----
>  src/gallium/drivers/nouveau/nvc0/nvc0_tex.c      | 18 ++++++++++--------
>  src/gallium/drivers/r600/evergreen_state.c       |  4 ++--
>  src/gallium/drivers/r600/r600_state.c            |  4 ++--
>  src/gallium/drivers/r600/r600_state_common.c     |  3 +--
>  src/gallium/drivers/radeonsi/si_descriptors.c    |  7 +++++--
>  src/gallium/drivers/radeonsi/si_state.c          | 10 +++++-----
>  src/gallium/drivers/radeonsi/si_state.h          |  2 +-
>  src/gallium/drivers/softpipe/sp_state_sampler.c  |  8 +++-----
>  src/gallium/drivers/softpipe/sp_tex_sample.c     | 13 +++++++++----
>  src/gallium/drivers/svga/svga_state_sampler.c    |  8 +++++---
>  src/gallium/drivers/trace/tr_dump_state.c        |  4 ++--
>  src/gallium/drivers/virgl/virgl_encode.c         |  7 +++++--
>  src/gallium/include/pipe/p_state.h               |  4 ++--
>  src/mesa/state_tracker/st_atom_texture.c         | 13 ++++---------
>  src/mesa/state_tracker/st_cb_texture.c           |  5 +++--
>  24 files changed, 81 insertions(+), 82 deletions(-)
> 
> diff --git a/src/gallium/auxiliary/util/u_dump_state.c b/src/gallium/auxiliary/util/u_dump_state.c
> index bad38fb..4568dc6 100644
> --- a/src/gallium/auxiliary/util/u_dump_state.c
> +++ b/src/gallium/auxiliary/util/u_dump_state.c
> @@ -743,22 +743,22 @@ util_dump_sampler_view(FILE *stream, const struct pipe_sampler_view *state)
>        return;
>     }
>  
>     util_dump_struct_begin(stream, "pipe_sampler_view");
>  
>     util_dump_member(stream, enum_tex_target, state, target);
>     util_dump_member(stream, format, state, format);
>     util_dump_member(stream, ptr, state, texture);
>  
>     if (state->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.last_level);
>        util_dump_member(stream, uint, state, u.tex.last_level);
>     }
>  
>     util_dump_member(stream, uint, state, swizzle_r);
>     util_dump_member(stream, uint, state, swizzle_g);
> diff --git a/src/gallium/docs/source/screen.rst b/src/gallium/docs/source/screen.rst
> index 34f2e72..3199e3c 100644
> --- a/src/gallium/docs/source/screen.rst
> +++ b/src/gallium/docs/source/screen.rst
> @@ -129,22 +129,22 @@ The integer capabilities:
>    pipe_draw_info::start_instance.
>  * ``PIPE_CAP_QUERY_TIMESTAMP``: Whether PIPE_QUERY_TIMESTAMP and
>    the pipe_screen::get_timestamp hook are implemented.
>  * ``PIPE_CAP_TEXTURE_MULTISAMPLE``: Whether all MSAA resources supported
>    for rendering are also supported for texturing.
>  * ``PIPE_CAP_MIN_MAP_BUFFER_ALIGNMENT``: The minimum alignment that should be
>    expected for a pointer returned by transfer_map if the resource is
>    PIPE_BUFFER. In other words, the pointer returned by transfer_map is
>    always aligned to this value.
>  * ``PIPE_CAP_TEXTURE_BUFFER_OFFSET_ALIGNMENT``: Describes the required
> -  alignment for pipe_sampler_view::u.buf.first_element, in bytes.
> -  If a driver does not support first/last_element, it should return 0.
> +  alignment for pipe_sampler_view::u.buf.offset, in bytes.
> +  If a driver does not support offset/size, it should return 0.
>  * ``PIPE_CAP_BUFFER_SAMPLER_VIEW_RGBA_ONLY``: Whether the driver only
>    supports R, RG, RGB and RGBA formats for PIPE_BUFFER sampler views.
>    When this is the case it should be assumed that the swizzle parameters
>    in the sampler view have no effect.
>  * ``PIPE_CAP_TGSI_TEXCOORD``: This CAP describes a hw limitation.
>    If true, the hardware cannot replace arbitrary shader inputs with sprite
>    coordinates and hence the inputs that are desired to be replaceable must
>    be declared with TGSI_SEMANTIC_TEXCOORD instead of TGSI_SEMANTIC_GENERIC.
>    The rasterizer's sprite_coord_enable state therefore also applies to the
>    TEXCOORD semantic.
> diff --git a/src/gallium/drivers/freedreno/a3xx/fd3_emit.c b/src/gallium/drivers/freedreno/a3xx/fd3_emit.c
> index 0fb2ee1..3466a0d 100644
> --- a/src/gallium/drivers/freedreno/a3xx/fd3_emit.c
> +++ b/src/gallium/drivers/freedreno/a3xx/fd3_emit.c
> @@ -199,22 +199,21 @@ emit_textures(struct fd_context *ctx, struct fd_ringbuffer *ring,
>  		for (i = 0; i < tex->num_textures; i++) {
>  			static const struct fd3_pipe_sampler_view dummy_view = {
>  					.base.target = PIPE_TEXTURE_1D, /* anything !PIPE_BUFFER */
>  					.base.u.tex.first_level = 1,
>  			};
>  			const struct fd3_pipe_sampler_view *view = tex->textures[i] ?
>  					fd3_pipe_sampler_view(tex->textures[i]) :
>  					&dummy_view;
>  			struct fd_resource *rsc = fd_resource(view->base.texture);
>  			if (rsc && rsc->base.b.target == PIPE_BUFFER) {
> -				OUT_RELOC(ring, rsc->bo, view->base.u.buf.first_element *
> -						  util_format_get_blocksize(view->base.format), 0, 0);
> +				OUT_RELOC(ring, rsc->bo, view->base.u.buf.offset, 0, 0);
>  				j = 1;
>  			} else {
>  				unsigned start = fd_sampler_first_level(&view->base);
>  				unsigned end   = fd_sampler_last_level(&view->base);
>  
>  				for (j = 0; j < (end - start + 1); j++) {
>  					struct fd_resource_slice *slice =
>  						fd_resource_slice(rsc, j + start);
>  					OUT_RELOC(ring, rsc->bo, slice->offset, 0, 0);
>  				}
> diff --git a/src/gallium/drivers/freedreno/a3xx/fd3_texture.c b/src/gallium/drivers/freedreno/a3xx/fd3_texture.c
> index 81336bf..ea2d341 100644
> --- a/src/gallium/drivers/freedreno/a3xx/fd3_texture.c
> +++ b/src/gallium/drivers/freedreno/a3xx/fd3_texture.c
> @@ -234,22 +234,21 @@ fd3_sampler_view_create(struct pipe_context *pctx, struct pipe_resource *prsc,
>  			fd3_tex_swiz(cso->format, cso->swizzle_r, cso->swizzle_g,
>  						cso->swizzle_b, cso->swizzle_a);
>  
>  	if (util_format_is_srgb(cso->format))
>  		so->texconst0 |= A3XX_TEX_CONST_0_SRGB;
>  
>  	if (prsc->target == PIPE_BUFFER) {
>  		lvl = 0;
>  		so->texconst1 =
>  			A3XX_TEX_CONST_1_FETCHSIZE(fd3_pipe2fetchsize(cso->format)) |
> -			A3XX_TEX_CONST_1_WIDTH(cso->u.buf.last_element -
> -								   cso->u.buf.first_element + 1) |
> +			A3XX_TEX_CONST_1_WIDTH(cso->u.buf.size / util_format_get_blocksize(cso->format)) |
>  			A3XX_TEX_CONST_1_HEIGHT(1);
>  	} else {
>  		unsigned miplevels;
>  
>  		lvl = fd_sampler_first_level(cso);
>  		miplevels = fd_sampler_last_level(cso) - lvl;
>  
>  		so->texconst0 |= A3XX_TEX_CONST_0_MIPLVLS(miplevels);
>  		so->texconst1 =
>  			A3XX_TEX_CONST_1_FETCHSIZE(fd3_pipe2fetchsize(cso->format)) |
> diff --git a/src/gallium/drivers/freedreno/a4xx/fd4_texture.c b/src/gallium/drivers/freedreno/a4xx/fd4_texture.c
> index da8c681..e62c732 100644
> --- a/src/gallium/drivers/freedreno/a4xx/fd4_texture.c
> +++ b/src/gallium/drivers/freedreno/a4xx/fd4_texture.c
> @@ -242,31 +242,30 @@ fd4_sampler_view_create(struct pipe_context *pctx, struct pipe_resource *prsc,
>  		fd4_tex_swiz(cso->format, cso->swizzle_r, cso->swizzle_g,
>  				cso->swizzle_b, cso->swizzle_a);
>  
>  	if (util_format_is_srgb(cso->format)) {
>  		if (use_astc_srgb_workaround(pctx, cso->format))
>  			so->astc_srgb = true;
>  		so->texconst0 |= A4XX_TEX_CONST_0_SRGB;
>  	}
>  
>  	if (cso->target == PIPE_BUFFER) {
> -		unsigned elements = cso->u.buf.last_element -
> -			cso->u.buf.first_element + 1;
> +		unsigned elements = cso->u.buf.size / util_format_get_blocksize(cso->format);
> +
>  		lvl = 0;
>  		so->texconst1 =
>  			A4XX_TEX_CONST_1_WIDTH(elements) |
>  			A4XX_TEX_CONST_1_HEIGHT(1);
>  		so->texconst2 =
>  			A4XX_TEX_CONST_2_FETCHSIZE(fd4_pipe2fetchsize(cso->format)) |
>  			A4XX_TEX_CONST_2_PITCH(elements * rsc->cpp);
> -		so->offset = cso->u.buf.first_element *
> -			util_format_get_blocksize(cso->format);
> +		so->offset = cso->u.buf.offset;
>  	} else {
>  		unsigned miplevels;
>  
>  		lvl = fd_sampler_first_level(cso);
>  		miplevels = fd_sampler_last_level(cso) - lvl;
>  		layers = cso->u.tex.last_layer - cso->u.tex.first_layer + 1;
>  
>  		so->texconst0 |= A4XX_TEX_CONST_0_MIPLVLS(miplevels);
>  		so->texconst1 =
>  			A4XX_TEX_CONST_1_WIDTH(u_minify(prsc->width0, lvl)) |
> diff --git a/src/gallium/drivers/ilo/ilo_state.c b/src/gallium/drivers/ilo/ilo_state.c
> index 4f1002e..7693133 100644
> --- a/src/gallium/drivers/ilo/ilo_state.c
> +++ b/src/gallium/drivers/ilo/ilo_state.c
> @@ -2008,23 +2008,22 @@ ilo_create_sampler_view(struct pipe_context *pipe,
>     pipe_reference_init(&view->base.reference, 1);
>     view->base.texture = NULL;
>     pipe_resource_reference(&view->base.texture, res);
>     view->base.context = pipe;
>  
>     if (res->target == PIPE_BUFFER) {
>        struct ilo_state_surface_buffer_info info;
>  
>        memset(&info, 0, sizeof(info));
>        info.vma = ilo_resource_get_vma(res);
> -      info.offset = templ->u.buf.first_element * info.struct_size;
> -      info.size = (templ->u.buf.last_element -
> -            templ->u.buf.first_element + 1) * info.struct_size;
> +      info.offset = templ->u.buf.offset;
> +      info.size = templ->u.buf.size;
>        info.access = ILO_STATE_SURFACE_ACCESS_SAMPLER;
>        info.format = ilo_format_translate_color(dev, templ->format);
>        info.format_size = util_format_get_blocksize(templ->format);
>        info.struct_size = info.format_size;
>        info.readonly = true;
>  
>        ilo_state_surface_init_for_buffer(&view->surface, dev, &info);
>     } else {
>        struct ilo_texture *tex = ilo_texture(res);
>        struct ilo_state_surface_image_info info;
> diff --git a/src/gallium/drivers/llvmpipe/lp_setup.c b/src/gallium/drivers/llvmpipe/lp_setup.c
> index 0a45db9..f622b19 100644
> --- a/src/gallium/drivers/llvmpipe/lp_setup.c
> +++ b/src/gallium/drivers/llvmpipe/lp_setup.c
> @@ -882,36 +882,34 @@ lp_setup_set_fragment_sampler_views(struct lp_setup_context *setup,
>                       if (view->target == PIPE_TEXTURE_CUBE ||
>                           view->target == PIPE_TEXTURE_CUBE_ARRAY) {
>                          assert(jit_tex->depth % 6 == 0);
>                       }
>                       assert(view->u.tex.first_layer <= view->u.tex.last_layer);
>                       assert(view->u.tex.last_layer < res->array_size);
>                    }
>                 }
>                 else {
>                    /*
> -                   * For buffers, we don't have first_element, instead adjust
> -                   * last_element (stored as width) plus the base pointer.
> +                   * For buffers, we don't have "offset", instead adjust
> +                   * the size (stored as width) plus the base pointer.
>                     */
>                    unsigned view_blocksize = util_format_get_blocksize(view->format);
>                    /* probably don't really need to fill that out */
>                    jit_tex->mip_offsets[0] = 0;
>                    jit_tex->row_stride[0] = 0;
>                    jit_tex->img_stride[0] = 0;
>  
>                    /* everything specified in number of elements here. */
> -                  jit_tex->width = view->u.buf.last_element - view->u.buf.first_element + 1;
> -                  jit_tex->base = (uint8_t *)jit_tex->base + view->u.buf.first_element *
> -                                  view_blocksize;
> +                  jit_tex->width = view->u.buf.size / view_blocksize;
> +                  jit_tex->base = (uint8_t *)jit_tex->base + view->u.buf.offset;
>                    /* XXX Unsure if we need to sanitize parameters? */
> -                  assert(view->u.buf.first_element <= view->u.buf.last_element);
> -                  assert(view->u.buf.last_element * view_blocksize < res->width0);
> +                  assert(view->u.buf.offset + view->u.buf.size <= res->width0);
>                 }
>              }
>           }
>           else {
>              /* display target texture/surface */
>              /*
>               * XXX: Where should this be unmapped?
>               */
>              struct llvmpipe_screen *screen = llvmpipe_screen(res->screen);
>              struct sw_winsys *winsys = screen->winsys;
> diff --git a/src/gallium/drivers/llvmpipe/lp_state_sampler.c b/src/gallium/drivers/llvmpipe/lp_state_sampler.c
> index 4441f2a..665cd9e 100644
> --- a/src/gallium/drivers/llvmpipe/lp_state_sampler.c
> +++ b/src/gallium/drivers/llvmpipe/lp_state_sampler.c
> @@ -301,25 +301,23 @@ prepare_shader_sampling(
>              }
>              else {
>                 unsigned view_blocksize = util_format_get_blocksize(view->format);
>                 addr = lp_tex->data;
>                 /* probably don't really need to fill that out */
>                 mip_offsets[0] = 0;
>                 row_stride[0] = 0;
>                 img_stride[0] = 0;
>  
>                 /* everything specified in number of elements here. */
> -               width0 = view->u.buf.last_element - view->u.buf.first_element + 1;
> -               addr = (uint8_t *)addr + view->u.buf.first_element *
> -                               view_blocksize;
> -               assert(view->u.buf.first_element <= view->u.buf.last_element);
> -               assert(view->u.buf.last_element * view_blocksize < res->width0);
> +               width0 = view->u.buf.size / view_blocksize;
> +               addr = (uint8_t *)addr + view->u.buf.offset;
> +               assert(view->u.buf.offset + view->u.buf.size <= res->width0);
>              }
>           }
>           else {
>              /* display target texture/surface */
>              /*
>               * XXX: Where should this be unmapped?
>               */
>              struct llvmpipe_screen *screen = llvmpipe_screen(tex->screen);
>              struct sw_winsys *winsys = screen->winsys;
>              addr = winsys->displaytarget_map(winsys, lp_tex->dt,
> diff --git a/src/gallium/drivers/nouveau/nv50/nv50_tex.c b/src/gallium/drivers/nouveau/nv50/nv50_tex.c
> index 953ab8f..ad23018 100644
> --- a/src/gallium/drivers/nouveau/nv50/nv50_tex.c
> +++ b/src/gallium/drivers/nouveau/nv50/nv50_tex.c
> @@ -124,25 +124,25 @@ nv50_create_texture_view(struct pipe_context *pipe,
>     tic[2] = 0x10001000 | G80_TIC_2_BORDER_SOURCE_COLOR;
>  
>     if (desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB)
>        tic[2] |= G80_TIC_2_SRGB_CONVERSION;
>  
>     if (!(flags & NV50_TEXVIEW_SCALED_COORDS))
>        tic[2] |= G80_TIC_2_NORMALIZED_COORDS;
>  
>     if (unlikely(!nouveau_bo_memtype(nv04_resource(texture)->bo))) {
>        if (target == PIPE_BUFFER) {
> -         addr += view->pipe.u.buf.first_element * desc->block.bits / 8;
> +         addr += view->pipe.u.buf.offset;
>           tic[2] |= G80_TIC_2_LAYOUT_PITCH | G80_TIC_2_TEXTURE_TYPE_ONE_D_BUFFER;
>           tic[3] = 0;
>           tic[4] = /* width */
> -            view->pipe.u.buf.last_element - view->pipe.u.buf.first_element + 1;
> +            view->pipe.u.buf.size / (desc->block.bits / 8);
>           tic[5] = 0;
>        } else {
>           tic[2] |= G80_TIC_2_LAYOUT_PITCH | G80_TIC_2_TEXTURE_TYPE_TWO_D_NO_MIPMAP;
>           tic[3] = mt->level[0].pitch;
>           tic[4] = mt->base.base.width0;
>           tic[5] = (1 << 16) | (mt->base.base.height0);
>        }
>        tic[6] =
>        tic[7] = 0;
>        tic[1] = addr;
> @@ -217,22 +217,21 @@ nv50_create_texture_view(struct pipe_context *pipe,
>     return &view->pipe;
>  }
>  
>  static void
>  nv50_update_tic(struct nv50_context *nv50, struct nv50_tic_entry *tic,
>                  struct nv04_resource *res)
>  {
>     uint64_t address = res->address;
>     if (res->base.target != PIPE_BUFFER)
>        return;
> -   address += tic->pipe.u.buf.first_element *
> -      util_format_get_blocksize(tic->pipe.format);
> +   address += tic->pipe.u.buf.offset;
>     if (tic->tic[1] == (uint32_t)address &&
>         (tic->tic[2] & 0xff) == address >> 32)
>        return;
>  
>     nv50_screen_tic_unlock(nv50->screen, tic);
>     tic->id = -1;
>     tic->tic[1] = address;
>     tic->tic[2] &= 0xffffff00;
>     tic->tic[2] |= address >> 32;
>  }
> diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_tex.c b/src/gallium/drivers/nouveau/nvc0/nvc0_tex.c
> index 40a9c93..b6e0ba8 100644
> --- a/src/gallium/drivers/nouveau/nvc0/nvc0_tex.c
> +++ b/src/gallium/drivers/nouveau/nvc0/nvc0_tex.c
> @@ -125,23 +125,23 @@ gm107_create_texture_view(struct pipe_context *pipe,
>  
>     if (!(flags & NV50_TEXVIEW_SCALED_COORDS))
>        tic[5] = GM107_TIC2_5_NORMALIZED_COORDS;
>     else
>        tic[5] = 0;
>  
>     /* check for linear storage type */
>     if (unlikely(!nouveau_bo_memtype(nv04_resource(texture)->bo))) {
>        if (texture->target == PIPE_BUFFER) {
>           assert(!(tic[5] & GM107_TIC2_5_NORMALIZED_COORDS));
> -         width = view->pipe.u.buf.last_element - view->pipe.u.buf.first_element;
> +         width = view->pipe.u.buf.size / (desc->block.bits / 8) - 1;
>           address +=
> -            view->pipe.u.buf.first_element * desc->block.bits / 8;
> +            view->pipe.u.buf.offset;
>           tic[2]  = GM107_TIC2_2_HEADER_VERSION_ONE_D_BUFFER;
>           tic[3] |= width >> 16;
>           tic[4] |= GM107_TIC2_4_TEXTURE_TYPE_ONE_D_BUFFER;
>           tic[4] |= width & 0xffff;
>        } else {
>           assert(!(mt->level[0].pitch & 0x1f));
>           /* must be 2D texture without mip maps */
>           tic[2]  = GM107_TIC2_2_HEADER_VERSION_PITCH;
>           tic[4] |= GM107_TIC2_4_TEXTURE_TYPE_TWO_D_NO_MIPMAP;
>           tic[3] |= mt->level[0].pitch >> 5;
> @@ -252,22 +252,25 @@ 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.first_element = view->u.buf.first_element;
> -      templ.u.buf.last_element = view->u.buf.last_element;
> +      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);
>     } 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);
>  }
> @@ -337,25 +340,25 @@ gf100_create_texture_view(struct pipe_context *pipe,
>        tic[2] |= G80_TIC_2_SRGB_CONVERSION;
>  
>     if (!(flags & NV50_TEXVIEW_SCALED_COORDS))
>        tic[2] |= G80_TIC_2_NORMALIZED_COORDS;
>  
>     /* check for linear storage type */
>     if (unlikely(!nouveau_bo_memtype(nv04_resource(texture)->bo))) {
>        if (texture->target == PIPE_BUFFER) {
>           assert(!(tic[2] & G80_TIC_2_NORMALIZED_COORDS));
>           address +=
> -            view->pipe.u.buf.first_element * desc->block.bits / 8;
> +            view->pipe.u.buf.offset;
>           tic[2] |= G80_TIC_2_LAYOUT_PITCH | G80_TIC_2_TEXTURE_TYPE_ONE_D_BUFFER;
>           tic[3] = 0;
>           tic[4] = /* width */
> -            view->pipe.u.buf.last_element - view->pipe.u.buf.first_element + 1;
> +            view->pipe.u.buf.size / (desc->block.bits / 8);
>           tic[5] = 0;
>        } else {
>           /* must be 2D texture without mip maps */
>           tic[2] |= G80_TIC_2_LAYOUT_PITCH | G80_TIC_2_TEXTURE_TYPE_TWO_D_NO_MIPMAP;
>           tic[3] = mt->level[0].pitch;
>           tic[4] = mt->base.base.width0;
>           tic[5] = (1 << 16) | mt->base.base.height0;
>        }
>        tic[6] =
>        tic[7] = 0;
> @@ -449,22 +452,21 @@ nvc0_create_texture_view(struct pipe_context *pipe,
>     return gf100_create_texture_view(pipe, texture, templ, flags, target);
>  }
>  
>  void
>  nvc0_update_tic(struct nvc0_context *nvc0, struct nv50_tic_entry *tic,
>                  struct nv04_resource *res)
>  {
>     uint64_t address = res->address;
>     if (res->base.target != PIPE_BUFFER)
>        return;
> -   address += tic->pipe.u.buf.first_element *
> -      util_format_get_blocksize(tic->pipe.format);
> +   address += tic->pipe.u.buf.offset;
>     if (tic->tic[1] == (uint32_t)address &&
>         (tic->tic[2] & 0xff) == address >> 32)
>        return;
>  
>     nvc0_screen_tic_unlock(nvc0->screen, tic);
>     tic->id = -1;
>     tic->tic[1] = address;
>     tic->tic[2] &= 0xffffff00;
>     tic->tic[2] |= address >> 32;
>  }
> diff --git a/src/gallium/drivers/r600/evergreen_state.c b/src/gallium/drivers/r600/evergreen_state.c
> index 7611520..3d1a19d 100644
> --- a/src/gallium/drivers/r600/evergreen_state.c
> +++ b/src/gallium/drivers/r600/evergreen_state.c
> @@ -606,22 +606,22 @@ texture_buffer_sampler_view(struct r600_context *rctx,
>  			    unsigned width0, unsigned height0)
>  			    
>  {
>  	struct r600_texture *tmp = (struct r600_texture*)view->base.texture;
>  	uint64_t va;
>  	int stride = util_format_get_blocksize(view->base.format);
>  	unsigned format, num_format, format_comp, endian;
>  	unsigned swizzle_res;
>  	unsigned char swizzle[4];
>  	const struct util_format_description *desc;
> -	unsigned offset = view->base.u.buf.first_element * stride;
> -	unsigned size = (view->base.u.buf.last_element - view->base.u.buf.first_element + 1) * stride;
> +	unsigned offset = view->base.u.buf.offset;
> +	unsigned size = view->base.u.buf.size;
>  
>  	swizzle[0] = view->base.swizzle_r;
>  	swizzle[1] = view->base.swizzle_g;
>  	swizzle[2] = view->base.swizzle_b;
>  	swizzle[3] = view->base.swizzle_a;
>  
>  	r600_vertex_data_type(view->base.format,
>  			      &format, &num_format, &format_comp,
>  			      &endian);
>  
> diff --git a/src/gallium/drivers/r600/r600_state.c b/src/gallium/drivers/r600/r600_state.c
> index 046573f..62b1c2c 100644
> --- a/src/gallium/drivers/r600/r600_state.c
> +++ b/src/gallium/drivers/r600/r600_state.c
> @@ -624,22 +624,22 @@ static void *r600_create_sampler_state(struct pipe_context *ctx,
>  }
>  
>  static struct pipe_sampler_view *
>  texture_buffer_sampler_view(struct r600_pipe_sampler_view *view,
>  			    unsigned width0, unsigned height0)
>  			    
>  {
>  	struct r600_texture *tmp = (struct r600_texture*)view->base.texture;
>  	int stride = util_format_get_blocksize(view->base.format);
>  	unsigned format, num_format, format_comp, endian;
> -	uint64_t offset = view->base.u.buf.first_element * stride;
> -	unsigned size = (view->base.u.buf.last_element - view->base.u.buf.first_element + 1) * stride;
> +	uint64_t offset = view->base.u.buf.offset;
> +	unsigned size = view->base.u.buf.size;
>  
>  	r600_vertex_data_type(view->base.format,
>  			      &format, &num_format, &format_comp,
>  			      &endian);
>  
>  	view->tex_resource = &tmp->resource;
>  	view->skip_mip_address_reloc = true;
>  
>  	view->tex_resource_words[0] = offset;
>  	view->tex_resource_words[1] = size - 1;
> diff --git a/src/gallium/drivers/r600/r600_state_common.c b/src/gallium/drivers/r600/r600_state_common.c
> index 11ef925..9008a4a 100644
> --- a/src/gallium/drivers/r600/r600_state_common.c
> +++ b/src/gallium/drivers/r600/r600_state_common.c
> @@ -2824,22 +2824,21 @@ static void r600_invalidate_buffer(struct pipe_context *ctx, struct pipe_resourc
>  			}
>  		}
>  		if (found) {
>  			r600_constant_buffers_dirty(rctx, state);
>  		}
>  	}
>  
>  	/* Texture buffer objects - update the virtual addresses in descriptors. */
>  	LIST_FOR_EACH_ENTRY(view, &rctx->b.texture_buffers, list) {
>  		if (view->base.texture == &rbuffer->b.b) {
> -			unsigned stride = util_format_get_blocksize(view->base.format);
> -			uint64_t offset = (uint64_t)view->base.u.buf.first_element * stride;
> +			uint64_t offset = view->base.u.buf.offset;
>  			uint64_t va = rbuffer->gpu_address + offset;
>  
>  			view->tex_resource_words[0] = va;
>  			view->tex_resource_words[2] &= C_038008_BASE_ADDRESS_HI;
>  			view->tex_resource_words[2] |= S_038008_BASE_ADDRESS_HI(va >> 32);
>  		}
>  	}
>  	/* Texture buffer objects - make bindings dirty if needed. */
>  	for (shader = 0; shader < PIPE_SHADER_TYPES; shader++) {
>  		struct r600_samplerview_state *state = &rctx->samplers[shader].views;
> diff --git a/src/gallium/drivers/radeonsi/si_descriptors.c b/src/gallium/drivers/radeonsi/si_descriptors.c
> index f03a895..a3e4564 100644
> --- a/src/gallium/drivers/radeonsi/si_descriptors.c
> +++ b/src/gallium/drivers/radeonsi/si_descriptors.c
> @@ -634,22 +634,25 @@ 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,
> -					  view->u.buf.last_element,
> +					  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),
>  					  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/radeonsi/si_state.c b/src/gallium/drivers/radeonsi/si_state.c
> index 8d9fe53..7e63d48 100644
> --- a/src/gallium/drivers/radeonsi/si_state.c
> +++ b/src/gallium/drivers/radeonsi/si_state.c
> @@ -2637,38 +2637,38 @@ static void si_set_min_samples(struct pipe_context *ctx, unsigned min_samples)
>   * Samplers
>   */
>  
>  /**
>   * Build the sampler view descriptor for a buffer texture.
>   * @param state 256-bit descriptor; only the high 128 bits are filled in
>   */
>  void
>  si_make_buffer_descriptor(struct si_screen *screen, struct r600_resource *buf,
>  			  enum pipe_format format,
> -			  unsigned first_element, unsigned last_element,
> +			  unsigned offset, unsigned size,
>  			  uint32_t *state)
>  {
>  	const struct util_format_description *desc;
>  	int first_non_void;
>  	uint64_t va;
>  	unsigned stride;
>  	unsigned num_records;
>  	unsigned num_format, data_format;
>  
>  	desc = util_format_description(format);
>  	first_non_void = util_format_get_first_non_void_channel(format);
>  	stride = desc->block.bits / 8;
> -	va = buf->gpu_address + first_element * stride;
> +	va = buf->gpu_address + offset;
>  	num_format = si_translate_buffer_numformat(&screen->b.b, desc, first_non_void);
>  	data_format = si_translate_buffer_dataformat(&screen->b.b, desc, first_non_void);
>  
> -	num_records = last_element + 1 - first_element;
> +	num_records = size / stride;
>  	num_records = MIN2(num_records, buf->b.b.width0 / stride);
>  
>  	if (screen->b.chip_class >= VI)
>  		num_records *= stride;
>  
>  	state[4] = va;
>  	state[5] = S_008F04_BASE_ADDRESS_HI(va >> 32) |
>  		   S_008F04_STRIDE(stride);
>  	state[6] = num_records;
>  	state[7] = S_008F0C_DST_SEL_X(si_map_swizzle(desc->swizzle[0])) |
> @@ -2953,22 +2953,22 @@ si_create_sampler_view_custom(struct pipe_context *ctx,
>  	    state->format == PIPE_FORMAT_S8X24_UINT ||
>  	    state->format == PIPE_FORMAT_X32_S8X24_UINT ||
>  	    state->format == PIPE_FORMAT_S8_UINT)
>  		view->is_stencil_sampler = true;
>  
>  	/* Buffer resource. */
>  	if (texture->target == PIPE_BUFFER) {
>  		si_make_buffer_descriptor(sctx->screen,
>  					  (struct r600_resource *)texture,
>  					  state->format,
> -					  state->u.buf.first_element,
> -					  state->u.buf.last_element,
> +					  state->u.buf.offset,
> +					  state->u.buf.size,
>  					  view->state);
>  
>  		LIST_ADDTAIL(&view->list, &sctx->b.texture_buffers);
>  		return &view->base;
>  	}
>  
>  	state_swizzle[0] = state->swizzle_r;
>  	state_swizzle[1] = state->swizzle_g;
>  	state_swizzle[2] = state->swizzle_b;
>  	state_swizzle[3] = state->swizzle_a;
> diff --git a/src/gallium/drivers/radeonsi/si_state.h b/src/gallium/drivers/radeonsi/si_state.h
> index b574c2e..f4f7575 100644
> --- a/src/gallium/drivers/radeonsi/si_state.h
> +++ b/src/gallium/drivers/radeonsi/si_state.h
> @@ -306,21 +306,21 @@ void si_set_rw_buffer(struct si_context *sctx,
>  struct si_shader_selector;
>  
>  void si_init_atom(struct si_context *sctx, struct r600_atom *atom,
>  		  struct r600_atom **list_elem,
>  		  void (*emit_func)(struct si_context *ctx, struct r600_atom *state));
>  void si_init_state_functions(struct si_context *sctx);
>  void si_init_screen_state_functions(struct si_screen *sscreen);
>  void
>  si_make_buffer_descriptor(struct si_screen *screen, struct r600_resource *buf,
>  			  enum pipe_format format,
> -			  unsigned first_element, unsigned last_element,
> +			  unsigned offset, unsigned size,
>  			  uint32_t *state);
>  void
>  si_make_texture_descriptor(struct si_screen *screen,
>  			   struct r600_texture *tex,
>  			   bool sampler,
>  			   enum pipe_texture_target target,
>  			   enum pipe_format pipe_format,
>  			   const unsigned char state_swizzle[4],
>  			   unsigned first_level, unsigned last_level,
>  			   unsigned first_layer, unsigned last_layer,
> diff --git a/src/gallium/drivers/softpipe/sp_state_sampler.c b/src/gallium/drivers/softpipe/sp_state_sampler.c
> index 0d5149c..f824743 100644
> --- a/src/gallium/drivers/softpipe/sp_state_sampler.c
> +++ b/src/gallium/drivers/softpipe/sp_state_sampler.c
> @@ -233,25 +233,23 @@ prepare_shader_sampling(
>              }
>              else {
>                 unsigned view_blocksize = util_format_get_blocksize(view->format);
>                 addr = sp_tex->data;
>                 /* probably don't really need to fill that out */
>                 mip_offsets[0] = 0;
>                 row_stride[0] = 0;
>                 img_stride[0] = 0;
>  
>                 /* everything specified in number of elements here. */
> -               width0 = view->u.buf.last_element - view->u.buf.first_element + 1;
> -               addr = (uint8_t *)addr + view->u.buf.first_element *
> -                               view_blocksize;
> -               assert(view->u.buf.first_element <= view->u.buf.last_element);
> -               assert(view->u.buf.last_element * view_blocksize < res->width0);
> +               width0 = view->u.buf.size / view_blocksize;
> +               addr = (uint8_t *)addr + view->u.buf.offset;
> +               assert(view->u.buf.offset + view->u.buf.size <= res->width0);
>              }
>           }
>           else {
>              /* display target texture/surface */
>              /*
>               * XXX: Where should this be unmapped?
>               */
>              struct softpipe_screen *screen = softpipe_screen(tex->screen);
>              struct sw_winsys *winsys = screen->winsys;
>              addr = winsys->displaytarget_map(winsys, sp_tex->dt,
> diff --git a/src/gallium/drivers/softpipe/sp_tex_sample.c b/src/gallium/drivers/softpipe/sp_tex_sample.c
> index 5998681..c457f89 100644
> --- a/src/gallium/drivers/softpipe/sp_tex_sample.c
> +++ b/src/gallium/drivers/softpipe/sp_tex_sample.c
> @@ -3185,21 +3185,21 @@ convert_cube(const struct sp_sampler_view *sp_sview,
>  
>  static void
>  sp_get_dims(const struct sp_sampler_view *sp_sview,
>              int level,
>              int dims[4])
>  {
>     const struct pipe_sampler_view *view = &sp_sview->base;
>     const struct pipe_resource *texture = view->texture;
>  
>     if (view->target == PIPE_BUFFER) {
> -      dims[0] = (view->u.buf.last_element - view->u.buf.first_element) + 1;
> +      dims[0] = view->u.buf.size / util_format_get_blocksize(view->format);
>        /* the other values are undefined, but let's avoid potential valgrind
>         * warnings.
>         */
>        dims[1] = dims[2] = dims[3] = 0;
>        return;
>     }
>  
>     /* undefined according to EXT_gpu_program */
>     level += view->u.tex.first_level;
>     if (level > view->u.tex.last_level)
> @@ -3257,31 +3257,36 @@ sp_get_texels(const struct sp_sampler_view *sp_sview,
>     const float *tx;
>     /* TODO write a better test for LOD */
>     const unsigned level =
>        sp_sview->base.target == PIPE_BUFFER ? 0 :
>        CLAMP(lod[0] + sp_sview->base.u.tex.first_level,
>              sp_sview->base.u.tex.first_level,
>              sp_sview->base.u.tex.last_level);
>     const int width = u_minify(texture->width0, level);
>     const int height = u_minify(texture->height0, level);
>     const int depth = u_minify(texture->depth0, level);
> +   unsigned elem_size, first_element, last_element;
>  
>     addr.value = 0;
>     addr.bits.level = level;
>  
>     switch (sp_sview->base.target) {
>     case PIPE_BUFFER:
> +      elem_size = util_format_get_blocksize(sp_sview->base.format);
> +      first_element = sp_sview->base.u.buf.offset / elem_size;
> +      last_element = (sp_sview->base.u.buf.offset +
> +                      sp_sview->base.u.buf.size) / elem_size - 1;
>        for (j = 0; j < TGSI_QUAD_SIZE; j++) {
>           const int x = CLAMP(v_i[j] + offset[0] +
> -                             sp_sview->base.u.buf.first_element,
> -                             sp_sview->base.u.buf.first_element,
> -                             sp_sview->base.u.buf.last_element);
> +                             first_element,
> +                             first_element,
> +                             last_element);
>           tx = get_texel_2d_no_border(sp_sview, addr, x, 0);
>           for (c = 0; c < 4; c++) {
>              rgba[c][j] = tx[c];
>           }
>        }
>        break;
>     case PIPE_TEXTURE_1D:
>        for (j = 0; j < TGSI_QUAD_SIZE; j++) {
>           const int x = CLAMP(v_i[j] + offset[0], 0, width - 1);
>           tx = get_texel_2d_no_border(sp_sview, addr, x,
> diff --git a/src/gallium/drivers/svga/svga_state_sampler.c b/src/gallium/drivers/svga/svga_state_sampler.c
> index 00e8fc0..2f0f838 100644
> --- a/src/gallium/drivers/svga/svga_state_sampler.c
> +++ b/src/gallium/drivers/svga/svga_state_sampler.c
> @@ -23,20 +23,21 @@
>   */
>  
>  
>  /**
>   * VGPU10 sampler and sampler view functions.
>   */
>  
>  
>  #include "pipe/p_defines.h"
>  #include "util/u_bitmask.h"
> +#include "util/u_format.h"
>  #include "util/u_inlines.h"
>  #include "util/u_math.h"
>  #include "util/u_memory.h"
>  
>  #include "svga_cmd.h"
>  #include "svga_context.h"
>  #include "svga_format.h"
>  #include "svga_resource_buffer.h"
>  #include "svga_resource_texture.h"
>  #include "svga_shader.h"
> @@ -118,23 +119,24 @@ svga_validate_pipe_sampler_view(struct svga_context *svga,
>        }
>  
>        format = svga_translate_format(ss, pformat,
>                                       PIPE_BIND_SAMPLER_VIEW);
>        assert(format != SVGA3D_FORMAT_INVALID);
>  
>        /* Convert the format to a sampler-friendly format, if needed */
>        format = svga_sampler_format(format);
>  
>        if (texture->target == PIPE_BUFFER) {
> -         viewDesc.buffer.firstElement = sv->base.u.buf.first_element;
> -         viewDesc.buffer.numElements = (sv->base.u.buf.last_element -
> -                                        sv->base.u.buf.first_element + 1);
> +         unsigned elem_size = util_format_get_blocksize(sv->base.format);
> +
> +         viewDesc.buffer.firstElement = sv->base.u.buf.offset / elem_size;
> +         viewDesc.buffer.numElements = sv->base.u.buf.size / elem_size;
>        }
>        else {
>           viewDesc.tex.mostDetailedMip = sv->base.u.tex.first_level;
>           viewDesc.tex.firstArraySlice = sv->base.u.tex.first_layer;
>           viewDesc.tex.mipLevels = (sv->base.u.tex.last_level -
>                                     sv->base.u.tex.first_level + 1);
>        }
>  
>        /* arraySize in viewDesc specifies the number of array slices in a
>         * texture array. For 3D texture, last_layer in
> diff --git a/src/gallium/drivers/trace/tr_dump_state.c b/src/gallium/drivers/trace/tr_dump_state.c
> index bc129e0..d80037a 100644
> --- a/src/gallium/drivers/trace/tr_dump_state.c
> +++ b/src/gallium/drivers/trace/tr_dump_state.c
> @@ -536,22 +536,22 @@ void trace_dump_sampler_view_template(const struct pipe_sampler_view *state,
>  
>     trace_dump_struct_begin("pipe_sampler_view");
>  
>     trace_dump_member(format, state, format);
>  
>     trace_dump_member_begin("u");
>     trace_dump_struct_begin(""); /* anonymous */
>     if (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, first_level);
>        trace_dump_member(uint, &state->u.tex, last_level);
>        trace_dump_struct_end(); /* anonymous */
> diff --git a/src/gallium/drivers/virgl/virgl_encode.c b/src/gallium/drivers/virgl/virgl_encode.c
> index 1a1c40b..be72f70 100644
> --- a/src/gallium/drivers/virgl/virgl_encode.c
> +++ b/src/gallium/drivers/virgl/virgl_encode.c
> @@ -15,20 +15,21 @@
>   * 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 <stdint.h>
>  
> +#include "util/u_format.h"
>  #include "util/u_memory.h"
>  #include "util/u_math.h"
>  #include "pipe/p_state.h"
>  #include "tgsi/tgsi_dump.h"
>  #include "tgsi/tgsi_parse.h"
>  
>  #include "virgl_context.h"
>  #include "virgl_encode.h"
>  #include "virgl_protocol.h"
>  #include "virgl_resource.h"
> @@ -555,28 +556,30 @@ int virgl_encode_sampler_state(struct virgl_context *ctx,
>        virgl_encoder_write_dword(ctx->cbuf, state->border_color.ui[i]);
>     return 0;
>  }
>  
>  
>  int virgl_encode_sampler_view(struct virgl_context *ctx,
>                               uint32_t handle,
>                               struct virgl_resource *res,
>                               const struct pipe_sampler_view *state)
>  {
> +   unsigned elem_size = util_format_get_blocksize(state->format);
> +
>     uint32_t tmp;
>     virgl_encoder_write_cmd_dword(ctx, VIRGL_CMD0(VIRGL_CCMD_CREATE_OBJECT, VIRGL_OBJECT_SAMPLER_VIEW, VIRGL_OBJ_SAMPLER_VIEW_SIZE));
>     virgl_encoder_write_dword(ctx->cbuf, handle);
>     virgl_encoder_write_res(ctx, res);
>     virgl_encoder_write_dword(ctx->cbuf, state->format);
>     if (res->u.b.target == PIPE_BUFFER) {
> -      virgl_encoder_write_dword(ctx->cbuf, state->u.buf.first_element);
> -      virgl_encoder_write_dword(ctx->cbuf, state->u.buf.last_element);
> +      virgl_encoder_write_dword(ctx->cbuf, state->u.buf.offset / elem_size);
> +      virgl_encoder_write_dword(ctx->cbuf, (state->u.buf.offset + state->u.buf.size) / elem_size - 1);
>     } else {
>        virgl_encoder_write_dword(ctx->cbuf, state->u.tex.first_layer | state->u.tex.last_layer << 16);
>        virgl_encoder_write_dword(ctx->cbuf, state->u.tex.first_level | state->u.tex.last_level << 8);
>     }
>     tmp = VIRGL_OBJ_SAMPLER_VIEW_SWIZZLE_R(state->swizzle_r) |
>        VIRGL_OBJ_SAMPLER_VIEW_SWIZZLE_G(state->swizzle_g) |
>        VIRGL_OBJ_SAMPLER_VIEW_SWIZZLE_B(state->swizzle_b) |
>        VIRGL_OBJ_SAMPLER_VIEW_SWIZZLE_A(state->swizzle_a);
>     virgl_encoder_write_dword(ctx->cbuf, tmp);
>     return 0;
> diff --git a/src/gallium/include/pipe/p_state.h b/src/gallium/include/pipe/p_state.h
> index a3ae870..1fd6353 100644
> --- a/src/gallium/include/pipe/p_state.h
> +++ b/src/gallium/include/pipe/p_state.h
> @@ -421,22 +421,22 @@ struct pipe_sampler_view
>     struct pipe_resource *texture; /**< texture into which this is a view  */
>     struct pipe_context *context; /**< context this view belongs to */
>     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 first_level:8;   /**< first mipmap level to use */
>           unsigned last_level:8;    /**< last mipmap level to use */
>        } tex;
>        struct {
> -         unsigned first_element;
> -         unsigned last_element;
> +         unsigned offset;   /**< offset in bytes */
> +         unsigned size;     /**< size of the readable sub-range in bytes */
>        } buf;
>     } u;
>     unsigned swizzle_r:3;         /**< PIPE_SWIZZLE_x for red component */
>     unsigned swizzle_g:3;         /**< PIPE_SWIZZLE_x for green component */
>     unsigned swizzle_b:3;         /**< PIPE_SWIZZLE_x for blue component */
>     unsigned swizzle_a:3;         /**< PIPE_SWIZZLE_x for alpha component */
>  };
>  
>  
>  /**
> diff --git a/src/mesa/state_tracker/st_atom_texture.c b/src/mesa/state_tracker/st_atom_texture.c
> index 923cb93..9ee476d 100644
> --- a/src/mesa/state_tracker/st_atom_texture.c
> +++ b/src/mesa/state_tracker/st_atom_texture.c
> @@ -272,35 +272,30 @@ st_create_texture_sampler_view_from_stobj(struct st_context *st,
>  {
>     struct pipe_sampler_view templ;
>     unsigned swizzle = get_texture_format_swizzle(st, stObj, glsl_version);
>  
>     u_sampler_view_default_template(&templ,
>                                     stObj->pt,
>                                     format);
>  
>     if (stObj->pt->target == PIPE_BUFFER) {
>        unsigned base, size;
> -      unsigned f, n;
> -      const struct util_format_description *desc
> -         = util_format_description(templ.format);
>  
>        base = stObj->base.BufferOffset;
>        if (base >= stObj->pt->width0)
>           return NULL;
>        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;
> -      if (!n)
> +      if (!size)
>           return NULL;
> -      templ.u.buf.first_element = f;
> -      templ.u.buf.last_element  = f + (n - 1);
> +
> +      templ.u.buf.offset = base;
> +      templ.u.buf.size = size;
>     } else {
>        templ.u.tex.first_level = stObj->base.MinLevel + stObj->base.BaseLevel;
>        templ.u.tex.last_level = last_level(stObj);
>        assert(templ.u.tex.first_level <= templ.u.tex.last_level);
>        templ.u.tex.first_layer = stObj->base.MinLayer;
>        templ.u.tex.last_layer = last_layer(stObj);
>        assert(templ.u.tex.first_layer <= templ.u.tex.last_layer);
>        templ.target = gl_target_to_pipe(stObj->base.Target);
>     }
>  
> diff --git a/src/mesa/state_tracker/st_cb_texture.c b/src/mesa/state_tracker/st_cb_texture.c
> index ab06195..5a2298c 100644
> --- a/src/mesa/state_tracker/st_cb_texture.c
> +++ b/src/mesa/state_tracker/st_cb_texture.c
> @@ -1125,22 +1125,23 @@ try_pbo_upload_common(struct gl_context *ctx,
>     /* Set up the sampler_view */
>     {
>        struct pipe_sampler_view templ;
>        struct pipe_sampler_view *sampler_view;
>        struct pipe_sampler_state sampler = {0};
>        const struct pipe_sampler_state *samplers[1] = {&sampler};
>  
>        memset(&templ, 0, sizeof(templ));
>        templ.target = PIPE_BUFFER;
>        templ.format = src_format;
> -      templ.u.buf.first_element = addr->first_element;
> -      templ.u.buf.last_element = addr->last_element;
> +      templ.u.buf.offset = addr->first_element * addr->bytes_per_pixel;
> +      templ.u.buf.size = (addr->last_element - addr->first_element + 1) *
> +                         addr->bytes_per_pixel;
>        templ.swizzle_r = PIPE_SWIZZLE_X;
>        templ.swizzle_g = PIPE_SWIZZLE_Y;
>        templ.swizzle_b = PIPE_SWIZZLE_Z;
>        templ.swizzle_a = PIPE_SWIZZLE_W;
>  
>        sampler_view = pipe->create_sampler_view(pipe, addr->buffer, &templ);
>        if (sampler_view == NULL)
>           goto fail;
>  
>        cso_set_sampler_views(cso, PIPE_SHADER_FRAGMENT, 1, &sampler_view);
> 



More information about the mesa-dev mailing list