Home | History | Annotate | Download | only in glx
      1 /*
      2  * Copyright  2013 Intel Corporation
      3  *
      4  * Permission is hereby granted, free of charge, to any person obtaining a
      5  * copy of this software and associated documentation files (the "Software"),
      6  * to deal in the Software without restriction, including without limitation
      7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      8  * and/or sell copies of the Software, and to permit persons to whom the
      9  * Software is furnished to do so, subject to the following conditions:
     10  *
     11  * The above copyright notice and this permission notice (including the next
     12  * paragraph) shall be included in all copies or substantial portions of the
     13  * Software.
     14  *
     15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
     18  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
     20  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
     21  * DEALINGS IN THE SOFTWARE.
     22  */
     23 
     24 #if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)
     25 
     26 #include "glxclient.h"
     27 #include "glx_error.h"
     28 #include "dri_interface.h"
     29 #include "dri2_priv.h"
     30 #if defined(HAVE_DRI3)
     31 #include "dri3_priv.h"
     32 #endif
     33 #include "drisw_priv.h"
     34 
     35 #define __RENDERER(attrib) \
     36     { GLX_RENDERER_##attrib##_MESA, __DRI2_RENDERER_##attrib }
     37 
     38 static const struct {
     39    unsigned int glx_attrib, dri2_attrib;
     40 } query_renderer_map[] = {
     41   __RENDERER(VENDOR_ID),
     42   __RENDERER(DEVICE_ID),
     43   __RENDERER(VERSION),
     44   __RENDERER(ACCELERATED),
     45   __RENDERER(VIDEO_MEMORY),
     46   __RENDERER(UNIFIED_MEMORY_ARCHITECTURE),
     47   __RENDERER(PREFERRED_PROFILE),
     48   __RENDERER(OPENGL_CORE_PROFILE_VERSION),
     49   __RENDERER(OPENGL_COMPATIBILITY_PROFILE_VERSION),
     50   __RENDERER(OPENGL_ES_PROFILE_VERSION),
     51   __RENDERER(OPENGL_ES2_PROFILE_VERSION),
     52 };
     53 
     54 #undef __RENDERER
     55 
     56 static int
     57 dri2_convert_glx_query_renderer_attribs(int attribute)
     58 {
     59    unsigned i;
     60 
     61    for (i = 0; i < ARRAY_SIZE(query_renderer_map); i++)
     62       if (query_renderer_map[i].glx_attrib == attribute)
     63          return query_renderer_map[i].dri2_attrib;
     64 
     65    return -1;
     66 }
     67 
     68 /* Convert internal dri context profile bits into GLX context profile bits */
     69 static inline void
     70 dri_convert_context_profile_bits(int attribute, unsigned int *value)
     71 {
     72    if (attribute == GLX_RENDERER_PREFERRED_PROFILE_MESA) {
     73       if (value[0] == (1U << __DRI_API_OPENGL_CORE))
     74          value[0] = GLX_CONTEXT_CORE_PROFILE_BIT_ARB;
     75       else if (value[0] == (1U << __DRI_API_OPENGL))
     76          value[0] = GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB;
     77    }
     78 }
     79 
     80 _X_HIDDEN int
     81 dri2_query_renderer_integer(struct glx_screen *base, int attribute,
     82                             unsigned int *value)
     83 {
     84    int ret;
     85    struct dri2_screen *const psc = (struct dri2_screen *) base;
     86 
     87    /* Even though there are invalid values (and
     88     * dri2_convert_glx_query_renderer_attribs may return -1), the higher level
     89     * GLX code is required to perform the filtering.  Assume that we got a
     90     * good value.
     91     */
     92    const int dri_attribute = dri2_convert_glx_query_renderer_attribs(attribute);
     93 
     94    if (psc->rendererQuery == NULL)
     95       return -1;
     96 
     97    ret = psc->rendererQuery->queryInteger(psc->driScreen, dri_attribute,
     98                                           value);
     99    dri_convert_context_profile_bits(attribute, value);
    100 
    101    return ret;
    102 }
    103 
    104 _X_HIDDEN int
    105 dri2_query_renderer_string(struct glx_screen *base, int attribute,
    106                            const char **value)
    107 {
    108    struct dri2_screen *const psc = (struct dri2_screen *) base;
    109 
    110    /* Even though queryString only accepts a subset of the possible GLX
    111     * queries, the higher level GLX code is required to perform the filtering.
    112     * Assume that we got a good value.
    113     */
    114    const int dri_attribute = dri2_convert_glx_query_renderer_attribs(attribute);
    115 
    116    if (psc->rendererQuery == NULL)
    117       return -1;
    118 
    119    return psc->rendererQuery->queryString(psc->driScreen, dri_attribute, value);
    120 }
    121 
    122 #if defined(HAVE_DRI3)
    123 _X_HIDDEN int
    124 dri3_query_renderer_integer(struct glx_screen *base, int attribute,
    125                             unsigned int *value)
    126 {
    127    int ret;
    128    struct dri3_screen *const psc = (struct dri3_screen *) base;
    129 
    130    /* Even though there are invalid values (and
    131     * dri2_convert_glx_query_renderer_attribs may return -1), the higher level
    132     * GLX code is required to perform the filtering.  Assume that we got a
    133     * good value.
    134     */
    135    const int dri_attribute = dri2_convert_glx_query_renderer_attribs(attribute);
    136 
    137    if (psc->rendererQuery == NULL)
    138       return -1;
    139 
    140    ret = psc->rendererQuery->queryInteger(psc->driScreen, dri_attribute,
    141                                           value);
    142    dri_convert_context_profile_bits(attribute, value);
    143 
    144    return ret;
    145 }
    146 
    147 _X_HIDDEN int
    148 dri3_query_renderer_string(struct glx_screen *base, int attribute,
    149                            const char **value)
    150 {
    151    struct dri3_screen *const psc = (struct dri3_screen *) base;
    152 
    153    /* Even though queryString only accepts a subset of the possible GLX
    154     * queries, the higher level GLX code is required to perform the filtering.
    155     * Assume that we got a good value.
    156     */
    157    const int dri_attribute = dri2_convert_glx_query_renderer_attribs(attribute);
    158 
    159    if (psc->rendererQuery == NULL)
    160       return -1;
    161 
    162    return psc->rendererQuery->queryString(psc->driScreen, dri_attribute, value);
    163 }
    164 #endif /* HAVE_DRI3 */
    165 
    166 _X_HIDDEN int
    167 drisw_query_renderer_integer(struct glx_screen *base, int attribute,
    168                              unsigned int *value)
    169 {
    170    int ret;
    171    struct drisw_screen *const psc = (struct drisw_screen *) base;
    172 
    173    /* Even though there are invalid values (and
    174     * dri2_convert_glx_query_renderer_attribs may return -1), the higher level
    175     * GLX code is required to perform the filtering.  Assume that we got a
    176     * good value.
    177     */
    178    const int dri_attribute = dri2_convert_glx_query_renderer_attribs(attribute);
    179 
    180    if (psc->rendererQuery == NULL)
    181       return -1;
    182 
    183    ret = psc->rendererQuery->queryInteger(psc->driScreen, dri_attribute,
    184                                           value);
    185    dri_convert_context_profile_bits(attribute, value);
    186 
    187    return ret;
    188 }
    189 
    190 _X_HIDDEN int
    191 drisw_query_renderer_string(struct glx_screen *base, int attribute,
    192                             const char **value)
    193 {
    194    struct drisw_screen *const psc = (struct drisw_screen *) base;
    195 
    196    /* Even though queryString only accepts a subset of the possible GLX
    197     * queries, the higher level GLX code is required to perform the filtering.
    198     * Assume that we got a good value.
    199     */
    200    const int dri_attribute = dri2_convert_glx_query_renderer_attribs(attribute);
    201 
    202    if (psc->rendererQuery == NULL)
    203       return -1;
    204 
    205    return psc->rendererQuery->queryString(psc->driScreen, dri_attribute, value);
    206 }
    207 
    208 
    209 #endif /* GLX_DIRECT_RENDERING */
    210