~mmach/netext73/mesa-haswell

« back to all changes in this revision

Viewing changes to src/mesa/state_tracker/st_sampler_view.c

  • Committer: mmach
  • Date: 2022-09-22 19:56:13 UTC
  • Revision ID: netbit73@gmail.com-20220922195613-wtik9mmy20tmor0i
2022-09-22 21:17:09

Show diffs side-by-side

added added

removed removed

Lines of Context:
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/format/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_texture.h"
42
 
 
43
 
/* Subtract remaining private references. Typically used before
44
 
 * destruction. See the header file for explanation.
45
 
 */
46
 
static void
47
 
st_remove_private_references(struct st_sampler_view *sv)
48
 
{
49
 
   if (sv->private_refcount) {
50
 
      assert(sv->private_refcount > 0);
51
 
      p_atomic_add(&sv->view->reference.count, -sv->private_refcount);
52
 
      sv->private_refcount = 0;
53
 
   }
54
 
}
55
 
 
56
 
/* Return a sampler view while incrementing the refcount by 1. */
57
 
static struct pipe_sampler_view *
58
 
get_sampler_view_reference(struct st_sampler_view *sv,
59
 
                           struct pipe_sampler_view *view)
60
 
{
61
 
   if (unlikely(sv->private_refcount <= 0)) {
62
 
      assert(sv->private_refcount == 0);
63
 
 
64
 
      /* This is the number of atomic increments we will skip. */
65
 
      sv->private_refcount = 100000000;
66
 
      p_atomic_add(&view->reference.count, sv->private_refcount);
67
 
   }
68
 
 
69
 
   /* Return a reference while decrementing the private refcount. */
70
 
   sv->private_refcount--;
71
 
   return view;
72
 
}
73
 
 
74
 
/**
75
 
 * Set the given view as the current context's view for the texture.
76
 
 *
77
 
 * Overwrites any pre-existing view of the context.
78
 
 *
79
 
 * Takes ownership of the view (i.e., stores the view without incrementing the
80
 
 * reference count).
81
 
 *
82
 
 * \return the view, or NULL on error. In case of error, the reference to the
83
 
 * view is released.
84
 
 */
85
 
static struct pipe_sampler_view *
86
 
st_texture_set_sampler_view(struct st_context *st,
87
 
                            struct gl_texture_object *stObj,
88
 
                            struct pipe_sampler_view *view,
89
 
                            bool glsl130_or_later, bool srgb_skip_decode,
90
 
                            bool get_reference, bool locked)
91
 
