101e04c3fSmrg/*
201e04c3fSmrg * Copyright © 2013 Intel Corporation
301e04c3fSmrg *
401e04c3fSmrg * Permission is hereby granted, free of charge, to any person obtaining a
501e04c3fSmrg * copy of this software and associated documentation files (the "Software"),
601e04c3fSmrg * to deal in the Software without restriction, including without limitation
701e04c3fSmrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
801e04c3fSmrg * and/or sell copies of the Software, and to permit persons to whom the
901e04c3fSmrg * Software is furnished to do so, subject to the following conditions:
1001e04c3fSmrg *
1101e04c3fSmrg * The above copyright notice and this permission notice (including the next
1201e04c3fSmrg * paragraph) shall be included in all copies or substantial portions of the
1301e04c3fSmrg * Software.
1401e04c3fSmrg *
1501e04c3fSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1601e04c3fSmrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1701e04c3fSmrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
1801e04c3fSmrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
1901e04c3fSmrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
2001e04c3fSmrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
2101e04c3fSmrg * DEALINGS IN THE SOFTWARE.
2201e04c3fSmrg */
2301e04c3fSmrg
2401e04c3fSmrg#if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)
2501e04c3fSmrg
2601e04c3fSmrg#include "glxclient.h"
2701e04c3fSmrg#include "glx_error.h"
289f464c52Smaya#include "GL/internal/dri_interface.h"
2901e04c3fSmrg#include "dri2_priv.h"
3001e04c3fSmrg#if defined(HAVE_DRI3)
3101e04c3fSmrg#include "dri3_priv.h"
3201e04c3fSmrg#endif
3301e04c3fSmrg#include "drisw_priv.h"
3401e04c3fSmrg
3501e04c3fSmrg#define __RENDERER(attrib) \
3601e04c3fSmrg    { GLX_RENDERER_##attrib##_MESA, __DRI2_RENDERER_##attrib }
3701e04c3fSmrg
3801e04c3fSmrgstatic const struct {
3901e04c3fSmrg   unsigned int glx_attrib, dri2_attrib;
4001e04c3fSmrg} query_renderer_map[] = {
4101e04c3fSmrg  __RENDERER(VENDOR_ID),
4201e04c3fSmrg  __RENDERER(DEVICE_ID),
4301e04c3fSmrg  __RENDERER(VERSION),
4401e04c3fSmrg  __RENDERER(ACCELERATED),
4501e04c3fSmrg  __RENDERER(VIDEO_MEMORY),
4601e04c3fSmrg  __RENDERER(UNIFIED_MEMORY_ARCHITECTURE),
4701e04c3fSmrg  __RENDERER(PREFERRED_PROFILE),
4801e04c3fSmrg  __RENDERER(OPENGL_CORE_PROFILE_VERSION),
4901e04c3fSmrg  __RENDERER(OPENGL_COMPATIBILITY_PROFILE_VERSION),
5001e04c3fSmrg  __RENDERER(OPENGL_ES_PROFILE_VERSION),
5101e04c3fSmrg  __RENDERER(OPENGL_ES2_PROFILE_VERSION),
5201e04c3fSmrg};
5301e04c3fSmrg
5401e04c3fSmrg#undef __RENDERER
5501e04c3fSmrg
5601e04c3fSmrgstatic int
5701e04c3fSmrgdri2_convert_glx_query_renderer_attribs(int attribute)
5801e04c3fSmrg{
5901e04c3fSmrg   unsigned i;
6001e04c3fSmrg
6101e04c3fSmrg   for (i = 0; i < ARRAY_SIZE(query_renderer_map); i++)
6201e04c3fSmrg      if (query_renderer_map[i].glx_attrib == attribute)
6301e04c3fSmrg         return query_renderer_map[i].dri2_attrib;
6401e04c3fSmrg
6501e04c3fSmrg   return -1;
6601e04c3fSmrg}
6701e04c3fSmrg
6801e04c3fSmrg/* Convert internal dri context profile bits into GLX context profile bits */
6901e04c3fSmrgstatic inline void
7001e04c3fSmrgdri_convert_context_profile_bits(int attribute, unsigned int *value)
7101e04c3fSmrg{
7201e04c3fSmrg   if (attribute == GLX_RENDERER_PREFERRED_PROFILE_MESA) {
7301e04c3fSmrg      if (value[0] == (1U << __DRI_API_OPENGL_CORE))
7401e04c3fSmrg         value[0] = GLX_CONTEXT_CORE_PROFILE_BIT_ARB;
7501e04c3fSmrg      else if (value[0] == (1U << __DRI_API_OPENGL))
7601e04c3fSmrg         value[0] = GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB;
7701e04c3fSmrg   }
7801e04c3fSmrg}
7901e04c3fSmrg
8001e04c3fSmrg_X_HIDDEN int
8101e04c3fSmrgdri2_query_renderer_integer(struct glx_screen *base, int attribute,
8201e04c3fSmrg                            unsigned int *value)
8301e04c3fSmrg{
8401e04c3fSmrg   int ret;
8501e04c3fSmrg   struct dri2_screen *const psc = (struct dri2_screen *) base;
8601e04c3fSmrg
8701e04c3fSmrg   /* Even though there are invalid values (and
8801e04c3fSmrg    * dri2_convert_glx_query_renderer_attribs may return -1), the higher level
8901e04c3fSmrg    * GLX code is required to perform the filtering.  Assume that we got a
9001e04c3fSmrg    * good value.
9101e04c3fSmrg    */
9201e04c3fSmrg   const int dri_attribute = dri2_convert_glx_query_renderer_attribs(attribute);
9301e04c3fSmrg
9401e04c3fSmrg   if (psc->rendererQuery == NULL)
9501e04c3fSmrg      return -1;
9601e04c3fSmrg
9701e04c3fSmrg   ret = psc->rendererQuery->queryInteger(psc->driScreen, dri_attribute,
9801e04c3fSmrg                                          value);
9901e04c3fSmrg   dri_convert_context_profile_bits(attribute, value);
10001e04c3fSmrg
10101e04c3fSmrg   return ret;
10201e04c3fSmrg}
10301e04c3fSmrg
10401e04c3fSmrg_X_HIDDEN int
10501e04c3fSmrgdri2_query_renderer_string(struct glx_screen *base, int attribute,
10601e04c3fSmrg                           const char **value)
10701e04c3fSmrg{
10801e04c3fSmrg   struct dri2_screen *const psc = (struct dri2_screen *) base;
10901e04c3fSmrg
11001e04c3fSmrg   /* Even though queryString only accepts a subset of the possible GLX
11101e04c3fSmrg    * queries, the higher level GLX code is required to perform the filtering.
11201e04c3fSmrg    * Assume that we got a good value.
11301e04c3fSmrg    */
11401e04c3fSmrg   const int dri_attribute = dri2_convert_glx_query_renderer_attribs(attribute);
11501e04c3fSmrg
11601e04c3fSmrg   if (psc->rendererQuery == NULL)
11701e04c3fSmrg      return -1;
11801e04c3fSmrg
11901e04c3fSmrg   return psc->rendererQuery->queryString(psc->driScreen, dri_attribute, value);
12001e04c3fSmrg}
12101e04c3fSmrg
12201e04c3fSmrg#if defined(HAVE_DRI3)
12301e04c3fSmrg_X_HIDDEN int
12401e04c3fSmrgdri3_query_renderer_integer(struct glx_screen *base, int attribute,
12501e04c3fSmrg                            unsigned int *value)
12601e04c3fSmrg{
12701e04c3fSmrg   int ret;
12801e04c3fSmrg   struct dri3_screen *const psc = (struct dri3_screen *) base;
12901e04c3fSmrg
13001e04c3fSmrg   /* Even though there are invalid values (and
13101e04c3fSmrg    * dri2_convert_glx_query_renderer_attribs may return -1), the higher level
13201e04c3fSmrg    * GLX code is required to perform the filtering.  Assume that we got a
13301e04c3fSmrg    * good value.
13401e04c3fSmrg    */
13501e04c3fSmrg   const int dri_attribute = dri2_convert_glx_query_renderer_attribs(attribute);
13601e04c3fSmrg
13701e04c3fSmrg   if (psc->rendererQuery == NULL)
13801e04c3fSmrg      return -1;
13901e04c3fSmrg
14001e04c3fSmrg   ret = psc->rendererQuery->queryInteger(psc->driScreen, dri_attribute,
14101e04c3fSmrg                                          value);
14201e04c3fSmrg   dri_convert_context_profile_bits(attribute, value);
14301e04c3fSmrg
14401e04c3fSmrg   return ret;
14501e04c3fSmrg}
14601e04c3fSmrg
14701e04c3fSmrg_X_HIDDEN int
14801e04c3fSmrgdri3_query_renderer_string(struct glx_screen *base, int attribute,
14901e04c3fSmrg                           const char **value)
15001e04c3fSmrg{
15101e04c3fSmrg   struct dri3_screen *const psc = (struct dri3_screen *) base;
15201e04c3fSmrg
15301e04c3fSmrg   /* Even though queryString only accepts a subset of the possible GLX
15401e04c3fSmrg    * queries, the higher level GLX code is required to perform the filtering.
15501e04c3fSmrg    * Assume that we got a good value.
15601e04c3fSmrg    */
15701e04c3fSmrg   const int dri_attribute = dri2_convert_glx_query_renderer_attribs(attribute);
15801e04c3fSmrg
15901e04c3fSmrg   if (psc->rendererQuery == NULL)
16001e04c3fSmrg      return -1;
16101e04c3fSmrg
16201e04c3fSmrg   return psc->rendererQuery->queryString(psc->driScreen, dri_attribute, value);
16301e04c3fSmrg}
16401e04c3fSmrg#endif /* HAVE_DRI3 */
16501e04c3fSmrg
16601e04c3fSmrg_X_HIDDEN int
16701e04c3fSmrgdrisw_query_renderer_integer(struct glx_screen *base, int attribute,
16801e04c3fSmrg                             unsigned int *value)
16901e04c3fSmrg{
17001e04c3fSmrg   int ret;
17101e04c3fSmrg   struct drisw_screen *const psc = (struct drisw_screen *) base;
17201e04c3fSmrg
17301e04c3fSmrg   /* Even though there are invalid values (and
17401e04c3fSmrg    * dri2_convert_glx_query_renderer_attribs may return -1), the higher level
17501e04c3fSmrg    * GLX code is required to perform the filtering.  Assume that we got a
17601e04c3fSmrg    * good value.
17701e04c3fSmrg    */
17801e04c3fSmrg   const int dri_attribute = dri2_convert_glx_query_renderer_attribs(attribute);
17901e04c3fSmrg
18001e04c3fSmrg   if (psc->rendererQuery == NULL)
18101e04c3fSmrg      return -1;
18201e04c3fSmrg
18301e04c3fSmrg   ret = psc->rendererQuery->queryInteger(psc->driScreen, dri_attribute,
18401e04c3fSmrg                                          value);
18501e04c3fSmrg   dri_convert_context_profile_bits(attribute, value);
18601e04c3fSmrg
18701e04c3fSmrg   return ret;
18801e04c3fSmrg}
18901e04c3fSmrg
19001e04c3fSmrg_X_HIDDEN int
19101e04c3fSmrgdrisw_query_renderer_string(struct glx_screen *base, int attribute,
19201e04c3fSmrg                            const char **value)
19301e04c3fSmrg{
19401e04c3fSmrg   struct drisw_screen *const psc = (struct drisw_screen *) base;
19501e04c3fSmrg
19601e04c3fSmrg   /* Even though queryString only accepts a subset of the possible GLX
19701e04c3fSmrg    * queries, the higher level GLX code is required to perform the filtering.
19801e04c3fSmrg    * Assume that we got a good value.
19901e04c3fSmrg    */
20001e04c3fSmrg   const int dri_attribute = dri2_convert_glx_query_renderer_attribs(attribute);
20101e04c3fSmrg
20201e04c3fSmrg   if (psc->rendererQuery == NULL)
20301e04c3fSmrg      return -1;
20401e04c3fSmrg
20501e04c3fSmrg   return psc->rendererQuery->queryString(psc->driScreen, dri_attribute, value);
20601e04c3fSmrg}
20701e04c3fSmrg
20801e04c3fSmrg
20901e04c3fSmrg#endif /* GLX_DIRECT_RENDERING */
210