Subversion Repositories Kolibri OS

Rev

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