{
92
 
   struct st_sampler_views *views;
93
 
   struct st_sampler_view *free = NULL;
94
 
   struct st_sampler_view *sv;
95
 
   GLuint i;
96
 
 
97
 
   if (!locked)
98
 
      simple_mtx_lock(&stObj->validate_mutex);
99
 
   views = stObj->sampler_views;
100
 
 
101
 
   for (i = 0; i < views->count; ++i) {
102
 
      sv = &views->views[i];
103
 
 
104
 
      /* Is the array entry used ? */
105
 
      if (sv->view) {
106
 
         /* check if the context matches */
107
 
         if (sv->view->context == st->pipe) {
108
 
            st_remove_private_references(sv);
109
 
            pipe_sampler_view_reference(&sv->view, NULL);
110
 
            goto found;
111
 
         }
112
 
      } else {
113
 
         /* Found a free slot, remember that */
114
 
         free = sv;
115
 
      }
116
 
   }
117
 
 
118
 
   /* Couldn't find a slot for our context, create a new one */
119
 
   if (free) {
120
 
      sv = free;
121
 
   } else {
122
 
      if (views->count >= views->max) {
123
 
         /* Allocate a larger container. */
124
 
         unsigned new_max = 2 * views->max;
125
 
         unsigned new_size = sizeof(*views) + new_max * sizeof(views->views[0]);
126
 
 
127
 
         if (new_max < views->max ||
128
 
             new_max > (UINT_MAX - sizeof(*views)) / sizeof(views->views[0])) {
129
 
            pipe_sampler_view_reference(&view, NULL);
130
 
            goto out;
131
 
         }
132
 
 
133
 
         struct st_sampler_views *new_views = malloc(new_size);
134
 
         if (!new_views) {
135
 
            pipe_sampler_view_reference(&view, NULL);
136
 
            goto out;
137
 
         }
138
 
 
139
 
         new_views->count = views->count;
140
 
         new_views->max = new_max;
141
 
         memcpy(&new_views->views[0], &views->views[0],
142
 
               views->count * sizeof(views->views[0]));
143
 
 
144
 
         /* Initialize the pipe_sampler_view pointers to zero so that we don't
145
 
          * have to worry about racing against readers when incrementing
146
 
          * views->count.
147
 
          */
148
 
         memset(&new_views->views[views->count], 0,
149
 
                (new_max - views->count) * sizeof(views->views[0]));
150
 
 
151
 
         /* Use memory release semantics to ensure that concurrent readers will
152
 
          * get the correct contents of the new container.
153
 
          *
154
 
          * Also, the write should be atomic, but that's guaranteed anyway on
155
 
          * all supported platforms.
156
 
          */
157
 
         p_atomic_set(&stObj->sampler_views, new_views);
158
 
 
159
 
         /* We keep the old container around until the texture object is
160
 
          * deleted, because another thread may still be reading from it. We
161
 
          * double the size of the container each time, so we end up with
162
 
          * at most twice the total memory allocation.
163
 
          */
164
 
         views->next = stObj->sampler_views_old;
165
 
         stObj->sampler_views_old = views;
166
 
 
167
 
         views = new_views;
168
 
      }
169
 
 
170
 
      sv = &views->views[views->count];
171
 
 
172
 
      /* Since modification is guarded by the lock, only the write part of the
173
 
       * increment has to be atomic, and that's already guaranteed on all
174
 
       * supported platforms without using an atomic intrinsic.
175
 
       */
176
 
      views->count++;
177
 
   }
178
 
 
179
 
found:
180
 
   assert(sv->view == NULL);
181
 
 
182
 
   sv->glsl130_or_later = glsl130_or_later;
183
 
   sv->srgb_skip_decode = srgb_skip_decode;
184
 
   sv->view = view;
185
 
   sv->st = st;
186
 
 
187
 
   if (get_reference)
188
 
      view = get_sampler_view_reference(sv, view);
189
 
 
190
 
out:
191
 
   if (!locked)
192
 
      simple_mtx_unlock(&stObj->validate_mutex);
193
 
   return view;
194
 
}
195
 
 
196
 
 
197
 
/**
198
 
 * Return the most-recently validated sampler view for the texture \p stObj
199
 
 * in the given context, if any.
200
 
 *
201
 
 * Performs no additional validation.
202
 
 */
203
 
struct st_sampler_view *
204
 
st_texture_get_current_sampler_view(const struct st_context *st,
205
 
                                    const struct gl_texture_object *stObj)
206
 
{
207
 
   struct st_sampler_views *views = p_atomic_read(&stObj->sampler_views);
208
 
 
209
 
   for (unsigned i = 0; i < views->count; ++i) {
210
 
      struct st_sampler_view *sv = &views->views[i];
211
 
      if (sv->view && sv->view->context == st->pipe)
212
 
         return sv;
213
 
   }
214
 
 
215
 
   return NULL;
216
 
}
217
 
 
218
 
 
219
 
/**
220
 
 * For the given texture object, release any sampler views which belong
221
 
 * to the calling context.  This is used to free any sampler views
222
 
 * which belong to the context before the context is destroyed.
223
 
 */
224
 
void
225
 
st_texture_release_context_sampler_view(struct st_context *st,
226
 
                                        struct gl_texture_object *stObj)
227
 
{
228
 
   GLuint i;
229
 
 
230
 
   simple_mtx_lock(&stObj->validate_mutex);
231
 
   struct st_sampler_views *views = stObj->sampler_views;
232
 
   for (i = 0; i < views->count; ++i) {
233
 
      struct st_sampler_view *sv = &views->views[i];
234
 
 
235
 
      if (sv->view && sv->view->context == st->pipe) {
236
 
         st_remove_private_references(sv);
237
 
         pipe_sampler_view_reference(&sv->view, NULL);
238
 
         break;
239
 
      }
240
 
   }
241
 
   simple_mtx_unlock(&stObj->validate_mutex);
242
 
}
243
 
 
244
 
 
245
 
