Home | History | Annotate | Download | only in state_tracker
      1 /*
      2  * Copyright 2016 VMware, Inc.
      3  * All Rights Reserved.
      4  *
      5  * Permission is hereby granted, free of charge, to any person obtaining a
      6  * copy of this software and associated documentation files (the
      7  * "Software"), to deal in the Software without restriction, including
      8  * without limitation the rights to use, copy, modify, merge, publish,
      9  * distribute, sub license, and/or sell copies of the Software, and to
     10  * permit persons to whom the Software is furnished to do so, subject to
     11  * the following conditions:
     12  *
     13  * The above copyright notice and this permission notice (including the
     14  * next paragraph) shall be included in all copies or substantial portions
     15  * of the Software.
     16  *
     17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
     18  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
     19  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
     20  * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
     21  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
     22  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
     23  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
     24  */
     25 
     26 #include "pipe/p_context.h"
     27 #include "util/u_format.h"
     28 #include "util/u_inlines.h"
     29 
     30 #include "main/context.h"
     31 #include "main/macros.h"
     32 #include "main/mtypes.h"
     33 #include "main/teximage.h"
     34 #include "main/texobj.h"
     35 #include "program/prog_instruction.h"
     36 
     37 #include "st_context.h"
     38 #include "st_sampler_view.h"
     39 #include "st_texture.h"
     40 #include "st_format.h"
     41 #include "st_cb_bufferobjects.h"
     42 #include "st_cb_texture.h"
     43 
     44 
     45 /**
     46  * Set the given view as the current context's view for the texture.
     47  *
     48  * Overwrites any pre-existing view of the context.
     49  *
     50  * Takes ownership of the view (i.e., stores the view without incrementing the
     51  * reference count).
     52  *
     53  * \return the view, or NULL on error. In case of error, the reference to the
     54  * view is released.
     55  */
     56 static struct pipe_sampler_view *
     57 st_texture_set_sampler_view(struct st_context *st,
     58                             struct st_texture_object *stObj,
     59                             struct pipe_sampler_view *view,
     60                             bool glsl130_or_later, bool srgb_skip_decode)
     61 {
     62    struct st_sampler_views *views;
     63    struct st_sampler_view *free = NULL;
     64    struct st_sampler_view *sv;
     65    GLuint i;
     66 
     67    simple_mtx_lock(&stObj->validate_mutex);
     68    views = stObj->sampler_views;
     69 
     70    for (i = 0; i < views->count; ++i) {
     71       sv = &views->views[i];
     72 
     73       /* Is the array entry used ? */
     74       if (sv->view) {
     75          /* check if the context matches */
     76          if (sv->view->context == st->pipe) {
     77             pipe_sampler_view_release(st->pipe, &sv->view);
     78             goto found;
     79          }
     80       } else {
     81          /* Found a free slot, remember that */
     82          free = sv;
     83       }
     84    }
     85 
     86    /* Couldn't find a slot for our context, create a new one */
     87    if (free) {
     88       sv = free;
     89    } else {
     90       if (views->count >= views->max) {
     91          /* Allocate a larger container. */
     92          unsigned new_max = 2 * views->max;
     93          unsigned new_size = sizeof(*views) + new_max * sizeof(views->views[0]);
     94 
     95          if (new_max < views->max ||
     96              new_max > (UINT_MAX - sizeof(*views)) / sizeof(views->views[0])) {
     97             pipe_sampler_view_release(st->pipe, &view);
     98             goto out;
     99          }
    100 
    101          struct st_sampler_views *new_views = malloc(new_size);
    102          if (!new_views) {
    103             pipe_sampler_view_release(st->pipe, &view);
    104             goto out;
    105          }
    106 
    107          new_views->count = views->count;
    108          new_views->max = new_max;
    109          memcpy(&new_views->views[0], &views->views[0],
    110                views->count * sizeof(views->views[0]));
    111 
    112          /* Initialize the pipe_sampler_view pointers to zero so that we don't
    113           * have to worry about racing against readers when incrementing
    114           * views->count.
    115           */
    116          memset(&new_views->views[views->count], 0,
    117                 (new_max - views->count) * sizeof(views->views[0]));
    118 
    119          /* Use memory release semantics to ensure that concurrent readers will
    120           * get the correct contents of the new container.
    121           *
    122           * Also, the write should be atomic, but that's guaranteed anyway on
    123           * all supported platforms.
    124           */
    125          p_atomic_set(&stObj->sampler_views, new_views);
    126 
    127          /* We keep the old container around until the texture object is
    128           * deleted, because another thread may still be reading from it. We
    129           * double the size of the container each time, so we end up with
    130           * at most twice the total memory allocation.
    131           */
    132          views->next = stObj->sampler_views_old;
    133          stObj->sampler_views_old = views;
    134 
    135          views = new_views;
    136       }
    137 
    138       sv = &views->views[views->count];
    139 
    140       /* Since modification is guarded by the lock, only the write part of the
    141        * increment has to be atomic, and that's already guaranteed on all
    142        * supported platforms without using an atomic intrinsic.
    143        */
    144       views->count++;
    145    }
    146 
    147 found:
    148    assert(sv->view == NULL);
    149 
    150    sv->glsl130_or_later = glsl130_or_later;
    151    sv->srgb_skip_decode = srgb_skip_decode;
    152    sv->view = view;
    153 
    154 out:
    155    simple_mtx_unlock(&stObj->validate_mutex);
    156    return view;
    157 }
    158 
    159 
    160 /**
    161  * Return the most-recently validated sampler view for the texture \p stObj
    162  * in the given context, if any.
    163  *
    164  * Performs no additional validation.
    165  */
    166 const struct st_sampler_view *
    167 st_texture_get_current_sampler_view(const struct st_context *st,
    168                                     const struct st_texture_object *stObj)
    169 {
    170    const struct st_sampler_views *views = p_atomic_read(&stObj->sampler_views);
    171 
    172    for (unsigned i = 0; i < views->count; ++i) {
    173       const struct st_sampler_view *sv = &views->views[i];
    174       if (sv->view && sv->view->context == st->pipe)
    175          return sv;
    176    }
    177 
    178    return NULL;
    179 }
    180 
    181 
    182 /**
    183  * For the given texture object, release any sampler views which belong
    184  * to the calling context.
    185  */
    186 void
    187 st_texture_release_sampler_view(struct st_context *st,
    188                                 struct st_texture_object *stObj)
    189 {
    190    GLuint i;
    191 
    192    simple_mtx_lock(&stObj->validate_mutex);
    193    struct st_sampler_views *views = stObj->sampler_views;
    194    for (i = 0; i < views->count; ++i) {
    195       struct pipe_sampler_view **sv = &views->views[i].view;
    196 
    197       if (*sv && (*sv)->context == st->pipe) {
    198          pipe_sampler_view_reference(sv, NULL);
    199          break;
    200       }
    201    }
    202    simple_mtx_unlock(&stObj->validate_mutex);
    203 }
    204 
    205 
    206 /**
    207  * Release all sampler views attached to the given texture object, regardless
    208  * of the context.
    209  */
    210 void
    211 st_texture_release_all_sampler_views(struct st_context *st,
    212                                      struct st_texture_object *stObj)
    213 {
    214    GLuint i;
    215 
    216    /* TODO: This happens while a texture is deleted, because the Driver API
    217     * is asymmetric: the driver allocates the texture object memory, but
    218     * mesa/main frees it.
    219     */
    220    if (!stObj->sampler_views)
    221       return;
    222 
    223    simple_mtx_lock(&stObj->validate_mutex);
    224    struct st_sampler_views *views = stObj->sampler_views;
    225    for (i = 0; i < views->count; ++i)
    226       pipe_sampler_view_release(st->pipe, &views->views[i].view);
    227    simple_mtx_unlock(&stObj->validate_mutex);
    228 }
    229 
    230 
    231 void
    232 st_texture_free_sampler_views(struct st_texture_object *stObj)
    233 {
    234    free(stObj->sampler_views);
    235    stObj->sampler_views = NULL;
    236 
    237    while (stObj->sampler_views_old) {
    238       struct st_sampler_views *views = stObj->sampler_views_old;
    239       stObj->sampler_views_old = views->next;
    240       free(views);
    241    }
    242 }
    243 
    244 
    245 /**
    246  * Return swizzle1(swizzle2)
    247  */
    248 static unsigned
    249 swizzle_swizzle(unsigned swizzle1, unsigned swizzle2)
    250 {
    251    unsigned i, swz[4];
    252 
    253    if (swizzle1 == SWIZZLE_XYZW) {
    254       /* identity swizzle, no change to swizzle2 */
    255       return swizzle2;
    256    }
    257 
    258    for (i = 0; i < 4; i++) {
    259       unsigned s = GET_SWZ(swizzle1, i);
    260       switch (s) {
    261       case SWIZZLE_X:
    262       case SWIZZLE_Y:
    263       case SWIZZLE_Z:
    264       case SWIZZLE_W:
    265          swz[i] = GET_SWZ(swizzle2, s);
    266          break;
    267       case SWIZZLE_ZERO:
    268          swz[i] = SWIZZLE_ZERO;
    269          break;
    270       case SWIZZLE_ONE:
    271          swz[i] = SWIZZLE_ONE;
    272          break;
    273       default:
    274          assert(!"Bad swizzle term");
    275          swz[i] = SWIZZLE_X;
    276       }
    277    }
    278 
    279    return MAKE_SWIZZLE4(swz[0], swz[1], swz[2], swz[3]);
    280 }
    281 
    282 
    283 /**
    284  * Given a user-specified texture base format, the actual gallium texture
    285  * format and the current GL_DEPTH_MODE, return a texture swizzle.
    286  *
    287  * Consider the case where the user requests a GL_RGB internal texture
    288  * format the driver actually uses an RGBA format.  The A component should
    289  * be ignored and sampling from the texture should always return (r,g,b,1).
    290  * But if we rendered to the texture we might have written A values != 1.
    291  * By sampling the texture with a ".xyz1" swizzle we'll get the expected A=1.
    292  * This function computes the texture swizzle needed to get the expected
    293  * values.
    294  *
    295  * In the case of depth textures, the GL_DEPTH_MODE state determines the
    296  * texture swizzle.
    297  *
    298  * This result must be composed with the user-specified swizzle to get
    299  * the final swizzle.
    300  */
    301 static unsigned
    302 compute_texture_format_swizzle(GLenum baseFormat, GLenum depthMode,
    303                                bool glsl130_or_later)
    304 {
    305    switch (baseFormat) {
    306    case GL_RGBA:
    307       return SWIZZLE_XYZW;
    308    case GL_RGB:
    309       return MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_ONE);
    310    case GL_RG:
    311       return MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_ZERO, SWIZZLE_ONE);
    312    case GL_RED:
    313       return MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_ZERO,
    314                            SWIZZLE_ZERO, SWIZZLE_ONE);
    315    case GL_ALPHA:
    316       return MAKE_SWIZZLE4(SWIZZLE_ZERO, SWIZZLE_ZERO,
    317                            SWIZZLE_ZERO, SWIZZLE_W);
    318    case GL_LUMINANCE:
    319       return MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_X, SWIZZLE_X, SWIZZLE_ONE);
    320    case GL_LUMINANCE_ALPHA:
    321       return MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_X, SWIZZLE_X, SWIZZLE_W);
    322    case GL_INTENSITY:
    323       return SWIZZLE_XXXX;
    324    case GL_STENCIL_INDEX:
    325    case GL_DEPTH_STENCIL:
    326    case GL_DEPTH_COMPONENT:
    327       /* Now examine the depth mode */
    328       switch (depthMode) {
    329       case GL_LUMINANCE:
    330          return MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_X, SWIZZLE_X, SWIZZLE_ONE);
    331       case GL_INTENSITY:
    332          return MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_X, SWIZZLE_X, SWIZZLE_X);
    333       case GL_ALPHA:
    334          /* The texture(sampler*Shadow) functions from GLSL 1.30 ignore
    335           * the depth mode and return float, while older shadow* functions
    336           * and ARB_fp instructions return vec4 according to the depth mode.
    337           *
    338           * The problem with the GLSL 1.30 functions is that GL_ALPHA forces
    339           * them to return 0, breaking them completely.
    340           *
    341           * A proper fix would increase code complexity and that's not worth
    342           * it for a rarely used feature such as the GL_ALPHA depth mode
    343           * in GL3. Therefore, change GL_ALPHA to GL_INTENSITY for all
    344           * shaders that use GLSL 1.30 or later.
    345           *
    346           * BTW, it's required that sampler views are updated when
    347           * shaders change (check_sampler_swizzle takes care of that).
    348           */
    349          if (glsl130_or_later)
    350             return SWIZZLE_XXXX;
    351          else
    352             return MAKE_SWIZZLE4(SWIZZLE_ZERO, SWIZZLE_ZERO,
    353                                  SWIZZLE_ZERO, SWIZZLE_X);
    354       case GL_RED:
    355          return MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_ZERO,
    356                               SWIZZLE_ZERO, SWIZZLE_ONE);
    357       default:
    358          assert(!"Unexpected depthMode");
    359          return SWIZZLE_XYZW;
    360       }
    361    default:
    362       assert(!"Unexpected baseFormat");
    363       return SWIZZLE_XYZW;
    364    }
    365 }
    366 
    367 
    368 static unsigned
    369 get_texture_format_swizzle(const struct st_context *st,
    370                            const struct st_texture_object *stObj,
    371                            bool glsl130_or_later)
    372 {
    373    GLenum baseFormat = _mesa_base_tex_image(&stObj->base)->_BaseFormat;
    374    unsigned tex_swizzle;
    375    GLenum depth_mode = stObj->base.DepthMode;
    376 
    377    /* In ES 3.0, DEPTH_TEXTURE_MODE is expected to be GL_RED for textures
    378     * with depth component data specified with a sized internal format.
    379     */
    380    if (_mesa_is_gles3(st->ctx) &&
    381        (baseFormat == GL_DEPTH_COMPONENT ||
    382         baseFormat == GL_DEPTH_STENCIL ||
    383         baseFormat == GL_STENCIL_INDEX)) {
    384       const struct gl_texture_image *firstImage =
    385          _mesa_base_tex_image(&stObj->base);
    386       if (firstImage->InternalFormat != GL_DEPTH_COMPONENT &&
    387           firstImage->InternalFormat != GL_DEPTH_STENCIL &&
    388           firstImage->InternalFormat != GL_STENCIL_INDEX)
    389          depth_mode = GL_RED;
    390    }
    391    tex_swizzle = compute_texture_format_swizzle(baseFormat,
    392                                                 depth_mode,
    393                                                 glsl130_or_later);
    394 
    395    /* Combine the texture format swizzle with user's swizzle */
    396    return swizzle_swizzle(stObj->base._Swizzle, tex_swizzle);
    397 }
    398 
    399 
    400 /**
    401  * Return TRUE if the texture's sampler view swizzle is not equal to
    402  * the texture's swizzle.
    403  *
    404  * \param stObj  the st texture object,
    405  */
    406 MAYBE_UNUSED static boolean
    407 check_sampler_swizzle(const struct st_context *st,
    408                       const struct st_texture_object *stObj,
    409                       const struct pipe_sampler_view *sv,
    410                       bool glsl130_or_later)
    411 {
    412    unsigned swizzle = get_texture_format_swizzle(st, stObj, glsl130_or_later);
    413 
    414    return ((sv->swizzle_r != GET_SWZ(swizzle, 0)) ||
    415            (sv->swizzle_g != GET_SWZ(swizzle, 1)) ||
    416            (sv->swizzle_b != GET_SWZ(swizzle, 2)) ||
    417            (sv->swizzle_a != GET_SWZ(swizzle, 3)));
    418 }
    419 
    420 
    421 static unsigned
    422 last_level(const struct st_texture_object *stObj)
    423 {
    424    unsigned ret = MIN2(stObj->base.MinLevel + stObj->base._MaxLevel,
    425                        stObj->pt->last_level);
    426    if (stObj->base.Immutable)
    427       ret = MIN2(ret, stObj->base.MinLevel + stObj->base.NumLevels - 1);
    428    return ret;
    429 }
    430 
    431 
    432 static unsigned
    433 last_layer(const struct st_texture_object *stObj)
    434 {
    435    if (stObj->base.Immutable && stObj->pt->array_size > 1)
    436       return MIN2(stObj->base.MinLayer + stObj->base.NumLayers - 1,
    437                   stObj->pt->array_size - 1);
    438    return stObj->pt->array_size - 1;
    439 }
    440 
    441 
    442 /**
    443  * Determine the format for the texture sampler view.
    444  */
    445 static enum pipe_format
    446 get_sampler_view_format(struct st_context *st,
    447                         const struct st_texture_object *stObj,
    448                         bool srgb_skip_decode)
    449 {
    450    enum pipe_format format;
    451 
    452    GLenum baseFormat = _mesa_base_tex_image(&stObj->base)->_BaseFormat;
    453    format = stObj->surface_based ? stObj->surface_format : stObj->pt->format;
    454 
    455    if (baseFormat == GL_DEPTH_COMPONENT ||
    456        baseFormat == GL_DEPTH_STENCIL ||
    457        baseFormat == GL_STENCIL_INDEX) {
    458       if (stObj->base.StencilSampling || baseFormat == GL_STENCIL_INDEX)
    459          format = util_format_stencil_only(format);
    460 
    461       return format;
    462    }
    463 
    464    /* If sRGB decoding is off, use the linear format */
    465    if (srgb_skip_decode)
    466       format = util_format_linear(format);
    467 
    468    /* Use R8_UNORM for video formats */
    469    switch (format) {
    470    case PIPE_FORMAT_NV12:
    471    case PIPE_FORMAT_IYUV:
    472       format = PIPE_FORMAT_R8_UNORM;
    473       break;
    474    default:
    475       break;
    476    }
    477    return format;
    478 }
    479 
    480 
    481 static struct pipe_sampler_view *
    482 st_create_texture_sampler_view_from_stobj(struct st_context *st,
    483 					  struct st_texture_object *stObj,
    484 					  enum pipe_format format,
    485                                           bool glsl130_or_later)
    486 {
    487    /* There is no need to clear this structure (consider CPU overhead). */
    488    struct pipe_sampler_view templ;
    489    unsigned swizzle = get_texture_format_swizzle(st, stObj, glsl130_or_later);
    490 
    491    templ.format = format;
    492 
    493    if (stObj->level_override) {
    494       templ.u.tex.first_level = templ.u.tex.last_level = stObj->level_override;
    495    } else {
    496       templ.u.tex.first_level = stObj->base.MinLevel + stObj->base.BaseLevel;
    497       templ.u.tex.last_level = last_level(stObj);
    498    }
    499    if (stObj->layer_override) {
    500       templ.u.tex.first_layer = templ.u.tex.last_layer = stObj->layer_override;
    501    } else {
    502       templ.u.tex.first_layer = stObj->base.MinLayer;
    503       templ.u.tex.last_layer = last_layer(stObj);
    504    }
    505    assert(templ.u.tex.first_layer <= templ.u.tex.last_layer);
    506    assert(templ.u.tex.first_level <= templ.u.tex.last_level);
    507    templ.target = gl_target_to_pipe(stObj->base.Target);
    508 
    509    templ.swizzle_r = GET_SWZ(swizzle, 0);
    510    templ.swizzle_g = GET_SWZ(swizzle, 1);
    511    templ.swizzle_b = GET_SWZ(swizzle, 2);
    512    templ.swizzle_a = GET_SWZ(swizzle, 3);
    513 
    514    return st->pipe->create_sampler_view(st->pipe, stObj->pt, &templ);
    515 }
    516 
    517 
    518 struct pipe_sampler_view *
    519 st_get_texture_sampler_view_from_stobj(struct st_context *st,
    520                                        struct st_texture_object *stObj,
    521                                        const struct gl_sampler_object *samp,
    522                                        bool glsl130_or_later,
    523                                        bool ignore_srgb_decode)
    524 {
    525    const struct st_sampler_view *sv;
    526    bool srgb_skip_decode = false;
    527 
    528    if (!ignore_srgb_decode && samp->sRGBDecode == GL_SKIP_DECODE_EXT)
    529       srgb_skip_decode = true;
    530 
    531    sv = st_texture_get_current_sampler_view(st, stObj);
    532 
    533    if (sv &&
    534        sv->glsl130_or_later == glsl130_or_later &&
    535        sv->srgb_skip_decode == srgb_skip_decode) {
    536       /* Debug check: make sure that the sampler view's parameters are
    537        * what they're supposed to be.
    538        */
    539       struct pipe_sampler_view *view = sv->view;
    540       assert(stObj->pt == view->texture);
    541       assert(!check_sampler_swizzle(st, stObj, view, glsl130_or_later));
    542       assert(get_sampler_view_format(st, stObj, srgb_skip_decode) == view->format);
    543       assert(gl_target_to_pipe(stObj->base.Target) == view->target);
    544       assert(stObj->level_override ||
    545              stObj->base.MinLevel + stObj->base.BaseLevel == view->u.tex.first_level);
    546       assert(stObj->level_override || last_level(stObj) == view->u.tex.last_level);
    547       assert(stObj->layer_override || stObj->base.MinLayer == view->u.tex.first_layer);
    548       assert(stObj->layer_override || last_layer(stObj) == view->u.tex.last_layer);
    549       assert(!stObj->layer_override ||
    550              (stObj->layer_override == view->u.tex.first_layer &&
    551               stObj->layer_override == view->u.tex.last_layer));
    552       return view;
    553    }
    554 
    555    /* create new sampler view */
    556    enum pipe_format format = get_sampler_view_format(st, stObj, srgb_skip_decode);
    557    struct pipe_sampler_view *view =
    558          st_create_texture_sampler_view_from_stobj(st, stObj, format, glsl130_or_later);
    559 
    560    view = st_texture_set_sampler_view(st, stObj, view, glsl130_or_later, srgb_skip_decode);
    561 
    562    return view;
    563 }
    564 
    565 
    566 struct pipe_sampler_view *
    567 st_get_buffer_sampler_view_from_stobj(struct st_context *st,
    568                                       struct st_texture_object *stObj)
    569 {
    570    const struct st_sampler_view *sv;
    571    struct st_buffer_object *stBuf =
    572       st_buffer_object(stObj->base.BufferObject);
    573 
    574    if (!stBuf || !stBuf->buffer)
    575       return NULL;
    576 
    577    sv = st_texture_get_current_sampler_view(st, stObj);
    578 
    579    struct pipe_resource *buf = stBuf->buffer;
    580 
    581    if (sv) {
    582       struct pipe_sampler_view *view = sv->view;
    583 
    584       if (view->texture == buf) {
    585          /* Debug check: make sure that the sampler view's parameters are
    586           * what they're supposed to be.
    587           */
    588          assert(st_mesa_format_to_pipe_format(st, stObj->base._BufferObjectFormat)
    589              == view->format);
    590          assert(view->target == PIPE_BUFFER);
    591          unsigned base = stObj->base.BufferOffset;
    592          MAYBE_UNUSED unsigned size = MIN2(buf->width0 - base,
    593                            (unsigned) stObj->base.BufferSize);
    594          assert(view->u.buf.offset == base);
    595          assert(view->u.buf.size == size);
    596          return view;
    597       }
    598    }
    599 
    600    unsigned base = stObj->base.BufferOffset;
    601 
    602    if (base >= buf->width0)
    603       return NULL;
    604 
    605    unsigned size = buf->width0 - base;
    606    size = MIN2(size, (unsigned)stObj->base.BufferSize);
    607    if (!size)
    608       return NULL;
    609 
    610    /* Create a new sampler view. There is no need to clear the entire
    611     * structure (consider CPU overhead).
    612     */
    613    struct pipe_sampler_view templ;
    614 
    615    templ.format =
    616       st_mesa_format_to_pipe_format(st, stObj->base._BufferObjectFormat);
    617    templ.target = PIPE_BUFFER;
    618    templ.swizzle_r = PIPE_SWIZZLE_X;
    619    templ.swizzle_g = PIPE_SWIZZLE_Y;
    620    templ.swizzle_b = PIPE_SWIZZLE_Z;
    621    templ.swizzle_a = PIPE_SWIZZLE_W;
    622    templ.u.buf.offset = base;
    623    templ.u.buf.size = size;
    624 
    625    struct pipe_sampler_view *view =
    626       st->pipe->create_sampler_view(st->pipe, buf, &templ);
    627 
    628    view = st_texture_set_sampler_view(st, stObj, view, false, false);
    629 
    630    return view;
    631 }
    632