w32tex
About: TeX Live provides a comprehensive TeX system including all the major TeX-related programs, macro packages, and fonts that are free software. Windows sources.
  Fossies Dox: w32tex-src.tar.xz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

cairo-drm-radeon.c
Go to the documentation of this file.
1 /* Cairo - a vector graphics library with display and print output
2  *
3  * Copyright © 2009 Chris Wilson
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it either under the terms of the GNU Lesser General Public
7  * License version 2.1 as published by the Free Software Foundation
8  * (the "LGPL") or, at your option, under the terms of the Mozilla
9  * Public License Version 1.1 (the "MPL"). If you do not alter this
10  * notice, a recipient may use your version of this file under either
11  * the MPL or the LGPL.
12  *
13  * You should have received a copy of the LGPL along with this library
14  * in the file COPYING-LGPL-2.1; if not, write to the Free Software
15  * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
16  * You should have received a copy of the MPL along with this library
17  * in the file COPYING-MPL-1.1
18  *
19  * The contents of this file are subject to the Mozilla Public License
20  * Version 1.1 (the "License"); you may not use this file except in
21  * compliance with the License. You may obtain a copy of the License at
22  * http://www.mozilla.org/MPL/
23  *
24  * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
25  * OF ANY KIND, either express or implied. See the LGPL or the MPL for
26  * the specific language governing rights and limitations.
27  *
28  */
29 
30 #include "cairoint.h"
31 
32 #include "cairo-drm-private.h"
34 
35 #include "cairo-error-private.h"
37 
38 #include <sys/ioctl.h>
39 #include <sys/mman.h>
40 #include <errno.h>
41 #include <drm/radeon_drm.h>
42 
44 radeon_info (int fd,
45  uint64_t *gart_size,
46  uint64_t *vram_size)
47 {
48  struct drm_radeon_gem_info info;
49  int ret;
50 
51  ret = ioctl (fd, DRM_IOCTL_RADEON_GEM_INFO, &info);
52  if (ret == -1)
53  return FALSE;
54 
55  if (gart_size != NULL)
56  *gart_size = info.gart_size;
57 
58  if (vram_size != NULL)
59  *vram_size = info.vram_size;
60 
61  return TRUE;
62 }
63 
64 void
66  radeon_bo_t *bo,
67  unsigned long offset,
68  unsigned long size,
69  const void *data)
70 {
71  struct drm_radeon_gem_pwrite pwrite;
72  int ret;
73 
74  memset (&pwrite, 0, sizeof (pwrite));
75  pwrite.handle = bo->base.handle;
76  pwrite.offset = offset;
77  pwrite.size = size;
78  pwrite.data_ptr = (uint64_t) (uintptr_t) data;
79  do {
80  ret = ioctl (device->base.fd, DRM_IOCTL_RADEON_GEM_PWRITE, &pwrite);
81  } while (ret == -1 && errno == EINTR);
82 
83  /* XXX temporary workaround */
84  if (ret == -1 && errno == ENOSYS) {
85  uint8_t *ptr;
86 
87  ptr = radeon_bo_map (device, bo);
88  if (ptr != NULL) {
89  memcpy (ptr + offset, data, size);
90  radeon_bo_unmap (bo);
91  }
92  }
93 }
94 
95 void
97  radeon_bo_t *bo,
98  unsigned long offset,
99  unsigned long size,
100  void *data)
101 {
102  struct drm_radeon_gem_pread pread;
103  int ret;
104 
105  memset (&pread, 0, sizeof (pread));
106  pread.handle = bo->base.handle;
107  pread.offset = offset;
108  pread.size = size;
109  pread.data_ptr = (uint64_t) (uintptr_t) data;
110  do {
111  ret = ioctl (device->base.fd, DRM_IOCTL_RADEON_GEM_PREAD, &pread);
112  } while (ret == -1 && errno == EINTR);
113 
114  /* XXX temporary workaround */
115  if (ret == -1 && errno == ENOSYS) {
116  uint8_t *ptr;
117 
118  ptr = radeon_bo_map (device, bo);
119  if (ptr != NULL) {
120  memcpy (data, ptr + offset, size);
121  radeon_bo_unmap (bo);
122  }
123  }
124 
125  VG (VALGRIND_MAKE_MEM_DEFINED (data, size));
126 }
127 
128 void
130 {
131  struct drm_radeon_gem_wait_idle wait;
132  int ret;
133 
134  wait.handle = bo->base.handle;
135  do {
136  ret = ioctl (device->base.fd, DRM_IOCTL_RADEON_GEM_WAIT_IDLE, &wait);
137  } while (ret == -1 && (errno == EINTR || errno == EBUSY));
138 }
139 
140 void *
142 {
143  struct drm_radeon_gem_mmap mmap_arg;
144  void *ptr;
145  int ret;
146 
147  assert (bo->virtual == NULL);
148 
149  memset (&mmap_arg, 0, sizeof (mmap_arg));
150  mmap_arg.handle = bo->base.handle;
151  mmap_arg.offset = 0;
152  mmap_arg.size = bo->base.size;
153 
154  do {
155  ret = ioctl (device->base.fd, DRM_IOCTL_RADEON_GEM_MMAP, &mmap_arg);
156  } while (ret == -1 && errno == EINTR);
157  if (unlikely (ret != 0)) {
159  return NULL;
160  }
161 
162  VG (VALGRIND_MAKE_MEM_DEFINED (&mmap_arg, sizeof (mmap_arg)));
163 
164  /* and mmap it */
165  ptr = mmap (0, bo->base.size, PROT_READ | PROT_WRITE,
166  MAP_SHARED, device->base.fd,
167  mmap_arg.addr_ptr);
168  if (unlikely (ptr == MAP_FAILED)) {
170  return NULL;
171  }
172 
173  bo->virtual = ptr;
174 
175  /* XXX set_domain? */
176  return bo->virtual;
177 }
178 
179 void
181 {
182  assert (bo->virtual != NULL);
183 
184  munmap (bo->virtual, bo->base.size);
185  bo->virtual = NULL;
186 }
187 
190  uint32_t size,
191  uint32_t initial_domain)
192 {
193  struct drm_radeon_gem_create create;
194  radeon_bo_t *bo;
195  int ret;
196 
197  bo = _cairo_freepool_alloc (&device->bo_pool);
198  if (unlikely (bo == NULL))
199  return NULL;
200 
201  create.size = size;
202  create.alignment = 0;
203  create.initial_domain = initial_domain;
204  create.flags = 0;
205  create.handle = 0;
206 
207  do {
208  ret = ioctl (device->base.fd, DRM_IOCTL_RADEON_GEM_CREATE, &create);
209  } while (ret == -1 && errno == EINTR);
210  if (ret == -1) {
211  _cairo_freepool_free (&device->bo_pool, bo);
212  return NULL;
213  }
214 
215  bo->base.handle = create.handle;
216  bo->base.size = size;
217 
218  bo->virtual = NULL;
219 
220  bo->in_batch = FALSE;
221  bo->read_domains = 0;
222  bo->write_domain = 0;
223 
224  CAIRO_REFERENCE_COUNT_INIT (&bo->base.ref_count, 1);
225  return &bo->base;
226 }
227 
230  uint32_t name)
231 {
232  radeon_bo_t *bo;
234 
235  bo = _cairo_freepool_alloc (&device->bo_pool);
236  if (unlikely (bo == NULL))
237  return NULL;
238 
239  status = _cairo_drm_bo_open_for_name (&device->base, &bo->base, name);
240  if (unlikely (status)) {
241  _cairo_freepool_free (&device->bo_pool, bo);
242  return NULL;
243  }
244 
245  bo->virtual = NULL;
246 
247  bo->in_batch = FALSE;
248  bo->read_domains = 0;
249  bo->write_domain = 0;
250 
252  return &bo->base;
253 }
254 
255 static void
256 radeon_bo_release (void *_dev, void *_bo)
257 {
258  radeon_device_t *device = _dev;
259  radeon_bo_t *bo = _bo;
260 
261  _cairo_drm_bo_close (&device->base, &bo->base);
262  _cairo_freepool_free (&device->bo_pool, bo);
263 }
264 
267  radeon_bo_t *bo,
269 {
271  uint8_t *dst;
272  int size, row;
273 
276  surface->width,
277  surface->height);
278  if (unlikely (image->base.status))
279  return &image->base;
280 
281  if (image->stride == surface->stride) {
282  size = surface->stride * surface->height;
283  radeon_bo_read (device, bo, 0, size, image->data);
284  } else {
285  int offset;
286 
287  size = surface->width;
288  if (surface->format != CAIRO_FORMAT_A8)
289  size *= 4;
290 
291  offset = 0;
292  row = surface->height;
293  dst = image->data;
294  while (row--) {
295  radeon_bo_read (device, bo, offset, size, dst);
296  offset += surface->stride;
297  dst += image->stride;
298  }
299  }
300 
301  return &image->base;
302 }
303 
304 static void
306 {
308 }
309 
312 {
314 
315  device->base.bo.release = radeon_bo_release;
316 
317  return CAIRO_STATUS_SUCCESS;
318 }
319 
320 static void
322 {
323  _cairo_freepool_fini (&device->bo_pool);
324 }
325 
326 void
328 {
329  _radeon_bo_cache_fini (device);
330  _cairo_drm_device_fini (&device->base);
331 }
#define name
#define _cairo_error_throw(status)
void _cairo_freepool_fini(cairo_freepool_t *freepool)
#define VG(x)
static void _cairo_freepool_free(cairo_freepool_t *freepool, void *ptr)
static void * _cairo_freepool_alloc(cairo_freepool_t *freepool)
void _cairo_freepool_init(cairo_freepool_t *freepool, unsigned nodesize)
cairo_surface_t * cairo_image_surface_create(cairo_format_t format, int width, int height)
#define CAIRO_REFERENCE_COUNT_INIT(RC, VALUE)
int cairo_bool_t
Definition: cairo.h:107
@ CAIRO_STATUS_SUCCESS
Definition: cairo.h:315
@ CAIRO_STATUS_NO_MEMORY
Definition: cairo.h:317
enum _cairo_status cairo_status_t
@ CAIRO_FORMAT_A8
Definition: cairo.h:420
void _cairo_drm_bo_close(const cairo_drm_device_t *dev, cairo_drm_bo_t *bo)
Definition: cairo-drm-bo.c:89
cairo_status_t _cairo_drm_bo_open_for_name(const cairo_drm_device_t *dev, cairo_drm_bo_t *bo, uint32_t name)
Definition: cairo-drm-bo.c:41
void _cairo_drm_device_fini(cairo_drm_device_t *device)
Definition: cairo-drm.c:356
void radeon_bo_read(const radeon_device_t *device, radeon_bo_t *bo, unsigned long offset, unsigned long size, void *data)
cairo_bool_t radeon_info(int fd, uint64_t *gart_size, uint64_t *vram_size)
cairo_surface_t * radeon_bo_get_image(const radeon_device_t *device, radeon_bo_t *bo, const cairo_drm_surface_t *surface)
cairo_status_t radeon_device_init(radeon_device_t *device, int fd)
void radeon_bo_wait(const radeon_device_t *device, radeon_bo_t *bo)
cairo_drm_bo_t * radeon_bo_create(radeon_device_t *device, uint32_t size, uint32_t initial_domain)
void * radeon_bo_map(const radeon_device_t *device, radeon_bo_t *bo)
void radeon_bo_unmap(radeon_bo_t *bo)
void radeon_bo_write(const radeon_device_t *device, radeon_bo_t *bo, unsigned long offset, unsigned long size, const void *data)
void radeon_device_fini(radeon_device_t *device)
cairo_drm_bo_t * radeon_bo_create_for_name(radeon_device_t *device, uint32_t name)
static void _radeon_device_init_bo_cache(radeon_device_t *device)
static void radeon_bo_release(void *_dev, void *_bo)
static void _radeon_bo_cache_fini(radeon_device_t *device)
@ FALSE
Definition: dd.h:101
@ TRUE
Definition: dd.h:102
#define info
Definition: dviinfo.c:42
struct rect data
Definition: dvipdfm.c:64
#define memcpy(d, s, n)
Definition: gsftopk.c:64
assert(pcxLoadImage24((char *)((void *) 0), fp, pinfo, hdr))
unsigned char * image
Definition: in_pcx.cpp:323
#define unlikely(x)
Definition: jbig2arith.cc:116
int wait()
#define NULL
Definition: ftobjs.h:61
sizeof(AF_ModuleRec)
unsigned int uint32_t
Definition: stdint.h:80
unsigned int uintptr_t
Definition: stdint.h:119
unsigned char uint8_t
Definition: stdint.h:78
unsigned __int64 uint64_t
Definition: stdint.h:90
int errno
static int ret
Definition: convert.c:72
UnlocalizedNumberFormatter create(const UnicodeString &skeletonString, UParseError *perror, UErrorCode &status)
static cairo_surface_t * surface
Definition: pdftocairo.cc:234
set set set set set set set macro pixldst1 abits if abits op else op endif endm macro pixldst2 abits if abits op else op endif endm macro pixldst4 abits if abits op else op endif endm macro pixldst0 abits op endm macro pixldst3 mem_operand op endm macro pixldst30 mem_operand op endm macro pixldst abits if abits elseif abits elseif abits elseif abits elseif abits pixldst0 abits else pixldst0 abits pixldst0 abits pixldst0 abits pixldst0 abits endif elseif abits else pixldst0 abits pixldst0 abits endif elseif abits else error unsupported bpp *numpix else pixst endif endm macro pixld1_s mem_operand if asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl elseif asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl else error unsupported endif endm macro pixld2_s mem_operand if mov asr add asl add asl mov asr sub UNIT_X add asl mov asr add asl add asl mov asr add UNIT_X add asl else pixld1_s mem_operand pixld1_s mem_operand endif endm macro pixld0_s mem_operand if asr adds SRC_WIDTH_FIXED bpl add asl elseif asr adds SRC_WIDTH_FIXED bpl add asl endif endm macro pixld_s_internal mem_operand if mem_operand pixld2_s mem_operand pixdeinterleave basereg elseif mem_operand elseif mem_operand elseif mem_operand elseif mem_operand pixld0_s mem_operand else pixld0_s mem_operand pixld0_s mem_operand pixld0_s mem_operand pixld0_s mem_operand endif elseif mem_operand else pixld0_s mem_operand pixld0_s mem_operand endif elseif mem_operand else error unsupported mem_operand if bpp mem_operand endif endm macro vuzp8 reg2 vuzp d d &reg2 endm macro vzip8 reg2 vzip d d &reg2 endm macro pixdeinterleave basereg basereg basereg basereg basereg endif endm macro pixinterleave basereg basereg basereg basereg basereg endif endm macro PF boost_increment endif if endif PF tst PF addne PF subne PF cmp ORIG_W if endif if endif if endif PF subge ORIG_W PF subges if endif if endif if endif endif endm macro cache_preload_simple endif if dst_r_bpp pld[DST_R, #(PREFETCH_DISTANCE_SIMPLE *dst_r_bpp/8)] endif if mask_bpp pld if[MASK, #(PREFETCH_DISTANCE_SIMPLE *mask_bpp/8)] endif endif endm macro fetch_mask_pixblock pixld mask_basereg pixblock_size MASK endm macro ensure_destination_ptr_alignment process_pixblock_tail_head if beq irp skip1(dst_w_bpp<=(lowbit *8)) &&((lowbit *8)<(pixblock_size *dst_w_bpp)) .if lowbit< 16 tst DST_R
set set set set set set set set set set set set set set set set set set set set *set set set macro pixldst op &r &cond WK op &r &cond WK op &r &cond WK else op &m &cond &ia op &r &cond WK else op &m &cond &ia elseif elseif else error unsupported base if elseif elseif else error unsupported unaligned pixldst unaligned endm macro pixst base base else pixldst base endif endm macro PF ptr
static int size
Definition: ppmlabel.c:24
static int offset
Definition: ppmtogif.c:642
bstring c int memset(void *s, int c, int length)
static int row
Definition: ps2pk.c:587
#define status
#define uint64_t
Definition: stdint.in.h:215
void(* release)(void *device, void *bo)
cairo_reference_count_t ref_count
cairo_drm_bo_backend_t bo
cairo_bool_t in_batch
cairo_drm_bo_t base
cairo_freepool_t bo_pool
cairo_drm_device_t base
Definition: sd.h:76
#define MAP_FAILED
Definition: umapfile.cpp:77