/**
246
 
 * Release all sampler views attached to the given texture object, regardless
247
 
 * of the context.  This is called fairly frequently.  For example, whenever
248
 
 * the texture's base level, max level or swizzle change.
249
 
 */
250
 
void
251
 
st_texture_release_all_sampler_views(struct st_context *st,
252
 
                                     struct gl_texture_object *stObj)
253
 
{
254
 
   /* TODO: This happens while a texture is deleted, because the Driver API
255
 
    * is asymmetric: the driver allocates the texture object memory, but
256
 
    * mesa/main frees it.
257
 
    */
258
 
   if (!stObj->sampler_views)
259
 
      return;
260
 
 
261
 
   simple_mtx_lock(&stObj->validate_mutex);
262
 
   struct st_sampler_views *views = stObj->sampler_views;
263
 
   for (unsigned i = 0; i < views->count; ++i) {
264
 
      struct st_sampler_view *stsv = &views->views[i];
265
 
      if (stsv->view) {
266
 
         st_remove_private_references(stsv);
267
 
 
268
 
         if (stsv->st && stsv->st != st) {
269
 
            /* Transfer this reference to the zombie list.  It will
270
 
             * likely be freed when the zombie list is freed.
271
 
             */
272
 
            st_save_zombie_sampler_view(stsv->st, stsv->view);
273
 
            stsv->view = NULL;
274
 
         } else {
275
 
            pipe_sampler_view_reference(&stsv->view, NULL);
276
 
         }
277
 
      }
278
 
   }
279
 
   views->count = 0;
280
 
   simple_mtx_unlock(&stObj->validate_mutex);
281
 
}
282
 
 
283
 
 
284
 
/*
285
 
 * Delete the texture's sampler views and st_sampler_views containers.
286
 
 * This is to be called just before a texture is deleted.
287
 
 */
288
 
void
289
 
st_delete_texture_sampler_views(struct st_context *st,
290
 
                                struct gl_texture_object *stObj)
291
 
{
292
 
   st_texture_release_all_sampler_views(st, stObj);
293
 
 
294
 
   /* Free the container of the current per-context sampler views */
295
 
   assert(stObj->sampler_views->count == 0);
296
 
   free(stObj->sampler_views);
297
 
   stObj->sampler_views = NULL;
298
 
 
299
 
   /* Free old sampler view containers */
300
 
   while (stObj->sampler_views_old) {
301
 
      struct st_sampler_views *views = stObj->sampler_views_old;
302
 
      stObj->sampler_views_old = views->next;
303
 
      free(views);
304
 
   }
305
 
}
306
 
 
307
 
 
308
 
/**
309
 
 * Return swizzle1(swizzle2)
310
 
 */
311
 
static unsigned
312
 
swizzle_swizzle(unsigned swizzle1, unsigned swizzle2)
313
 
{
314
 
   unsigned i, swz[4];
315
 
 
316
 
   if (swizzle1 == SWIZZLE_XYZW) {
317
 
      /* identity swizzle, no change to swizzle2 */
318
 
      return swizzle2;
319
 
   }
320
 
 
321
 
   for (i = 0; i < 4; i++) {
322
 
      unsigned s = GET_SWZ(swizzle1, i);
323
 
      switch (s) {
324
 
      case SWIZZLE_X:
325
 
      case SWIZZLE_Y:
326
 
      case SWIZZLE_Z:
327
 
      case SWIZZLE_W:
328
 
         swz[i] = GET_SWZ(swizzle2, s);
329
 
         break;
330
 
      case SWIZZLE_ZERO:
331
 
         swz[i] = SWIZZLE_ZERO;
332
 
         break;
333
 
      case SWIZZLE_ONE:
334
 
         swz[i] = SWIZZLE_ONE;
335
 
         break;
336
 
      default:
337
 
         assert(!"Bad swizzle term");
338
 
         swz[i] = SWIZZLE_X;
339
 
      }
340
 
   }
341
 
 
342
 
   return MAKE_SWIZZLE4(swz[0], swz[1], swz[2], swz[3]);
343
 
}
344
 
 
345
 
 
346
 
