Path: blob/21.2-virgl/src/gallium/frontends/dri/dri_screen.c
4566 views
/**************************************************************************1*2* Copyright 2009, VMware, Inc.3* All Rights Reserved.4*5* Permission is hereby granted, free of charge, to any person obtaining a6* copy of this software and associated documentation files (the7* "Software"), to deal in the Software without restriction, including8* without limitation the rights to use, copy, modify, merge, publish,9* distribute, sub license, and/or sell copies of the Software, and to10* permit persons to whom the Software is furnished to do so, subject to11* the following conditions:12*13* The above copyright notice and this permission notice (including the14* next paragraph) shall be included in all copies or substantial portions15* of the Software.16*17* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS18* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF19* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.20* IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR21* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,22* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE23* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.24*25**************************************************************************/26/*27* Author: Keith Whitwell <[email protected]>28* Author: Jakob Bornecrantz <[email protected]>29*/3031#include "utils.h"3233#include "dri_screen.h"34#include "dri_context.h"35#include "dri_helpers.h"3637#include "util/u_inlines.h"38#include "pipe/p_screen.h"39#include "pipe/p_format.h"40#include "pipe-loader/pipe_loader.h"41#include "state_tracker/st_gl_api.h" /* for st_gl_api_create */42#include "frontend/drm_driver.h"4344#include "util/u_debug.h"45#include "util/format/u_format_s3tc.h"4647#define MSAA_VISUAL_MAX_SAMPLES 324849#undef false5051const __DRIconfigOptionsExtension gallium_config_options = {52.base = { __DRI_CONFIG_OPTIONS, 2 },53.getXml = pipe_loader_get_driinfo_xml54};5556#define false 05758static void59dri_fill_st_options(struct dri_screen *screen)60{61struct st_config_options *options = &screen->options;62const struct driOptionCache *optionCache = &screen->dev->option_cache;6364options->disable_blend_func_extended =65driQueryOptionb(optionCache, "disable_blend_func_extended");66options->disable_arb_gpu_shader5 =67driQueryOptionb(optionCache, "disable_arb_gpu_shader5");68options->disable_glsl_line_continuations =69driQueryOptionb(optionCache, "disable_glsl_line_continuations");70options->force_glsl_extensions_warn =71driQueryOptionb(optionCache, "force_glsl_extensions_warn");72options->force_glsl_version =73driQueryOptioni(optionCache, "force_glsl_version");74options->allow_extra_pp_tokens =75driQueryOptionb(optionCache, "allow_extra_pp_tokens");76options->allow_glsl_extension_directive_midshader =77driQueryOptionb(optionCache, "allow_glsl_extension_directive_midshader");78options->allow_glsl_120_subset_in_110 =79driQueryOptionb(optionCache, "allow_glsl_120_subset_in_110");80options->allow_glsl_builtin_const_expression =81driQueryOptionb(optionCache, "allow_glsl_builtin_const_expression");82options->allow_glsl_relaxed_es =83driQueryOptionb(optionCache, "allow_glsl_relaxed_es");84options->allow_glsl_builtin_variable_redeclaration =85driQueryOptionb(optionCache, "allow_glsl_builtin_variable_redeclaration");86options->allow_higher_compat_version =87driQueryOptionb(optionCache, "allow_higher_compat_version");88options->glsl_ignore_write_to_readonly_var =89driQueryOptionb(optionCache, "glsl_ignore_write_to_readonly_var");90options->glsl_zero_init = driQueryOptionb(optionCache, "glsl_zero_init");91options->force_integer_tex_nearest =92driQueryOptionb(optionCache, "force_integer_tex_nearest");93options->vs_position_always_invariant =94driQueryOptionb(optionCache, "vs_position_always_invariant");95options->force_glsl_abs_sqrt =96driQueryOptionb(optionCache, "force_glsl_abs_sqrt");97options->allow_glsl_cross_stage_interpolation_mismatch =98driQueryOptionb(optionCache, "allow_glsl_cross_stage_interpolation_mismatch");99options->allow_draw_out_of_order =100driQueryOptionb(optionCache, "allow_draw_out_of_order");101options->allow_incorrect_primitive_id =102driQueryOptionb(optionCache, "allow_incorrect_primitive_id");103options->ignore_map_unsynchronized =104driQueryOptionb(optionCache, "ignore_map_unsynchronized");105options->force_gl_names_reuse =106driQueryOptionb(optionCache, "force_gl_names_reuse");107options->transcode_etc =108driQueryOptionb(optionCache, "transcode_etc");109options->transcode_astc =110driQueryOptionb(optionCache, "transcode_astc");111112char *vendor_str = driQueryOptionstr(optionCache, "force_gl_vendor");113/* not an empty string */114if (*vendor_str)115options->force_gl_vendor = strdup(vendor_str);116117driComputeOptionsSha1(optionCache, options->config_options_sha1);118}119120static unsigned121dri_loader_get_cap(struct dri_screen *screen, enum dri_loader_cap cap)122{123const __DRIdri2LoaderExtension *dri2_loader = screen->sPriv->dri2.loader;124const __DRIimageLoaderExtension *image_loader = screen->sPriv->image.loader;125126if (dri2_loader && dri2_loader->base.version >= 4 &&127dri2_loader->getCapability)128return dri2_loader->getCapability(screen->sPriv->loaderPrivate, cap);129130if (image_loader && image_loader->base.version >= 2 &&131image_loader->getCapability)132return image_loader->getCapability(screen->sPriv->loaderPrivate, cap);133134return 0;135}136137static const __DRIconfig **138dri_fill_in_modes(struct dri_screen *screen)139{140static const mesa_format mesa_formats[] = {141MESA_FORMAT_B10G10R10A2_UNORM,142MESA_FORMAT_B10G10R10X2_UNORM,143MESA_FORMAT_R10G10B10A2_UNORM,144MESA_FORMAT_R10G10B10X2_UNORM,145MESA_FORMAT_B8G8R8A8_UNORM,146MESA_FORMAT_B8G8R8X8_UNORM,147MESA_FORMAT_B8G8R8A8_SRGB,148MESA_FORMAT_B8G8R8X8_SRGB,149MESA_FORMAT_B5G6R5_UNORM,150MESA_FORMAT_RGBA_FLOAT16,151MESA_FORMAT_RGBX_FLOAT16,152153/* The 32-bit RGBA format must not precede the 32-bit BGRA format.154* Likewise for RGBX and BGRX. Otherwise, the GLX client and the GLX155* server may disagree on which format the GLXFBConfig represents,156* resulting in swapped color channels.157*158* The problem, as of 2017-05-30:159* When matching a GLXFBConfig to a __DRIconfig, GLX ignores the channel160* order and chooses the first __DRIconfig with the expected channel161* sizes. Specifically, GLX compares the GLXFBConfig's and __DRIconfig's162* __DRI_ATTRIB_{CHANNEL}_SIZE but ignores __DRI_ATTRIB_{CHANNEL}_MASK.163*164* EGL does not suffer from this problem. It correctly compares the165* channel masks when matching EGLConfig to __DRIconfig.166*/167168/* Required by Android, for HAL_PIXEL_FORMAT_RGBA_8888. */169MESA_FORMAT_R8G8B8A8_UNORM,170171/* Required by Android, for HAL_PIXEL_FORMAT_RGBX_8888. */172MESA_FORMAT_R8G8B8X8_UNORM,173174/* Required by Android, for HAL_PIXEL_FORMAT_RGBA_8888. */175MESA_FORMAT_R8G8B8A8_SRGB,176177/* Required by Android, for HAL_PIXEL_FORMAT_RGBX_8888. */178MESA_FORMAT_R8G8B8X8_SRGB,179};180static const enum pipe_format pipe_formats[] = {181PIPE_FORMAT_B10G10R10A2_UNORM,182PIPE_FORMAT_B10G10R10X2_UNORM,183PIPE_FORMAT_R10G10B10A2_UNORM,184PIPE_FORMAT_R10G10B10X2_UNORM,185PIPE_FORMAT_BGRA8888_UNORM,186PIPE_FORMAT_BGRX8888_UNORM,187PIPE_FORMAT_BGRA8888_SRGB,188PIPE_FORMAT_BGRX8888_SRGB,189PIPE_FORMAT_B5G6R5_UNORM,190PIPE_FORMAT_R16G16B16A16_FLOAT,191PIPE_FORMAT_R16G16B16X16_FLOAT,192PIPE_FORMAT_RGBA8888_UNORM,193PIPE_FORMAT_RGBX8888_UNORM,194PIPE_FORMAT_RGBA8888_SRGB,195PIPE_FORMAT_RGBX8888_SRGB,196};197mesa_format format;198__DRIconfig **configs = NULL;199uint8_t depth_bits_array[5];200uint8_t stencil_bits_array[5];201unsigned depth_buffer_factor;202unsigned msaa_samples_max;203unsigned i;204struct pipe_screen *p_screen = screen->base.screen;205bool pf_z16, pf_x8z24, pf_z24x8, pf_s8z24, pf_z24s8, pf_z32;206bool mixed_color_depth;207bool allow_rgba_ordering;208bool allow_rgb10;209bool allow_fp16;210211static const GLenum back_buffer_modes[] = {212__DRI_ATTRIB_SWAP_NONE, __DRI_ATTRIB_SWAP_UNDEFINED,213__DRI_ATTRIB_SWAP_COPY214};215216if (driQueryOptionb(&screen->dev->option_cache, "always_have_depth_buffer")) {217/* all visuals will have a depth buffer */218depth_buffer_factor = 0;219}220else {221depth_bits_array[0] = 0;222stencil_bits_array[0] = 0;223depth_buffer_factor = 1;224}225226allow_rgba_ordering = dri_loader_get_cap(screen, DRI_LOADER_CAP_RGBA_ORDERING);227allow_rgb10 = driQueryOptionb(&screen->dev->option_cache, "allow_rgb10_configs");228allow_fp16 = driQueryOptionb(&screen->dev->option_cache, "allow_fp16_configs");229allow_fp16 &= dri_loader_get_cap(screen, DRI_LOADER_CAP_FP16);230231msaa_samples_max = (screen->st_api->feature_mask & ST_API_FEATURE_MS_VISUALS_MASK)232? MSAA_VISUAL_MAX_SAMPLES : 1;233234pf_x8z24 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_Z24X8_UNORM,235PIPE_TEXTURE_2D, 0, 0,236PIPE_BIND_DEPTH_STENCIL);237pf_z24x8 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_X8Z24_UNORM,238PIPE_TEXTURE_2D, 0, 0,239PIPE_BIND_DEPTH_STENCIL);240pf_s8z24 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_Z24_UNORM_S8_UINT,241PIPE_TEXTURE_2D, 0, 0,242PIPE_BIND_DEPTH_STENCIL);243pf_z24s8 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_S8_UINT_Z24_UNORM,244PIPE_TEXTURE_2D, 0, 0,245PIPE_BIND_DEPTH_STENCIL);246pf_z16 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_Z16_UNORM,247PIPE_TEXTURE_2D, 0, 0,248PIPE_BIND_DEPTH_STENCIL);249pf_z32 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_Z32_UNORM,250PIPE_TEXTURE_2D, 0, 0,251PIPE_BIND_DEPTH_STENCIL);252253if (pf_z16) {254depth_bits_array[depth_buffer_factor] = 16;255stencil_bits_array[depth_buffer_factor++] = 0;256}257if (pf_x8z24 || pf_z24x8) {258depth_bits_array[depth_buffer_factor] = 24;259stencil_bits_array[depth_buffer_factor++] = 0;260screen->d_depth_bits_last = pf_x8z24;261}262if (pf_s8z24 || pf_z24s8) {263depth_bits_array[depth_buffer_factor] = 24;264stencil_bits_array[depth_buffer_factor++] = 8;265screen->sd_depth_bits_last = pf_s8z24;266}267if (pf_z32) {268depth_bits_array[depth_buffer_factor] = 32;269stencil_bits_array[depth_buffer_factor++] = 0;270}271272mixed_color_depth =273p_screen->get_param(p_screen, PIPE_CAP_MIXED_COLOR_DEPTH_BITS);274275assert(ARRAY_SIZE(mesa_formats) == ARRAY_SIZE(pipe_formats));276277/* Add configs. */278for (format = 0; format < ARRAY_SIZE(mesa_formats); format++) {279__DRIconfig **new_configs = NULL;280unsigned num_msaa_modes = 0; /* includes a single-sample mode */281uint8_t msaa_modes[MSAA_VISUAL_MAX_SAMPLES];282283/* Expose only BGRA ordering if the loader doesn't support RGBA ordering. */284if (!allow_rgba_ordering &&285(mesa_formats[format] == MESA_FORMAT_R8G8B8A8_UNORM ||286mesa_formats[format] == MESA_FORMAT_R8G8B8X8_UNORM ||287mesa_formats[format] == MESA_FORMAT_R8G8B8A8_SRGB ||288mesa_formats[format] == MESA_FORMAT_R8G8B8X8_SRGB))289continue;290291if (!allow_rgb10 &&292(mesa_formats[format] == MESA_FORMAT_B10G10R10A2_UNORM ||293mesa_formats[format] == MESA_FORMAT_B10G10R10X2_UNORM ||294mesa_formats[format] == MESA_FORMAT_R10G10B10A2_UNORM ||295mesa_formats[format] == MESA_FORMAT_R10G10B10X2_UNORM))296continue;297298if (!allow_fp16 &&299(mesa_formats[format] == MESA_FORMAT_RGBA_FLOAT16 ||300mesa_formats[format] == MESA_FORMAT_RGBX_FLOAT16))301continue;302303if (!p_screen->is_format_supported(p_screen, pipe_formats[format],304PIPE_TEXTURE_2D, 0, 0,305PIPE_BIND_RENDER_TARGET |306PIPE_BIND_DISPLAY_TARGET))307continue;308309for (i = 1; i <= msaa_samples_max; i++) {310int samples = i > 1 ? i : 0;311312if (p_screen->is_format_supported(p_screen, pipe_formats[format],313PIPE_TEXTURE_2D, samples, samples,314PIPE_BIND_RENDER_TARGET)) {315msaa_modes[num_msaa_modes++] = samples;316}317}318319if (num_msaa_modes) {320/* Single-sample configs with an accumulation buffer. */321new_configs = driCreateConfigs(mesa_formats[format],322depth_bits_array, stencil_bits_array,323depth_buffer_factor, back_buffer_modes,324ARRAY_SIZE(back_buffer_modes),325msaa_modes, 1,326GL_TRUE, !mixed_color_depth);327configs = driConcatConfigs(configs, new_configs);328329/* Multi-sample configs without an accumulation buffer. */330if (num_msaa_modes > 1) {331new_configs = driCreateConfigs(mesa_formats[format],332depth_bits_array, stencil_bits_array,333depth_buffer_factor, back_buffer_modes,334ARRAY_SIZE(back_buffer_modes),335msaa_modes+1, num_msaa_modes-1,336GL_FALSE, !mixed_color_depth);337configs = driConcatConfigs(configs, new_configs);338}339}340}341342if (configs == NULL) {343debug_printf("%s: driCreateConfigs failed\n", __FUNCTION__);344return NULL;345}346347return (const __DRIconfig **)configs;348}349350/**351* Roughly the converse of dri_fill_in_modes.352*/353void354dri_fill_st_visual(struct st_visual *stvis,355const struct dri_screen *screen,356const struct gl_config *mode)357{358memset(stvis, 0, sizeof(*stvis));359360if (!mode)361return;362363/* Deduce the color format. */364switch (mode->redMask) {365case 0:366/* Formats > 32 bpp */367assert(mode->floatMode);368if (mode->alphaShift > -1) {369assert(mode->alphaShift == 48);370stvis->color_format = PIPE_FORMAT_R16G16B16A16_FLOAT;371} else {372stvis->color_format = PIPE_FORMAT_R16G16B16X16_FLOAT;373}374break;375376case 0x3FF00000:377if (mode->alphaMask) {378assert(mode->alphaMask == 0xC0000000);379stvis->color_format = PIPE_FORMAT_B10G10R10A2_UNORM;380} else {381stvis->color_format = PIPE_FORMAT_B10G10R10X2_UNORM;382}383break;384385case 0x000003FF:386if (mode->alphaMask) {387assert(mode->alphaMask == 0xC0000000);388stvis->color_format = PIPE_FORMAT_R10G10B10A2_UNORM;389} else {390stvis->color_format = PIPE_FORMAT_R10G10B10X2_UNORM;391}392break;393394case 0x00FF0000:395if (mode->alphaMask) {396assert(mode->alphaMask == 0xFF000000);397stvis->color_format = mode->sRGBCapable ?398PIPE_FORMAT_BGRA8888_SRGB :399PIPE_FORMAT_BGRA8888_UNORM;400} else {401stvis->color_format = mode->sRGBCapable ?402PIPE_FORMAT_BGRX8888_SRGB :403PIPE_FORMAT_BGRX8888_UNORM;404}405break;406407case 0x000000FF:408if (mode->alphaMask) {409assert(mode->alphaMask == 0xFF000000);410stvis->color_format = mode->sRGBCapable ?411PIPE_FORMAT_RGBA8888_SRGB :412PIPE_FORMAT_RGBA8888_UNORM;413} else {414stvis->color_format = mode->sRGBCapable ?415PIPE_FORMAT_RGBX8888_SRGB :416PIPE_FORMAT_RGBX8888_UNORM;417}418break;419420case 0x0000F800:421stvis->color_format = PIPE_FORMAT_B5G6R5_UNORM;422break;423424default:425assert(!"unsupported visual: invalid red mask");426return;427}428429if (mode->samples > 0) {430stvis->samples = mode->samples;431}432433switch (mode->depthBits) {434default:435case 0:436stvis->depth_stencil_format = PIPE_FORMAT_NONE;437break;438case 16:439stvis->depth_stencil_format = PIPE_FORMAT_Z16_UNORM;440break;441case 24:442if (mode->stencilBits == 0) {443stvis->depth_stencil_format = (screen->d_depth_bits_last) ?444PIPE_FORMAT_Z24X8_UNORM:445PIPE_FORMAT_X8Z24_UNORM;446} else {447stvis->depth_stencil_format = (screen->sd_depth_bits_last) ?448PIPE_FORMAT_Z24_UNORM_S8_UINT:449PIPE_FORMAT_S8_UINT_Z24_UNORM;450}451break;452case 32:453stvis->depth_stencil_format = PIPE_FORMAT_Z32_UNORM;454break;455}456457stvis->accum_format = (mode->accumRedBits > 0) ?458PIPE_FORMAT_R16G16B16A16_SNORM : PIPE_FORMAT_NONE;459460stvis->buffer_mask |= ST_ATTACHMENT_FRONT_LEFT_MASK;461if (mode->doubleBufferMode) {462stvis->buffer_mask |= ST_ATTACHMENT_BACK_LEFT_MASK;463}464if (mode->stereoMode) {465stvis->buffer_mask |= ST_ATTACHMENT_FRONT_RIGHT_MASK;466if (mode->doubleBufferMode)467stvis->buffer_mask |= ST_ATTACHMENT_BACK_RIGHT_MASK;468}469470if (mode->depthBits > 0 || mode->stencilBits > 0)471stvis->buffer_mask |= ST_ATTACHMENT_DEPTH_STENCIL_MASK;472/* let the gallium frontend allocate the accum buffer */473}474475static bool476dri_get_egl_image(struct st_manager *smapi,477void *egl_image,478struct st_egl_image *stimg)479{480struct dri_screen *screen = (struct dri_screen *)smapi;481__DRIimage *img = NULL;482const struct dri2_format_mapping *map;483484if (screen->lookup_egl_image) {485img = screen->lookup_egl_image(screen, egl_image);486}487488if (!img)489return FALSE;490491stimg->texture = NULL;492pipe_resource_reference(&stimg->texture, img->texture);493map = dri2_get_mapping_by_fourcc(img->dri_fourcc);494stimg->format = map ? map->pipe_format : img->texture->format;495stimg->level = img->level;496stimg->layer = img->layer;497498if (img->imported_dmabuf && map) {499/* Guess sized internal format for dma-bufs. Could be used500* by EXT_EGL_image_storage.501*/502mesa_format mesa_format = driImageFormatToGLFormat(map->dri_format);503stimg->internalformat = driGLFormatToSizedInternalGLFormat(mesa_format);504}505506return TRUE;507}508509static int510dri_get_param(struct st_manager *smapi,511enum st_manager_param param)512{513struct dri_screen *screen = (struct dri_screen *)smapi;514515switch(param) {516case ST_MANAGER_BROKEN_INVALIDATE:517return screen->broken_invalidate;518default:519return 0;520}521}522523void524dri_destroy_screen_helper(struct dri_screen * screen)525{526if (screen->base.destroy)527screen->base.destroy(&screen->base);528529if (screen->st_api && screen->st_api->destroy)530screen->st_api->destroy(screen->st_api);531532if (screen->base.screen)533screen->base.screen->destroy(screen->base.screen);534535mtx_destroy(&screen->opencl_func_mutex);536}537538void539dri_destroy_screen(__DRIscreen * sPriv)540{541struct dri_screen *screen = dri_screen(sPriv);542543dri_destroy_screen_helper(screen);544545pipe_loader_release(&screen->dev, 1);546547free(screen->options.force_gl_vendor);548549/* The caller in dri_util preserves the fd ownership */550free(screen);551sPriv->driverPrivate = NULL;552sPriv->extensions = NULL;553}554555static void556dri_postprocessing_init(struct dri_screen *screen)557{558unsigned i;559560for (i = 0; i < PP_FILTERS; i++) {561screen->pp_enabled[i] = driQueryOptioni(&screen->dev->option_cache,562pp_filters[i].name);563}564}565566static void567dri_set_background_context(struct st_context_iface *st,568struct util_queue_monitoring *queue_info)569{570struct dri_context *ctx = (struct dri_context *)st->st_manager_private;571const __DRIbackgroundCallableExtension *backgroundCallable =572ctx->sPriv->dri2.backgroundCallable;573574/* Note: Mesa will only call this function if GL multithreading is enabled575* We only do that if the loader exposed the __DRI_BACKGROUND_CALLABLE576* extension. So we know that backgroundCallable is not NULL.577*/578assert(backgroundCallable);579backgroundCallable->setBackgroundContext(ctx->cPriv->loaderPrivate);580581if (ctx->hud)582hud_add_queue_for_monitoring(ctx->hud, queue_info);583}584585void586dri_init_options(struct dri_screen *screen)587{588pipe_loader_load_options(screen->dev);589590dri_fill_st_options(screen);591}592593const __DRIconfig **594dri_init_screen_helper(struct dri_screen *screen,595struct pipe_screen *pscreen)596{597screen->base.screen = pscreen;598screen->base.get_egl_image = dri_get_egl_image;599screen->base.get_param = dri_get_param;600screen->base.set_background_context = dri_set_background_context;601602screen->st_api = st_gl_api_create();603if (!screen->st_api)604return NULL;605606if(pscreen->get_param(pscreen, PIPE_CAP_NPOT_TEXTURES))607screen->target = PIPE_TEXTURE_2D;608else609screen->target = PIPE_TEXTURE_RECT;610611dri_postprocessing_init(screen);612613screen->st_api->query_versions(screen->st_api, &screen->base,614&screen->options,615&screen->sPriv->max_gl_core_version,616&screen->sPriv->max_gl_compat_version,617&screen->sPriv->max_gl_es1_version,618&screen->sPriv->max_gl_es2_version);619620return dri_fill_in_modes(screen);621}622623/* vim: set sw=3 ts=8 sts=3 expandtab: */624625626