1 /**************************************************************************
3 * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
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:
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial portions
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 TUNGSTEN GRAPHICS 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.
26 **************************************************************************/
30 * Texture Image-related functions.
34 #include "main/imports.h"
35 #include "main/context.h"
36 #include "main/texstore.h"
37 #include "main/texformat.h"
38 #include "main/enums.h"
39 #include "main/macros.h"
41 #include "pipe/p_context.h"
42 #include "pipe/p_defines.h"
43 #include "st_context.h"
44 #include "st_format.h"
48 struct pipe_format_rgbazs info
,
53 if (info
.swizzleX
== comp
) {
56 else if (info
.swizzleY
== comp
) {
59 else if (info
.swizzleZ
== comp
) {
62 else if (info
.swizzleW
== comp
) {
68 return size
<< (info
.exp8
* 3);
73 struct pipe_format_rgbazs info
)
75 GLuint size
= format_bits( info
, PIPE_FORMAT_COMP_R
);
77 size
= MAX2( size
, format_bits( info
, PIPE_FORMAT_COMP_G
) );
78 size
= MAX2( size
, format_bits( info
, PIPE_FORMAT_COMP_B
) );
79 size
= MAX2( size
, format_bits( info
, PIPE_FORMAT_COMP_A
) );
80 size
= MAX2( size
, format_bits( info
, PIPE_FORMAT_COMP_Z
) );
81 size
= MAX2( size
, format_bits( info
, PIPE_FORMAT_COMP_S
) );
87 struct pipe_format_rgbazs info
)
90 format_bits( info
, PIPE_FORMAT_COMP_R
) +
91 format_bits( info
, PIPE_FORMAT_COMP_G
) +
92 format_bits( info
, PIPE_FORMAT_COMP_B
) +
93 format_bits( info
, PIPE_FORMAT_COMP_A
) +
94 format_bits( info
, PIPE_FORMAT_COMP_Z
) +
95 format_bits( info
, PIPE_FORMAT_COMP_S
);
104 struct pipe_format_info
*pinfo
)
107 static const struct pipe_format_info info
[] = {
109 PIPE_FORMAT_U_R8_G8_B8_A8
, /* format */
110 GL_RGBA
, /* base_format */
111 GL_UNSIGNED_BYTE
, /* datatype for renderbuffers */
112 8, 8, 8, 8, 0, 0, /* color bits */
113 0, 0, /* depth, stencil */
114 4 /* size in bytes */
117 PIPE_FORMAT_U_A8_R8_G8_B8
,
118 GL_RGBA
, /* base_format */
119 GL_UNSIGNED_BYTE
, /* datatype for renderbuffers */
120 8, 8, 8, 8, 0, 0, /* color bits */
121 0, 0, /* depth, stencil */
122 4 /* size in bytes */
125 PIPE_FORMAT_U_A1_R5_G5_B5
,
126 GL_RGBA
, /* base_format */
127 GL_UNSIGNED_SHORT
, /* datatype for renderbuffers */
128 5, 5, 5, 1, 0, 0, /* color bits */
129 0, 0, /* depth, stencil */
130 2 /* size in bytes */
133 PIPE_FORMAT_U_R5_G6_B5
,
134 GL_RGBA
, /* base_format */
135 GL_UNSIGNED_SHORT
, /* datatype for renderbuffers */
136 5, 6, 5, 0, 0, 0, /* color bits */
137 0, 0, /* depth, stencil */
138 2 /* size in bytes */
141 PIPE_FORMAT_S_R16_G16_B16_A16
,
142 GL_RGBA
, /* base_format */
143 GL_UNSIGNED_SHORT
, /* datatype for renderbuffers */
144 16, 16, 16, 16, 0, 0, /* color bits */
145 0, 0, /* depth, stencil */
146 8 /* size in bytes */
150 GL_DEPTH_COMPONENT
, /* base_format */
151 GL_UNSIGNED_SHORT
, /* datatype for renderbuffers */
152 0, 0, 0, 0, 0, 0, /* color bits */
153 16, 0, /* depth, stencil */
154 2 /* size in bytes */
158 GL_DEPTH_COMPONENT
, /* base_format */
159 GL_UNSIGNED_INT
, /* datatype for renderbuffers */
160 0, 0, 0, 0, 0, 0, /* color bits */
161 32, 0, /* depth, stencil */
162 4 /* size in bytes */
166 GL_DEPTH_STENCIL_EXT
, /* base_format */
167 GL_UNSIGNED_INT
, /* datatype for renderbuffers */
168 0, 0, 0, 0, 0, 0, /* color bits */
169 24, 8, /* depth, stencil */
170 4 /* size in bytes */
172 /* XXX lots more cases to add */
176 for (i
= 0; i
< sizeof(info
) / sizeof(info
[0]); i
++) {
177 if (info
[i
].format
== format
)
183 union pipe_format fmt
;
185 fmt
.value32
= format
;
186 if (fmt
.header
.layout
== PIPE_FORMAT_LAYOUT_RGBAZS
) {
187 struct pipe_format_rgbazs info
;
193 "PIPE_FORMAT: X(%u), Y(%u), Z(%u), W(%u)\n",
201 if (format
== PIPE_FORMAT_U_A1_R5_G5_B5
|| format
== PIPE_FORMAT_U_R5_G6_B5
) {
202 pinfo
->datatype
= GL_UNSIGNED_SHORT
;
207 size
= format_max_bits( info
);
209 if (info
.type
== PIPE_FORMAT_TYPE_UNORM
)
210 pinfo
->datatype
= GL_UNSIGNED_BYTE
;
212 pinfo
->datatype
= GL_BYTE
;
214 else if (size
== 16) {
215 if (info
.type
== PIPE_FORMAT_TYPE_UNORM
)
216 pinfo
->datatype
= GL_UNSIGNED_SHORT
;
218 pinfo
->datatype
= GL_SHORT
;
221 assert( size
<= 32 );
222 if (info
.type
== PIPE_FORMAT_TYPE_UNORM
)
223 pinfo
->datatype
= GL_UNSIGNED_INT
;
225 pinfo
->datatype
= GL_INT
;
230 pinfo
->red_bits
= format_bits( info
, PIPE_FORMAT_COMP_R
);
231 pinfo
->green_bits
= format_bits( info
, PIPE_FORMAT_COMP_G
);
232 pinfo
->blue_bits
= format_bits( info
, PIPE_FORMAT_COMP_B
);
233 pinfo
->alpha_bits
= format_bits( info
, PIPE_FORMAT_COMP_A
);
234 pinfo
->depth_bits
= format_bits( info
, PIPE_FORMAT_COMP_Z
);
235 pinfo
->stencil_bits
= format_bits( info
, PIPE_FORMAT_COMP_S
);
238 pinfo
->size
= format_size( info
) / 8;
240 /* Luminance & Intensity bits */
241 if( info
.swizzleX
== PIPE_FORMAT_COMP_R
&& info
.swizzleY
== PIPE_FORMAT_COMP_R
&& info
.swizzleZ
== PIPE_FORMAT_COMP_R
) {
242 if( info
.swizzleW
== PIPE_FORMAT_COMP_R
) {
243 pinfo
->luminance_bits
= 0;
244 pinfo
->intensity_bits
= pinfo
->red_bits
;
247 pinfo
->luminance_bits
= pinfo
->red_bits
;
248 pinfo
->intensity_bits
= 0;
254 if (pinfo
->depth_bits
) {
255 if (pinfo
->stencil_bits
) {
256 pinfo
->base_format
= GL_DEPTH_STENCIL_EXT
;
259 pinfo
->base_format
= GL_DEPTH_COMPONENT
;
262 else if (pinfo
->stencil_bits
) {
263 pinfo
->base_format
= GL_STENCIL_INDEX
;
266 pinfo
->base_format
= GL_RGBA
;
270 struct pipe_format_ycbcr info
;
272 assert( fmt
.header
.layout
== PIPE_FORMAT_LAYOUT_YCBCR
);
282 "ST_FORMAT: R(%u), G(%u), B(%u), A(%u), Z(%u), S(%u)\n",
288 pinfo
->stencil_bits
);
291 pinfo
->format
= format
;
298 * Return bytes per pixel for the given format.
301 st_sizeof_format(GLuint pipeFormat
)
303 struct pipe_format_info info
;
304 if (!st_get_format_info( pipeFormat
, &info
)) {
313 * Return bytes per pixel for the given format.
316 st_format_datatype(GLuint pipeFormat
)
318 struct pipe_format_info info
;
319 if (!st_get_format_info( pipeFormat
, &info
)) {
323 return info
.datatype
;
328 st_mesa_format_to_pipe_format(GLuint mesaFormat
)
330 switch (mesaFormat
) {
332 case MESA_FORMAT_ARGB8888_REV
:
333 case MESA_FORMAT_ARGB8888
:
334 return PIPE_FORMAT_U_A8_R8_G8_B8
;
335 case MESA_FORMAT_AL88
:
336 return PIPE_FORMAT_U_A8_L8
;
338 return PIPE_FORMAT_U_A8
;
340 return PIPE_FORMAT_U_L8
;
342 return PIPE_FORMAT_U_I8
;
343 case MESA_FORMAT_Z16
:
344 return PIPE_FORMAT_U_Z16
;
352 * Search list of formats for first RGBA format.
356 struct pipe_context
*pipe
)
358 if (pipe
->is_format_supported( pipe
, PIPE_FORMAT_U_R8_G8_B8_A8
)) {
359 return PIPE_FORMAT_U_R8_G8_B8_A8
;
361 if (pipe
->is_format_supported( pipe
, PIPE_FORMAT_U_A8_R8_G8_B8
)) {
362 return PIPE_FORMAT_U_A8_R8_G8_B8
;
364 if (pipe
->is_format_supported( pipe
, PIPE_FORMAT_U_R5_G6_B5
)) {
365 return PIPE_FORMAT_U_R5_G6_B5
;
367 return PIPE_FORMAT_NONE
;
372 * Search list of formats for first RGBA format with >8 bits/channel.
375 default_deep_rgba_format(
376 struct pipe_context
*pipe
)
378 if (pipe
->is_format_supported( pipe
, PIPE_FORMAT_S_R16_G16_B16_A16
)) {
379 return PIPE_FORMAT_S_R16_G16_B16_A16
;
381 return PIPE_FORMAT_NONE
;
386 * Search list of formats for first depth/Z format.
389 default_depth_format(
390 struct pipe_context
*pipe
)
392 if (pipe
->is_format_supported( pipe
, PIPE_FORMAT_U_Z16
)) {
393 return PIPE_FORMAT_U_Z16
;
395 if (pipe
->is_format_supported( pipe
, PIPE_FORMAT_U_Z32
)) {
396 return PIPE_FORMAT_U_Z32
;
398 if (pipe
->is_format_supported( pipe
, PIPE_FORMAT_S8_Z24
)) {
399 return PIPE_FORMAT_S8_Z24
;
401 return PIPE_FORMAT_NONE
;
405 * Choose the PIPE_FORMAT_ to use for storing a texture image based
406 * on the user's internalFormat, format and type parameters.
407 * We query the pipe device for a list of formats which it supports
408 * and choose from them.
409 * If we find a device that needs a more intricate selection mechanism,
410 * this function _could_ get pushed down into the pipe device.
412 * Note: also used for glRenderbufferStorageEXT()
414 * Note: format and type may be GL_NONE (see renderbuffers)
416 * \return PIPE_FORMAT_NONE if error/problem.
419 st_choose_pipe_format(struct pipe_context
*pipe
, GLint internalFormat
,
420 GLenum format
, GLenum type
)
422 switch (internalFormat
) {
425 case GL_COMPRESSED_RGBA
:
426 if (format
== GL_BGRA
) {
427 if (type
== GL_UNSIGNED_BYTE
|| type
== GL_UNSIGNED_INT_8_8_8_8_REV
) {
428 if (pipe
->is_format_supported( pipe
, PIPE_FORMAT_U_A8_R8_G8_B8
))
429 return PIPE_FORMAT_U_A8_R8_G8_B8
;
431 else if (type
== GL_UNSIGNED_SHORT_4_4_4_4_REV
) {
432 if (pipe
->is_format_supported( pipe
, PIPE_FORMAT_U_A4_R4_G4_B4
))
433 return PIPE_FORMAT_U_A4_R4_G4_B4
;
435 else if (type
== GL_UNSIGNED_SHORT_1_5_5_5_REV
) {
436 if (pipe
->is_format_supported( pipe
, PIPE_FORMAT_U_A1_R5_G5_B5
))
437 return PIPE_FORMAT_U_A1_R5_G5_B5
;
440 return default_rgba_format( pipe
);
444 case GL_COMPRESSED_RGB
:
445 if (format
== GL_RGB
&& type
== GL_UNSIGNED_SHORT_5_6_5
) {
446 if (pipe
->is_format_supported( pipe
, PIPE_FORMAT_U_R5_G6_B5
))
447 return PIPE_FORMAT_U_R5_G6_B5
;
449 return default_rgba_format( pipe
);
454 return default_rgba_format( pipe
);
456 return default_deep_rgba_format( pipe
);
460 if (pipe
->is_format_supported( pipe
, PIPE_FORMAT_U_A4_R4_G4_B4
))
461 return PIPE_FORMAT_U_A4_R4_G4_B4
;
462 return default_rgba_format( pipe
);
465 if (pipe
->is_format_supported( pipe
, PIPE_FORMAT_U_A1_R5_G5_B5
))
466 return PIPE_FORMAT_U_A1_R5_G5_B5
;
467 return default_rgba_format( pipe
);
473 return default_rgba_format( pipe
);
478 if (pipe
->is_format_supported( pipe
, PIPE_FORMAT_U_A1_R5_G5_B5
))
479 return PIPE_FORMAT_U_A1_R5_G5_B5
;
480 return default_rgba_format( pipe
);
487 case GL_COMPRESSED_ALPHA
:
488 if (pipe
->is_format_supported( pipe
, PIPE_FORMAT_U_A8
))
489 return PIPE_FORMAT_U_A8
;
490 return default_rgba_format( pipe
);
498 case GL_COMPRESSED_LUMINANCE
:
499 if (pipe
->is_format_supported( pipe
, PIPE_FORMAT_U_A8
))
500 return PIPE_FORMAT_U_A8
;
501 return default_rgba_format( pipe
);
504 case GL_LUMINANCE_ALPHA
:
505 case GL_LUMINANCE4_ALPHA4
:
506 case GL_LUMINANCE6_ALPHA2
:
507 case GL_LUMINANCE8_ALPHA8
:
508 case GL_LUMINANCE12_ALPHA4
:
509 case GL_LUMINANCE12_ALPHA12
:
510 case GL_LUMINANCE16_ALPHA16
:
511 case GL_COMPRESSED_LUMINANCE_ALPHA
:
512 if (pipe
->is_format_supported( pipe
, PIPE_FORMAT_U_A8_L8
))
513 return PIPE_FORMAT_U_A8_L8
;
514 return default_rgba_format( pipe
);
521 case GL_COMPRESSED_INTENSITY
:
522 if (pipe
->is_format_supported( pipe
, PIPE_FORMAT_U_I8
))
523 return PIPE_FORMAT_U_I8
;
524 return default_rgba_format( pipe
);
527 if (type
== GL_UNSIGNED_SHORT_8_8_MESA
|| type
== GL_UNSIGNED_BYTE
) {
528 if (pipe
->is_format_supported( pipe
, PIPE_FORMAT_YCBCR
))
529 return PIPE_FORMAT_YCBCR
;
532 if (pipe
->is_format_supported( pipe
, PIPE_FORMAT_YCBCR_REV
))
533 return PIPE_FORMAT_YCBCR_REV
;
535 return PIPE_FORMAT_NONE
;
538 case GL_COMPRESSED_RGB_FXT1_3DFX
:
539 return &_mesa_texformat_rgb_fxt1
;
540 case GL_COMPRESSED_RGBA_FXT1_3DFX
:
541 return &_mesa_texformat_rgba_fxt1
;
545 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT
:
546 return &_mesa_texformat_rgb_dxt1
;
548 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT
:
549 return &_mesa_texformat_rgba_dxt1
;
553 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT
:
554 return &_mesa_texformat_rgba_dxt3
;
556 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT
:
557 return &_mesa_texformat_rgba_dxt5
;
560 case GL_DEPTH_COMPONENT16
:
561 if (pipe
->is_format_supported( pipe
, PIPE_FORMAT_U_Z16
))
562 return PIPE_FORMAT_U_Z16
;
564 case GL_DEPTH_COMPONENT24
:
565 if (pipe
->is_format_supported( pipe
, PIPE_FORMAT_S8_Z24
))
566 return PIPE_FORMAT_S8_Z24
;
568 case GL_DEPTH_COMPONENT32
:
569 if (pipe
->is_format_supported( pipe
, PIPE_FORMAT_U_Z32
))
570 return PIPE_FORMAT_U_Z32
;
572 case GL_DEPTH_COMPONENT
:
573 return default_depth_format( pipe
);
575 case GL_STENCIL_INDEX
:
576 case GL_STENCIL_INDEX1_EXT
:
577 case GL_STENCIL_INDEX4_EXT
:
578 case GL_STENCIL_INDEX8_EXT
:
579 case GL_STENCIL_INDEX16_EXT
:
580 if (pipe
->is_format_supported( pipe
, PIPE_FORMAT_U_S8
))
581 return PIPE_FORMAT_U_S8
;
582 if (pipe
->is_format_supported( pipe
, PIPE_FORMAT_S8_Z24
))
583 return PIPE_FORMAT_S8_Z24
;
584 return PIPE_FORMAT_NONE
;
586 case GL_DEPTH_STENCIL_EXT
:
587 case GL_DEPTH24_STENCIL8_EXT
:
588 if (pipe
->is_format_supported( pipe
, PIPE_FORMAT_S8_Z24
))
589 return PIPE_FORMAT_S8_Z24
;
590 return PIPE_FORMAT_NONE
;
593 return PIPE_FORMAT_NONE
;
599 /* It works out that this function is fine for all the supported
600 * hardware. However, there is still a need to map the formats onto
601 * hardware descriptors.
603 /* Note that the i915 can actually support many more formats than
604 * these if we take the step of simply swizzling the colors
605 * immediately after sampling...
607 const struct gl_texture_format
*
608 st_ChooseTextureFormat(GLcontext
* ctx
, GLint internalFormat
,
609 GLenum format
, GLenum type
)
612 struct intel_context
*intel
= intel_context(ctx
);
613 const GLboolean do32bpt
= (intel
->intelScreen
->front
.cpp
== 4);
615 const GLboolean do32bpt
= 1;
618 switch (internalFormat
) {
621 case GL_COMPRESSED_RGBA
:
622 if (format
== GL_BGRA
) {
623 if (type
== GL_UNSIGNED_BYTE
|| type
== GL_UNSIGNED_INT_8_8_8_8_REV
) {
624 return &_mesa_texformat_argb8888
;
626 else if (type
== GL_UNSIGNED_SHORT_4_4_4_4_REV
) {
627 return &_mesa_texformat_argb4444
;
629 else if (type
== GL_UNSIGNED_SHORT_1_5_5_5_REV
) {
630 return &_mesa_texformat_argb1555
;
633 return do32bpt
? &_mesa_texformat_argb8888
: &_mesa_texformat_argb4444
;
637 case GL_COMPRESSED_RGB
:
638 if (format
== GL_RGB
&& type
== GL_UNSIGNED_SHORT_5_6_5
) {
639 return &_mesa_texformat_rgb565
;
641 return do32bpt
? &_mesa_texformat_argb8888
: &_mesa_texformat_rgb565
;
647 return do32bpt
? &_mesa_texformat_argb8888
: &_mesa_texformat_argb4444
;
651 return &_mesa_texformat_argb4444
;
654 return &_mesa_texformat_argb1555
;
660 return &_mesa_texformat_argb8888
;
665 return &_mesa_texformat_rgb565
;
672 case GL_COMPRESSED_ALPHA
:
673 return &_mesa_texformat_a8
;
681 case GL_COMPRESSED_LUMINANCE
:
682 return &_mesa_texformat_l8
;
685 case GL_LUMINANCE_ALPHA
:
686 case GL_LUMINANCE4_ALPHA4
:
687 case GL_LUMINANCE6_ALPHA2
:
688 case GL_LUMINANCE8_ALPHA8
:
689 case GL_LUMINANCE12_ALPHA4
:
690 case GL_LUMINANCE12_ALPHA12
:
691 case GL_LUMINANCE16_ALPHA16
:
692 case GL_COMPRESSED_LUMINANCE_ALPHA
:
693 return &_mesa_texformat_al88
;
700 case GL_COMPRESSED_INTENSITY
:
701 return &_mesa_texformat_i8
;
704 if (type
== GL_UNSIGNED_SHORT_8_8_MESA
|| type
== GL_UNSIGNED_BYTE
)
705 return &_mesa_texformat_ycbcr
;
707 return &_mesa_texformat_ycbcr_rev
;
709 case GL_COMPRESSED_RGB_FXT1_3DFX
:
710 return &_mesa_texformat_rgb_fxt1
;
711 case GL_COMPRESSED_RGBA_FXT1_3DFX
:
712 return &_mesa_texformat_rgba_fxt1
;
716 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT
:
717 return &_mesa_texformat_rgb_dxt1
;
719 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT
:
720 return &_mesa_texformat_rgba_dxt1
;
724 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT
:
725 return &_mesa_texformat_rgba_dxt3
;
727 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT
:
728 return &_mesa_texformat_rgba_dxt5
;
730 case GL_DEPTH_COMPONENT
:
731 case GL_DEPTH_COMPONENT16
:
732 case GL_DEPTH_COMPONENT24
:
733 case GL_DEPTH_COMPONENT32
:
734 return &_mesa_texformat_z16
;
736 case GL_DEPTH_STENCIL_EXT
:
737 case GL_DEPTH24_STENCIL8_EXT
:
738 return &_mesa_texformat_z24_s8
;
741 fprintf(stderr
, "unexpected texture format %s in %s\n",
742 _mesa_lookup_enum_by_nr(internalFormat
), __FUNCTION__
);
746 return NULL
; /* never get here */