/**
347
 
 * Given a user-specified texture base format, the actual gallium texture
348
 
 * format and the current GL_DEPTH_MODE, return a texture swizzle.
349
 
 *
350
 
 * Consider the case where the user requests a GL_RGB internal texture
351
 
 * format the driver actually uses an RGBA format.  The A component should
352
 
 * be ignored and sampling from the texture should always return (r,g,b,1).
353
 
 * But if we rendered to the texture we might have written A values != 1.
354
 
 * By sampling the texture with a ".xyz1" swizzle we'll get the expected A=1.
355
 
 * This function computes the texture swizzle needed to get the expected
356
 
 * values.
357
 
 *
358
 
 * In the case of depth textures, the GL_DEPTH_MODE state determines the
359
 
 * texture swizzle.
360
 
 *
361
 
 * This result must be composed with the user-specified swizzle to get
362
 
 * the final swizzle.
363
 
 */
364
 
static unsigned
365
 
compute_texture_format_swizzle(GLenum baseFormat, GLenum depthMode,
366
 
                               bool glsl130_or_later)
367
 
{
368
 
   switch (baseFormat) {
369
 
   case GL_RGBA:
370
 
      return SWIZZLE_XYZW;
371
 
   case GL_RGB:
372
 
      return MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_ONE);
373
 
   case GL_RG:
374
 
      return MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_ZERO, SWIZZLE_ONE);
375
 
   case GL_RED:
376
 
      return MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_ZERO,
377
 
                           SWIZZLE_ZERO, SWIZZLE_ONE);
378
 
   case GL_ALPHA:
379
 
      return MAKE_SWIZZLE4(SWIZZLE_ZERO, SWIZZLE_ZERO,
380
 
                           SWIZZLE_ZERO, SWIZZLE_W);
381
 
   case GL_LUMINANCE:
382
 
      return MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_X, SWIZZLE_X, SWIZZLE_ONE);
383
 
   case GL_LUMINANCE_ALPHA:
384
 
      return MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_X, SWIZZLE_X, SWIZZLE_W);
385
 
   case GL_INTENSITY:
386
 
      return SWIZZLE_XXXX;
387
 
   case GL_STENCIL_INDEX:
388
 
   case GL_DEPTH_STENCIL:
389
 
   case GL_DEPTH_COMPONENT:
390
 
      /* Now examine the depth mode */
391
 
      switch (depthMode) {
392
 
      case GL_LUMINANCE:
393
 
         return MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_X, SWIZZLE_X, SWIZZLE_ONE);
394
 
      case GL_INTENSITY:
395
 
         return MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_X, SWIZZLE_X, SWIZZLE_X);
396
 
      case GL_ALPHA:
397
 
         /* The texture(sampler*Shadow) functions from GLSL 1.30 ignore
398
 
          * the depth mode and return float, while older shadow* functions
399
 
          * and ARB_fp instructions return vec4 according to the depth mode.
400
 
          *
401
 
          * The problem with the GLSL 1.30 functions is that GL_ALPHA forces
402
 
          * them to return 0, breaking them completely.
403
 
          *
404
 
          * A proper fix would increase code complexity and that's not worth
405
 
          * it for a rarely used feature such as the GL_ALPHA depth mode
406
 
          * in GL3. Therefore, change GL_ALPHA to GL_INTENSITY for all
407
 
          * shaders that use GLSL 1.30 or later.
408
 
          *
409
 
          * BTW, it's required that sampler views are updated when
410
 
          * shaders change (check_sampler_swizzle takes care of that).
411
 
          */
412
 
         if (glsl130_or_later)
413
 
            return SWIZZLE_XXXX;
414
 
         else
415
 
            return MAKE_SWIZZLE4(SWIZZLE_ZERO, SWIZZLE_ZERO,
416
 
                                 SWIZZLE_ZERO, SWIZZLE_X);
