2
* Copyright 2016 VMware, Inc.
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:
13
* The above copyright notice and this permission notice (including the
14
* next paragraph) shall be included in all copies or substantial portions
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.
26
#include "pipe/p_context.h"
27
#include "util/format/u_format.h"
28
#include "util/u_inlines.h"
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"
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"
43
/* Subtract remaining private references. Typically used before
44
* destruction. See the header file for explanation.
47
st_remove_private_references(struct st_sampler_view *sv)
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;
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)
61
if (unlikely(sv->private_refcount <= 0)) {
62
assert(sv->private_refcount == 0);
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);
69
/* Return a reference while decrementing the private refcount. */
70
sv->private_refcount--;
75
* Set the given view as the current context's view for the texture.
77
* Overwrites any pre-existing view of the context.
79
* Takes ownership of the view (i.e., stores the view without incrementing the
82
* \return the view, or NULL on error. In case of error, the reference to the
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)
92
struct st_sampler_views *views;
93
struct st_sampler_view *free = NULL;
94
struct st_sampler_view *sv;
98
simple_mtx_lock(&stObj->validate_mutex);
99
views = stObj->sampler_views;
101
for (i = 0; i < views->count; ++i) {
102
sv = &views->views[i];
104
/* Is the array entry used ? */
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);
113
/* Found a free slot, remember that */
118
/* Couldn't find a slot for our context, create a new one */
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]);
127
if (new_max < views->max ||
128
new_max > (UINT_MAX - sizeof(*views)) / sizeof(views->views[0])) {
129
pipe_sampler_view_reference(&view, NULL);
133
struct st_sampler_views *new_views = malloc(new_size);
135
pipe_sampler_view_reference(&view, NULL);
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]));
144
/* Initialize the pipe_sampler_view pointers to zero so that we don't
145
* have to worry about racing against readers when incrementing
148
memset(&new_views->views[views->count], 0,
149
(new_max - views->count) * sizeof(views->views[0]));
151
/* Use memory release semantics to ensure that concurrent readers will
152
* get the correct contents of the new container.
154
* Also, the write should be atomic, but that's guaranteed anyway on
155
* all supported platforms.
157
p_atomic_set(&stObj->sampler_views, new_views);
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.
164
views->next = stObj->sampler_views_old;
165
stObj->sampler_views_old = views;
170
sv = &views->views[views->count];
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.
180
assert(sv->view == NULL);
182
sv->glsl130_or_later = glsl130_or_later;
183
sv->srgb_skip_decode = srgb_skip_decode;
188
view = get_sampler_view_reference(sv, view);
192
simple_mtx_unlock(&stObj->validate_mutex);
198
* Return the most-recently validated sampler view for the texture \p stObj
199
* in the given context, if any.
201
* Performs no additional validation.
203
struct st_sampler_view *
204
st_texture_get_current_sampler_view(const struct st_context *st,
205
const struct gl_texture_object *stObj)
207
struct st_sampler_views *views = p_atomic_read(&stObj->sampler_views);
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)
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.
225
st_texture_release_context_sampler_view(struct st_context *st,
226
struct gl_texture_object *stObj)
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];
235
if (sv->view && sv->view->context == st->pipe) {
236
st_remove_private_references(sv);
237
pipe_sampler_view_reference(&sv->view, NULL);
241
simple_mtx_unlock(&stObj->validate_mutex);
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.
251
st_texture_release_all_sampler_views(struct st_context *st,
252
struct gl_texture_object *stObj)
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.
258
if (!stObj->sampler_views)
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];
266
st_remove_private_references(stsv);
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.
272
st_save_zombie_sampler_view(stsv->st, stsv->view);
275
pipe_sampler_view_reference(&stsv->view, NULL);
280
simple_mtx_unlock(&stObj->validate_mutex);
285
* Delete the texture's sampler views and st_sampler_views containers.
286
* This is to be called just before a texture is deleted.
289
st_delete_texture_sampler_views(struct st_context *st,
290
struct gl_texture_object *stObj)
292
st_texture_release_all_sampler_views(st, stObj);
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;
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;
309
* Return swizzle1(swizzle2)
312
swizzle_swizzle(unsigned swizzle1, unsigned swizzle2)
316
if (swizzle1 == SWIZZLE_XYZW) {
317
/* identity swizzle, no change to swizzle2 */
321
for (i = 0; i < 4; i++) {
322
unsigned s = GET_SWZ(swizzle1, i);
328
swz[i] = GET_SWZ(swizzle2, s);
331
swz[i] = SWIZZLE_ZERO;
334
swz[i] = SWIZZLE_ONE;
337
assert(!"Bad swizzle term");
342
return MAKE_SWIZZLE4(swz[0], swz[1], swz[2], swz[3]);
347
* Given a user-specified texture base format, the actual gallium texture
348
* format and the current GL_DEPTH_MODE, return a texture swizzle.
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
358
* In the case of depth textures, the GL_DEPTH_MODE state determines the
361
* This result must be composed with the user-specified swizzle to get
365
compute_texture_format_swizzle(GLenum baseFormat, GLenum depthMode,
366
bool glsl130_or_later)
368
switch (baseFormat) {
372
return MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_ONE);
374
return MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_ZERO, SWIZZLE_ONE);
376
return MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_ZERO,
377
SWIZZLE_ZERO, SWIZZLE_ONE);
379
return MAKE_SWIZZLE4(SWIZZLE_ZERO, SWIZZLE_ZERO,
380
SWIZZLE_ZERO, SWIZZLE_W);
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);
387
case GL_STENCIL_INDEX:
388
case GL_DEPTH_STENCIL:
389
case GL_DEPTH_COMPONENT:
390
/* Now examine the depth mode */
393
return MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_X, SWIZZLE_X, SWIZZLE_ONE);
395
return MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_X, SWIZZLE_X, SWIZZLE_X);
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.
401
* The problem with the GLSL 1.30 functions is that GL_ALPHA forces
402
* them to return 0, breaking them completely.
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.
409
* BTW, it's required that sampler views are updated when
410
* shaders change (check_sampler_swizzle takes care of that).
412
if (glsl130_or_later)
415
return MAKE_SWIZZLE4(SWIZZLE_ZERO, SWIZZLE_ZERO,
416
SWIZZLE_ZERO, SWIZZLE_X);
418
return MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_ZERO,
419
SWIZZLE_ZERO, SWIZZLE_ONE);
421
assert(!"Unexpected depthMode");
425
assert(!"Unexpected baseFormat");
432
get_texture_format_swizzle(const struct st_context *st,
433
const struct gl_texture_object *texObj,
434
bool glsl130_or_later)
436
GLenum baseFormat = _mesa_base_tex_image(texObj)->_BaseFormat;
437
unsigned tex_swizzle;
438
GLenum depth_mode = texObj->Attrib.DepthMode;
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.
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)
454
tex_swizzle = compute_texture_format_swizzle(baseFormat,
458
/* Combine the texture format swizzle with user's swizzle */
459
return swizzle_swizzle(texObj->Attrib._Swizzle, tex_swizzle);
464
* Return TRUE if the texture's sampler view swizzle is not equal to
465
* the texture's swizzle.
467
* \param texObj the st texture object,
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)
475
unsigned swizzle = get_texture_format_swizzle(st, texObj, glsl130_or_later);
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)));
485
last_level(const struct gl_texture_object *texObj)
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);
497
last_layer(const struct gl_texture_object *texObj)
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;
508
* Determine the format for the texture sampler view.
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)
515
enum pipe_format format;
517
GLenum baseFormat = _mesa_base_tex_image(texObj)->_BaseFormat;
518
format = texObj->surface_based ? texObj->surface_format : texObj->pt->format;
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);
529
/* If sRGB decoding is off, use the linear format */
530
if (srgb_skip_decode)
531
format = util_format_linear(format);
533
/* if resource format matches then YUV wasn't lowered */
534
if (format == texObj->pt->format)
537
/* Use R8_UNORM for video formats */
539
case PIPE_FORMAT_NV12:
540
if (texObj->pt->format == PIPE_FORMAT_R8_G8B8_420_UNORM) {
541
format = PIPE_FORMAT_R8_G8B8_420_UNORM;
545
case PIPE_FORMAT_IYUV:
546
format = PIPE_FORMAT_R8_UNORM;
548
case PIPE_FORMAT_P010:
549
case PIPE_FORMAT_P012:
550
case PIPE_FORMAT_P016:
551
format = PIPE_FORMAT_R16_UNORM;
553
case PIPE_FORMAT_Y210:
554
case PIPE_FORMAT_Y212:
555
case PIPE_FORMAT_Y216:
556
format = PIPE_FORMAT_R16G16_UNORM;
558
case PIPE_FORMAT_Y410:
559
format = PIPE_FORMAT_R10G10B10A2_UNORM;
561
case PIPE_FORMAT_Y412:
562
case PIPE_FORMAT_Y416:
563
format = PIPE_FORMAT_R16G16B16A16_UNORM;
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;
572
format = PIPE_FORMAT_R8G8_UNORM;
574
case PIPE_FORMAT_AYUV:
575
format = PIPE_FORMAT_RGBA8888_UNORM;
577
case PIPE_FORMAT_XYUV:
578
format = PIPE_FORMAT_RGBX8888_UNORM;
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)
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);
597
templ.format = format;
599
if (texObj->level_override >= 0) {
600
templ.u.tex.first_level = templ.u.tex.last_level = texObj->level_override;
602
templ.u.tex.first_level = texObj->Attrib.MinLevel +
603
texObj->Attrib.BaseLevel;
604
templ.u.tex.last_level = last_level(texObj);
606
if (texObj->layer_override >= 0) {
607
templ.u.tex.first_layer = templ.u.tex.last_layer = texObj->layer_override;
609
templ.u.tex.first_layer = texObj->Attrib.MinLayer;
610
templ.u.tex.last_layer = last_layer(texObj);
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);
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);
621
return st->pipe->create_sampler_view(st->pipe, texObj->pt, &templ);
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,
632
struct st_sampler_view *sv;
633
bool srgb_skip_decode = false;
635
if (!ignore_srgb_decode && samp->Attrib.sRGBDecode == GL_SKIP_DECODE_EXT)
636
srgb_skip_decode = true;
638
simple_mtx_lock(&texObj->validate_mutex);
639
sv = st_texture_get_current_sampler_view(st, texObj);
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.
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));
663
view = get_sampler_view_reference(sv, view);
664
simple_mtx_unlock(&texObj->validate_mutex);
668
/* create new sampler view */
669
enum pipe_format format = get_sampler_view_format(st, texObj,
671
struct pipe_sampler_view *view =
672
st_create_texture_sampler_view_from_stobj(st, texObj, format,
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);
684
struct pipe_sampler_view *
685
st_get_buffer_sampler_view_from_stobj(struct st_context *st,
686
struct gl_texture_object *texObj,
689
struct st_sampler_view *sv;
690
struct gl_buffer_object *stBuf =
691
texObj->BufferObject;
693
if (!stBuf || !stBuf->buffer)
696
sv = st_texture_get_current_sampler_view(st, texObj);
698
struct pipe_resource *buf = stBuf->buffer;
701
struct pipe_sampler_view *view = sv->view;
703
if (view->texture == buf) {
704
/* Debug check: make sure that the sampler view's parameters are
705
* what they're supposed to be.
707
assert(st_mesa_format_to_pipe_format(st,
708
texObj->_BufferObjectFormat)
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);
717
view = get_sampler_view_reference(sv, view);
722
unsigned base = texObj->BufferOffset;
724
if (base >= buf->width0)
727
unsigned size = buf->width0 - base;
728
size = MIN2(size, (unsigned)texObj->BufferSize);
732
/* Create a new sampler view. There is no need to clear the entire
733
* structure (consider CPU overhead).
735
struct pipe_sampler_view templ;
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;
747
struct pipe_sampler_view *view =
748
st->pipe->create_sampler_view(st->pipe, buf, &templ);
750
view = st_texture_set_sampler_view(st, texObj, view, false, false,
751
get_reference, false);