| /* |
| * Copyright © 2013 Intel Corporation |
| * |
| * Permission is hereby granted, free of charge, to any person obtaining a |
| * copy of this software and associated documentation files (the "Software"), |
| * to deal in the Software without restriction, including without limitation |
| * the rights to use, copy, modify, merge, publish, distribute, sublicense, |
| * and/or sell copies of the Software, and to permit persons to whom the |
| * Software is furnished to do so, subject to the following conditions: |
| * |
| * The above copyright notice and this permission notice (including the next |
| * paragraph) shall be included in all copies or substantial portions of the |
| * Software. |
| * |
| * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
| * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
| * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
| * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
| * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
| * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
| * DEALINGS IN THE SOFTWARE. |
| */ |
| |
| #if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL) |
| |
| #include "glxclient.h" |
| #include "glx_error.h" |
| #include "GL/internal/dri_interface.h" |
| #include "dri2_priv.h" |
| #if defined(HAVE_DRI3) |
| #include "dri3_priv.h" |
| #endif |
| #include "drisw_priv.h" |
| |
| #define __RENDERER(attrib) \ |
| { GLX_RENDERER_##attrib##_MESA, __DRI2_RENDERER_##attrib } |
| |
| static const struct { |
| unsigned int glx_attrib, dri2_attrib; |
| } query_renderer_map[] = { |
| __RENDERER(VENDOR_ID), |
| __RENDERER(DEVICE_ID), |
| __RENDERER(VERSION), |
| __RENDERER(ACCELERATED), |
| __RENDERER(VIDEO_MEMORY), |
| __RENDERER(UNIFIED_MEMORY_ARCHITECTURE), |
| __RENDERER(PREFERRED_PROFILE), |
| __RENDERER(OPENGL_CORE_PROFILE_VERSION), |
| __RENDERER(OPENGL_COMPATIBILITY_PROFILE_VERSION), |
| __RENDERER(OPENGL_ES_PROFILE_VERSION), |
| __RENDERER(OPENGL_ES2_PROFILE_VERSION), |
| }; |
| |
| #undef __RENDERER |
| |
| static int |
| dri2_convert_glx_query_renderer_attribs(int attribute) |
| { |
| unsigned i; |
| |
| for (i = 0; i < ARRAY_SIZE(query_renderer_map); i++) |
| if (query_renderer_map[i].glx_attrib == attribute) |
| return query_renderer_map[i].dri2_attrib; |
| |
| return -1; |
| } |
| |
| /* Convert internal dri context profile bits into GLX context profile bits */ |
| static inline void |
| dri_convert_context_profile_bits(int attribute, unsigned int *value) |
| { |
| if (attribute == GLX_RENDERER_PREFERRED_PROFILE_MESA) { |
| if (value[0] == (1U << __DRI_API_OPENGL_CORE)) |
| value[0] = GLX_CONTEXT_CORE_PROFILE_BIT_ARB; |
| else if (value[0] == (1U << __DRI_API_OPENGL)) |
| value[0] = GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB; |
| } |
| } |
| |
| _X_HIDDEN int |
| dri2_query_renderer_integer(struct glx_screen *base, int attribute, |
| unsigned int *value) |
| { |
| int ret; |
| struct dri2_screen *const psc = (struct dri2_screen *) base; |
| |
| /* Even though there are invalid values (and |
| * dri2_convert_glx_query_renderer_attribs may return -1), the higher level |
| * GLX code is required to perform the filtering. Assume that we got a |
| * good value. |
| */ |
| const int dri_attribute = dri2_convert_glx_query_renderer_attribs(attribute); |
| |
| if (psc->rendererQuery == NULL) |
| return -1; |
| |
| ret = psc->rendererQuery->queryInteger(psc->driScreen, dri_attribute, |
| value); |
| dri_convert_context_profile_bits(attribute, value); |
| |
| return ret; |
| } |
| |
| _X_HIDDEN int |
| dri2_query_renderer_string(struct glx_screen *base, int attribute, |
| const char **value) |
| { |
| struct dri2_screen *const psc = (struct dri2_screen *) base; |
| |
| /* Even though queryString only accepts a subset of the possible GLX |
| * queries, the higher level GLX code is required to perform the filtering. |
| * Assume that we got a good value. |
| */ |
| const int dri_attribute = dri2_convert_glx_query_renderer_attribs(attribute); |
| |
| if (psc->rendererQuery == NULL) |
| return -1; |
| |
| return psc->rendererQuery->queryString(psc->driScreen, dri_attribute, value); |
| } |
| |
| #if defined(HAVE_DRI3) |
| _X_HIDDEN int |
| dri3_query_renderer_integer(struct glx_screen *base, int attribute, |
| unsigned int *value) |
| { |
| int ret; |
| struct dri3_screen *const psc = (struct dri3_screen *) base; |
| |
| /* Even though there are invalid values (and |
| * dri2_convert_glx_query_renderer_attribs may return -1), the higher level |
| * GLX code is required to perform the filtering. Assume that we got a |
| * good value. |
| */ |
| const int dri_attribute = dri2_convert_glx_query_renderer_attribs(attribute); |
| |
| if (psc->rendererQuery == NULL) |
| return -1; |
| |
| ret = psc->rendererQuery->queryInteger(psc->driScreen, dri_attribute, |
| value); |
| dri_convert_context_profile_bits(attribute, value); |
| |
| return ret; |
| } |
| |
| _X_HIDDEN int |
| dri3_query_renderer_string(struct glx_screen *base, int attribute, |
| const char **value) |
| { |
| struct dri3_screen *const psc = (struct dri3_screen *) base; |
| |
| /* Even though queryString only accepts a subset of the possible GLX |
| * queries, the higher level GLX code is required to perform the filtering. |
| * Assume that we got a good value. |
| */ |
| const int dri_attribute = dri2_convert_glx_query_renderer_attribs(attribute); |
| |
| if (psc->rendererQuery == NULL) |
| return -1; |
| |
| return psc->rendererQuery->queryString(psc->driScreen, dri_attribute, value); |
| } |
| #endif /* HAVE_DRI3 */ |
| |
| _X_HIDDEN int |
| drisw_query_renderer_integer(struct glx_screen *base, int attribute, |
| unsigned int *value) |
| { |
| int ret; |
| struct drisw_screen *const psc = (struct drisw_screen *) base; |
| |
| /* Even though there are invalid values (and |
| * dri2_convert_glx_query_renderer_attribs may return -1), the higher level |
| * GLX code is required to perform the filtering. Assume that we got a |
| * good value. |
| */ |
| const int dri_attribute = dri2_convert_glx_query_renderer_attribs(attribute); |
| |
| if (psc->rendererQuery == NULL) |
| return -1; |
| |
| ret = psc->rendererQuery->queryInteger(psc->driScreen, dri_attribute, |
| value); |
| dri_convert_context_profile_bits(attribute, value); |
| |
| return ret; |
| } |
| |
| _X_HIDDEN int |
| drisw_query_renderer_string(struct glx_screen *base, int attribute, |
| const char **value) |
| { |
| struct drisw_screen *const psc = (struct drisw_screen *) base; |
| |
| /* Even though queryString only accepts a subset of the possible GLX |
| * queries, the higher level GLX code is required to perform the filtering. |
| * Assume that we got a good value. |
| */ |
| const int dri_attribute = dri2_convert_glx_query_renderer_attribs(attribute); |
| |
| if (psc->rendererQuery == NULL) |
| return -1; |
| |
| return psc->rendererQuery->queryString(psc->driScreen, dri_attribute, value); |
| } |
| |
| |
| #endif /* GLX_DIRECT_RENDERING */ |