1 /**************************************************************************
2 *
3 * Copyright (C) 2016 Red Hat Inc.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be included
13 * in all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
16 * OR 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
19 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
20 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
21 * OTHER DEALINGS IN THE SOFTWARE.
22 *
23 **************************************************************************/
24
25
26 #ifdef HAVE_CONFIG_H
27 #include "config.h"
28 #endif
29
30 #include <epoxy/glx.h>
31 #include "virglrenderer.h"
32 #include "vrend_winsys_glx.h"
33
34 struct virgl_glx {
35 Display *display;
36 GLXFBConfig* fbConfigs;
37 GLXPbuffer pbuffer;
38 };
39
virgl_glx_init(void)40 struct virgl_glx *virgl_glx_init(void)
41 {
42 struct virgl_glx *d;
43
44 d = malloc(sizeof(struct virgl_glx));
45 if (!d)
46 return NULL;
47
48 d->display = XOpenDisplay(NULL);
49
50 if (!d->display) {
51 free(d);
52 return NULL;
53 }
54
55 int visualAttribs[] = { None };
56 int numberOfFramebufferConfigurations = 0;
57
58 d->fbConfigs = glXChooseFBConfig(d->display, DefaultScreen(d->display),
59 visualAttribs, &numberOfFramebufferConfigurations);
60
61 int pbufferAttribs[] = {
62 GLX_PBUFFER_WIDTH, 32,
63 GLX_PBUFFER_HEIGHT, 32,
64 None
65 };
66 d->pbuffer = glXCreatePbuffer(d->display, d->fbConfigs[0], pbufferAttribs);
67
68 return d;
69 }
70
virgl_glx_destroy(struct virgl_glx * d)71 void virgl_glx_destroy(struct virgl_glx *d)
72 {
73 XFree(d->fbConfigs);
74 glXDestroyPbuffer(d->display,d->pbuffer);
75 XCloseDisplay(d->display);
76 free(d);
77 }
78
virgl_glx_create_context(struct virgl_glx * d,struct virgl_gl_ctx_param * vparams)79 virgl_renderer_gl_context virgl_glx_create_context(struct virgl_glx *d, struct virgl_gl_ctx_param *vparams)
80 {
81 int context_attribs[] = {
82 GLX_CONTEXT_MAJOR_VERSION_ARB, vparams->major_ver,
83 GLX_CONTEXT_MINOR_VERSION_ARB, vparams->minor_ver,
84 None
85 };
86
87 GLXContext ctx =
88 glXCreateContextAttribsARB(d->display, d->fbConfigs[0],
89 vparams->shared ? glXGetCurrentContext() : NULL,
90 True, context_attribs);
91 return (virgl_renderer_gl_context)ctx;
92 }
93
virgl_glx_destroy_context(struct virgl_glx * d,virgl_renderer_gl_context virglctx)94 void virgl_glx_destroy_context(struct virgl_glx *d, virgl_renderer_gl_context virglctx)
95 {
96 GLXContext ctx = (GLXContext)virglctx;
97
98 glXDestroyContext(d->display,ctx);
99 }
100
virgl_glx_make_context_current(struct virgl_glx * d,virgl_renderer_gl_context virglctx)101 int virgl_glx_make_context_current(struct virgl_glx *d, virgl_renderer_gl_context virglctx)
102 {
103 return glXMakeContextCurrent(d->display, d->pbuffer, d->pbuffer, virglctx) ? 0 : -1;
104 }
105
virgl_glx_query_video_memory(struct virgl_glx * d)106 uint32_t virgl_glx_query_video_memory(struct virgl_glx *d)
107 {
108 uint32_t video_memory = 0;
109 if (d) {
110 if (epoxy_has_glx_extension(d->display, DefaultScreen(d->display), "GLX_MESA_query_renderer")) {
111 glXQueryCurrentRendererIntegerMESA(GLX_RENDERER_VIDEO_MEMORY_MESA, &video_memory);
112 }
113 }
114
115 return video_memory;
116 }
117