417
 
      case GL_RED:
418
 
         return MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_ZERO,
419
 
                              SWIZZLE_ZERO, SWIZZLE_ONE);
420
 
      default:
421
 
         assert(!"Unexpected depthMode");
422
 
         return SWIZZLE_XYZW;
423
 
      }
424
 
   default:
425
 
      assert(!"Unexpected baseFormat");
426
 
      return SWIZZLE_XYZW;
427
 
   }
428
 
}
429
 
 
430
 
 
431
 
static unsigned
432
 
get_texture_format_swizzle(const struct st_context *st,
433
 
                           const struct gl_texture_object *texObj,
434
 
                           bool glsl130_or_later)
435
 
{
436
 
   GLenum baseFormat = _mesa_base_tex_image(texObj)->_BaseFormat;
437
 
   unsigned tex_swizzle;
438
 
   GLenum depth_mode = texObj->Attrib.DepthMode;
439
 
 
440
 
   /* In ES 3.0, DEPTH_TEXTURE_MODE is expected to be GL_RED for textures
441
 
    * with depth component data specified with a sized internal format.
442
 
    */
443
 
   if (_mesa_is_gles3(st->ctx) &&
444
 
       (baseFormat == GL_DEPTH_COMPONENT ||
445
 
        baseFormat == GL_DEPTH_STENCIL ||
446
 
        baseFormat == GL_STENCIL_INDEX)) {
447
 
      const struct gl_texture_image *firstImage =
448
 
         _mesa_base_tex_image(texObj);
449
 
      if (firstImage->InternalFormat != GL_DEPTH_COMPONENT &&
450
 
          firstImage->InternalFormat != GL_DEPTH_STENCIL &&
451
 
          firstImage->InternalFormat != GL_STENCIL_INDEX)
452
 
         depth_mode = GL_RED;
453
 
   }
454
 
   tex_swizzle = compute_texture_format_swizzle(baseFormat,
455
 
                                                depth_mode,
456
 
                                                glsl130_or_later);
457
 
 
458
 
   /* Combine the texture format swizzle with user's swizzle */
459
 
   return swizzle_swizzle(texObj->Attrib._Swizzle, tex_swizzle);
460
 
}
461
 
 
462
 
 
463
 
/**
464
 
 * Return TRUE if the texture's sampler view swizzle is not equal to
465
 
 * the texture's swizzle.
466
 
 *
467
 
 * \param texObj  the st texture object,
468
 
 */
469
 
ASSERTED static boolean
470
 
check_sampler_swizzle(const struct st_context *st,
471
 
                      const struct gl_texture_object *texObj,
472
 
                      const struct pipe_sampler_view *sv,
473
 
                      bool glsl130_or_later)
474
 
{
475
 
   unsigned swizzle = get_texture_format_swizzle(st, texObj, glsl130_or_later);
476
 
 
477
 
   return ((sv->swizzle_r != GET_SWZ(swizzle, 0)) ||
478
 
           (sv->swizzle_g != GET_SWZ(swizzle, 1)) ||
479
 
           (sv->swizzle_b != GET_SWZ(swizzle, 2)) ||
480
 
           (sv->swizzle_a != GET_SWZ(swizzle, 3)));
481
 
}
482
 
 
483
 
 
484
 
static unsigned
485
 
last_level(const struct gl_texture_object *texObj)
486
 
{
487
 
   unsigned ret = MIN2(texObj->Attrib.MinLevel + texObj->_MaxLevel,
488
 
                       texObj->pt->last_level);
489
 
   if (texObj->Immutable)
490
 
      ret = MIN2(ret, texObj->Attrib.MinLevel +
491
 
                 texObj->Attrib.NumLevels - 1);
492
 
   return ret;
493
 
}
494
 
 
495
 
 
496
 
static unsigned
497
 
last_layer(const struct gl_texture_object *texObj)
498
 
