0d7b63af75a1f532041f884d98abb4618c2844c9
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 * Try to find a matching sampler view for the given context.
47 * If none is found an empty slot is initialized with a
48 * template and returned instead.
50 static struct st_sampler_view
*
51 st_texture_get_sampler_view(struct st_context
*st
,
52 struct st_texture_object
*stObj
)
54 struct st_sampler_view
*free
= NULL
;
57 for (i
= 0; i
< stObj
->num_sampler_views
; ++i
) {
58 struct st_sampler_view
*sv
= &stObj
->sampler_views
[i
];
59 /* Is the array entry used ? */
61 /* check if the context matches */
62 if (sv
->view
->context
== st
->pipe
) {
66 /* Found a free slot, remember that */
71 /* Couldn't find a slot for our context, create a new one */
74 /* Haven't even found a free one, resize the array */
75 unsigned new_size
= (stObj
->num_sampler_views
+ 1) *
76 sizeof(struct st_sampler_view
);
77 stObj
->sampler_views
= realloc(stObj
->sampler_views
, new_size
);
78 free
= &stObj
->sampler_views
[stObj
->num_sampler_views
++];
82 assert(free
->view
== NULL
);
89 * For the given texture object, release any sampler views which belong
90 * to the calling context.
93 st_texture_release_sampler_view(struct st_context
*st
,
94 struct st_texture_object
*stObj
)
98 for (i
= 0; i
< stObj
->num_sampler_views
; ++i
) {
99 struct pipe_sampler_view
**sv
= &stObj
->sampler_views
[i
].view
;
101 if (*sv
&& (*sv
)->context
== st
->pipe
) {
102 pipe_sampler_view_reference(sv
, NULL
);
110 * Release all sampler views attached to the given texture object, regardless
114 st_texture_release_all_sampler_views(struct st_context
*st
,
115 struct st_texture_object
*stObj
)
119 /* XXX This should use sampler_views[i]->pipe, not st->pipe */
120 for (i
= 0; i
< stObj
->num_sampler_views
; ++i
)
121 pipe_sampler_view_release(st
->pipe
, &stObj
->sampler_views
[i
].view
);
126 st_texture_free_sampler_views(struct st_texture_object
*stObj
)
128 free(stObj
->sampler_views
);
129 stObj
->sampler_views
= NULL
;
130 stObj
->num_sampler_views
= 0;
135 * Return swizzle1(swizzle2)
138 swizzle_swizzle(unsigned swizzle1
, unsigned swizzle2
)
142 if (swizzle1
== SWIZZLE_XYZW
) {
143 /* identity swizzle, no change to swizzle2 */
147 for (i
= 0; i
< 4; i
++) {
148 unsigned s
= GET_SWZ(swizzle1
, i
);
154 swz
[i
] = GET_SWZ(swizzle2
, s
);
157 swz
[i
] = SWIZZLE_ZERO
;
160 swz
[i
] = SWIZZLE_ONE
;
163 assert(!"Bad swizzle term");
168 return MAKE_SWIZZLE4(swz
[0], swz
[1], swz
[2], swz
[3]);
173 * Given a user-specified texture base format, the actual gallium texture
174 * format and the current GL_DEPTH_MODE, return a texture swizzle.
176 * Consider the case where the user requests a GL_RGB internal texture
177 * format the driver actually uses an RGBA format. The A component should
178 * be ignored and sampling from the texture should always return (r,g,b,1).
179 * But if we rendered to the texture we might have written A values != 1.
180 * By sampling the texture with a ".xyz1" swizzle we'll get the expected A=1.
181 * This function computes the texture swizzle needed to get the expected
184 * In the case of depth textures, the GL_DEPTH_MODE state determines the
187 * This result must be composed with the user-specified swizzle to get
191 compute_texture_format_swizzle(GLenum baseFormat
, GLenum depthMode
,
192 bool glsl130_or_later
)
194 switch (baseFormat
) {
198 return MAKE_SWIZZLE4(SWIZZLE_X
, SWIZZLE_Y
, SWIZZLE_Z
, SWIZZLE_ONE
);
200 return MAKE_SWIZZLE4(SWIZZLE_X
, SWIZZLE_Y
, SWIZZLE_ZERO
, SWIZZLE_ONE
);
202 return MAKE_SWIZZLE4(SWIZZLE_X
, SWIZZLE_ZERO
,
203 SWIZZLE_ZERO
, SWIZZLE_ONE
);
205 return MAKE_SWIZZLE4(SWIZZLE_ZERO
, SWIZZLE_ZERO
,
206 SWIZZLE_ZERO
, SWIZZLE_W
);
208 return MAKE_SWIZZLE4(SWIZZLE_X
, SWIZZLE_X
, SWIZZLE_X
, SWIZZLE_ONE
);
209 case GL_LUMINANCE_ALPHA
:
210 return MAKE_SWIZZLE4(SWIZZLE_X
, SWIZZLE_X
, SWIZZLE_X
, SWIZZLE_W
);
213 case GL_STENCIL_INDEX
:
214 case GL_DEPTH_STENCIL
:
215 case GL_DEPTH_COMPONENT
:
216 /* Now examine the depth mode */
219 return MAKE_SWIZZLE4(SWIZZLE_X
, SWIZZLE_X
, SWIZZLE_X
, SWIZZLE_ONE
);
221 return MAKE_SWIZZLE4(SWIZZLE_X
, SWIZZLE_X
, SWIZZLE_X
, SWIZZLE_X
);
223 /* The texture(sampler*Shadow) functions from GLSL 1.30 ignore
224 * the depth mode and return float, while older shadow* functions
225 * and ARB_fp instructions return vec4 according to the depth mode.
227 * The problem with the GLSL 1.30 functions is that GL_ALPHA forces
228 * them to return 0, breaking them completely.
230 * A proper fix would increase code complexity and that's not worth
231 * it for a rarely used feature such as the GL_ALPHA depth mode
232 * in GL3. Therefore, change GL_ALPHA to GL_INTENSITY for all
233 * shaders that use GLSL 1.30 or later.
235 * BTW, it's required that sampler views are updated when
236 * shaders change (check_sampler_swizzle takes care of that).
238 if (glsl130_or_later
)
241 return MAKE_SWIZZLE4(SWIZZLE_ZERO
, SWIZZLE_ZERO
,
242 SWIZZLE_ZERO
, SWIZZLE_X
);
244 return MAKE_SWIZZLE4(SWIZZLE_X
, SWIZZLE_ZERO
,
245 SWIZZLE_ZERO
, SWIZZLE_ONE
);
247 assert(!"Unexpected depthMode");
251 assert(!"Unexpected baseFormat");
258 get_texture_format_swizzle(const struct st_context
*st
,
259 const struct st_texture_object
*stObj
,
260 bool glsl130_or_later
)
262 GLenum baseFormat
= _mesa_base_tex_image(&stObj
->base
)->_BaseFormat
;
263 unsigned tex_swizzle
;
264 GLenum depth_mode
= stObj
->base
.DepthMode
;
266 /* In ES 3.0, DEPTH_TEXTURE_MODE is expected to be GL_RED for textures
267 * with depth component data specified with a sized internal format.
269 if (_mesa_is_gles3(st
->ctx
) &&
270 (baseFormat
== GL_DEPTH_COMPONENT
||
271 baseFormat
== GL_DEPTH_STENCIL
||
272 baseFormat
== GL_STENCIL_INDEX
)) {
273 const struct gl_texture_image
*firstImage
=
274 _mesa_base_tex_image(&stObj
->base
);
275 if (firstImage
->InternalFormat
!= GL_DEPTH_COMPONENT
&&
276 firstImage
->InternalFormat
!= GL_DEPTH_STENCIL
&&
277 firstImage
->InternalFormat
!= GL_STENCIL_INDEX
)
280 tex_swizzle
= compute_texture_format_swizzle(baseFormat
,
284 /* Combine the texture format swizzle with user's swizzle */
285 return swizzle_swizzle(stObj
->base
._Swizzle
, tex_swizzle
);
290 * Return TRUE if the texture's sampler view swizzle is not equal to
291 * the texture's swizzle.
293 * \param stObj the st texture object,
295 MAYBE_UNUSED
static boolean
296 check_sampler_swizzle(const struct st_context
*st
,
297 const struct st_texture_object
*stObj
,
298 const struct pipe_sampler_view
*sv
,
299 bool glsl130_or_later
)
301 unsigned swizzle
= get_texture_format_swizzle(st
, stObj
, glsl130_or_later
);
303 return ((sv
->swizzle_r
!= GET_SWZ(swizzle
, 0)) ||
304 (sv
->swizzle_g
!= GET_SWZ(swizzle
, 1)) ||
305 (sv
->swizzle_b
!= GET_SWZ(swizzle
, 2)) ||
306 (sv
->swizzle_a
!= GET_SWZ(swizzle
, 3)));
311 last_level(const struct st_texture_object
*stObj
)
313 unsigned ret
= MIN2(stObj
->base
.MinLevel
+ stObj
->base
._MaxLevel
,
314 stObj
->pt
->last_level
);
315 if (stObj
->base
.Immutable
)
316 ret
= MIN2(ret
, stObj
->base
.MinLevel
+ stObj
->base
.NumLevels
- 1);
322 last_layer(const struct st_texture_object
*stObj
)
324 if (stObj
->base
.Immutable
&& stObj
->pt
->array_size
> 1)
325 return MIN2(stObj
->base
.MinLayer
+ stObj
->base
.NumLayers
- 1,
326 stObj
->pt
->array_size
- 1);
327 return stObj
->pt
->array_size
- 1;
332 * Determine the format for the texture sampler view.
334 static enum pipe_format
335 get_sampler_view_format(struct st_context
*st
,
336 const struct st_texture_object
*stObj
,
337 bool srgb_skip_decode
)
339 enum pipe_format format
;
341 GLenum baseFormat
= _mesa_base_tex_image(&stObj
->base
)->_BaseFormat
;
342 format
= stObj
->surface_based
? stObj
->surface_format
: stObj
->pt
->format
;
344 if (baseFormat
== GL_DEPTH_COMPONENT
||
345 baseFormat
== GL_DEPTH_STENCIL
||
346 baseFormat
== GL_STENCIL_INDEX
) {
347 if (stObj
->base
.StencilSampling
|| baseFormat
== GL_STENCIL_INDEX
)
348 format
= util_format_stencil_only(format
);
353 /* If sRGB decoding is off, use the linear format */
354 if (srgb_skip_decode
)
355 format
= util_format_linear(format
);
357 /* Use R8_UNORM for video formats */
359 case PIPE_FORMAT_NV12
:
360 case PIPE_FORMAT_IYUV
:
361 format
= PIPE_FORMAT_R8_UNORM
;
370 static struct pipe_sampler_view
*
371 st_create_texture_sampler_view_from_stobj(struct st_context
*st
,
372 struct st_texture_object
*stObj
,
373 enum pipe_format format
,
374 bool glsl130_or_later
)
376 /* There is no need to clear this structure (consider CPU overhead). */
377 struct pipe_sampler_view templ
;
378 unsigned swizzle
= get_texture_format_swizzle(st
, stObj
, glsl130_or_later
);
380 templ
.format
= format
;
382 if (stObj
->level_override
) {
383 templ
.u
.tex
.first_level
= templ
.u
.tex
.last_level
= stObj
->level_override
;
385 templ
.u
.tex
.first_level
= stObj
->base
.MinLevel
+ stObj
->base
.BaseLevel
;
386 templ
.u
.tex
.last_level
= last_level(stObj
);
388 if (stObj
->layer_override
) {
389 templ
.u
.tex
.first_layer
= templ
.u
.tex
.last_layer
= stObj
->layer_override
;
391 templ
.u
.tex
.first_layer
= stObj
->base
.MinLayer
;
392 templ
.u
.tex
.last_layer
= last_layer(stObj
);
394 assert(templ
.u
.tex
.first_layer
<= templ
.u
.tex
.last_layer
);
395 assert(templ
.u
.tex
.first_level
<= templ
.u
.tex
.last_level
);
396 templ
.target
= gl_target_to_pipe(stObj
->base
.Target
);
398 templ
.swizzle_r
= GET_SWZ(swizzle
, 0);
399 templ
.swizzle_g
= GET_SWZ(swizzle
, 1);
400 templ
.swizzle_b
= GET_SWZ(swizzle
, 2);
401 templ
.swizzle_a
= GET_SWZ(swizzle
, 3);
403 return st
->pipe
->create_sampler_view(st
->pipe
, stObj
->pt
, &templ
);
407 struct pipe_sampler_view
*
408 st_get_texture_sampler_view_from_stobj(struct st_context
*st
,
409 struct st_texture_object
*stObj
,
410 const struct gl_sampler_object
*samp
,
411 bool glsl130_or_later
,
412 bool ignore_srgb_decode
)
414 struct st_sampler_view
*sv
;
415 struct pipe_sampler_view
*view
;
416 bool srgb_skip_decode
= false;
418 sv
= st_texture_get_sampler_view(st
, stObj
);
421 if (!ignore_srgb_decode
&& samp
->sRGBDecode
== GL_SKIP_DECODE_EXT
)
422 srgb_skip_decode
= true;
425 sv
->glsl130_or_later
== glsl130_or_later
&&
426 sv
->srgb_skip_decode
== srgb_skip_decode
) {
427 /* Debug check: make sure that the sampler view's parameters are
428 * what they're supposed to be.
430 MAYBE_UNUSED
struct pipe_sampler_view
*view
= sv
->view
;
431 assert(stObj
->pt
== view
->texture
);
432 assert(!check_sampler_swizzle(st
, stObj
, view
, glsl130_or_later
));
433 assert(get_sampler_view_format(st
, stObj
, srgb_skip_decode
) == view
->format
);
434 assert(gl_target_to_pipe(stObj
->base
.Target
) == view
->target
);
435 assert(stObj
->level_override
||
436 stObj
->base
.MinLevel
+ stObj
->base
.BaseLevel
== view
->u
.tex
.first_level
);
437 assert(stObj
->level_override
|| last_level(stObj
) == view
->u
.tex
.last_level
);
438 assert(stObj
->layer_override
|| stObj
->base
.MinLayer
== view
->u
.tex
.first_layer
);
439 assert(stObj
->layer_override
|| last_layer(stObj
) == view
->u
.tex
.last_layer
);
440 assert(!stObj
->layer_override
||
441 (stObj
->layer_override
== view
->u
.tex
.first_layer
&&
442 stObj
->layer_override
== view
->u
.tex
.last_layer
));
445 /* create new sampler view */
446 enum pipe_format format
= get_sampler_view_format(st
, stObj
, srgb_skip_decode
);
448 sv
->glsl130_or_later
= glsl130_or_later
;
449 sv
->srgb_skip_decode
= srgb_skip_decode
;
451 pipe_sampler_view_release(st
->pipe
, &sv
->view
);
453 st_create_texture_sampler_view_from_stobj(st
, stObj
, format
, glsl130_or_later
);
460 struct pipe_sampler_view
*
461 st_get_buffer_sampler_view_from_stobj(struct st_context
*st
,
462 struct st_texture_object
*stObj
)
464 struct st_sampler_view
*sv
;
465 struct st_buffer_object
*stBuf
=
466 st_buffer_object(stObj
->base
.BufferObject
);
468 if (!stBuf
|| !stBuf
->buffer
)
471 sv
= st_texture_get_sampler_view(st
, stObj
);
473 struct pipe_resource
*buf
= stBuf
->buffer
;
474 struct pipe_sampler_view
*view
= sv
->view
;
476 if (view
&& view
->texture
== buf
) {
477 /* Debug check: make sure that the sampler view's parameters are
478 * what they're supposed to be.
480 assert(st_mesa_format_to_pipe_format(st
, stObj
->base
._BufferObjectFormat
)
482 assert(view
->target
== PIPE_BUFFER
);
483 unsigned base
= stObj
->base
.BufferOffset
;
484 MAYBE_UNUSED
unsigned size
= MIN2(buf
->width0
- base
,
485 (unsigned) stObj
->base
.BufferSize
);
486 assert(view
->u
.buf
.offset
== base
);
487 assert(view
->u
.buf
.size
== size
);
489 unsigned base
= stObj
->base
.BufferOffset
;
491 if (base
>= buf
->width0
)
494 unsigned size
= buf
->width0
- base
;
495 size
= MIN2(size
, (unsigned)stObj
->base
.BufferSize
);
499 /* Create a new sampler view. There is no need to clear the entire
500 * structure (consider CPU overhead).
502 struct pipe_sampler_view templ
;
505 st_mesa_format_to_pipe_format(st
, stObj
->base
._BufferObjectFormat
);
506 templ
.target
= PIPE_BUFFER
;
507 templ
.swizzle_r
= PIPE_SWIZZLE_X
;
508 templ
.swizzle_g
= PIPE_SWIZZLE_Y
;
509 templ
.swizzle_b
= PIPE_SWIZZLE_Z
;
510 templ
.swizzle_a
= PIPE_SWIZZLE_W
;
511 templ
.u
.buf
.offset
= base
;
512 templ
.u
.buf
.size
= size
;
514 pipe_sampler_view_release(st
->pipe
, &sv
->view
);
515 view
= sv
->view
= st
->pipe
->create_sampler_view(st
->pipe
, buf
, &templ
);