6279422067e38940ebbfb545c92eb4d8cf5b7ea7
[mesa.git] / src / gallium / winsys / drm / i965 / gem / i965_drm_api.c
1
2 #include <stdio.h>
3 #include "state_tracker/drm_api.h"
4
5 #include "i965_drm_winsys.h"
6 #include "util/u_memory.h"
7
8 #include "i965/brw_context.h" /* XXX: shouldn't be doing this */
9 #include "i965/brw_screen.h" /* XXX: shouldn't be doing this */
10
11 #include "trace/tr_drm.h"
12
13 /*
14 * Helper functions
15 */
16
17
18 static void
19 i965_libdrm_get_device_id(unsigned int *device_id)
20 {
21 char path[512];
22 FILE *file;
23 void *shutup_gcc;
24
25 /*
26 * FIXME: Fix this up to use a drm ioctl or whatever.
27 */
28
29 snprintf(path, sizeof(path), "/sys/class/drm/card0/device/device");
30 file = fopen(path, "r");
31 if (!file) {
32 return;
33 }
34
35 shutup_gcc = fgets(path, sizeof(path), file);
36 sscanf(path, "%x", device_id);
37 fclose(file);
38 }
39
40 static struct i965_libdrm_buffer *
41 i965_libdrm_buffer_from_handle(struct i965_libdrm_winsys *idws,
42 const char* name, unsigned handle)
43 {
44 struct i965_libdrm_buffer *buf = CALLOC_STRUCT(i965_libdrm_buffer);
45 uint32_t tile = 0, swizzle = 0;
46
47 if (BRW_DUMP)
48 debug_printf("%s\n", __FUNCTION__);
49
50 if (!buf)
51 return NULL;
52 pipe_reference_init(&buf->base.reference, 1);
53 buf->bo = drm_intel_bo_gem_create_from_name(idws->gem, name, handle);
54 buf->base.size = buf->bo->size;
55 buf->base.sws = &idws->base;
56 buf->flinked = TRUE;
57 buf->flink = handle;
58
59
60 if (!buf->bo)
61 goto err;
62
63 drm_intel_bo_get_tiling(buf->bo, &tile, &swizzle);
64 if (tile != 0)
65 buf->map_gtt = TRUE;
66
67 return buf;
68
69 err:
70 FREE(buf);
71 return NULL;
72 }
73
74
75 /*
76 * Exported functions
77 */
78
79
80 static struct pipe_texture *
81 i965_libdrm_texture_from_shared_handle(struct drm_api *api,
82 struct pipe_screen *screen,
83 struct pipe_texture *template,
84 const char* name,
85 unsigned pitch,
86 unsigned handle)
87 {
88 /* XXX: this is silly -- there should be a way to get directly from
89 * the "drm_api" struct to ourselves, without peering into
90 * unrelated code:
91 */
92 struct i965_libdrm_winsys *idws = i965_libdrm_winsys(brw_screen(screen)->sws);
93 struct i965_libdrm_buffer *buffer;
94
95 if (BRW_DUMP)
96 debug_printf("%s\n", __FUNCTION__);
97
98 buffer = i965_libdrm_buffer_from_handle(idws, name, handle);
99 if (!buffer)
100 return NULL;
101
102 return brw_texture_blanket_winsys_buffer(screen, template, pitch, &buffer->base);
103 }
104
105
106 static boolean
107 i965_libdrm_shared_handle_from_texture(struct drm_api *api,
108 struct pipe_screen *screen,
109 struct pipe_texture *texture,
110 unsigned *pitch,
111 unsigned *handle)
112 {
113 struct i965_libdrm_buffer *buf = NULL;
114 struct brw_winsys_buffer *buffer = NULL;
115
116 if (BRW_DUMP)
117 debug_printf("%s\n", __FUNCTION__);
118
119 if (!brw_texture_get_winsys_buffer(texture, &buffer, pitch))
120 return FALSE;
121
122 buf = i965_libdrm_buffer(buffer);
123 if (!buf->flinked) {
124 if (drm_intel_bo_flink(buf->bo, &buf->flink))
125 return FALSE;
126 buf->flinked = TRUE;
127 }
128
129 *handle = buf->flink;
130
131 return TRUE;
132 }
133
134 static boolean
135 i965_libdrm_local_handle_from_texture(struct drm_api *api,
136 struct pipe_screen *screen,
137 struct pipe_texture *texture,
138 unsigned *pitch,
139 unsigned *handle)
140 {
141 struct brw_winsys_buffer *buffer = NULL;
142
143 if (BRW_DUMP)
144 debug_printf("%s\n", __FUNCTION__);
145
146 if (!brw_texture_get_winsys_buffer(texture, &buffer, pitch))
147 return FALSE;
148
149 *handle = i965_libdrm_buffer(buffer)->bo->handle;
150
151 return TRUE;
152 }
153
154 static void
155 i965_libdrm_winsys_destroy(struct brw_winsys_screen *iws)
156 {
157 struct i965_libdrm_winsys *idws = i965_libdrm_winsys(iws);
158
159 if (BRW_DUMP)
160 debug_printf("%s\n", __FUNCTION__);
161
162 drm_intel_bufmgr_destroy(idws->gem);
163
164 FREE(idws);
165 }
166
167 static struct pipe_screen *
168 i965_libdrm_create_screen(struct drm_api *api, int drmFD,
169 struct drm_create_screen_arg *arg)
170 {
171 struct i965_libdrm_winsys *idws;
172 unsigned int deviceID;
173
174 debug_printf("%s\n", __FUNCTION__);
175
176 if (arg != NULL) {
177 switch(arg->mode) {
178 case DRM_CREATE_NORMAL:
179 break;
180 default:
181 return NULL;
182 }
183 }
184
185 idws = CALLOC_STRUCT(i965_libdrm_winsys);
186 if (!idws)
187 return NULL;
188
189 i965_libdrm_get_device_id(&deviceID);
190
191 i965_libdrm_winsys_init_buffer_functions(idws);
192
193 idws->fd = drmFD;
194 idws->id = deviceID;
195
196 idws->base.destroy = i965_libdrm_winsys_destroy;
197
198 idws->gem = drm_intel_bufmgr_gem_init(idws->fd, BRW_BATCH_SIZE);
199 drm_intel_bufmgr_gem_enable_reuse(idws->gem);
200
201 idws->send_cmd = !debug_get_bool_option("BRW_NO_HW", FALSE);
202
203 return brw_create_screen(&idws->base, deviceID);
204 }
205
206 static struct pipe_context *
207 i965_libdrm_create_context(struct drm_api *api, struct pipe_screen *screen)
208 {
209 return brw_create_context(screen);
210 }
211
212 static void
213 destroy(struct drm_api *api)
214 {
215 if (BRW_DUMP)
216 debug_printf("%s\n", __FUNCTION__);
217
218 }
219
220 struct drm_api i965_libdrm_api =
221 {
222 .create_context = i965_libdrm_create_context,
223 .create_screen = i965_libdrm_create_screen,
224 .texture_from_shared_handle = i965_libdrm_texture_from_shared_handle,
225 .shared_handle_from_texture = i965_libdrm_shared_handle_from_texture,
226 .local_handle_from_texture = i965_libdrm_local_handle_from_texture,
227 .destroy = destroy,
228 };
229
230 struct drm_api *
231 drm_api_create()
232 {
233 return trace_drm_create(&i965_libdrm_api);
234 }