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 #include "glxclient.h"
24 #include "glx_error.h"
25 
26 #include <assert.h>
27 
28 static Bool
__glXQueryRendererInteger(struct glx_screen * psc,int attribute,unsigned int * value)29 __glXQueryRendererInteger(struct glx_screen *psc, int attribute,
30                           unsigned int *value)
31 {
32    unsigned int values_for_query = 0;
33    unsigned int buffer[32];
34    int err;
35 
36    /* This probably means the caller is trying to use an extension function
37     * that isn't actually supported.
38     */
39    if (psc->vtable->query_renderer_integer == NULL)
40       return False;
41 
42    switch (attribute) {
43    case GLX_RENDERER_VENDOR_ID_MESA:
44    case GLX_RENDERER_DEVICE_ID_MESA:
45       values_for_query = 1;
46       break;
47    case GLX_RENDERER_VERSION_MESA:
48       values_for_query = 3;
49       break;
50    case GLX_RENDERER_ACCELERATED_MESA:
51    case GLX_RENDERER_VIDEO_MEMORY_MESA:
52    case GLX_RENDERER_UNIFIED_MEMORY_ARCHITECTURE_MESA:
53    case GLX_RENDERER_PREFERRED_PROFILE_MESA:
54       values_for_query = 1;
55       break;
56    case GLX_RENDERER_OPENGL_CORE_PROFILE_VERSION_MESA:
57    case GLX_RENDERER_OPENGL_COMPATIBILITY_PROFILE_VERSION_MESA:
58    case GLX_RENDERER_OPENGL_ES_PROFILE_VERSION_MESA:
59    case GLX_RENDERER_OPENGL_ES2_PROFILE_VERSION_MESA:
60       values_for_query = 2;
61       break;
62 
63    default:
64       return False;
65    }
66 
67    err = psc->vtable->query_renderer_integer(psc, attribute, buffer);
68 
69    /* If there was no error, copy the correct number of values from the driver
70     * out to the application.
71     */
72    if (err == 0)
73       memcpy(value, buffer, sizeof(unsigned int) * values_for_query);
74 
75    return err == 0;
76 }
77 
78 _X_HIDDEN Bool
glXQueryRendererIntegerMESA(Display * dpy,int screen,int renderer,int attribute,unsigned int * value)79 glXQueryRendererIntegerMESA(Display *dpy, int screen,
80                             int renderer, int attribute,
81                             unsigned int *value)
82 {
83    struct glx_screen *psc;
84 
85    if (dpy == NULL)
86       return False;
87 
88    /* This probably means the caller passed the wrong display pointer or
89     * screen number.
90     */
91    psc = GetGLXScreenConfigs(dpy, screen);
92    if (psc == NULL)
93       return False;
94 
95    /* Right now only a single renderer per display / screen combination is
96     * supported.
97     */
98    if (renderer != 0)
99       return False;
100 
101    return __glXQueryRendererInteger(psc, attribute, value);
102 }
103 
104 _X_HIDDEN Bool
glXQueryCurrentRendererIntegerMESA(int attribute,unsigned int * value)105 glXQueryCurrentRendererIntegerMESA(int attribute, unsigned int *value)
106 {
107    struct glx_context *gc = __glXGetCurrentContext();
108 
109    if (gc == &dummyContext)
110       return False;
111 
112    return __glXQueryRendererInteger(gc->psc, attribute, value);
113 }
114 
115 static const char *
__glXQueryRendererString(struct glx_screen * psc,int attribute)116 __glXQueryRendererString(struct glx_screen *psc, int attribute)
117 {
118    const char *value;
119    int err;
120 
121    /* This probably means the caller is trying to use an extension function
122     * that isn't actually supported.
123     */
124    if (psc->vtable->query_renderer_integer == NULL)
125       return NULL;
126 
127    switch (attribute) {
128    case GLX_RENDERER_VENDOR_ID_MESA:
129    case GLX_RENDERER_DEVICE_ID_MESA:
130       break;
131    default:
132       return NULL;
133    }
134 
135    err = psc->vtable->query_renderer_string(psc, attribute, &value);
136    return (err == 0) ? value : NULL;
137 }
138 
139 _X_HIDDEN const char *
glXQueryRendererStringMESA(Display * dpy,int screen,int renderer,int attribute)140 glXQueryRendererStringMESA(Display *dpy, int screen,
141                            int renderer, int attribute)
142 {
143    struct glx_screen *psc;
144 
145    if (dpy == NULL)
146       return False;
147 
148    /* This probably means the caller passed the wrong display pointer or
149     * screen number.
150     */
151    psc = GetGLXScreenConfigs(dpy, screen);
152    if (psc == NULL)
153       return False;
154 
155    /* Right now only a single renderer per display / screen combination is
156     * supported.
157     */
158    if (renderer != 0)
159       return False;
160 
161    return __glXQueryRendererString(psc, attribute);
162 }
163 
164 _X_HIDDEN const char *
glXQueryCurrentRendererStringMESA(int attribute)165 glXQueryCurrentRendererStringMESA(int attribute)
166 {
167    struct glx_context *gc = __glXGetCurrentContext();
168 
169    if (gc == &dummyContext)
170       return False;
171 
172    return __glXQueryRendererString(gc->psc, attribute);
173 }
174