03dba5034739a9a78679126e4d9d4736bdc710d2
[platform/upstream/libdrm.git] / intel / intel_bufmgr.c
1 /*
2  * Copyright © 2007 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 DEALINGS
21  * IN THE SOFTWARE.
22  *
23  * Authors:
24  *    Eric Anholt <eric@anholt.net>
25  *
26  */
27
28 #ifdef HAVE_CONFIG_H
29 #include "config.h"
30 #endif
31
32 #include <string.h>
33 #include <stdlib.h>
34 #include <stdint.h>
35 #include <assert.h>
36 #include <errno.h>
37 #include <drm.h>
38 #include <i915_drm.h>
39 #include <pciaccess.h>
40 #include "libdrm.h"
41 #include "intel_bufmgr.h"
42 #include "intel_bufmgr_priv.h"
43 #include "xf86drm.h"
44
45 /** @file intel_bufmgr.c
46  *
47  * Convenience functions for buffer management methods.
48  */
49
50 drm_public drm_intel_bo *
51 drm_intel_bo_alloc(drm_intel_bufmgr *bufmgr, const char *name,
52                    unsigned long size, unsigned int alignment)
53 {
54         return bufmgr->bo_alloc(bufmgr, name, size, alignment);
55 }
56
57 drm_public drm_intel_bo *
58 drm_intel_bo_alloc_for_render(drm_intel_bufmgr *bufmgr, const char *name,
59                               unsigned long size, unsigned int alignment)
60 {
61         return bufmgr->bo_alloc_for_render(bufmgr, name, size, alignment);
62 }
63
64 drm_public drm_intel_bo *
65 drm_intel_bo_alloc_tiled(drm_intel_bufmgr *bufmgr, const char *name,
66                         int x, int y, int cpp, uint32_t *tiling_mode,
67                         unsigned long *pitch, unsigned long flags)
68 {
69         return bufmgr->bo_alloc_tiled(bufmgr, name, x, y, cpp,
70                                       tiling_mode, pitch, flags);
71 }
72
73 drm_public void
74 drm_intel_bo_reference(drm_intel_bo *bo)
75 {
76         bo->bufmgr->bo_reference(bo);
77 }
78
79 drm_public void
80 drm_intel_bo_unreference(drm_intel_bo *bo)
81 {
82         if (bo == NULL)
83                 return;
84
85         bo->bufmgr->bo_unreference(bo);
86 }
87
88 drm_public int
89 drm_intel_bo_map(drm_intel_bo *buf, int write_enable)
90 {
91         return buf->bufmgr->bo_map(buf, write_enable);
92 }
93
94 drm_public int
95 drm_intel_bo_unmap(drm_intel_bo *buf)
96 {
97         return buf->bufmgr->bo_unmap(buf);
98 }
99
100 drm_public int
101 drm_intel_bo_subdata(drm_intel_bo *bo, unsigned long offset,
102                      unsigned long size, const void *data)
103 {
104         return bo->bufmgr->bo_subdata(bo, offset, size, data);
105 }
106
107 drm_public int
108 drm_intel_bo_get_subdata(drm_intel_bo *bo, unsigned long offset,
109                          unsigned long size, void *data)
110 {
111         int ret;
112         if (bo->bufmgr->bo_get_subdata)
113                 return bo->bufmgr->bo_get_subdata(bo, offset, size, data);
114
115         if (size == 0 || data == NULL)
116                 return 0;
117
118         ret = drm_intel_bo_map(bo, 0);
119         if (ret)
120                 return ret;
121         memcpy(data, (unsigned char *)bo->virtual + offset, size);
122         drm_intel_bo_unmap(bo);
123         return 0;
124 }
125
126 drm_public void
127 drm_intel_bo_wait_rendering(drm_intel_bo *bo)
128 {
129         bo->bufmgr->bo_wait_rendering(bo);
130 }
131
132 drm_public void
133 drm_intel_bufmgr_destroy(drm_intel_bufmgr *bufmgr)
134 {
135         bufmgr->destroy(bufmgr);
136 }
137
138 drm_public int
139 drm_intel_bo_exec(drm_intel_bo *bo, int used,
140                   drm_clip_rect_t * cliprects, int num_cliprects, int DR4)
141 {
142         return bo->bufmgr->bo_exec(bo, used, cliprects, num_cliprects, DR4);
143 }
144
145 drm_public int
146 drm_intel_bo_mrb_exec(drm_intel_bo *bo, int used,
147                 drm_clip_rect_t *cliprects, int num_cliprects, int DR4,
148                 unsigned int rings)
149 {
150         if (bo->bufmgr->bo_mrb_exec)
151                 return bo->bufmgr->bo_mrb_exec(bo, used,
152                                         cliprects, num_cliprects, DR4,
153                                         rings);
154
155         switch (rings) {
156         case I915_EXEC_DEFAULT:
157         case I915_EXEC_RENDER:
158                 return bo->bufmgr->bo_exec(bo, used,
159                                            cliprects, num_cliprects, DR4);
160         default:
161                 return -ENODEV;
162         }
163 }
164
165 drm_public void
166 drm_intel_bufmgr_set_debug(drm_intel_bufmgr *bufmgr, int enable_debug)
167 {
168         bufmgr->debug = enable_debug;
169 }
170
171 drm_public int
172 drm_intel_bufmgr_check_aperture_space(drm_intel_bo ** bo_array, int count)
173 {
174         return bo_array[0]->bufmgr->check_aperture_space(bo_array, count);
175 }
176
177 drm_public int
178 drm_intel_bo_flink(drm_intel_bo *bo, uint32_t * name)
179 {
180         if (bo->bufmgr->bo_flink)
181                 return bo->bufmgr->bo_flink(bo, name);
182
183         return -ENODEV;
184 }
185
186 drm_public int
187 drm_intel_bo_emit_reloc(drm_intel_bo *bo, uint32_t offset,
188                         drm_intel_bo *target_bo, uint32_t target_offset,
189                         uint32_t read_domains, uint32_t write_domain)
190 {
191         return bo->bufmgr->bo_emit_reloc(bo, offset,
192                                          target_bo, target_offset,
193                                          read_domains, write_domain);
194 }
195
196 /* For fence registers, not GL fences */
197 drm_public int
198 drm_intel_bo_emit_reloc_fence(drm_intel_bo *bo, uint32_t offset,
199                               drm_intel_bo *target_bo, uint32_t target_offset,
200                               uint32_t read_domains, uint32_t write_domain)
201 {
202         return bo->bufmgr->bo_emit_reloc_fence(bo, offset,
203                                                target_bo, target_offset,
204                                                read_domains, write_domain);
205 }
206
207
208 drm_public int
209 drm_intel_bo_pin(drm_intel_bo *bo, uint32_t alignment)
210 {
211         if (bo->bufmgr->bo_pin)
212                 return bo->bufmgr->bo_pin(bo, alignment);
213
214         return -ENODEV;
215 }
216
217 drm_public int
218 drm_intel_bo_unpin(drm_intel_bo *bo)
219 {
220         if (bo->bufmgr->bo_unpin)
221                 return bo->bufmgr->bo_unpin(bo);
222
223         return -ENODEV;
224 }
225
226 drm_public int
227 drm_intel_bo_set_tiling(drm_intel_bo *bo, uint32_t * tiling_mode,
228                         uint32_t stride)
229 {
230         if (bo->bufmgr->bo_set_tiling)
231                 return bo->bufmgr->bo_set_tiling(bo, tiling_mode, stride);
232
233         *tiling_mode = I915_TILING_NONE;
234         return 0;
235 }
236
237 drm_public int
238 drm_intel_bo_get_tiling(drm_intel_bo *bo, uint32_t * tiling_mode,
239                         uint32_t * swizzle_mode)
240 {
241         if (bo->bufmgr->bo_get_tiling)
242                 return bo->bufmgr->bo_get_tiling(bo, tiling_mode, swizzle_mode);
243
244         *tiling_mode = I915_TILING_NONE;
245         *swizzle_mode = I915_BIT_6_SWIZZLE_NONE;
246         return 0;
247 }
248
249 drm_public int
250 drm_intel_bo_disable_reuse(drm_intel_bo *bo)
251 {
252         if (bo->bufmgr->bo_disable_reuse)
253                 return bo->bufmgr->bo_disable_reuse(bo);
254         return 0;
255 }
256
257 drm_public int
258 drm_intel_bo_is_reusable(drm_intel_bo *bo)
259 {
260         if (bo->bufmgr->bo_is_reusable)
261                 return bo->bufmgr->bo_is_reusable(bo);
262         return 0;
263 }
264
265 drm_public int
266 drm_intel_bo_busy(drm_intel_bo *bo)
267 {
268         if (bo->bufmgr->bo_busy)
269                 return bo->bufmgr->bo_busy(bo);
270         return 0;
271 }
272
273 drm_public int
274 drm_intel_bo_madvise(drm_intel_bo *bo, int madv)
275 {
276         if (bo->bufmgr->bo_madvise)
277                 return bo->bufmgr->bo_madvise(bo, madv);
278         return -1;
279 }
280
281 drm_public int
282 drm_intel_bo_references(drm_intel_bo *bo, drm_intel_bo *target_bo)
283 {
284         return bo->bufmgr->bo_references(bo, target_bo);
285 }
286
287 drm_public int
288 drm_intel_get_pipe_from_crtc_id(drm_intel_bufmgr *bufmgr, int crtc_id)
289 {
290         if (bufmgr->get_pipe_from_crtc_id)
291                 return bufmgr->get_pipe_from_crtc_id(bufmgr, crtc_id);
292         return -1;
293 }
294
295 static size_t
296 drm_intel_probe_agp_aperture_size(int fd)
297 {
298         struct pci_device *pci_dev;
299         size_t size = 0;
300         int ret;
301
302         ret = pci_system_init();
303         if (ret)
304                 goto err;
305
306         /* XXX handle multiple adaptors? */
307         pci_dev = pci_device_find_by_slot(0, 0, 2, 0);
308         if (pci_dev == NULL)
309                 goto err;
310
311         ret = pci_device_probe(pci_dev);
312         if (ret)
313                 goto err;
314
315         size = pci_dev->regions[2].size;
316 err:
317         pci_system_cleanup ();
318         return size;
319 }
320
321 drm_public int
322 drm_intel_get_aperture_sizes(int fd, size_t *mappable, size_t *total)
323 {
324
325         struct drm_i915_gem_get_aperture aperture;
326         int ret;
327
328         ret = drmIoctl(fd, DRM_IOCTL_I915_GEM_GET_APERTURE, &aperture);
329         if (ret)
330                 return ret;
331
332         *mappable = 0;
333         /* XXX add a query for the kernel value? */
334         if (*mappable == 0)
335                 *mappable = drm_intel_probe_agp_aperture_size(fd);
336         if (*mappable == 0)
337                 *mappable = 64 * 1024 * 1024; /* minimum possible value */
338         *total = aperture.aper_size;
339         return 0;
340 }