Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /**************************************************************************
  2.  *
  3.  * Copyright 2009, 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.  * Author: Keith Whitwell <keithw@vmware.com>
  29.  * Author: Jakob Bornecrantz <wallbraker@gmail.com>
  30.  */
  31.  
  32. #include "utils.h"
  33. #include "xmlpool.h"
  34.  
  35. #include "dri_screen.h"
  36.  
  37. #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 "state_tracker/drm_driver.h"
  43.  
  44. #include "util/u_debug.h"
  45. #include "util/u_format_s3tc.h"
  46.  
  47. #define MSAA_VISUAL_MAX_SAMPLES 32
  48.  
  49. #undef false
  50.  
  51. const __DRIconfigOptionsExtension gallium_config_options = {
  52.    .base = { __DRI_CONFIG_OPTIONS, 1 },
  53.    .xml =
  54.  
  55.    DRI_CONF_BEGIN
  56.       DRI_CONF_SECTION_QUALITY
  57.          DRI_CONF_FORCE_S3TC_ENABLE("false")
  58.          DRI_CONF_PP_CELSHADE(0)
  59.          DRI_CONF_PP_NORED(0)
  60.          DRI_CONF_PP_NOGREEN(0)
  61.          DRI_CONF_PP_NOBLUE(0)
  62.          DRI_CONF_PP_JIMENEZMLAA(0, 0, 32)
  63.          DRI_CONF_PP_JIMENEZMLAA_COLOR(0, 0, 32)
  64.       DRI_CONF_SECTION_END
  65.  
  66.       DRI_CONF_SECTION_DEBUG
  67.          DRI_CONF_FORCE_GLSL_EXTENSIONS_WARN("false")
  68.          DRI_CONF_DISABLE_GLSL_LINE_CONTINUATIONS("false")
  69.          DRI_CONF_DISABLE_BLEND_FUNC_EXTENDED("false")
  70.          DRI_CONF_DISABLE_SHADER_BIT_ENCODING("false")
  71.          DRI_CONF_FORCE_GLSL_VERSION(0)
  72.          DRI_CONF_ALLOW_GLSL_EXTENSION_DIRECTIVE_MIDSHADER("false")
  73.       DRI_CONF_SECTION_END
  74.  
  75.       DRI_CONF_SECTION_MISCELLANEOUS
  76.          DRI_CONF_ALWAYS_HAVE_DEPTH_BUFFER("false")
  77.       DRI_CONF_SECTION_END
  78.    DRI_CONF_END
  79. };
  80.  
  81. #define false 0
  82.  
  83. static void
  84. dri_fill_st_options(struct st_config_options *options,
  85.                     const struct driOptionCache * optionCache)
  86. {
  87.    options->disable_blend_func_extended =
  88.       driQueryOptionb(optionCache, "disable_blend_func_extended");
  89.    options->disable_glsl_line_continuations =
  90.       driQueryOptionb(optionCache, "disable_glsl_line_continuations");
  91.    options->disable_shader_bit_encoding =
  92.       driQueryOptionb(optionCache, "disable_shader_bit_encoding");
  93.    options->force_glsl_extensions_warn =
  94.       driQueryOptionb(optionCache, "force_glsl_extensions_warn");
  95.    options->force_glsl_version =
  96.       driQueryOptioni(optionCache, "force_glsl_version");
  97.    options->force_s3tc_enable =
  98.       driQueryOptionb(optionCache, "force_s3tc_enable");
  99.    options->allow_glsl_extension_directive_midshader =
  100.       driQueryOptionb(optionCache, "allow_glsl_extension_directive_midshader");
  101. }
  102.  
  103. static const __DRIconfig **
  104. dri_fill_in_modes(struct dri_screen *screen)
  105. {
  106.    static const mesa_format mesa_formats[3] = {
  107.       MESA_FORMAT_B8G8R8A8_UNORM,
  108.       MESA_FORMAT_B8G8R8X8_UNORM,
  109.       MESA_FORMAT_B5G6R5_UNORM,
  110.    };
  111.    static const enum pipe_format pipe_formats[3] = {
  112.       PIPE_FORMAT_BGRA8888_UNORM,
  113.       PIPE_FORMAT_BGRX8888_UNORM,
  114.       PIPE_FORMAT_B5G6R5_UNORM,
  115.    };
  116.    mesa_format format;
  117.    __DRIconfig **configs = NULL;
  118.    uint8_t depth_bits_array[5];
  119.    uint8_t stencil_bits_array[5];
  120.    unsigned depth_buffer_factor;
  121.    unsigned msaa_samples_max;
  122.    unsigned i;
  123.    struct pipe_screen *p_screen = screen->base.screen;
  124.    boolean pf_z16, pf_x8z24, pf_z24x8, pf_s8z24, pf_z24s8, pf_z32;
  125.  
  126.    static const GLenum back_buffer_modes[] = {
  127.       GLX_NONE, GLX_SWAP_UNDEFINED_OML, GLX_SWAP_COPY_OML
  128.    };
  129.  
  130.    if (driQueryOptionb(&screen->optionCache, "always_have_depth_buffer")) {
  131.       /* all visuals will have a depth buffer */
  132.       depth_buffer_factor = 0;
  133.    }
  134.    else {
  135.       depth_bits_array[0] = 0;
  136.       stencil_bits_array[0] = 0;
  137.       depth_buffer_factor = 1;
  138.    }
  139.  
  140.    msaa_samples_max = (screen->st_api->feature_mask & ST_API_FEATURE_MS_VISUALS_MASK)
  141.       ? MSAA_VISUAL_MAX_SAMPLES : 1;
  142.  
  143.    pf_x8z24 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_Z24X8_UNORM,
  144.                                             PIPE_TEXTURE_2D, 0,
  145.                                             PIPE_BIND_DEPTH_STENCIL);
  146.    pf_z24x8 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_X8Z24_UNORM,
  147.                                             PIPE_TEXTURE_2D, 0,
  148.                                             PIPE_BIND_DEPTH_STENCIL);
  149.    pf_s8z24 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_Z24_UNORM_S8_UINT,
  150.                                             PIPE_TEXTURE_2D, 0,
  151.                                             PIPE_BIND_DEPTH_STENCIL);
  152.    pf_z24s8 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_S8_UINT_Z24_UNORM,
  153.                                             PIPE_TEXTURE_2D, 0,
  154.                                             PIPE_BIND_DEPTH_STENCIL);
  155.    pf_z16 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_Z16_UNORM,
  156.                                           PIPE_TEXTURE_2D, 0,
  157.                                           PIPE_BIND_DEPTH_STENCIL);
  158.    pf_z32 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_Z32_UNORM,
  159.                                           PIPE_TEXTURE_2D, 0,
  160.                                           PIPE_BIND_DEPTH_STENCIL);
  161.  
  162.    if (pf_z16) {
  163.       depth_bits_array[depth_buffer_factor] = 16;
  164.       stencil_bits_array[depth_buffer_factor++] = 0;
  165.    }
  166.    if (pf_x8z24 || pf_z24x8) {
  167.       depth_bits_array[depth_buffer_factor] = 24;
  168.       stencil_bits_array[depth_buffer_factor++] = 0;
  169.       screen->d_depth_bits_last = pf_x8z24;
  170.    }
  171.    if (pf_s8z24 || pf_z24s8) {
  172.       depth_bits_array[depth_buffer_factor] = 24;
  173.       stencil_bits_array[depth_buffer_factor++] = 8;
  174.       screen->sd_depth_bits_last = pf_s8z24;
  175.    }
  176.    if (pf_z32) {
  177.       depth_bits_array[depth_buffer_factor] = 32;
  178.       stencil_bits_array[depth_buffer_factor++] = 0;
  179.    }
  180.  
  181.    assert(ARRAY_SIZE(mesa_formats) == ARRAY_SIZE(pipe_formats));
  182.  
  183.    /* Add configs. */
  184.    for (format = 0; format < ARRAY_SIZE(mesa_formats); format++) {
  185.       __DRIconfig **new_configs = NULL;
  186.       unsigned num_msaa_modes = 0; /* includes a single-sample mode */
  187.       uint8_t msaa_modes[MSAA_VISUAL_MAX_SAMPLES];
  188.  
  189.       for (i = 1; i <= msaa_samples_max; i++) {
  190.          int samples = i > 1 ? i : 0;
  191.  
  192.          if (p_screen->is_format_supported(p_screen, pipe_formats[format],
  193.                                            PIPE_TEXTURE_2D, samples,
  194.                                            PIPE_BIND_RENDER_TARGET)) {
  195.             msaa_modes[num_msaa_modes++] = samples;
  196.          }
  197.       }
  198.  
  199.       if (num_msaa_modes) {
  200.          /* Single-sample configs with an accumulation buffer. */
  201.          new_configs = driCreateConfigs(mesa_formats[format],
  202.                                         depth_bits_array, stencil_bits_array,
  203.                                         depth_buffer_factor, back_buffer_modes,
  204.                                         ARRAY_SIZE(back_buffer_modes),
  205.                                         msaa_modes, 1,
  206.                                         GL_TRUE);
  207.          configs = driConcatConfigs(configs, new_configs);
  208.  
  209.          /* Multi-sample configs without an accumulation buffer. */
  210.          if (num_msaa_modes > 1) {
  211.             new_configs = driCreateConfigs(mesa_formats[format],
  212.                                            depth_bits_array, stencil_bits_array,
  213.                                            depth_buffer_factor, back_buffer_modes,
  214.                                            ARRAY_SIZE(back_buffer_modes),
  215.                                            msaa_modes+1, num_msaa_modes-1,
  216.                                            GL_FALSE);
  217.             configs = driConcatConfigs(configs, new_configs);
  218.          }
  219.       }
  220.    }
  221.  
  222.    if (configs == NULL) {
  223.       debug_printf("%s: driCreateConfigs failed\n", __FUNCTION__);
  224.       return NULL;
  225.    }
  226.  
  227.    return (const __DRIconfig **)configs;
  228. }
  229.  
  230. /**
  231.  * Roughly the converse of dri_fill_in_modes.
  232.  */
  233. void
  234. dri_fill_st_visual(struct st_visual *stvis, struct dri_screen *screen,
  235.                    const struct gl_config *mode)
  236. {
  237.    memset(stvis, 0, sizeof(*stvis));
  238.  
  239.    if (!mode)
  240.       return;
  241.  
  242.    if (mode->redBits == 8) {
  243.       if (mode->alphaBits == 8)
  244.          stvis->color_format = PIPE_FORMAT_BGRA8888_UNORM;
  245.       else
  246.          stvis->color_format = PIPE_FORMAT_BGRX8888_UNORM;
  247.    } else {
  248.       stvis->color_format = PIPE_FORMAT_B5G6R5_UNORM;
  249.    }
  250.  
  251.    if (mode->sampleBuffers) {
  252.       stvis->samples = mode->samples;
  253.    }
  254.  
  255.    switch (mode->depthBits) {
  256.    default:
  257.    case 0:
  258.       stvis->depth_stencil_format = PIPE_FORMAT_NONE;
  259.       break;
  260.    case 16:
  261.       stvis->depth_stencil_format = PIPE_FORMAT_Z16_UNORM;
  262.       break;
  263.    case 24:
  264.       if (mode->stencilBits == 0) {
  265.          stvis->depth_stencil_format = (screen->d_depth_bits_last) ?
  266.                                           PIPE_FORMAT_Z24X8_UNORM:
  267.                                           PIPE_FORMAT_X8Z24_UNORM;
  268.       } else {
  269.          stvis->depth_stencil_format = (screen->sd_depth_bits_last) ?
  270.                                           PIPE_FORMAT_Z24_UNORM_S8_UINT:
  271.                                           PIPE_FORMAT_S8_UINT_Z24_UNORM;
  272.       }
  273.       break;
  274.    case 32:
  275.       stvis->depth_stencil_format = PIPE_FORMAT_Z32_UNORM;
  276.       break;
  277.    }
  278.  
  279.    stvis->accum_format = (mode->haveAccumBuffer) ?
  280.       PIPE_FORMAT_R16G16B16A16_SNORM : PIPE_FORMAT_NONE;
  281.  
  282.    stvis->buffer_mask |= ST_ATTACHMENT_FRONT_LEFT_MASK;
  283.    stvis->render_buffer = ST_ATTACHMENT_FRONT_LEFT;
  284.    if (mode->doubleBufferMode) {
  285.       stvis->buffer_mask |= ST_ATTACHMENT_BACK_LEFT_MASK;
  286.       stvis->render_buffer = ST_ATTACHMENT_BACK_LEFT;
  287.    }
  288.    if (mode->stereoMode) {
  289.       stvis->buffer_mask |= ST_ATTACHMENT_FRONT_RIGHT_MASK;
  290.       if (mode->doubleBufferMode)
  291.          stvis->buffer_mask |= ST_ATTACHMENT_BACK_RIGHT_MASK;
  292.    }
  293.  
  294.    if (mode->haveDepthBuffer || mode->haveStencilBuffer)
  295.       stvis->buffer_mask |= ST_ATTACHMENT_DEPTH_STENCIL_MASK;
  296.    /* let the state tracker allocate the accum buffer */
  297. }
  298.  
  299. static boolean
  300. dri_get_egl_image(struct st_manager *smapi,
  301.                   void *egl_image,
  302.                   struct st_egl_image *stimg)
  303. {
  304.    struct dri_screen *screen = (struct dri_screen *)smapi;
  305.    __DRIimage *img = NULL;
  306.  
  307.    if (screen->lookup_egl_image) {
  308.       img = screen->lookup_egl_image(screen, egl_image);
  309.    }
  310.  
  311.    if (!img)
  312.       return FALSE;
  313.  
  314.    stimg->texture = NULL;
  315.    pipe_resource_reference(&stimg->texture, img->texture);
  316.    stimg->level = img->level;
  317.    stimg->layer = img->layer;
  318.  
  319.    return TRUE;
  320. }
  321.  
  322. static int
  323. dri_get_param(struct st_manager *smapi,
  324.               enum st_manager_param param)
  325. {
  326.    struct dri_screen *screen = (struct dri_screen *)smapi;
  327.  
  328.    switch(param) {
  329.    case ST_MANAGER_BROKEN_INVALIDATE:
  330.       return screen->broken_invalidate;
  331.    default:
  332.       return 0;
  333.    }
  334. }
  335.  
  336. static void
  337. dri_destroy_option_cache(struct dri_screen * screen)
  338. {
  339.    int i;
  340.  
  341.    if (screen->optionCache.info) {
  342.       for (i = 0; i < (1 << screen->optionCache.tableSize); ++i) {
  343.          free(screen->optionCache.info[i].name);
  344.          free(screen->optionCache.info[i].ranges);
  345.       }
  346.       free(screen->optionCache.info);
  347.    }
  348.  
  349.    free(screen->optionCache.values);
  350.  
  351.    /* Default values are copied to screen->optionCache->values in
  352.     * initOptionCache. The info field, however, is a pointer copy, so don't free
  353.     * that twice.
  354.     */
  355.    free(screen->optionCacheDefaults.values);
  356. }
  357.  
  358. void
  359. dri_destroy_screen_helper(struct dri_screen * screen)
  360. {
  361.    if (screen->st_api && screen->st_api->destroy)
  362.       screen->st_api->destroy(screen->st_api);
  363.  
  364.    if (screen->base.screen)
  365.       screen->base.screen->destroy(screen->base.screen);
  366.  
  367.    dri_destroy_option_cache(screen);
  368.    pipe_mutex_destroy(screen->opencl_func_mutex);
  369. }
  370.  
  371. void
  372. dri_destroy_screen(__DRIscreen * sPriv)
  373. {
  374.    struct dri_screen *screen = dri_screen(sPriv);
  375.  
  376.    dri_destroy_screen_helper(screen);
  377.  
  378. #if !GALLIUM_STATIC_TARGETS
  379.    pipe_loader_release(&screen->dev, 1);
  380. #endif // !GALLIUM_STATIC_TARGETS
  381.  
  382.    free(screen);
  383.    sPriv->driverPrivate = NULL;
  384.    sPriv->extensions = NULL;
  385. }
  386.  
  387. static void
  388. dri_postprocessing_init(struct dri_screen *screen)
  389. {
  390.    unsigned i;
  391.  
  392.    for (i = 0; i < PP_FILTERS; i++) {
  393.       screen->pp_enabled[i] = driQueryOptioni(&screen->optionCache,
  394.                                               pp_filters[i].name);
  395.    }
  396. }
  397.  
  398. const __DRIconfig **
  399. dri_init_screen_helper(struct dri_screen *screen,
  400.                        struct pipe_screen *pscreen,
  401.                        const char* driver_name)
  402. {
  403.    screen->base.screen = pscreen;
  404.    if (!screen->base.screen) {
  405.       debug_printf("%s: failed to create pipe_screen\n", __FUNCTION__);
  406.       return NULL;
  407.    }
  408.  
  409.    screen->base.get_egl_image = dri_get_egl_image;
  410.    screen->base.get_param = dri_get_param;
  411.  
  412.    screen->st_api = st_gl_api_create();
  413.    if (!screen->st_api)
  414.       return NULL;
  415.  
  416.    if(pscreen->get_param(pscreen, PIPE_CAP_NPOT_TEXTURES))
  417.       screen->target = PIPE_TEXTURE_2D;
  418.    else
  419.       screen->target = PIPE_TEXTURE_RECT;
  420.  
  421.    driParseOptionInfo(&screen->optionCacheDefaults, gallium_config_options.xml);
  422.  
  423.    driParseConfigFiles(&screen->optionCache,
  424.                        &screen->optionCacheDefaults,
  425.                        screen->sPriv->myNum,
  426.                        driver_name);
  427.  
  428.    dri_fill_st_options(&screen->options, &screen->optionCache);
  429.  
  430.    /* Handle force_s3tc_enable. */
  431.    if (!util_format_s3tc_enabled && screen->options.force_s3tc_enable) {
  432.       /* Ensure libtxc_dxtn has been loaded if available.
  433.        * Forcing S3TC on before calling this would prevent loading
  434.        * the library.
  435.        * This is just a precaution, the driver should have called it
  436.        * already.
  437.        */
  438.       util_format_s3tc_init();
  439.  
  440.       util_format_s3tc_enabled = TRUE;
  441.    }
  442.  
  443.    dri_postprocessing_init(screen);
  444.  
  445.    screen->st_api->query_versions(screen->st_api, &screen->base,
  446.                                   &screen->options,
  447.                                   &screen->sPriv->max_gl_core_version,
  448.                                   &screen->sPriv->max_gl_compat_version,
  449.                                   &screen->sPriv->max_gl_es1_version,
  450.                                   &screen->sPriv->max_gl_es2_version);
  451.  
  452.    return dri_fill_in_modes(screen);
  453. }
  454.  
  455. /* vim: set sw=3 ts=8 sts=3 expandtab: */
  456.