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/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_bufferobjects.h"
42 #include "st_cb_texture.h"
46 * Set the given view as the current context's view for the texture.
48 * Overwrites any pre-existing view of the context.
50 * Takes ownership of the view (i.e., stores the view without incrementing the
53 * \return the view, or NULL on error. In case of error, the reference to the
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
)
62 struct st_sampler_views
*views
;
63 struct st_sampler_view
*free
= NULL
;
64 struct st_sampler_view
*sv
;
67 simple_mtx_lock(&stObj
->validate_mutex
);
68 views
= stObj
->sampler_views
;
70 for (i
= 0; i
< views
->count
; ++i
) {
71 sv
= &views
->views
[i
];
73 /* Is the array entry used ? */
75 /* check if the context matches */
76 if (sv
->view
->context
== st
->pipe
) {
77 pipe_sampler_view_reference(&sv
->view
, NULL
);
81 /* Found a free slot, remember that */
86 /* Couldn't find a slot for our context, create a new one */
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]);
95 if (new_max
< views
->max
||
96 new_max
> (UINT_MAX
- sizeof(*views
)) / sizeof(views
->views
[0])) {
97 pipe_sampler_view_reference(&view
, NULL
);
101 struct st_sampler_views
*new_views
= malloc(new_size
);
103 pipe_sampler_view_reference(&view
, NULL
);
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]));
112 /* Initialize the pipe_sampler_view pointers to zero so that we don't
113 * have to worry about racing against readers when incrementing
116 memset(&new_views
->views
[views
->count
], 0,
117 (new_max
- views
->count
) * sizeof(views
->views
[0]));
119 /* Use memory release semantics to ensure that concurrent readers will
120 * get the correct contents of the new container.
122 * Also, the write should be atomic, but that's guaranteed anyway on
123 * all supported platforms.
125 p_atomic_set(&stObj
->sampler_views
, new_views
);
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.
132 views
->next
= stObj
->sampler_views_old
;
133 stObj
->sampler_views_old
= views
;
138 sv
= &views
->views
[views
->count
];
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.
148 assert(sv
->view
== NULL
);
150 sv
->glsl130_or_later
= glsl130_or_later
;
151 sv
->srgb_skip_decode
= srgb_skip_decode
;
156 simple_mtx_unlock(&stObj
->validate_mutex
);
162 * Return the most-recently validated sampler view for the texture \p stObj
163 * in the given context, if any.
165 * Performs no additional validation.
167 const struct st_sampler_view
*
168 st_texture_get_current_sampler_view(const struct st_context
*st
,
169 const struct st_texture_object
*stObj
)
171 const struct st_sampler_views
*views
= p_atomic_read(&stObj
->sampler_views
);
173 for (unsigned i
= 0; i
< views
->count
; ++i
) {
174 const struct st_sampler_view
*sv
= &views
->views
[i
];
175 if (sv
->view
&& sv
->view
->context
== st
->pipe
)
184 * For the given texture object, release any sampler views which belong
185 * to the calling context. This is used to free any sampler views
186 * which belong to the context before the context is destroyed.
189 st_texture_release_context_sampler_view(struct st_context
*st
,
190 struct st_texture_object
*stObj
)
194 simple_mtx_lock(&stObj
->validate_mutex
);
195 struct st_sampler_views
*views
= stObj
->sampler_views
;
196 for (i
= 0; i
< views
->count
; ++i
) {
197 struct pipe_sampler_view
**sv
= &views
->views
[i
].view
;
199 if (*sv
&& (*sv
)->context
== st
->pipe
) {
200 pipe_sampler_view_reference(sv
, NULL
);
204 simple_mtx_unlock(&stObj
->validate_mutex
);
209 * Release all sampler views attached to the given texture object, regardless
210 * of the context. This is called fairly frequently. For example, whenever
211 * the texture's base level, max level or swizzle change.
214 st_texture_release_all_sampler_views(struct st_context
*st
,
215 struct st_texture_object
*stObj
)
217 /* TODO: This happens while a texture is deleted, because the Driver API
218 * is asymmetric: the driver allocates the texture object memory, but
219 * mesa/main frees it.
221 if (!stObj
->sampler_views
)
224 simple_mtx_lock(&stObj
->validate_mutex
);
225 struct st_sampler_views
*views
= stObj
->sampler_views
;
226 for (unsigned i
= 0; i
< views
->count
; ++i
) {
227 struct st_sampler_view
*stsv
= &views
->views
[i
];
229 if (stsv
->st
!= st
) {
230 /* Transfer this reference to the zombie list. It will
231 * likely be freed when the zombie list is freed.
233 st_save_zombie_sampler_view(stsv
->st
, stsv
->view
);
236 pipe_sampler_view_reference(&stsv
->view
, NULL
);
241 simple_mtx_unlock(&stObj
->validate_mutex
);
246 * Delete the texture's sampler views and st_sampler_views containers.
247 * This is to be called just before a texture is deleted.
250 st_delete_texture_sampler_views(struct st_context
*st
,
251 struct st_texture_object
*stObj
)
253 st_texture_release_all_sampler_views(st
, stObj
);
255 /* Free the container of the current per-context sampler views */
256 assert(stObj
->sampler_views
->count
== 0);
257 free(stObj
->sampler_views
);
258 stObj
->sampler_views
= NULL
;
260 /* Free old sampler view containers */
261 while (stObj
->sampler_views_old
) {
262 struct st_sampler_views
*views
= stObj
->sampler_views_old
;
263 stObj
->sampler_views_old
= views
->next
;
270 * Return swizzle1(swizzle2)
273 swizzle_swizzle(unsigned swizzle1
, unsigned swizzle2
)
277 if (swizzle1
== SWIZZLE_XYZW
) {
278 /* identity swizzle, no change to swizzle2 */
282 for (i
= 0; i
< 4; i
++) {
283 unsigned s
= GET_SWZ(swizzle1
, i
);
289 swz
[i
] = GET_SWZ(swizzle2
, s
);
292 swz
[i
] = SWIZZLE_ZERO
;
295 swz
[i
] = SWIZZLE_ONE
;
298 assert(!"Bad swizzle term");
303 return MAKE_SWIZZLE4(swz
[0], swz
[1], swz
[2], swz
[3]);
308 * Given a user-specified texture base format, the actual gallium texture
309 * format and the current GL_DEPTH_MODE, return a texture swizzle.
311 * Consider the case where the user requests a GL_RGB internal texture
312 * format the driver actually uses an RGBA format. The A component should
313 * be ignored and sampling from the texture should always return (r,g,b,1).
314 * But if we rendered to the texture we might have written A values != 1.
315 * By sampling the texture with a ".xyz1" swizzle we'll get the expected A=1.
316 * This function computes the texture swizzle needed to get the expected
319 * In the case of depth textures, the GL_DEPTH_MODE state determines the
322 * This result must be composed with the user-specified swizzle to get
326 compute_texture_format_swizzle(GLenum baseFormat
, GLenum depthMode
,
327 bool glsl130_or_later
)
329 switch (baseFormat
) {
333 return MAKE_SWIZZLE4(SWIZZLE_X
, SWIZZLE_Y
, SWIZZLE_Z
, SWIZZLE_ONE
);
335 return MAKE_SWIZZLE4(SWIZZLE_X
, SWIZZLE_Y
, SWIZZLE_ZERO
, SWIZZLE_ONE
);
337 return MAKE_SWIZZLE4(SWIZZLE_X
, SWIZZLE_ZERO
,
338 SWIZZLE_ZERO
, SWIZZLE_ONE
);
340 return MAKE_SWIZZLE4(SWIZZLE_ZERO
, SWIZZLE_ZERO
,
341 SWIZZLE_ZERO
, SWIZZLE_W
);
343 return MAKE_SWIZZLE4(SWIZZLE_X
, SWIZZLE_X
, SWIZZLE_X
, SWIZZLE_ONE
);
344 case GL_LUMINANCE_ALPHA
:
345 return MAKE_SWIZZLE4(SWIZZLE_X
, SWIZZLE_X
, SWIZZLE_X
, SWIZZLE_W
);
348 case GL_STENCIL_INDEX
:
349 case GL_DEPTH_STENCIL
:
350 case GL_DEPTH_COMPONENT
:
351 /* Now examine the depth mode */
354 return MAKE_SWIZZLE4(SWIZZLE_X
, SWIZZLE_X
, SWIZZLE_X
, SWIZZLE_ONE
);
356 return MAKE_SWIZZLE4(SWIZZLE_X
, SWIZZLE_X
, SWIZZLE_X
, SWIZZLE_X
);
358 /* The texture(sampler*Shadow) functions from GLSL 1.30 ignore
359 * the depth mode and return float, while older shadow* functions
360 * and ARB_fp instructions return vec4 according to the depth mode.
362 * The problem with the GLSL 1.30 functions is that GL_ALPHA forces
363 * them to return 0, breaking them completely.
365 * A proper fix would increase code complexity and that's not worth
366 * it for a rarely used feature such as the GL_ALPHA depth mode
367 * in GL3. Therefore, change GL_ALPHA to GL_INTENSITY for all
368 * shaders that use GLSL 1.30 or later.
370 * BTW, it's required that sampler views are updated when
371 * shaders change (check_sampler_swizzle takes care of that).
373 if (glsl130_or_later
)
376 return MAKE_SWIZZLE4(SWIZZLE_ZERO
, SWIZZLE_ZERO
,
377 SWIZZLE_ZERO
, SWIZZLE_X
);
379 return MAKE_SWIZZLE4(SWIZZLE_X
, SWIZZLE_ZERO
,
380 SWIZZLE_ZERO
, SWIZZLE_ONE
);
382 assert(!"Unexpected depthMode");
386 assert(!"Unexpected baseFormat");
393 get_texture_format_swizzle(const struct st_context
*st
,
394 const struct st_texture_object
*stObj
,
395 bool glsl130_or_later
)
397 GLenum baseFormat
= _mesa_base_tex_image(&stObj
->base
)->_BaseFormat
;
398 unsigned tex_swizzle
;
399 GLenum depth_mode
= stObj
->base
.DepthMode
;
401 /* In ES 3.0, DEPTH_TEXTURE_MODE is expected to be GL_RED for textures
402 * with depth component data specified with a sized internal format.
404 if (_mesa_is_gles3(st
->ctx
) &&
405 (baseFormat
== GL_DEPTH_COMPONENT
||
406 baseFormat
== GL_DEPTH_STENCIL
||
407 baseFormat
== GL_STENCIL_INDEX
)) {
408 const struct gl_texture_image
*firstImage
=
409 _mesa_base_tex_image(&stObj
->base
);
410 if (firstImage
->InternalFormat
!= GL_DEPTH_COMPONENT
&&
411 firstImage
->InternalFormat
!= GL_DEPTH_STENCIL
&&
412 firstImage
->InternalFormat
!= GL_STENCIL_INDEX
)
415 tex_swizzle
= compute_texture_format_swizzle(baseFormat
,
419 /* Combine the texture format swizzle with user's swizzle */
420 return swizzle_swizzle(stObj
->base
._Swizzle
, tex_swizzle
);
425 * Return TRUE if the texture's sampler view swizzle is not equal to
426 * the texture's swizzle.
428 * \param stObj the st texture object,
430 ASSERTED
static boolean
431 check_sampler_swizzle(const struct st_context
*st
,
432 const struct st_texture_object
*stObj
,
433 const struct pipe_sampler_view
*sv
,
434 bool glsl130_or_later
)
436 unsigned swizzle
= get_texture_format_swizzle(st
, stObj
, glsl130_or_later
);
438 return ((sv
->swizzle_r
!= GET_SWZ(swizzle
, 0)) ||
439 (sv
->swizzle_g
!= GET_SWZ(swizzle
, 1)) ||
440 (sv
->swizzle_b
!= GET_SWZ(swizzle
, 2)) ||
441 (sv
->swizzle_a
!= GET_SWZ(swizzle
, 3)));
446 last_level(const struct st_texture_object
*stObj
)
448 unsigned ret
= MIN2(stObj
->base
.MinLevel
+ stObj
->base
._MaxLevel
,
449 stObj
->pt
->last_level
);
450 if (stObj
->base
.Immutable
)
451 ret
= MIN2(ret
, stObj
->base
.MinLevel
+ stObj
->base
.NumLevels
- 1);
457 last_layer(const struct st_texture_object
*stObj
)
459 if (stObj
->base
.Immutable
&& stObj
->pt
->array_size
> 1)
460 return MIN2(stObj
->base
.MinLayer
+ stObj
->base
.NumLayers
- 1,
461 stObj
->pt
->array_size
- 1);
462 return stObj
->pt
->array_size
- 1;
467 * Determine the format for the texture sampler view.
469 static enum pipe_format
470 get_sampler_view_format(struct st_context
*st
,
471 const struct st_texture_object
*stObj
,
472 bool srgb_skip_decode
)
474 enum pipe_format format
;
476 GLenum baseFormat
= _mesa_base_tex_image(&stObj
->base
)->_BaseFormat
;
477 format
= stObj
->surface_based
? stObj
->surface_format
: stObj
->pt
->format
;
479 if (baseFormat
== GL_DEPTH_COMPONENT
||
480 baseFormat
== GL_DEPTH_STENCIL
||
481 baseFormat
== GL_STENCIL_INDEX
) {
482 if (stObj
->base
.StencilSampling
|| baseFormat
== GL_STENCIL_INDEX
)
483 format
= util_format_stencil_only(format
);
488 /* If sRGB decoding is off, use the linear format */
489 if (srgb_skip_decode
)
490 format
= util_format_linear(format
);
492 /* Use R8_UNORM for video formats */
494 case PIPE_FORMAT_NV12
:
495 case PIPE_FORMAT_IYUV
:
496 format
= PIPE_FORMAT_R8_UNORM
;
498 case PIPE_FORMAT_P016
:
499 format
= PIPE_FORMAT_R16_UNORM
;
501 case PIPE_FORMAT_YUYV
:
502 case PIPE_FORMAT_UYVY
:
503 format
= PIPE_FORMAT_R8G8_UNORM
;
505 case PIPE_FORMAT_AYUV
:
506 format
= PIPE_FORMAT_RGBA8888_UNORM
;
508 case PIPE_FORMAT_XYUV
:
509 format
= PIPE_FORMAT_RGBX8888_UNORM
;
518 static struct pipe_sampler_view
*
519 st_create_texture_sampler_view_from_stobj(struct st_context
*st
,
520 struct st_texture_object
*stObj
,
521 enum pipe_format format
,
522 bool glsl130_or_later
)
524 /* There is no need to clear this structure (consider CPU overhead). */
525 struct pipe_sampler_view templ
;
526 unsigned swizzle
= get_texture_format_swizzle(st
, stObj
, glsl130_or_later
);
528 templ
.format
= format
;
530 if (stObj
->level_override
>= 0) {
531 templ
.u
.tex
.first_level
= templ
.u
.tex
.last_level
= stObj
->level_override
;
533 templ
.u
.tex
.first_level
= stObj
->base
.MinLevel
+ stObj
->base
.BaseLevel
;
534 templ
.u
.tex
.last_level
= last_level(stObj
);
536 if (stObj
->layer_override
>= 0) {
537 templ
.u
.tex
.first_layer
= templ
.u
.tex
.last_layer
= stObj
->layer_override
;
539 templ
.u
.tex
.first_layer
= stObj
->base
.MinLayer
;
540 templ
.u
.tex
.last_layer
= last_layer(stObj
);
542 assert(templ
.u
.tex
.first_layer
<= templ
.u
.tex
.last_layer
);
543 assert(templ
.u
.tex
.first_level
<= templ
.u
.tex
.last_level
);
544 templ
.target
= gl_target_to_pipe(stObj
->base
.Target
);
546 templ
.swizzle_r
= GET_SWZ(swizzle
, 0);
547 templ
.swizzle_g
= GET_SWZ(swizzle
, 1);
548 templ
.swizzle_b
= GET_SWZ(swizzle
, 2);
549 templ
.swizzle_a
= GET_SWZ(swizzle
, 3);
551 return st
->pipe
->create_sampler_view(st
->pipe
, stObj
->pt
, &templ
);
555 struct pipe_sampler_view
*
556 st_get_texture_sampler_view_from_stobj(struct st_context
*st
,
557 struct st_texture_object
*stObj
,
558 const struct gl_sampler_object
*samp
,
559 bool glsl130_or_later
,
560 bool ignore_srgb_decode
)
562 const struct st_sampler_view
*sv
;
563 bool srgb_skip_decode
= false;
565 if (!ignore_srgb_decode
&& samp
->sRGBDecode
== GL_SKIP_DECODE_EXT
)
566 srgb_skip_decode
= true;
568 sv
= st_texture_get_current_sampler_view(st
, stObj
);
571 sv
->glsl130_or_later
== glsl130_or_later
&&
572 sv
->srgb_skip_decode
== srgb_skip_decode
) {
573 /* Debug check: make sure that the sampler view's parameters are
574 * what they're supposed to be.
576 struct pipe_sampler_view
*view
= sv
->view
;
577 assert(stObj
->pt
== view
->texture
);
578 assert(!check_sampler_swizzle(st
, stObj
, view
, glsl130_or_later
));
579 assert(get_sampler_view_format(st
, stObj
, srgb_skip_decode
) == view
->format
);
580 assert(gl_target_to_pipe(stObj
->base
.Target
) == view
->target
);
581 assert(stObj
->level_override
>= 0 ||
582 stObj
->base
.MinLevel
+ stObj
->base
.BaseLevel
== view
->u
.tex
.first_level
);
583 assert(stObj
->level_override
>= 0 || last_level(stObj
) == view
->u
.tex
.last_level
);
584 assert(stObj
->layer_override
>= 0 || stObj
->base
.MinLayer
== view
->u
.tex
.first_layer
);
585 assert(stObj
->layer_override
>= 0 || last_layer(stObj
) == view
->u
.tex
.last_layer
);
586 assert(stObj
->layer_override
< 0 ||
587 (stObj
->layer_override
== view
->u
.tex
.first_layer
&&
588 stObj
->layer_override
== view
->u
.tex
.last_layer
));
592 /* create new sampler view */
593 enum pipe_format format
= get_sampler_view_format(st
, stObj
,
595 struct pipe_sampler_view
*view
=
596 st_create_texture_sampler_view_from_stobj(st
, stObj
, format
,
599 view
= st_texture_set_sampler_view(st
, stObj
, view
,
600 glsl130_or_later
, srgb_skip_decode
);
606 struct pipe_sampler_view
*
607 st_get_buffer_sampler_view_from_stobj(struct st_context
*st
,
608 struct st_texture_object
*stObj
)
610 const struct st_sampler_view
*sv
;
611 struct st_buffer_object
*stBuf
=
612 st_buffer_object(stObj
->base
.BufferObject
);
614 if (!stBuf
|| !stBuf
->buffer
)
617 sv
= st_texture_get_current_sampler_view(st
, stObj
);
619 struct pipe_resource
*buf
= stBuf
->buffer
;
622 struct pipe_sampler_view
*view
= sv
->view
;
624 if (view
->texture
== buf
) {
625 /* Debug check: make sure that the sampler view's parameters are
626 * what they're supposed to be.
628 assert(st_mesa_format_to_pipe_format(st
,
629 stObj
->base
._BufferObjectFormat
)
631 assert(view
->target
== PIPE_BUFFER
);
632 ASSERTED
unsigned base
= stObj
->base
.BufferOffset
;
633 ASSERTED
unsigned size
= MIN2(buf
->width0
- base
,
634 (unsigned) stObj
->base
.BufferSize
);
635 assert(view
->u
.buf
.offset
== base
);
636 assert(view
->u
.buf
.size
== size
);
641 unsigned base
= stObj
->base
.BufferOffset
;
643 if (base
>= buf
->width0
)
646 unsigned size
= buf
->width0
- base
;
647 size
= MIN2(size
, (unsigned)stObj
->base
.BufferSize
);
651 /* Create a new sampler view. There is no need to clear the entire
652 * structure (consider CPU overhead).
654 struct pipe_sampler_view templ
;
657 st_mesa_format_to_pipe_format(st
, stObj
->base
._BufferObjectFormat
);
658 templ
.target
= PIPE_BUFFER
;
659 templ
.swizzle_r
= PIPE_SWIZZLE_X
;
660 templ
.swizzle_g
= PIPE_SWIZZLE_Y
;
661 templ
.swizzle_b
= PIPE_SWIZZLE_Z
;
662 templ
.swizzle_a
= PIPE_SWIZZLE_W
;
663 templ
.u
.buf
.offset
= base
;
664 templ
.u
.buf
.size
= size
;
666 struct pipe_sampler_view
*view
=
667 st
->pipe
->create_sampler_view(st
->pipe
, buf
, &templ
);
669 view
= st_texture_set_sampler_view(st
, stObj
, view
, false, false);