{
499
 
   if (texObj->Immutable && texObj->pt->array_size > 1)
500
 
      return MIN2(texObj->Attrib.MinLayer +
501
 
                  texObj->Attrib.NumLayers - 1,
502
 
                  texObj->pt->array_size - 1);
503
 
   return texObj->pt->array_size - 1;
504
 
}
505
 
 
506
 
 
507
 
/**
508
 
 * Determine the format for the texture sampler view.
509
 
 */
510
 
static enum pipe_format
511
 
get_sampler_view_format(struct st_context *st,
512
 
                        const struct gl_texture_object *texObj,
513
 
                        bool srgb_skip_decode)
514
 
{
515
 
   enum pipe_format format;
516
 
 
517
 
   GLenum baseFormat = _mesa_base_tex_image(texObj)->_BaseFormat;
518
 
   format = texObj->surface_based ? texObj->surface_format : texObj->pt->format;
519
 
 
520
 
   if (baseFormat == GL_DEPTH_COMPONENT ||
521
 
       baseFormat == GL_DEPTH_STENCIL ||
522
 
       baseFormat == GL_STENCIL_INDEX) {
523
 
      if (texObj->StencilSampling || baseFormat == GL_STENCIL_INDEX)
524
 
         format = util_format_stencil_only(format);
525
 
 
526
 
      return format;
527
 
   }
528
 
 
529
 
   /* If sRGB decoding is off, use the linear format */
530
 
   if (srgb_skip_decode)
531
 
      format = util_format_linear(format);
532
 
 
533
 
   /* if resource format matches then YUV wasn't lowered */
534
 
   if (format == texObj->pt->format)
535
 
      return format;
536
 
 
537
 
   /* Use R8_UNORM for video formats */
538
 
   switch (format) {
539
 
   case PIPE_FORMAT_NV12:
540
 
      if (texObj->pt->format == PIPE_FORMAT_R8_G8B8_420_UNORM) {
541
 
         format = PIPE_FORMAT_R8_G8B8_420_UNORM;
542
 
         break;
543
 
      }
544
 
      FALLTHROUGH;
545
 
   case PIPE_FORMAT_IYUV:
546
 
      format = PIPE_FORMAT_R8_UNORM;
547
 
      break;
548
 
   case PIPE_FORMAT_P010:
549
 
   case PIPE_FORMAT_P012:
550
 
   case PIPE_FORMAT_P016:
551
 
      format = PIPE_FORMAT_R16_UNORM;
552
 
      break;
553
 
   case PIPE_FORMAT_Y210:
554
 
   case PIPE_FORMAT_Y212:
555
 
   case PIPE_FORMAT_Y216:
556
 
      format = PIPE_FORMAT_R16G16_UNORM;
557
 
      break;
558
 
   case PIPE_FORMAT_Y410:
559
 
      format = PIPE_FORMAT_R10G10B10A2_UNORM;
560
 
      break;
561
 
   case PIPE_FORMAT_Y412:
562
 
   case PIPE_FORMAT_Y416:
563
 
      format = PIPE_FORMAT_R16G16B16A16_UNORM;
564
 
      break;
565
 
   case PIPE_FORMAT_YUYV:
566
 
   case PIPE_FORMAT_UYVY:
567
 
      if (texObj->pt->format == PIPE_FORMAT_R8G8_R8B8_UNORM ||
568
 
          texObj->pt->format == PIPE_FORMAT_G8R8_B8R8_UNORM) {
569
 
         format = texObj->pt->format;
570
 
         break;
571
 
      }
572
 
      format = PIPE_FORMAT_R8G8_UNORM;
573
 
      break;
574
 
   case PIPE_FORMAT_AYUV:
575
 
      format = PIPE_FORMAT_RGBA8888_UNORM;
576
 
      break;
577
 
   case PIPE_FORMAT_XYUV:
578
 
      format = PIPE_FORMAT_RGBX8888_UNORM;
579
 
      break;
580
 
   default:
581
 
      break;
582
 
   }
583
 
   return format;
584
 
}
585
 
 
586
 
 
587
 
static struct pipe_sampler_view *
588
 
st_create_texture_sampler_view_from_stobj(struct st_context *st,
589
 
                                          struct gl_texture_object *texObj,
590
 
                                          enum pipe_format format,
591
 
                                          bool glsl130_or_later)
