1
/**************************************************************************
3
* Copyright 2009, VMware, Inc.
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 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.
26
**************************************************************************/
28
* Author: Keith Whitwell <keithw@vmware.com>
29
* Author: Jakob Bornecrantz <wallbraker@gmail.com>
34
#include "dri_screen.h"
35
#include "dri_context.h"
36
#include "dri_helpers.h"
38
#include "util/u_inlines.h"
39
#include "pipe/p_screen.h"
40
#include "pipe/p_format.h"
41
#include "pipe-loader/pipe_loader.h"
42
#include "state_tracker/st_gl_api.h" /* for st_gl_api_create */
43
#include "frontend/drm_driver.h"
45
#include "util/u_debug.h"
46
#include "util/u_driconf.h"
47
#include "util/format/u_format_s3tc.h"
49
#define MSAA_VISUAL_MAX_SAMPLES 32
53
const __DRIconfigOptionsExtension gallium_config_options = {
54
.base = { __DRI_CONFIG_OPTIONS, 2 },
55
.getXml = pipe_loader_get_driinfo_xml
61
dri_init_options(struct dri_screen *screen)
63
pipe_loader_config_options(screen->dev);
65
struct st_config_options *options = &screen->options;
66
const struct driOptionCache *optionCache = &screen->dev->option_cache;
68
u_driconf_fill_st_options(options, optionCache);
72
dri_loader_get_cap(struct dri_screen *screen, enum dri_loader_cap cap)
74
const __DRIdri2LoaderExtension *dri2_loader = screen->sPriv->dri2.loader;
75
const __DRIimageLoaderExtension *image_loader = screen->sPriv->image.loader;
77
if (dri2_loader && dri2_loader->base.version >= 4 &&
78
dri2_loader->getCapability)
79
return dri2_loader->getCapability(screen->sPriv->loaderPrivate, cap);
81
if (image_loader && image_loader->base.version >= 2 &&
82
image_loader->getCapability)
83
return image_loader->getCapability(screen->sPriv->loaderPrivate, cap);
88
static const __DRIconfig **
89
dri_fill_in_modes(struct dri_screen *screen)
91
static const mesa_format mesa_formats[] = {
92
MESA_FORMAT_B10G10R10A2_UNORM,
93
MESA_FORMAT_B10G10R10X2_UNORM,
94
MESA_FORMAT_R10G10B10A2_UNORM,
95
MESA_FORMAT_R10G10B10X2_UNORM,
96
MESA_FORMAT_B8G8R8A8_UNORM,
97
MESA_FORMAT_B8G8R8X8_UNORM,
98
MESA_FORMAT_B8G8R8A8_SRGB,
99
MESA_FORMAT_B8G8R8X8_SRGB,
100
MESA_FORMAT_B5G6R5_UNORM,
101
MESA_FORMAT_RGBA_FLOAT16,
102
MESA_FORMAT_RGBX_FLOAT16,
104
/* The 32-bit RGBA format must not precede the 32-bit BGRA format.
105
* Likewise for RGBX and BGRX. Otherwise, the GLX client and the GLX
106
* server may disagree on which format the GLXFBConfig represents,
107
* resulting in swapped color channels.
109
* The problem, as of 2017-05-30:
110
* When matching a GLXFBConfig to a __DRIconfig, GLX ignores the channel
111
* order and chooses the first __DRIconfig with the expected channel
112
* sizes. Specifically, GLX compares the GLXFBConfig's and __DRIconfig's
113
* __DRI_ATTRIB_{CHANNEL}_SIZE but ignores __DRI_ATTRIB_{CHANNEL}_MASK.
115
* EGL does not suffer from this problem. It correctly compares the
116
* channel masks when matching EGLConfig to __DRIconfig.
119
/* Required by Android, for HAL_PIXEL_FORMAT_RGBA_8888. */
120
MESA_FORMAT_R8G8B8A8_UNORM,
122
/* Required by Android, for HAL_PIXEL_FORMAT_RGBX_8888. */
123
MESA_FORMAT_R8G8B8X8_UNORM,
125
/* Required by Android, for HAL_PIXEL_FORMAT_RGBA_8888. */
126
MESA_FORMAT_R8G8B8A8_SRGB,
128
/* Required by Android, for HAL_PIXEL_FORMAT_RGBX_8888. */
129
MESA_FORMAT_R8G8B8X8_SRGB,
131
static const enum pipe_format pipe_formats[] = {
132
PIPE_FORMAT_B10G10R10A2_UNORM,
133
PIPE_FORMAT_B10G10R10X2_UNORM,
134
PIPE_FORMAT_R10G10B10A2_UNORM,
135
PIPE_FORMAT_R10G10B10X2_UNORM,
136
PIPE_FORMAT_BGRA8888_UNORM,
137
PIPE_FORMAT_BGRX8888_UNORM,
138
PIPE_FORMAT_BGRA8888_SRGB,
139
PIPE_FORMAT_BGRX8888_SRGB,
140
PIPE_FORMAT_B5G6R5_UNORM,
141
PIPE_FORMAT_R16G16B16A16_FLOAT,
142
PIPE_FORMAT_R16G16B16X16_FLOAT,
143
PIPE_FORMAT_RGBA8888_UNORM,
144
PIPE_FORMAT_RGBX8888_UNORM,
145
PIPE_FORMAT_RGBA8888_SRGB,
146
PIPE_FORMAT_RGBX8888_SRGB,
149
__DRIconfig **configs = NULL;
150
uint8_t depth_bits_array[5];
151
uint8_t stencil_bits_array[5];
152
unsigned depth_buffer_factor;
153
unsigned msaa_samples_max;
155
struct pipe_screen *p_screen = screen->base.screen;
156
bool pf_z16, pf_x8z24, pf_z24x8, pf_s8z24, pf_z24s8, pf_z32;
157
bool mixed_color_depth;
158
bool allow_rgba_ordering;
162
static const GLenum back_buffer_modes[] = {
163
__DRI_ATTRIB_SWAP_NONE, __DRI_ATTRIB_SWAP_UNDEFINED,
164
__DRI_ATTRIB_SWAP_COPY
167
if (driQueryOptionb(&screen->dev->option_cache, "always_have_depth_buffer")) {
168
/* all visuals will have a depth buffer */
169
depth_buffer_factor = 0;
172
depth_bits_array[0] = 0;
173
stencil_bits_array[0] = 0;
174
depth_buffer_factor = 1;
177
allow_rgba_ordering = dri_loader_get_cap(screen, DRI_LOADER_CAP_RGBA_ORDERING);
178
allow_rgb10 = driQueryOptionb(&screen->dev->option_cache, "allow_rgb10_configs");
179
allow_fp16 = dri_loader_get_cap(screen, DRI_LOADER_CAP_FP16);
181
msaa_samples_max = (screen->st_api->feature_mask & ST_API_FEATURE_MS_VISUALS_MASK)
182
? MSAA_VISUAL_MAX_SAMPLES : 1;
184
pf_x8z24 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_Z24X8_UNORM,
185
PIPE_TEXTURE_2D, 0, 0,
186
PIPE_BIND_DEPTH_STENCIL);
187
pf_z24x8 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_X8Z24_UNORM,
188
PIPE_TEXTURE_2D, 0, 0,
189
PIPE_BIND_DEPTH_STENCIL);
190
pf_s8z24 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_Z24_UNORM_S8_UINT,
191
PIPE_TEXTURE_2D, 0, 0,
192
PIPE_BIND_DEPTH_STENCIL);
193
pf_z24s8 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_S8_UINT_Z24_UNORM,
194
PIPE_TEXTURE_2D, 0, 0,
195
PIPE_BIND_DEPTH_STENCIL);
196
pf_z16 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_Z16_UNORM,
197
PIPE_TEXTURE_2D, 0, 0,
198
PIPE_BIND_DEPTH_STENCIL);
199
pf_z32 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_Z32_UNORM,
200
PIPE_TEXTURE_2D, 0, 0,
201
PIPE_BIND_DEPTH_STENCIL);
204
depth_bits_array[depth_buffer_factor] = 16;
205
stencil_bits_array[depth_buffer_factor++] = 0;
207
if (pf_x8z24 || pf_z24x8) {
208
depth_bits_array[depth_buffer_factor] = 24;
209
stencil_bits_array[depth_buffer_factor++] = 0;
210
screen->d_depth_bits_last = pf_x8z24;
212
if (pf_s8z24 || pf_z24s8) {
213
depth_bits_array[depth_buffer_factor] = 24;
214
stencil_bits_array[depth_buffer_factor++] = 8;
215
screen->sd_depth_bits_last = pf_s8z24;
218
depth_bits_array[depth_buffer_factor] = 32;
219
stencil_bits_array[depth_buffer_factor++] = 0;
223
p_screen->get_param(p_screen, PIPE_CAP_MIXED_COLOR_DEPTH_BITS);
225
assert(ARRAY_SIZE(mesa_formats) == ARRAY_SIZE(pipe_formats));
228
for (format = 0; format < ARRAY_SIZE(mesa_formats); format++) {
229
__DRIconfig **new_configs = NULL;
230
unsigned num_msaa_modes = 0; /* includes a single-sample mode */
231
uint8_t msaa_modes[MSAA_VISUAL_MAX_SAMPLES];
233
/* Expose only BGRA ordering if the loader doesn't support RGBA ordering. */
234
if (!allow_rgba_ordering &&
235
(mesa_formats[format] == MESA_FORMAT_R8G8B8A8_UNORM ||
236
mesa_formats[format] == MESA_FORMAT_R8G8B8X8_UNORM ||
237
mesa_formats[format] == MESA_FORMAT_R8G8B8A8_SRGB ||
238
mesa_formats[format] == MESA_FORMAT_R8G8B8X8_SRGB))
242
(mesa_formats[format] == MESA_FORMAT_B10G10R10A2_UNORM ||
243
mesa_formats[format] == MESA_FORMAT_B10G10R10X2_UNORM ||
244
mesa_formats[format] == MESA_FORMAT_R10G10B10A2_UNORM ||
245
mesa_formats[format] == MESA_FORMAT_R10G10B10X2_UNORM))
249
(mesa_formats[format] == MESA_FORMAT_RGBA_FLOAT16 ||
250
mesa_formats[format] == MESA_FORMAT_RGBX_FLOAT16))
253
if (!p_screen->is_format_supported(p_screen, pipe_formats[format],
254
PIPE_TEXTURE_2D, 0, 0,
255
PIPE_BIND_RENDER_TARGET |
256
PIPE_BIND_DISPLAY_TARGET))
259
for (i = 1; i <= msaa_samples_max; i++) {
260
int samples = i > 1 ? i : 0;
262
if (p_screen->is_format_supported(p_screen, pipe_formats[format],
263
PIPE_TEXTURE_2D, samples, samples,
264
PIPE_BIND_RENDER_TARGET)) {
265
msaa_modes[num_msaa_modes++] = samples;
269
if (num_msaa_modes) {
270
/* Single-sample configs with an accumulation buffer. */
271
new_configs = driCreateConfigs(mesa_formats[format],
272
depth_bits_array, stencil_bits_array,
273
depth_buffer_factor, back_buffer_modes,
274
ARRAY_SIZE(back_buffer_modes),
276
GL_TRUE, !mixed_color_depth);
277
configs = driConcatConfigs(configs, new_configs);
279
/* Multi-sample configs without an accumulation buffer. */
280
if (num_msaa_modes > 1) {
281
new_configs = driCreateConfigs(mesa_formats[format],
282
depth_bits_array, stencil_bits_array,
283
depth_buffer_factor, back_buffer_modes,
284
ARRAY_SIZE(back_buffer_modes),
285
msaa_modes+1, num_msaa_modes-1,
286
GL_FALSE, !mixed_color_depth);
287
configs = driConcatConfigs(configs, new_configs);
292
if (configs == NULL) {
293
debug_printf("%s: driCreateConfigs failed\n", __FUNCTION__);
297
return (const __DRIconfig **)configs;
301
* Roughly the converse of dri_fill_in_modes.
304
dri_fill_st_visual(struct st_visual *stvis,
305
const struct dri_screen *screen,
306
const struct gl_config *mode)
308
memset(stvis, 0, sizeof(*stvis));
313
/* Deduce the color format. */
314
switch (mode->redMask) {
316
/* Formats > 32 bpp */
317
assert(mode->floatMode);
318
if (mode->alphaShift > -1) {
319
assert(mode->alphaShift == 48);
320
stvis->color_format = PIPE_FORMAT_R16G16B16A16_FLOAT;
322
stvis->color_format = PIPE_FORMAT_R16G16B16X16_FLOAT;
327
if (mode->alphaMask) {
328
assert(mode->alphaMask == 0xC0000000);
329
stvis->color_format = PIPE_FORMAT_B10G10R10A2_UNORM;
331
stvis->color_format = PIPE_FORMAT_B10G10R10X2_UNORM;
336
if (mode->alphaMask) {
337
assert(mode->alphaMask == 0xC0000000);
338
stvis->color_format = PIPE_FORMAT_R10G10B10A2_UNORM;
340
stvis->color_format = PIPE_FORMAT_R10G10B10X2_UNORM;
345
if (mode->alphaMask) {
346
assert(mode->alphaMask == 0xFF000000);
347
stvis->color_format = mode->sRGBCapable ?
348
PIPE_FORMAT_BGRA8888_SRGB :
349
PIPE_FORMAT_BGRA8888_UNORM;
351
stvis->color_format = mode->sRGBCapable ?
352
PIPE_FORMAT_BGRX8888_SRGB :
353
PIPE_FORMAT_BGRX8888_UNORM;
358
if (mode->alphaMask) {
359
assert(mode->alphaMask == 0xFF000000);
360
stvis->color_format = mode->sRGBCapable ?
361
PIPE_FORMAT_RGBA8888_SRGB :
362
PIPE_FORMAT_RGBA8888_UNORM;
364
stvis->color_format = mode->sRGBCapable ?
365
PIPE_FORMAT_RGBX8888_SRGB :
366
PIPE_FORMAT_RGBX8888_UNORM;
371
stvis->color_format = PIPE_FORMAT_B5G6R5_UNORM;
375
assert(!"unsupported visual: invalid red mask");
379
if (mode->samples > 0) {
380
if (debug_get_bool_option("DRI_NO_MSAA", false))
383
stvis->samples = mode->samples;
386
switch (mode->depthBits) {
389
stvis->depth_stencil_format = PIPE_FORMAT_NONE;
392
stvis->depth_stencil_format = PIPE_FORMAT_Z16_UNORM;
395
if (mode->stencilBits == 0) {
396
stvis->depth_stencil_format = (screen->d_depth_bits_last) ?
397
PIPE_FORMAT_Z24X8_UNORM:
398
PIPE_FORMAT_X8Z24_UNORM;
400
stvis->depth_stencil_format = (screen->sd_depth_bits_last) ?
401
PIPE_FORMAT_Z24_UNORM_S8_UINT:
402
PIPE_FORMAT_S8_UINT_Z24_UNORM;
406
stvis->depth_stencil_format = PIPE_FORMAT_Z32_UNORM;
410
stvis->accum_format = (mode->accumRedBits > 0) ?
411
PIPE_FORMAT_R16G16B16A16_SNORM : PIPE_FORMAT_NONE;
413
stvis->buffer_mask |= ST_ATTACHMENT_FRONT_LEFT_MASK;
414
if (mode->doubleBufferMode) {
415
stvis->buffer_mask |= ST_ATTACHMENT_BACK_LEFT_MASK;
417
if (mode->stereoMode) {
418
stvis->buffer_mask |= ST_ATTACHMENT_FRONT_RIGHT_MASK;
419
if (mode->doubleBufferMode)
420
stvis->buffer_mask |= ST_ATTACHMENT_BACK_RIGHT_MASK;
423
if (mode->depthBits > 0 || mode->stencilBits > 0)
424
stvis->buffer_mask |= ST_ATTACHMENT_DEPTH_STENCIL_MASK;
425
/* let the gallium frontend allocate the accum buffer */
429
dri_get_egl_image(struct st_manager *smapi,
431
struct st_egl_image *stimg)
433
struct dri_screen *screen = (struct dri_screen *)smapi;
434
__DRIimage *img = NULL;
435
const struct dri2_format_mapping *map;
437
if (screen->lookup_egl_image_validated) {
438
img = screen->lookup_egl_image_validated(screen, egl_image);
439
} else if (screen->lookup_egl_image) {
440
img = screen->lookup_egl_image(screen, egl_image);
446
stimg->texture = NULL;
447
pipe_resource_reference(&stimg->texture, img->texture);
448
map = dri2_get_mapping_by_fourcc(img->dri_fourcc);
449
stimg->format = map ? map->pipe_format : img->texture->format;
450
stimg->level = img->level;
451
stimg->layer = img->layer;
453
if (img->imported_dmabuf && map) {
454
/* Guess sized internal format for dma-bufs. Could be used
455
* by EXT_EGL_image_storage.
457
mesa_format mesa_format = driImageFormatToGLFormat(map->dri_format);
458
stimg->internalformat = driGLFormatToSizedInternalGLFormat(mesa_format);
465
dri_validate_egl_image(struct st_manager *smapi,
468
struct dri_screen *screen = (struct dri_screen *)smapi;
470
return screen->validate_egl_image(screen, egl_image);
474
dri_get_param(struct st_manager *smapi,
475
enum st_manager_param param)
477
struct dri_screen *screen = (struct dri_screen *)smapi;
480
case ST_MANAGER_BROKEN_INVALIDATE:
481
return screen->broken_invalidate;
488
dri_destroy_screen_helper(struct dri_screen * screen)
490
if (screen->base.destroy)
491
screen->base.destroy(&screen->base);
493
if (screen->st_api && screen->st_api->destroy)
494
screen->st_api->destroy(screen->st_api);
496
if (screen->base.screen)
497
screen->base.screen->destroy(screen->base.screen);
499
mtx_destroy(&screen->opencl_func_mutex);
503
dri_destroy_screen(__DRIscreen * sPriv)
505
struct dri_screen *screen = dri_screen(sPriv);
507
dri_destroy_screen_helper(screen);
509
pipe_loader_release(&screen->dev, 1);
511
free(screen->options.force_gl_vendor);
512
free(screen->options.force_gl_renderer);
513
free(screen->options.mesa_extension_override);
515
/* The caller in dri_util preserves the fd ownership */
517
sPriv->driverPrivate = NULL;
518
sPriv->extensions = NULL;
522
dri_postprocessing_init(struct dri_screen *screen)
526
for (i = 0; i < PP_FILTERS; i++) {
527
screen->pp_enabled[i] = driQueryOptioni(&screen->dev->option_cache,
533
dri_set_background_context(struct st_context_iface *st,
534
struct util_queue_monitoring *queue_info)
536
struct dri_context *ctx = (struct dri_context *)st->st_manager_private;
537
const __DRIbackgroundCallableExtension *backgroundCallable =
538
ctx->sPriv->dri2.backgroundCallable;
540
/* Note: Mesa will only call this function if GL multithreading is enabled
541
* We only do that if the loader exposed the __DRI_BACKGROUND_CALLABLE
542
* extension. So we know that backgroundCallable is not NULL.
544
assert(backgroundCallable);
545
backgroundCallable->setBackgroundContext(ctx->cPriv->loaderPrivate);
548
hud_add_queue_for_monitoring(ctx->hud, queue_info);
552
dri_init_screen_helper(struct dri_screen *screen,
553
struct pipe_screen *pscreen)
555
screen->base.screen = pscreen;
556
screen->base.get_egl_image = dri_get_egl_image;
557
screen->base.get_param = dri_get_param;
558
screen->base.set_background_context = dri_set_background_context;
560
if (screen->validate_egl_image)
561
screen->base.validate_egl_image = dri_validate_egl_image;
563
screen->st_api = st_gl_api_create();
567
if(pscreen->get_param(pscreen, PIPE_CAP_NPOT_TEXTURES))
568
screen->target = PIPE_TEXTURE_2D;
570
screen->target = PIPE_TEXTURE_RECT;
572
dri_postprocessing_init(screen);
574
screen->st_api->query_versions(screen->st_api, &screen->base,
576
&screen->sPriv->max_gl_core_version,
577
&screen->sPriv->max_gl_compat_version,
578
&screen->sPriv->max_gl_es1_version,
579
&screen->sPriv->max_gl_es2_version);
581
return dri_fill_in_modes(screen);
584
/* vim: set sw=3 ts=8 sts=3 expandtab: */