st/mesa: apply DepthMode swizzle to stencil texturing as well
[mesa.git] / src / mesa / state_tracker / st_atom_texture.c
1 /**************************************************************************
2 *
3 * Copyright 2007 VMware, Inc.
4 * All Rights Reserved.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sub license, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
13 *
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial portions
16 * of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21 * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
22 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 *
26 **************************************************************************/
27
28 /*
29 * Authors:
30 * Keith Whitwell <keithw@vmware.com>
31 * Brian Paul
32 */
33
34
35 #include "main/macros.h"
36 #include "main/mtypes.h"
37 #include "main/samplerobj.h"
38 #include "main/teximage.h"
39 #include "main/texobj.h"
40 #include "program/prog_instruction.h"
41
42 #include "st_context.h"
43 #include "st_atom.h"
44 #include "st_texture.h"
45 #include "st_format.h"
46 #include "st_cb_texture.h"
47 #include "pipe/p_context.h"
48 #include "util/u_format.h"
49 #include "util/u_inlines.h"
50 #include "cso_cache/cso_context.h"
51
52
53 /**
54 * Return swizzle1(swizzle2)
55 */
56 static unsigned
57 swizzle_swizzle(unsigned swizzle1, unsigned swizzle2)
58 {
59 unsigned i, swz[4];
60
61 for (i = 0; i < 4; i++) {
62 unsigned s = GET_SWZ(swizzle1, i);
63 switch (s) {
64 case SWIZZLE_X:
65 case SWIZZLE_Y:
66 case SWIZZLE_Z:
67 case SWIZZLE_W:
68 swz[i] = GET_SWZ(swizzle2, s);
69 break;
70 case SWIZZLE_ZERO:
71 swz[i] = SWIZZLE_ZERO;
72 break;
73 case SWIZZLE_ONE:
74 swz[i] = SWIZZLE_ONE;
75 break;
76 default:
77 assert(!"Bad swizzle term");
78 swz[i] = SWIZZLE_X;
79 }
80 }
81
82 return MAKE_SWIZZLE4(swz[0], swz[1], swz[2], swz[3]);
83 }
84
85
86 /**
87 * Given a user-specified texture base format, the actual gallium texture
88 * format and the current GL_DEPTH_MODE, return a texture swizzle.
89 *
90 * Consider the case where the user requests a GL_RGB internal texture
91 * format the driver actually uses an RGBA format. The A component should
92 * be ignored and sampling from the texture should always return (r,g,b,1).
93 * But if we rendered to the texture we might have written A values != 1.
94 * By sampling the texture with a ".xyz1" swizzle we'll get the expected A=1.
95 * This function computes the texture swizzle needed to get the expected
96 * values.
97 *
98 * In the case of depth textures, the GL_DEPTH_MODE state determines the
99 * texture swizzle.
100 *
101 * This result must be composed with the user-specified swizzle to get
102 * the final swizzle.
103 */
104 static unsigned
105 compute_texture_format_swizzle(GLenum baseFormat, GLenum depthMode,
106 enum pipe_format actualFormat,
107 unsigned glsl_version)
108 {
109 switch (baseFormat) {
110 case GL_RGBA:
111 return SWIZZLE_XYZW;
112 case GL_RGB:
113 if (util_format_has_alpha(actualFormat))
114 return MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_ONE);
115 else
116 return SWIZZLE_XYZW;
117 case GL_RG:
118 if (util_format_get_nr_components(actualFormat) > 2)
119 return MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_ZERO, SWIZZLE_ONE);
120 else
121 return SWIZZLE_XYZW;
122 case GL_RED:
123 if (util_format_get_nr_components(actualFormat) > 1)
124 return MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_ZERO,
125 SWIZZLE_ZERO, SWIZZLE_ONE);
126 else
127 return SWIZZLE_XYZW;
128 case GL_ALPHA:
129 if (util_format_get_nr_components(actualFormat) > 1)
130 return MAKE_SWIZZLE4(SWIZZLE_ZERO, SWIZZLE_ZERO,
131 SWIZZLE_ZERO, SWIZZLE_W);
132 else
133 return SWIZZLE_XYZW;
134 case GL_LUMINANCE:
135 if (util_format_get_nr_components(actualFormat) > 1)
136 return MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_X, SWIZZLE_X, SWIZZLE_ONE);
137 else
138 return SWIZZLE_XYZW;
139 case GL_LUMINANCE_ALPHA:
140 if (util_format_get_nr_components(actualFormat) > 2)
141 return MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_X, SWIZZLE_X, SWIZZLE_W);
142 else
143 return SWIZZLE_XYZW;
144 case GL_INTENSITY:
145 if (util_format_get_nr_components(actualFormat) > 1)
146 return SWIZZLE_XXXX;
147 else
148 return SWIZZLE_XYZW;
149 case GL_STENCIL_INDEX:
150 case GL_DEPTH_STENCIL:
151 case GL_DEPTH_COMPONENT:
152 /* Now examine the depth mode */
153 switch (depthMode) {
154 case GL_LUMINANCE:
155 return MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_X, SWIZZLE_X, SWIZZLE_ONE);
156 case GL_INTENSITY:
157 return MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_X, SWIZZLE_X, SWIZZLE_X);
158 case GL_ALPHA:
159 /* The texture(sampler*Shadow) functions from GLSL 1.30 ignore
160 * the depth mode and return float, while older shadow* functions
161 * and ARB_fp instructions return vec4 according to the depth mode.
162 *
163 * The problem with the GLSL 1.30 functions is that GL_ALPHA forces
164 * them to return 0, breaking them completely.
165 *
166 * A proper fix would increase code complexity and that's not worth
167 * it for a rarely used feature such as the GL_ALPHA depth mode
168 * in GL3. Therefore, change GL_ALPHA to GL_INTENSITY for all
169 * shaders that use GLSL 1.30 or later.
170 *
171 * BTW, it's required that sampler views are updated when
172 * shaders change (check_sampler_swizzle takes care of that).
173 */
174 if (glsl_version && glsl_version >= 130)
175 return SWIZZLE_XXXX;
176 else
177 return MAKE_SWIZZLE4(SWIZZLE_ZERO, SWIZZLE_ZERO,
178 SWIZZLE_ZERO, SWIZZLE_X);
179 case GL_RED:
180 return MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_ZERO,
181 SWIZZLE_ZERO, SWIZZLE_ONE);
182 default:
183 assert(!"Unexpected depthMode");
184 return SWIZZLE_XYZW;
185 }
186 default:
187 assert(!"Unexpected baseFormat");
188 return SWIZZLE_XYZW;
189 }
190 }
191
192
193 static unsigned
194 get_texture_format_swizzle(const struct st_texture_object *stObj,
195 unsigned glsl_version)
196 {
197 GLenum baseFormat = _mesa_texture_base_format(&stObj->base);
198 unsigned tex_swizzle;
199
200 if (baseFormat != GL_NONE) {
201 tex_swizzle = compute_texture_format_swizzle(baseFormat,
202 stObj->base.DepthMode,
203 stObj->pt->format,
204 glsl_version);
205 }
206 else {
207 tex_swizzle = SWIZZLE_XYZW;
208 }
209
210 /* Combine the texture format swizzle with user's swizzle */
211 return swizzle_swizzle(stObj->base._Swizzle, tex_swizzle);
212 }
213
214
215 /**
216 * Return TRUE if the texture's sampler view swizzle is not equal to
217 * the texture's swizzle.
218 *
219 * \param stObj the st texture object,
220 */
221 static boolean
222 check_sampler_swizzle(const struct st_texture_object *stObj,
223 struct pipe_sampler_view *sv, unsigned glsl_version)
224 {
225 unsigned swizzle = get_texture_format_swizzle(stObj, glsl_version);
226
227 return ((sv->swizzle_r != GET_SWZ(swizzle, 0)) ||
228 (sv->swizzle_g != GET_SWZ(swizzle, 1)) ||
229 (sv->swizzle_b != GET_SWZ(swizzle, 2)) ||
230 (sv->swizzle_a != GET_SWZ(swizzle, 3)));
231 }
232
233
234 static unsigned last_level(struct st_texture_object *stObj)
235 {
236 unsigned ret = MIN2(stObj->base.MinLevel + stObj->base._MaxLevel,
237 stObj->pt->last_level);
238 if (stObj->base.Immutable)
239 ret = MIN2(ret, stObj->base.MinLevel + stObj->base.NumLevels - 1);
240 return ret;
241 }
242
243 static unsigned last_layer(struct st_texture_object *stObj)
244 {
245 if (stObj->base.Immutable && stObj->pt->array_size > 1)
246 return MIN2(stObj->base.MinLayer + stObj->base.NumLayers - 1,
247 stObj->pt->array_size - 1);
248 return stObj->pt->array_size - 1;
249 }
250
251 static struct pipe_sampler_view *
252 st_create_texture_sampler_view_from_stobj(struct pipe_context *pipe,
253 struct st_texture_object *stObj,
254 enum pipe_format format,
255 unsigned glsl_version)
256 {
257 struct pipe_sampler_view templ;
258 unsigned swizzle = get_texture_format_swizzle(stObj, glsl_version);
259
260 u_sampler_view_default_template(&templ,
261 stObj->pt,
262 format);
263
264 if (stObj->pt->target == PIPE_BUFFER) {
265 unsigned base, size;
266 unsigned f, n;
267 const struct util_format_description *desc
268 = util_format_description(templ.format);
269
270 base = stObj->base.BufferOffset;
271 if (base >= stObj->pt->width0)
272 return NULL;
273 size = MIN2(stObj->pt->width0 - base, (unsigned)stObj->base.BufferSize);
274
275 f = (base / (desc->block.bits / 8)) * desc->block.width;
276 n = (size / (desc->block.bits / 8)) * desc->block.width;
277 if (!n)
278 return NULL;
279 templ.u.buf.first_element = f;
280 templ.u.buf.last_element = f + (n - 1);
281 } else {
282 templ.u.tex.first_level = stObj->base.MinLevel + stObj->base.BaseLevel;
283 templ.u.tex.last_level = last_level(stObj);
284 assert(templ.u.tex.first_level <= templ.u.tex.last_level);
285 templ.u.tex.first_layer = stObj->base.MinLayer;
286 templ.u.tex.last_layer = last_layer(stObj);
287 assert(templ.u.tex.first_layer <= templ.u.tex.last_layer);
288 templ.target = gl_target_to_pipe(stObj->base.Target);
289 }
290
291 if (swizzle != SWIZZLE_NOOP) {
292 templ.swizzle_r = GET_SWZ(swizzle, 0);
293 templ.swizzle_g = GET_SWZ(swizzle, 1);
294 templ.swizzle_b = GET_SWZ(swizzle, 2);
295 templ.swizzle_a = GET_SWZ(swizzle, 3);
296 }
297
298 return pipe->create_sampler_view(pipe, stObj->pt, &templ);
299 }
300
301
302 static struct pipe_sampler_view *
303 st_get_texture_sampler_view_from_stobj(struct st_context *st,
304 struct st_texture_object *stObj,
305 enum pipe_format format,
306 unsigned glsl_version)
307 {
308 struct pipe_sampler_view **sv;
309 const struct st_texture_image *firstImage;
310 if (!stObj || !stObj->pt) {
311 return NULL;
312 }
313
314 sv = st_texture_get_sampler_view(st, stObj);
315
316 if (util_format_is_depth_and_stencil(format)) {
317 if (stObj->base.StencilSampling)
318 format = util_format_stencil_only(format);
319 else {
320 firstImage = st_texture_image_const(_mesa_base_tex_image(&stObj->base));
321 if (firstImage->base._BaseFormat == GL_STENCIL_INDEX)
322 format = util_format_stencil_only(format);
323 }
324 }
325
326 /* if sampler view has changed dereference it */
327 if (*sv) {
328 if (check_sampler_swizzle(stObj, *sv, glsl_version) ||
329 (format != (*sv)->format) ||
330 gl_target_to_pipe(stObj->base.Target) != (*sv)->target ||
331 stObj->base.MinLevel + stObj->base.BaseLevel != (*sv)->u.tex.first_level ||
332 last_level(stObj) != (*sv)->u.tex.last_level ||
333 stObj->base.MinLayer != (*sv)->u.tex.first_layer ||
334 last_layer(stObj) != (*sv)->u.tex.last_layer) {
335 pipe_sampler_view_reference(sv, NULL);
336 }
337 }
338
339 if (!*sv) {
340 *sv = st_create_texture_sampler_view_from_stobj(st->pipe, stObj,
341 format, glsl_version);
342
343 } else if ((*sv)->context != st->pipe) {
344 /* Recreate view in correct context, use existing view as template */
345 struct pipe_sampler_view *new_sv =
346 st->pipe->create_sampler_view(st->pipe, stObj->pt, *sv);
347 pipe_sampler_view_reference(sv, NULL);
348 *sv = new_sv;
349 }
350
351 return *sv;
352 }
353
354 static GLboolean
355 update_single_texture(struct st_context *st,
356 struct pipe_sampler_view **sampler_view,
357 GLuint texUnit, unsigned glsl_version)
358 {
359 struct gl_context *ctx = st->ctx;
360 const struct gl_sampler_object *samp;
361 struct gl_texture_object *texObj;
362 struct st_texture_object *stObj;
363 enum pipe_format view_format;
364 GLboolean retval;
365
366 samp = _mesa_get_samplerobj(ctx, texUnit);
367
368 texObj = ctx->Texture.Unit[texUnit]._Current;
369
370 if (!texObj) {
371 texObj = _mesa_get_fallback_texture(ctx, TEXTURE_2D_INDEX);
372 samp = &texObj->Sampler;
373 }
374 stObj = st_texture_object(texObj);
375
376 retval = st_finalize_texture(ctx, st->pipe, texObj);
377 if (!retval) {
378 /* out of mem */
379 return GL_FALSE;
380 }
381
382 /* Determine the format of the texture sampler view */
383 if (texObj->Target == GL_TEXTURE_BUFFER) {
384 view_format =
385 st_mesa_format_to_pipe_format(st, stObj->base._BufferObjectFormat);
386 }
387 else {
388 view_format =
389 stObj->surface_based ? stObj->surface_format : stObj->pt->format;
390
391 /* If sRGB decoding is off, use the linear format */
392 if (samp->sRGBDecode == GL_SKIP_DECODE_EXT) {
393 view_format = util_format_linear(view_format);
394 }
395 }
396
397 *sampler_view =
398 st_get_texture_sampler_view_from_stobj(st, stObj, view_format,
399 glsl_version);
400 return GL_TRUE;
401 }
402
403
404
405 static void
406 update_textures(struct st_context *st,
407 gl_shader_stage mesa_shader,
408 const struct gl_program *prog,
409 unsigned max_units,
410 struct pipe_sampler_view **sampler_views,
411 unsigned *num_textures)
412 {
413 const GLuint old_max = *num_textures;
414 GLbitfield samplers_used = prog->SamplersUsed;
415 GLuint unit;
416 struct gl_shader_program *shader =
417 st->ctx->_Shader->CurrentProgram[mesa_shader];
418 unsigned glsl_version = shader ? shader->Version : 0;
419 unsigned shader_stage = st_shader_stage_to_ptarget(mesa_shader);
420
421 if (samplers_used == 0x0 && old_max == 0)
422 return;
423
424 *num_textures = 0;
425
426 /* loop over sampler units (aka tex image units) */
427 for (unit = 0; unit < max_units; unit++, samplers_used >>= 1) {
428 struct pipe_sampler_view *sampler_view = NULL;
429
430 if (samplers_used & 1) {
431 const GLuint texUnit = prog->SamplerUnits[unit];
432 GLboolean retval;
433
434 retval = update_single_texture(st, &sampler_view, texUnit,
435 glsl_version);
436 if (retval == GL_FALSE)
437 continue;
438
439 *num_textures = unit + 1;
440 }
441 else if (samplers_used == 0 && unit >= old_max) {
442 /* if we've reset all the old views and we have no more new ones */
443 break;
444 }
445
446 pipe_sampler_view_reference(&(sampler_views[unit]), sampler_view);
447 }
448
449 cso_set_sampler_views(st->cso_context,
450 shader_stage,
451 *num_textures,
452 sampler_views);
453 }
454
455
456
457 static void
458 update_vertex_textures(struct st_context *st)
459 {
460 const struct gl_context *ctx = st->ctx;
461
462 if (ctx->Const.Program[MESA_SHADER_VERTEX].MaxTextureImageUnits > 0) {
463 update_textures(st,
464 MESA_SHADER_VERTEX,
465 &ctx->VertexProgram._Current->Base,
466 ctx->Const.Program[MESA_SHADER_VERTEX].MaxTextureImageUnits,
467 st->state.sampler_views[PIPE_SHADER_VERTEX],
468 &st->state.num_sampler_views[PIPE_SHADER_VERTEX]);
469 }
470 }
471
472
473 static void
474 update_fragment_textures(struct st_context *st)
475 {
476 const struct gl_context *ctx = st->ctx;
477
478 update_textures(st,
479 MESA_SHADER_FRAGMENT,
480 &ctx->FragmentProgram._Current->Base,
481 ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxTextureImageUnits,
482 st->state.sampler_views[PIPE_SHADER_FRAGMENT],
483 &st->state.num_sampler_views[PIPE_SHADER_FRAGMENT]);
484 }
485
486
487 static void
488 update_geometry_textures(struct st_context *st)
489 {
490 const struct gl_context *ctx = st->ctx;
491
492 if (ctx->GeometryProgram._Current) {
493 update_textures(st,
494 MESA_SHADER_GEOMETRY,
495 &ctx->GeometryProgram._Current->Base,
496 ctx->Const.Program[MESA_SHADER_GEOMETRY].MaxTextureImageUnits,
497 st->state.sampler_views[PIPE_SHADER_GEOMETRY],
498 &st->state.num_sampler_views[PIPE_SHADER_GEOMETRY]);
499 }
500 }
501
502
503 static void
504 update_tessctrl_textures(struct st_context *st)
505 {
506 const struct gl_context *ctx = st->ctx;
507
508 if (ctx->TessCtrlProgram._Current) {
509 update_textures(st,
510 MESA_SHADER_TESS_CTRL,
511 &ctx->TessCtrlProgram._Current->Base,
512 ctx->Const.Program[MESA_SHADER_TESS_CTRL].MaxTextureImageUnits,
513 st->state.sampler_views[PIPE_SHADER_TESS_CTRL],
514 &st->state.num_sampler_views[PIPE_SHADER_TESS_CTRL]);
515 }
516 }
517
518
519 static void
520 update_tesseval_textures(struct st_context *st)
521 {
522 const struct gl_context *ctx = st->ctx;
523
524 if (ctx->TessEvalProgram._Current) {
525 update_textures(st,
526 MESA_SHADER_TESS_EVAL,
527 &ctx->TessEvalProgram._Current->Base,
528 ctx->Const.Program[MESA_SHADER_TESS_EVAL].MaxTextureImageUnits,
529 st->state.sampler_views[PIPE_SHADER_TESS_EVAL],
530 &st->state.num_sampler_views[PIPE_SHADER_TESS_EVAL]);
531 }
532 }
533
534
535 static void
536 update_compute_textures(struct st_context *st)
537 {
538 const struct gl_context *ctx = st->ctx;
539
540 if (ctx->ComputeProgram._Current) {
541 update_textures(st,
542 MESA_SHADER_COMPUTE,
543 &ctx->ComputeProgram._Current->Base,
544 ctx->Const.Program[MESA_SHADER_COMPUTE].MaxTextureImageUnits,
545 st->state.sampler_views[PIPE_SHADER_COMPUTE],
546 &st->state.num_sampler_views[PIPE_SHADER_COMPUTE]);
547 }
548 }
549
550
551 const struct st_tracked_state st_update_fragment_texture = {
552 "st_update_texture", /* name */
553 { /* dirty */
554 _NEW_TEXTURE, /* mesa */
555 ST_NEW_FRAGMENT_PROGRAM | ST_NEW_SAMPLER_VIEWS, /* st */
556 },
557 update_fragment_textures /* update */
558 };
559
560
561 const struct st_tracked_state st_update_vertex_texture = {
562 "st_update_vertex_texture", /* name */
563 { /* dirty */
564 _NEW_TEXTURE, /* mesa */
565 ST_NEW_VERTEX_PROGRAM | ST_NEW_SAMPLER_VIEWS, /* st */
566 },
567 update_vertex_textures /* update */
568 };
569
570
571 const struct st_tracked_state st_update_geometry_texture = {
572 "st_update_geometry_texture", /* name */
573 { /* dirty */
574 _NEW_TEXTURE, /* mesa */
575 ST_NEW_GEOMETRY_PROGRAM | ST_NEW_SAMPLER_VIEWS, /* st */
576 },
577 update_geometry_textures /* update */
578 };
579
580
581 const struct st_tracked_state st_update_tessctrl_texture = {
582 "st_update_tessctrl_texture", /* name */
583 { /* dirty */
584 _NEW_TEXTURE, /* mesa */
585 ST_NEW_TESSCTRL_PROGRAM | ST_NEW_SAMPLER_VIEWS, /* st */
586 },
587 update_tessctrl_textures /* update */
588 };
589
590
591 const struct st_tracked_state st_update_tesseval_texture = {
592 "st_update_tesseval_texture", /* name */
593 { /* dirty */
594 _NEW_TEXTURE, /* mesa */
595 ST_NEW_TESSEVAL_PROGRAM | ST_NEW_SAMPLER_VIEWS, /* st */
596 },
597 update_tesseval_textures /* update */
598 };
599
600
601 const struct st_tracked_state st_update_compute_texture = {
602 "st_update_compute_texture", /* name */
603 { /* dirty */
604 _NEW_TEXTURE, /* mesa */
605 ST_NEW_COMPUTE_PROGRAM | ST_NEW_SAMPLER_VIEWS, /* st */
606 },
607 update_compute_textures /* update */
608 };