592
 
{
593
 
   /* There is no need to clear this structure (consider CPU overhead). */
594
 
   struct pipe_sampler_view templ;
595
 
   unsigned swizzle = get_texture_format_swizzle(st, texObj, glsl130_or_later);
596
 
 
597
 
   templ.format = format;
598
 
 
599
 
   if (texObj->level_override >= 0) {
600
 
      templ.u.tex.first_level = templ.u.tex.last_level = texObj->level_override;
601
 
   } else {
602
 
      templ.u.tex.first_level = texObj->Attrib.MinLevel +
603
 
                                texObj->Attrib.BaseLevel;
604
 
      templ.u.tex.last_level = last_level(texObj);
605
 
   }
606
 
   if (texObj->layer_override >= 0) {
607
 
      templ.u.tex.first_layer = templ.u.tex.last_layer = texObj->layer_override;
608
 
   } else {
609
 
      templ.u.tex.first_layer = texObj->Attrib.MinLayer;
610
 
      templ.u.tex.last_layer = last_layer(texObj);
611
 
   }
612
 
   assert(templ.u.tex.first_layer <= templ.u.tex.last_layer);
613
 
   assert(templ.u.tex.first_level <= templ.u.tex.last_level);
614
 
   templ.target = gl_target_to_pipe(texObj->Target);
615
 
 
616
 
   templ.swizzle_r = GET_SWZ(swizzle, 0);
617
 
   templ.swizzle_g = GET_SWZ(swizzle, 1);
618
 
   templ.swizzle_b = GET_SWZ(swizzle, 2);
619
 
   templ.swizzle_a = GET_SWZ(swizzle, 3);
620
 
 
621
 
   return st->pipe->create_sampler_view(st->pipe, texObj->pt, &templ);
622
 
}
623
 
 
624
 
struct pipe_sampler_view *
625
 
st_get_texture_sampler_view_from_stobj(struct st_context *st,
626
 
                                       struct gl_texture_object *texObj,
627
 
                                       const struct gl_sampler_object *samp,
628
 
                                       bool glsl130_or_later,
629
 
                                       bool ignore_srgb_decode,
630
 
                                       bool get_reference)
631
 
{
632
 
   struct st_sampler_view *sv;
633
 
   bool srgb_skip_decode = false;
634
 
 
635
 
   if (!ignore_srgb_decode && samp->Attrib.sRGBDecode == GL_SKIP_DECODE_EXT)
636
 
      srgb_skip_decode = true;
637
 
 
638
 
   simple_mtx_lock(&texObj->validate_mutex);
639
 
   sv = st_texture_get_current_sampler_view(st, texObj);
640
 
 
641
 
   if (sv &&
642
 
       sv->glsl130_or_later == glsl130_or_later &&
643
 
       sv->srgb_skip_decode == srgb_skip_decode) {
644
 
      /* Debug check: make sure that the sampler view's parameters are
645
 
       * what they're supposed to be.
646
 
       */
647
 
      struct pipe_sampler_view *view = sv->view;
648
 
      assert(texObj->pt == view->texture);
649
 
      assert(!check_sampler_swizzle(st, texObj, view, glsl130_or_later));
650
 
      assert(get_sampler_view_format(st, texObj, srgb_skip_decode) == view->format);
651
 
      assert(gl_target_to_pipe(texObj->Target) == view->target);
652
 
      assert(texObj->level_override >= 0 ||
653
 
             texObj->Attrib.MinLevel +
654
 
             texObj->Attrib.BaseLevel == view->u.tex.first_level);
655
 
      assert(texObj->level_override >= 0 || last_level(texObj) == view->u.tex.last_level);
656
 
      assert(texObj->layer_override >= 0 ||
657
 
             texObj->Attrib.MinLayer == view->u.tex.first_layer);
658
 
      assert(texObj->layer_override >= 0 || last_layer(texObj) == view->u.tex.last_layer);
659
 
      assert(texObj->layer_override < 0 ||
660
 
             (texObj->layer_override == view->u.tex.first_layer &&
661
 
              texObj->layer_override == view->u.tex.last_layer));
662
 
      if (get_reference)
663
 
         view = get_sampler_view_reference(sv, view);
664
 
      simple_mtx_unlock(&texObj->validate_mutex);
665
 
      return view;
666
 
   }
667
 
 
668
 
   /* create new sampler view */
669
 
   enum pipe_format format = get_sampler_view_format(st, texObj,
670
 
                                                     srgb_skip_decode);
671
 
   struct pipe_sampler_view *view =
672
 
         st_create_texture_sampler_view_from_stobj(st, texObj, format,
673
 
                                                   glsl130_or_later);
674
 
 
675
 
   view = st_texture_set_sampler_view(st, texObj, view,
676
 
                                      glsl130_or_later, srgb_skip_decode,
677
 
                                      get_reference, true);
678
 
   simple_mtx_unlock(&texObj->validate_mutex);
679
 
 
680
 
   return view;
681
 
}
682
 
 
683
 
 
684
 
