2 * Extra utility functions related to EGL configs.
9 #include "eglconfigutil.h"
14 * Convert an _EGLConfig to a __GLcontextModes object.
15 * NOTE: This routine may be incomplete - we're only making sure that
16 * the fields needed by Mesa (for _mesa_create_context/framebuffer) are
20 _eglConfigToContextModesRec(const _EGLConfig
*config
, __GLcontextModes
*mode
)
22 memset(mode
, 0, sizeof(*mode
));
24 mode
->rgbMode
= GL_TRUE
; /* no color index */
25 mode
->colorIndexMode
= GL_FALSE
;
26 mode
->doubleBufferMode
= GL_TRUE
; /* always DB for now */
27 mode
->stereoMode
= GL_FALSE
;
29 mode
->redBits
= GET_CONFIG_ATTRIB(config
, EGL_RED_SIZE
);
30 mode
->greenBits
= GET_CONFIG_ATTRIB(config
, EGL_GREEN_SIZE
);
31 mode
->blueBits
= GET_CONFIG_ATTRIB(config
, EGL_BLUE_SIZE
);
32 mode
->alphaBits
= GET_CONFIG_ATTRIB(config
, EGL_ALPHA_SIZE
);
33 mode
->rgbBits
= GET_CONFIG_ATTRIB(config
, EGL_BUFFER_SIZE
);
35 /* no rgba masks - fix? */
37 mode
->depthBits
= GET_CONFIG_ATTRIB(config
, EGL_DEPTH_SIZE
);
38 mode
->haveDepthBuffer
= mode
->depthBits
> 0;
40 mode
->stencilBits
= GET_CONFIG_ATTRIB(config
, EGL_STENCIL_SIZE
);
41 mode
->haveStencilBuffer
= mode
->stencilBits
> 0;
45 mode
->level
= GET_CONFIG_ATTRIB(config
, EGL_LEVEL
);
46 mode
->samples
= GET_CONFIG_ATTRIB(config
, EGL_SAMPLES
);
47 mode
->sampleBuffers
= GET_CONFIG_ATTRIB(config
, EGL_SAMPLE_BUFFERS
);
49 /* surface type - not really needed */
50 mode
->visualType
= GLX_TRUE_COLOR
;
51 mode
->renderType
= GLX_RGBA_BIT
;
56 * Convert a __GLcontextModes object to an _EGLConfig.
59 _eglConfigFromContextModesRec(_EGLConfig
*conf
, const __GLcontextModes
*m
,
60 EGLint conformant
, EGLint renderable_type
)
62 EGLint config_caveat
, surface_type
;
65 if (!m
->rgbMode
|| !(m
->renderType
& GLX_RGBA_BIT
))
68 config_caveat
= EGL_NONE
;
69 if (m
->visualRating
== GLX_SLOW_CONFIG
)
70 config_caveat
= EGL_SLOW_CONFIG
;
72 if (m
->visualRating
== GLX_NON_CONFORMANT_CONFIG
)
73 conformant
&= ~EGL_OPENGL_BIT
;
74 if (!(conformant
& EGL_OPENGL_ES_BIT
))
75 config_caveat
= EGL_NON_CONFORMANT_CONFIG
;
78 if (m
->drawableType
& GLX_WINDOW_BIT
)
79 surface_type
|= EGL_WINDOW_BIT
;
80 if (m
->drawableType
& GLX_PIXMAP_BIT
)
81 surface_type
|= EGL_PIXMAP_BIT
;
82 if (m
->drawableType
& GLX_PBUFFER_BIT
)
83 surface_type
|= EGL_PBUFFER_BIT
;
85 SET_CONFIG_ATTRIB(conf
, EGL_BUFFER_SIZE
, m
->rgbBits
);
86 SET_CONFIG_ATTRIB(conf
, EGL_RED_SIZE
, m
->redBits
);
87 SET_CONFIG_ATTRIB(conf
, EGL_GREEN_SIZE
, m
->greenBits
);
88 SET_CONFIG_ATTRIB(conf
, EGL_BLUE_SIZE
, m
->blueBits
);
89 SET_CONFIG_ATTRIB(conf
, EGL_ALPHA_SIZE
, m
->alphaBits
);
91 SET_CONFIG_ATTRIB(conf
, EGL_BIND_TO_TEXTURE_RGB
, m
->bindToTextureRgb
);
92 SET_CONFIG_ATTRIB(conf
, EGL_BIND_TO_TEXTURE_RGBA
, m
->bindToTextureRgba
);
93 SET_CONFIG_ATTRIB(conf
, EGL_COLOR_BUFFER_TYPE
, EGL_RGB_BUFFER
);
94 SET_CONFIG_ATTRIB(conf
, EGL_CONFIG_CAVEAT
, config_caveat
);
96 SET_CONFIG_ATTRIB(conf
, EGL_CONFORMANT
, conformant
);
97 SET_CONFIG_ATTRIB(conf
, EGL_DEPTH_SIZE
, m
->depthBits
);
98 SET_CONFIG_ATTRIB(conf
, EGL_LEVEL
, m
->level
);
99 SET_CONFIG_ATTRIB(conf
, EGL_MAX_PBUFFER_WIDTH
, m
->maxPbufferWidth
);
100 SET_CONFIG_ATTRIB(conf
, EGL_MAX_PBUFFER_HEIGHT
, m
->maxPbufferHeight
);
101 SET_CONFIG_ATTRIB(conf
, EGL_MAX_PBUFFER_PIXELS
, m
->maxPbufferPixels
);
103 SET_CONFIG_ATTRIB(conf
, EGL_NATIVE_RENDERABLE
, m
->xRenderable
);
104 SET_CONFIG_ATTRIB(conf
, EGL_NATIVE_VISUAL_ID
, m
->visualID
);
105 SET_CONFIG_ATTRIB(conf
, EGL_NATIVE_VISUAL_TYPE
, m
->visualType
);
106 SET_CONFIG_ATTRIB(conf
, EGL_RENDERABLE_TYPE
, renderable_type
);
107 SET_CONFIG_ATTRIB(conf
, EGL_SAMPLE_BUFFERS
, m
->sampleBuffers
);
108 SET_CONFIG_ATTRIB(conf
, EGL_SAMPLES
, m
->samples
);
109 SET_CONFIG_ATTRIB(conf
, EGL_STENCIL_SIZE
, m
->stencilBits
);
111 SET_CONFIG_ATTRIB(conf
, EGL_SURFACE_TYPE
, surface_type
);
113 /* what to do with GLX_TRANSPARENT_INDEX? */
114 if (m
->transparentPixel
== GLX_TRANSPARENT_RGB
) {
115 SET_CONFIG_ATTRIB(conf
, EGL_TRANSPARENT_TYPE
, EGL_TRANSPARENT_RGB
);
116 SET_CONFIG_ATTRIB(conf
, EGL_TRANSPARENT_RED_VALUE
, m
->transparentRed
);
117 SET_CONFIG_ATTRIB(conf
, EGL_TRANSPARENT_GREEN_VALUE
, m
->transparentGreen
);
118 SET_CONFIG_ATTRIB(conf
, EGL_TRANSPARENT_BLUE_VALUE
, m
->transparentBlue
);
121 SET_CONFIG_ATTRIB(conf
, EGL_TRANSPARENT_TYPE
, EGL_NONE
);
129 * Creates a set of \c _EGLConfigs that a driver will expose.
131 * A set of \c __GLcontextModes will be created based on the supplied
132 * parameters. The number of modes processed will be 2 *
133 * \c num_depth_stencil_bits * \c num_db_modes.
135 * For the most part, data is just copied from \c depth_bits, \c stencil_bits,
136 * \c db_modes, and \c visType into each \c __GLcontextModes element.
137 * However, the meanings of \c fb_format and \c fb_type require further
138 * explanation. The \c fb_format specifies which color components are in
139 * each pixel and what the default order is. For example, \c GL_RGB specifies
140 * that red, green, blue are available and red is in the "most significant"
141 * position and blue is in the "least significant". The \c fb_type specifies
142 * the bit sizes of each component and the actual ordering. For example, if
143 * \c GL_UNSIGNED_SHORT_5_6_5_REV is specified with \c GL_RGB, bits [15:11]
144 * are the blue value, bits [10:5] are the green value, and bits [4:0] are
147 * One sublte issue is the combination of \c GL_RGB or \c GL_BGR and either
148 * of the \c GL_UNSIGNED_INT_8_8_8_8 modes. The resulting mask values in the
149 * \c __GLcontextModes structure is \b identical to the \c GL_RGBA or
150 * \c GL_BGRA case, except the \c alphaMask is zero. This means that, as
151 * far as this routine is concerned, \c GL_RGB with \c GL_UNSIGNED_INT_8_8_8_8
152 * still uses 32-bits.
154 * If in doubt, look at the tables used in the function.
156 * \param configs the array of configs generated
157 * \param fb_format Format of the framebuffer. Currently only \c GL_RGB,
158 * \c GL_RGBA, \c GL_BGR, and \c GL_BGRA are supported.
159 * \param fb_type Type of the pixels in the framebuffer. Currently only
160 * \c GL_UNSIGNED_SHORT_5_6_5,
161 * \c GL_UNSIGNED_SHORT_5_6_5_REV,
162 * \c GL_UNSIGNED_INT_8_8_8_8, and
163 * \c GL_UNSIGNED_INT_8_8_8_8_REV are supported.
164 * \param depth_bits Array of depth buffer sizes to be exposed.
165 * \param stencil_bits Array of stencil buffer sizes to be exposed.
166 * \param num_depth_stencil_bits Number of entries in both \c depth_bits and
168 * \param db_modes Array of buffer swap modes. If an element has a
169 * value of \c GLX_NONE, then it represents a
170 * single-buffered mode. Other valid values are
171 * \c GLX_SWAP_EXCHANGE_OML, \c GLX_SWAP_COPY_OML, and
172 * \c GLX_SWAP_UNDEFINED_OML. See the
173 * GLX_OML_swap_method extension spec for more details.
174 * \param num_db_modes Number of entries in \c db_modes.
175 * \param visType GLX visual type. Usually either \c GLX_TRUE_COLOR or
176 * \c GLX_DIRECT_COLOR.
179 * \c GL_TRUE on success or \c GL_FALSE on failure. Currently the only
180 * cause of failure is a bad parameter (i.e., unsupported \c fb_format or
184 * There is currently no way to support packed RGB modes (i.e., modes with
185 * exactly 3 bytes per pixel) or floating-point modes. This could probably
186 * be done by creating some new, private enums with clever names likes
187 * \c GL_UNSIGNED_3BYTE_8_8_8, \c GL_4FLOAT_32_32_32_32,
188 * \c GL_4HALF_16_16_16_16, etc. We can cross that bridge when we come to it.
191 _eglFillInConfigs(_EGLConfig
* configs
,
192 GLenum fb_format
, GLenum fb_type
,
193 const uint8_t * depth_bits
, const uint8_t * stencil_bits
,
194 unsigned num_depth_stencil_bits
,
195 const GLenum
* db_modes
, unsigned num_db_modes
,
198 static const uint8_t bits_table
[3][4] = {
200 { 5, 6, 5, 0 }, /* Any GL_UNSIGNED_SHORT_5_6_5 */
201 { 8, 8, 8, 0 }, /* Any RGB with any GL_UNSIGNED_INT_8_8_8_8 */
202 { 8, 8, 8, 8 } /* Any RGBA with any GL_UNSIGNED_INT_8_8_8_8 */
205 /* The following arrays are all indexed by the fb_type masked with 0x07.
206 * Given the four supported fb_type values, this results in valid array
207 * indices of 3, 4, 5, and 7.
209 static const uint32_t masks_table_rgb
[8][4] = {
210 {0x00000000, 0x00000000, 0x00000000, 0x00000000},
211 {0x00000000, 0x00000000, 0x00000000, 0x00000000},
212 {0x00000000, 0x00000000, 0x00000000, 0x00000000},
213 {0x0000F800, 0x000007E0, 0x0000001F, 0x00000000}, /* 5_6_5 */
214 {0x0000001F, 0x000007E0, 0x0000F800, 0x00000000}, /* 5_6_5_REV */
215 {0xFF000000, 0x00FF0000, 0x0000FF00, 0x00000000}, /* 8_8_8_8 */
216 {0x00000000, 0x00000000, 0x00000000, 0x00000000},
217 {0x000000FF, 0x0000FF00, 0x00FF0000, 0x00000000} /* 8_8_8_8_REV */
220 static const uint32_t masks_table_rgba
[8][4] = {
221 {0x00000000, 0x00000000, 0x00000000, 0x00000000},
222 {0x00000000, 0x00000000, 0x00000000, 0x00000000},
223 {0x00000000, 0x00000000, 0x00000000, 0x00000000},
224 {0x0000F800, 0x000007E0, 0x0000001F, 0x00000000}, /* 5_6_5 */
225 {0x0000001F, 0x000007E0, 0x0000F800, 0x00000000}, /* 5_6_5_REV */
226 {0xFF000000, 0x00FF0000, 0x0000FF00, 0x000000FF}, /* 8_8_8_8 */
227 {0x00000000, 0x00000000, 0x00000000, 0x00000000},
228 {0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000}, /* 8_8_8_8_REV */
232 static const uint32_t masks_table_bgr
[8][4] = {
233 {0x00000000, 0x00000000, 0x00000000, 0x00000000},
234 {0x00000000, 0x00000000, 0x00000000, 0x00000000},
235 {0x00000000, 0x00000000, 0x00000000, 0x00000000},
236 {0x0000001F, 0x000007E0, 0x0000F800, 0x00000000}, /* 5_6_5 */
237 {0x0000F800, 0x000007E0, 0x0000001F, 0x00000000}, /* 5_6_5_REV */
238 {0x0000FF00, 0x00FF0000, 0xFF000000, 0x00000000}, /* 8_8_8_8 */
239 {0x00000000, 0x00000000, 0x00000000, 0x00000000},
240 {0x00FF0000, 0x0000FF00, 0x000000FF, 0x00000000}, /* 8_8_8_8_REV */
243 static const uint32_t masks_table_bgra
[8][4] = {
244 {0x00000000, 0x00000000, 0x00000000, 0x00000000},
245 {0x00000000, 0x00000000, 0x00000000, 0x00000000},
246 {0x00000000, 0x00000000, 0x00000000, 0x00000000},
247 {0x0000001F, 0x000007E0, 0x0000F800, 0x00000000}, /* 5_6_5 */
248 {0x0000F800, 0x000007E0, 0x0000001F, 0x00000000}, /* 5_6_5_REV */
249 {0x0000FF00, 0x00FF0000, 0xFF000000, 0x000000FF}, /* 8_8_8_8 */
250 {0x00000000, 0x00000000, 0x00000000, 0x00000000},
251 {0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000}, /* 8_8_8_8_REV */
255 static const uint8_t bytes_per_pixel
[8] = {
256 0, 0, 0, 2, 2, 4, 0, 4
259 const uint8_t * bits
;
260 const uint32_t * masks
;
261 const int index
= fb_type
& 0x07;
267 if ( bytes_per_pixel
[index
] == 0 ) {
269 "[_eglFillInConfigs:%u] Framebuffer type 0x%04x has 0 bytes per pixel.",
274 /* Valid types are GL_UNSIGNED_SHORT_5_6_5 and GL_UNSIGNED_INT_8_8_8_8 and
277 * Valid formats are GL_RGBA, GL_RGB, and GL_BGRA.
279 switch ( fb_format
) {
281 bits
= (bytes_per_pixel
[index
] == 2) ? bits_table
[0] : bits_table
[1];
282 masks
= masks_table_rgb
[index
];
286 bits
= (bytes_per_pixel
[index
] == 2) ? bits_table
[0] : bits_table
[2];
287 masks
= masks_table_rgba
[index
];
292 bits
= (bytes_per_pixel
[index
] == 2) ? bits_table
[0] : bits_table
[1];
293 masks
= masks_table_bgr
[index
];
297 bits
= (bytes_per_pixel
[index
] == 2) ? bits_table
[0] : bits_table
[2];
298 masks
= masks_table_bgra
[index
];
303 _eglLog(_EGL_WARNING
,
304 "[_eglFillInConfigs:%u] Framebuffer format 0x%04x is not GL_RGB, GL_RGBA, GL_BGR, or GL_BGRA.",
305 __LINE__
, fb_format
);
310 for (k
= 0; k
< num_depth_stencil_bits
; k
++) {
311 for (i
= 0; i
< num_db_modes
; i
++) {
312 for (j
= 0; j
< 2; j
++) {
313 _eglSetConfigAttrib(config
, EGL_RED_SIZE
, bits
[0]);
314 _eglSetConfigAttrib(config
, EGL_GREEN_SIZE
, bits
[1]);
315 _eglSetConfigAttrib(config
, EGL_BLUE_SIZE
, bits
[2]);
316 _eglSetConfigAttrib(config
, EGL_ALPHA_SIZE
, bits
[3]);
317 _eglSetConfigAttrib(config
, EGL_BUFFER_SIZE
,
318 bits
[0] + bits
[1] + bits
[2] + bits
[3]);
320 _eglSetConfigAttrib(config
, EGL_STENCIL_SIZE
, stencil_bits
[k
]);
321 _eglSetConfigAttrib(config
, EGL_DEPTH_SIZE
, depth_bits
[i
]);
323 _eglSetConfigAttrib(config
, EGL_SURFACE_TYPE
, EGL_SCREEN_BIT_MESA
|
324 EGL_PBUFFER_BIT
| EGL_PIXMAP_BIT
| EGL_WINDOW_BIT
);