Merge branch 'mesa_7_5_branch' into mesa_7_6_branch
[mesa.git] / src / gallium / winsys / drm / intel / gem / intel_drm_api.c
1
2 #include "state_tracker/drm_api.h"
3
4 #include "intel_drm_winsys.h"
5 #include "util/u_memory.h"
6
7 #include "i915simple/i915_context.h"
8 #include "i915simple/i915_screen.h"
9
10
11 /*
12 * Helper functions
13 */
14
15
16 static void
17 intel_drm_get_device_id(unsigned int *device_id)
18 {
19 char path[512];
20 FILE *file;
21 void *shutup_gcc;
22
23 /*
24 * FIXME: Fix this up to use a drm ioctl or whatever.
25 */
26
27 snprintf(path, sizeof(path), "/sys/class/drm/card0/device/device");
28 file = fopen(path, "r");
29 if (!file) {
30 return;
31 }
32
33 shutup_gcc = fgets(path, sizeof(path), file);
34 sscanf(path, "%x", device_id);
35 fclose(file);
36 }
37
38 static struct intel_buffer *
39 intel_drm_buffer_from_handle(struct intel_drm_winsys *idws,
40 const char* name, unsigned handle)
41 {
42 struct intel_drm_buffer *buf = CALLOC_STRUCT(intel_drm_buffer);
43
44 if (!buf)
45 return NULL;
46
47 buf->magic = 0xDEAD1337;
48 buf->bo = drm_intel_bo_gem_create_from_name(idws->pools.gem, name, handle);
49 buf->flinked = TRUE;
50 buf->flink = handle;
51
52 if (!buf->bo)
53 goto err;
54
55 return (struct intel_buffer *)buf;
56
57 err:
58 FREE(buf);
59 return NULL;
60 }
61
62
63 /*
64 * Exported functions
65 */
66
67
68 static struct pipe_texture *
69 intel_drm_texture_from_shared_handle(struct drm_api *api,
70 struct pipe_screen *screen,
71 struct pipe_texture *templ,
72 const char* name,
73 unsigned pitch,
74 unsigned handle)
75 {
76 struct intel_drm_winsys *idws = intel_drm_winsys(i915_screen(screen)->iws);
77 struct intel_buffer *buffer;
78
79 buffer = intel_drm_buffer_from_handle(idws, name, handle);
80 if (!buffer)
81 return NULL;
82
83 return i915_texture_blanket_intel(screen, templ, pitch, buffer);
84 }
85
86 static boolean
87 intel_drm_shared_handle_from_texture(struct drm_api *api,
88 struct pipe_screen *screen,
89 struct pipe_texture *texture,
90 unsigned *pitch,
91 unsigned *handle)
92 {
93 struct intel_drm_buffer *buf = NULL;
94 struct intel_buffer *buffer = NULL;
95 if (!i915_get_texture_buffer_intel(texture, &buffer, pitch))
96 return FALSE;
97
98 buf = intel_drm_buffer(buffer);
99 if (!buf->flinked) {
100 if (drm_intel_bo_flink(buf->bo, &buf->flink))
101 return FALSE;
102 buf->flinked = TRUE;
103 }
104
105 *handle = buf->flink;
106
107 return TRUE;
108 }
109
110 static boolean
111 intel_drm_local_handle_from_texture(struct drm_api *api,
112 struct pipe_screen *screen,
113 struct pipe_texture *texture,
114 unsigned *pitch,
115 unsigned *handle)
116 {
117 struct intel_buffer *buffer = NULL;
118 if (!i915_get_texture_buffer_intel(texture, &buffer, pitch))
119 return FALSE;
120
121 *handle = intel_drm_buffer(buffer)->bo->handle;
122
123 return TRUE;
124 }
125
126 static void
127 intel_drm_winsys_destroy(struct intel_winsys *iws)
128 {
129 struct intel_drm_winsys *idws = intel_drm_winsys(iws);
130
131 drm_intel_bufmgr_destroy(idws->pools.gem);
132
133 FREE(idws);
134 }
135
136 static struct pipe_screen *
137 intel_drm_create_screen(struct drm_api *api, int drmFD,
138 struct drm_create_screen_arg *arg)
139 {
140 struct intel_drm_winsys *idws;
141 unsigned int deviceID;
142
143 if (arg != NULL) {
144 switch(arg->mode) {
145 case DRM_CREATE_NORMAL:
146 break;
147 default:
148 return NULL;
149 }
150 }
151
152 idws = CALLOC_STRUCT(intel_drm_winsys);
153 if (!idws)
154 return NULL;
155
156 intel_drm_get_device_id(&deviceID);
157
158 intel_drm_winsys_init_batchbuffer_functions(idws);
159 intel_drm_winsys_init_buffer_functions(idws);
160 intel_drm_winsys_init_fence_functions(idws);
161
162 idws->fd = drmFD;
163 idws->id = deviceID;
164 idws->max_batch_size = 16 * 4096;
165
166 idws->base.destroy = intel_drm_winsys_destroy;
167
168 idws->pools.gem = drm_intel_bufmgr_gem_init(idws->fd, idws->max_batch_size);
169
170 idws->softpipe = FALSE;
171 idws->dump_cmd = debug_get_bool_option("INTEL_DUMP_CMD", FALSE);
172
173 return i915_create_screen(&idws->base, deviceID);
174 }
175
176 static struct pipe_context *
177 intel_drm_create_context(struct drm_api *api, struct pipe_screen *screen)
178 {
179 return i915_create_context(screen);
180 }
181
182 static void
183 destroy(struct drm_api *api)
184 {
185
186 }
187
188 struct drm_api intel_drm_api =
189 {
190 .create_context = intel_drm_create_context,
191 .create_screen = intel_drm_create_screen,
192 .texture_from_shared_handle = intel_drm_texture_from_shared_handle,
193 .shared_handle_from_texture = intel_drm_shared_handle_from_texture,
194 .local_handle_from_texture = intel_drm_local_handle_from_texture,
195 .destroy = destroy,
196 };
197
198 struct drm_api *
199 drm_api_create()
200 {
201 return &intel_drm_api;
202 }