1 #include <stdlib.h>
2 #include <fcntl.h>
3 #include <unistd.h>
4 #include <sys/mman.h>
5 #include <assert.h>
6
7 #include <xf86drm.h>
8
9 #include "X11/Xlib.h"
10 #include "va.h"
11 #include "va_backend.h"
12
13 #include "va_dri.h"
14 #include "va_dricommon.h"
15
16 struct dri1_drawable
17 {
18 struct dri_drawable base;
19 union dri_buffer buffer;
20 int width;
21 int height;
22 };
23
24 static struct dri_drawable *
dri1CreateDrawable(VADriverContextP ctx,XID x_drawable)25 dri1CreateDrawable(VADriverContextP ctx, XID x_drawable)
26 {
27 struct dri1_drawable *dri1_drawable;
28
29 dri1_drawable = calloc(1, sizeof(*dri1_drawable));
30
31 if (!dri1_drawable)
32 return NULL;
33
34 dri1_drawable->base.x_drawable = x_drawable;
35
36 return &dri1_drawable->base;
37 }
38
39 static void
dri1DestroyDrawable(VADriverContextP ctx,struct dri_drawable * dri_drawable)40 dri1DestroyDrawable(VADriverContextP ctx, struct dri_drawable *dri_drawable)
41 {
42 free(dri_drawable);
43 }
44
45 static void
dri1SwapBuffer(VADriverContextP ctx,struct dri_drawable * dri_drawable)46 dri1SwapBuffer(VADriverContextP ctx, struct dri_drawable *dri_drawable)
47 {
48
49 }
50
51 static union dri_buffer *
dri1GetRenderingBuffer(VADriverContextP ctx,struct dri_drawable * dri_drawable)52 dri1GetRenderingBuffer(VADriverContextP ctx, struct dri_drawable *dri_drawable)
53 {
54 struct dri1_drawable *dri1_drawable = (struct dri1_drawable *)dri_drawable;
55
56 return &dri1_drawable->buffer;
57 }
58
59 static void
dri1Close(VADriverContextP ctx)60 dri1Close(VADriverContextP ctx)
61 {
62 struct dri_state *dri_state = (struct dri_state *)ctx->drm_state;
63
64 free_drawable_hashtable(ctx);
65 VA_DRIDestroyContext(ctx->native_dpy, ctx->x11_screen, dri_state->hwContextID);
66 assert(dri_state->pSAREA != MAP_FAILED);
67 drmUnmap(dri_state->pSAREA, SAREA_MAX);
68 assert(dri_state->base.fd >= 0);
69 drmCloseOnce(dri_state->base.fd);
70 VA_DRICloseConnection(ctx->native_dpy, ctx->x11_screen);
71 }
72
73 Bool
isDRI1Connected(VADriverContextP ctx,char ** driver_name)74 isDRI1Connected(VADriverContextP ctx, char **driver_name)
75 {
76 struct dri_state *dri_state = (struct dri_state *)ctx->drm_state;
77 int direct_capable;
78 int driver_major;
79 int driver_minor;
80 int driver_patch;
81 int newlyopened;
82 char *BusID;
83 drm_magic_t magic;
84
85 *driver_name = NULL;
86 dri_state->base.fd = -1;
87 dri_state->pSAREA = MAP_FAILED;
88 dri_state->base.auth_type = VA_NONE;
89
90 if (!VA_DRIQueryDirectRenderingCapable(ctx->native_dpy,
91 ctx->x11_screen,
92 &direct_capable))
93 goto err_out0;
94
95 if (!direct_capable)
96 goto err_out0;
97
98 if (!VA_DRIGetClientDriverName(ctx->native_dpy, ctx->x11_screen,
99 &driver_major, &driver_minor,
100 &driver_patch, driver_name))
101 goto err_out0;
102
103 if (!VA_DRIOpenConnection(ctx->native_dpy, ctx->x11_screen,
104 &dri_state->hSAREA, &BusID))
105 goto err_out0;
106
107
108 dri_state->base.fd = drmOpenOnce(NULL, BusID, &newlyopened);
109 XFree(BusID);
110
111 if (dri_state->base.fd < 0)
112 goto err_out1;
113
114
115 if (drmGetMagic(dri_state->base.fd, &magic))
116 goto err_out1;
117
118 if (newlyopened && !VA_DRIAuthConnection(ctx->native_dpy, ctx->x11_screen, magic))
119 goto err_out1;
120
121 if (drmMap(dri_state->base.fd, dri_state->hSAREA, SAREA_MAX, &dri_state->pSAREA))
122 goto err_out1;
123
124 if (!VA_DRICreateContext(ctx->native_dpy, ctx->x11_screen,
125 DefaultVisual(ctx->native_dpy, ctx->x11_screen),
126 &dri_state->hwContextID, &dri_state->hwContext))
127 goto err_out1;
128
129 dri_state->base.auth_type = VA_DRI1;
130 dri_state->createDrawable = dri1CreateDrawable;
131 dri_state->destroyDrawable = dri1DestroyDrawable;
132 dri_state->swapBuffer = dri1SwapBuffer;
133 dri_state->getRenderingBuffer = dri1GetRenderingBuffer;
134 dri_state->close = dri1Close;
135
136 return True;
137
138 err_out1:
139 if (dri_state->pSAREA != MAP_FAILED)
140 drmUnmap(dri_state->pSAREA, SAREA_MAX);
141
142 if (dri_state->base.fd >= 0)
143 drmCloseOnce(dri_state->base.fd);
144
145 VA_DRICloseConnection(ctx->native_dpy, ctx->x11_screen);
146
147 err_out0:
148 if (*driver_name)
149 XFree(*driver_name);
150
151 dri_state->pSAREA = MAP_FAILED;
152 dri_state->base.fd = -1;
153 *driver_name = NULL;
154
155 return False;
156 }
157
158