struct pipe_sampler_view *
685
 
st_get_buffer_sampler_view_from_stobj(struct st_context *st,
686
 
                                      struct gl_texture_object *texObj,
687
 
                                      bool get_reference)
688
 
{
689
 
   struct st_sampler_view *sv;
690
 
   struct gl_buffer_object *stBuf =
691
 
      texObj->BufferObject;
692
 
 
693
 
   if (!stBuf || !stBuf->buffer)
694
 
      return NULL;
695
 
 
696
 
   sv = st_texture_get_current_sampler_view(st, texObj);
697
 
 
698
 
   struct pipe_resource *buf = stBuf->buffer;
699
 
 
700
 
   if (sv) {
701
 
      struct pipe_sampler_view *view = sv->view;
702
 
 
703
 
      if (view->texture == buf) {
704
 
         /* Debug check: make sure that the sampler view's parameters are
705
 
          * what they're supposed to be.
706
 
          */
707
 
         assert(st_mesa_format_to_pipe_format(st,
708
 
                                              texObj->_BufferObjectFormat)
709
 
             == view->format);
710
 
         assert(view->target == PIPE_BUFFER);
711
 
         ASSERTED unsigned base = texObj->BufferOffset;
712
 
         ASSERTED unsigned size = MIN2(buf->width0 - base,
713
 
                           (unsigned) texObj->BufferSize);
714
 
         assert(view->u.buf.offset == base);
715
 
         assert(view->u.buf.size == size);
716
 
         if (get_reference)
717
 
            view = get_sampler_view_reference(sv, view);
718
 
         return view;
719
 
      }
720
 
   }
721
 
 
722
 
   unsigned base = texObj->BufferOffset;
723
 
 
724
 
   if (base >= buf->width0)
725
 
      return NULL;
726
 
 
727
 
   unsigned size = buf->width0 - base;
728
 
   size = MIN2(size, (unsigned)texObj->BufferSize);
729
 
   if (!size)
730
 
      return NULL;
731
 
 
732
 
   /* Create a new sampler view. There is no need to clear the entire
733
 
    * structure (consider CPU overhead).
734
 
    */
735
 
   struct pipe_sampler_view templ;
736
 
 
737
 
   templ.format =
738
 
      st_mesa_format_to_pipe_format(st, texObj->_BufferObjectFormat);
739
 
   templ.target = PIPE_BUFFER;
740
 
   templ.swizzle_r = PIPE_SWIZZLE_X;
741
 
   templ.swizzle_g = PIPE_SWIZZLE_Y;
742
 
   templ.swizzle_b = PIPE_SWIZZLE_Z;
743
 
   templ.swizzle_a = PIPE_SWIZZLE_W;
744
 
   templ.u.buf.offset = base;
745
 
   templ.u.buf.size = size;
746
 
 
747
 
   struct pipe_sampler_view *view =
748
 
      st->pipe->create_sampler_view(st->pipe, buf, &templ);
749
 
 
750
 
   view = st_texture_set_sampler_view(st, texObj, view, false, false,
751
 
                                      get_reference, false);
752
 
 
753
 
   return view;
754
 
}