You can subscribe to this list here.
| 1999 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
(59) |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 2000 |
Jan
(467) |
Feb
(445) |
Mar
(274) |
Apr
(212) |
May
(526) |
Jun
(365) |
Jul
(299) |
Aug
(239) |
Sep
(255) |
Oct
(268) |
Nov
(183) |
Dec
(120) |
| 2001 |
Jan
(174) |
Feb
(221) |
Mar
(316) |
Apr
(196) |
May
(195) |
Jun
(163) |
Jul
(39) |
Aug
(81) |
Sep
(62) |
Oct
(73) |
Nov
(77) |
Dec
(56) |
| 2002 |
Jan
(36) |
Feb
(130) |
Mar
(129) |
Apr
(170) |
May
(151) |
Jun
(183) |
Jul
(199) |
Aug
(192) |
Sep
(171) |
Oct
(188) |
Nov
(194) |
Dec
(119) |
| 2003 |
Jan
(119) |
Feb
(165) |
Mar
(198) |
Apr
(284) |
May
(277) |
Jun
(204) |
Jul
(67) |
Aug
(78) |
Sep
(201) |
Oct
(100) |
Nov
(30) |
Dec
(170) |
| 2004 |
Jan
(69) |
Feb
(111) |
Mar
(82) |
Apr
(88) |
May
(63) |
Jun
(56) |
Jul
(30) |
Aug
(59) |
Sep
(57) |
Oct
(58) |
Nov
(39) |
Dec
(18) |
| 2005 |
Jan
(44) |
Feb
(34) |
Mar
(22) |
Apr
(12) |
May
(16) |
Jun
(54) |
Jul
(15) |
Aug
(44) |
Sep
(24) |
Oct
(21) |
Nov
(57) |
Dec
(13) |
| 2006 |
Jan
(37) |
Feb
(36) |
Mar
(45) |
Apr
(11) |
May
(12) |
Jun
(16) |
Jul
(11) |
Aug
(55) |
Sep
(44) |
Oct
(43) |
Nov
(23) |
Dec
(34) |
| 2007 |
Jan
(59) |
Feb
(42) |
Mar
(38) |
Apr
(109) |
May
(45) |
Jun
(54) |
Jul
(65) |
Aug
(75) |
Sep
(44) |
Oct
(95) |
Nov
(82) |
Dec
(41) |
| 2008 |
Jan
(58) |
Feb
(64) |
Mar
(82) |
Apr
(37) |
May
(51) |
Jun
(112) |
Jul
(95) |
Aug
(53) |
Sep
(34) |
Oct
(43) |
Nov
(21) |
Dec
(25) |
| 2009 |
Jan
(25) |
Feb
(94) |
Mar
(46) |
Apr
(20) |
May
(16) |
Jun
(10) |
Jul
(20) |
Aug
(17) |
Sep
(8) |
Oct
(22) |
Nov
(29) |
Dec
(27) |
| 2010 |
Jan
(22) |
Feb
(19) |
Mar
(22) |
Apr
(10) |
May
(6) |
Jun
(14) |
Jul
(2) |
Aug
(4) |
Sep
(8) |
Oct
(6) |
Nov
(4) |
Dec
(6) |
| 2011 |
Jan
(2) |
Feb
(4) |
Mar
(5) |
Apr
(2) |
May
(1) |
Jun
(3) |
Jul
(2) |
Aug
(1) |
Sep
(6) |
Oct
(6) |
Nov
(3) |
Dec
(16) |
| 2012 |
Jan
(9) |
Feb
(13) |
Mar
(14) |
Apr
(8) |
May
(7) |
Jun
(22) |
Jul
(7) |
Aug
(19) |
Sep
(8) |
Oct
(9) |
Nov
(9) |
Dec
|
| 2013 |
Jan
(14) |
Feb
(7) |
Mar
(12) |
Apr
(11) |
May
(9) |
Jun
(4) |
Jul
(6) |
Aug
(4) |
Sep
(8) |
Oct
(5) |
Nov
(19) |
Dec
(6) |
| 2014 |
Jan
(14) |
Feb
(1) |
Mar
(4) |
Apr
(9) |
May
(7) |
Jun
(4) |
Jul
(10) |
Aug
(5) |
Sep
(17) |
Oct
|
Nov
(7) |
Dec
|
| 2015 |
Jan
(9) |
Feb
(10) |
Mar
(25) |
Apr
(8) |
May
(11) |
Jun
(5) |
Jul
(5) |
Aug
(32) |
Sep
(15) |
Oct
(4) |
Nov
(6) |
Dec
(6) |
| 2016 |
Jan
(9) |
Feb
(11) |
Mar
(3) |
Apr
(7) |
May
(1) |
Jun
(6) |
Jul
(13) |
Aug
(4) |
Sep
(8) |
Oct
(8) |
Nov
(16) |
Dec
(5) |
| 2017 |
Jan
(17) |
Feb
(6) |
Mar
(8) |
Apr
(29) |
May
(9) |
Jun
(11) |
Jul
(8) |
Aug
(13) |
Sep
(5) |
Oct
(21) |
Nov
(16) |
Dec
(9) |
| 2018 |
Jan
(19) |
Feb
(27) |
Mar
(24) |
Apr
(4) |
May
(8) |
Jun
(2) |
Jul
(7) |
Aug
(21) |
Sep
(55) |
Oct
(11) |
Nov
(5) |
Dec
(6) |
| 2019 |
Jan
(7) |
Feb
(9) |
Mar
(5) |
Apr
(9) |
May
(3) |
Jun
(7) |
Jul
(8) |
Aug
(2) |
Sep
(4) |
Oct
(11) |
Nov
(8) |
Dec
(12) |
| 2020 |
Jan
(7) |
Feb
(5) |
Mar
(4) |
Apr
(12) |
May
(9) |
Jun
(3) |
Jul
(1) |
Aug
(4) |
Sep
(1) |
Oct
|
Nov
(3) |
Dec
(7) |
| 2021 |
Jan
(9) |
Feb
(9) |
Mar
(6) |
Apr
(12) |
May
(4) |
Jun
(8) |
Jul
(5) |
Aug
(6) |
Sep
(7) |
Oct
(3) |
Nov
(12) |
Dec
(6) |
| 2022 |
Jan
(5) |
Feb
(4) |
Mar
(6) |
Apr
(3) |
May
(4) |
Jun
(5) |
Jul
(8) |
Aug
(16) |
Sep
(1) |
Oct
(7) |
Nov
(8) |
Dec
(2) |
| 2023 |
Jan
(1) |
Feb
(5) |
Mar
(4) |
Apr
|
May
(2) |
Jun
|
Jul
(6) |
Aug
(4) |
Sep
(13) |
Oct
(7) |
Nov
(6) |
Dec
(2) |
| 2024 |
Jan
(5) |
Feb
(8) |
Mar
(5) |
Apr
(3) |
May
(2) |
Jun
(13) |
Jul
(2) |
Aug
(5) |
Sep
(4) |
Oct
(3) |
Nov
|
Dec
(2) |
| 2025 |
Jan
(2) |
Feb
|
Mar
(1) |
Apr
(5) |
May
(11) |
Jun
(9) |
Jul
(4) |
Aug
(2) |
Sep
|
Oct
(8) |
Nov
(8) |
Dec
(12) |
| 2026 |
Jan
|
Feb
(2) |
Mar
(1) |
Apr
(9) |
May
(3) |
Jun
(1) |
Jul
(5) |
Aug
(1) |
Sep
(3) |
Oct
(1) |
Nov
|
Dec
|
| S | M | T | W | T | F | S |
|---|---|---|---|---|---|---|
|
|
1
|
2
(1) |
3
(3) |
4
|
5
(1) |
6
|
|
7
|
8
|
9
|
10
|
11
|
12
|
13
|
|
14
|
15
|
16
|
17
(1) |
18
|
19
|
20
|
|
21
|
22
(3) |
23
|
24
|
25
|
26
|
27
|
|
28
|
29
|
30
(1) |
|
|
|
|
|
From: <ai...@ke...> - 2009-06-30 02:24:35
|
libdrm/radeon/radeon_cs_gem.c | 17 ++++++++++++-----
1 file changed, 12 insertions(+), 5 deletions(-)
New commits:
commit de1ed01214874dcdd6116ff2587c8710d6ed4d2d
Author: Dave Airlie <ai...@re...>
Date: Tue Jun 30 12:19:28 2009 +1000
radeon: add support for write followed by read relocs.
the DDX does this and used to handle it internally
diff --git a/libdrm/radeon/radeon_cs_gem.c b/libdrm/radeon/radeon_cs_gem.c
index b9f6f4b..82ef16c 100644
--- a/libdrm/radeon/radeon_cs_gem.c
+++ b/libdrm/radeon/radeon_cs_gem.c
@@ -144,12 +144,19 @@ static int cs_gem_write_reloc(struct radeon_cs *cs,
* domain set then the read_domain should also be set for this
* new relocation.
*/
- if (reloc->read_domain && !read_domain) {
- return -EINVAL;
- }
- if (reloc->write_domain && !write_domain) {
- return -EINVAL;
+ /* the DDX expects to read and write from same pixmap */
+ if (write_domain && (reloc->read_domain & write_domain)) {
+ reloc->read_domain = 0;
+ reloc->write_domain = write_domain;
+ } else if (read_domain & reloc->write_domain) {
+ reloc->read_domain = 0;
+ } else {
+ if (write_domain != reloc->write_domain)
+ return -EINVAL;
+ if (read_domain != reloc->read_domain)
+ return -EINVAL;
}
+
reloc->read_domain |= read_domain;
reloc->write_domain |= write_domain;
/* update flags */
|
|
From: <ai...@ke...> - 2009-06-22 23:51:26
|
shared-core/i915_drm.h | 52 -------------------------------------------------
1 file changed, 52 deletions(-)
New commits:
commit 790097c51330090b2b7b90429b9ab8ddf259fd8e
Author: Dave Airlie <ai...@re...>
Date: Tue Jun 23 09:51:05 2009 +1000
remove some old ttm bits
diff --git a/shared-core/i915_drm.h b/shared-core/i915_drm.h
index c8fec5f..2539966 100644
--- a/shared-core/i915_drm.h
+++ b/shared-core/i915_drm.h
@@ -395,58 +395,6 @@ typedef struct drm_i915_hws_addr {
uint64_t addr;
} drm_i915_hws_addr_t;
-/*
- * Relocation header is 4 uint32_ts
- * 0 - 32 bit reloc count
- * 1 - 32-bit relocation type
- * 2-3 - 64-bit user buffer handle ptr for another list of relocs.
- */
-#define I915_RELOC_HEADER 4
-
-/*
- * type 0 relocation has 4-uint32_t stride
- * 0 - offset into buffer
- * 1 - delta to add in
- * 2 - buffer handle
- * 3 - reserved (for optimisations later).
- */
-/*
- * type 1 relocation has 4-uint32_t stride.
- * Hangs off the first item in the op list.
- * Performed after all valiations are done.
- * Try to group relocs into the same relocatee together for
- * performance reasons.
- * 0 - offset into buffer
- * 1 - delta to add in
- * 2 - buffer index in op list.
- * 3 - relocatee index in op list.
- */
-#define I915_RELOC_TYPE_0 0
-#define I915_RELOC0_STRIDE 4
-#define I915_RELOC_TYPE_1 1
-#define I915_RELOC1_STRIDE 4
-
-
-struct drm_i915_op_arg {
- uint64_t next;
- uint64_t reloc_ptr;
- int handled;
- unsigned int pad64;
- union {
- struct drm_bo_op_req req;
- struct drm_bo_arg_rep rep;
- } d;
-
-};
-
-struct drm_i915_execbuffer {
- uint64_t ops_list;
- uint32_t num_buffers;
- struct drm_i915_batchbuffer batch;
- drm_context_t context; /* for lockless use in the future */
- struct drm_fence_arg fence_arg;
-};
-
struct drm_i915_gem_init {
/**
* Beginning offset in the GTT to be managed by the DRM memory
|
|
From: <th...@ke...> - 2009-06-22 21:42:46
|
linux-core/Makefile | 2
linux-core/Makefile.kernel | 7
linux-core/drmP.h | 21
linux-core/drm_agpsupport.c | 171 --
linux-core/drm_bo.c | 2730 --------------------------------------------
linux-core/drm_bo_lock.c | 189 ---
linux-core/drm_bo_move.c | 614 ---------
linux-core/drm_compat.c | 99 -
linux-core/drm_drv.c | 36
linux-core/drm_fence.c | 829 -------------
linux-core/drm_fops.c | 35
linux-core/drm_object.c | 294 ----
linux-core/drm_objects.h | 821 -------------
linux-core/drm_proc.c | 102 -
linux-core/drm_stub.c | 14
linux-core/drm_ttm.c | 512 --------
linux-core/drm_vm.c | 198 ---
linux-core/via_buffer.c | 163 --
linux-core/via_fence.c | 169 --
linux-core/xgi_cmdlist.c | 3
linux-core/xgi_drv.c | 11
linux-core/xgi_drv.h | 12
linux-core/xgi_fence.c | 87 -
shared-core/drm.h | 318 -----
shared-core/via_drv.c | 40
shared-core/via_drv.h | 14
shared-core/via_map.c | 10
27 files changed, 4 insertions(+), 7497 deletions(-)
New commits:
commit 9a33f62be1c478334572ea9384af60c37d1644a0
Author: Thomas Hellstrom <thellstrom-at-vmware-dot-com>
Date: Mon Jun 22 23:07:26 2009 +0200
drm: Strip old ttm.
Signed-off-by: Thomas Hellstrom <thellstrom-at-vmware-dot-com>
diff --git a/linux-core/Makefile b/linux-core/Makefile
index 9257a49..591b6cf 100644
--- a/linux-core/Makefile
+++ b/linux-core/Makefile
@@ -58,7 +58,7 @@ endif
# Modules for all architectures
MODULE_LIST := drm.o tdfx.o r128.o radeon.o mga.o sis.o savage.o via.o \
- mach64.o nouveau.o xgi.o
+ mach64.o xgi.o
# Modules only for ix86 architectures
ifneq (,$(findstring 86,$(MACHINE)))
diff --git a/linux-core/Makefile.kernel b/linux-core/Makefile.kernel
index 0bea35d..e83f15c 100644
--- a/linux-core/Makefile.kernel
+++ b/linux-core/Makefile.kernel
@@ -12,9 +12,8 @@ drm-objs := drm_auth.o drm_bufs.o drm_context.o drm_dma.o drm_drawable.o \
drm_lock.o drm_memory.o drm_proc.o drm_stub.o drm_vm.o \
drm_sysfs.o drm_pci.o drm_agpsupport.o drm_scatter.o \
drm_memory_debug.o ati_pcigart.o drm_sman.o \
- drm_hashtab.o drm_mm.o drm_object.o drm_compat.o \
- drm_fence.o drm_ttm.o drm_bo.o drm_bo_move.o drm_bo_lock.o \
- drm_regman.o drm_vm_nopage_compat.o drm_gem.o
+ drm_hashtab.o drm_mm.o drm_compat.o \
+ drm_vm_nopage_compat.o drm_gem.o
tdfx-objs := tdfx_drv.o
r128-objs := r128_drv.o r128_cce.o r128_state.o r128_irq.o
mga-objs := mga_drv.o mga_dma.o mga_state.o mga_warp.o mga_irq.o
@@ -35,7 +34,7 @@ sis-objs := sis_drv.o sis_mm.o
ffb-objs := ffb_drv.o ffb_context.o
savage-objs := savage_drv.o savage_bci.o savage_state.o
via-objs := via_irq.o via_drv.o via_map.o via_mm.o via_dma.o via_verifier.o \
- via_video.o via_dmablit.o via_fence.o via_buffer.o
+ via_video.o via_dmablit.o
mach64-objs := mach64_drv.o mach64_dma.o mach64_irq.o mach64_state.o
xgi-objs := xgi_cmdlist.o xgi_drv.o xgi_fb.o xgi_misc.o xgi_pcie.o \
xgi_fence.o
diff --git a/linux-core/drmP.h b/linux-core/drmP.h
index 6770282..9b4b071 100644
--- a/linux-core/drmP.h
+++ b/linux-core/drmP.h
@@ -155,8 +155,6 @@ typedef unsigned long uintptr_t;
#define DRM_MEM_MM 22
#define DRM_MEM_HASHTAB 23
#define DRM_MEM_OBJECTS 24
-#define DRM_MEM_FENCE 25
-#define DRM_MEM_TTM 26
#define DRM_MEM_BUFOBJ 27
#define DRM_MAX_CTXBITMAP (PAGE_SIZE * 8)
@@ -660,8 +658,6 @@ struct drm_gem_object {
void *driver_private;
};
-#include "drm_objects.h"
-
/**
* DRM driver structure. This structure represent the common code for
* a family of cards. There will one drm_device for each card present
@@ -855,10 +851,6 @@ struct drm_device {
struct list_head maplist; /**< Linked list of regions */
int map_count; /**< Number of mappable regions */
struct drm_open_hash map_hash; /**< User token hash table for maps */
- struct drm_mm offset_manager; /**< User token manager */
- struct drm_open_hash object_hash; /**< User token hash table for objects */
- struct address_space *dev_mapping; /**< For unmap_mapping_range() */
- struct page *ttm_dummy_page;
/** \name Context handle management */
/*@{ */
@@ -953,9 +945,6 @@ struct drm_device {
unsigned int agp_buffer_token;
struct drm_minor *primary; /**< render type primary screen head */
- struct drm_fence_manager fm;
- struct drm_buffer_manager bm;
-
/** \name Drawable information */
/*@{ */
spinlock_t drw_lock;
@@ -978,15 +967,6 @@ struct drm_device {
/*@} */
};
-#if __OS_HAS_AGP
-struct drm_agp_ttm_backend {
- struct drm_ttm_backend backend;
- DRM_AGP_MEM *mem;
- struct agp_bridge_data *bridge;
- int populated;
-};
-#endif
-
static __inline__ int drm_core_check_feature(struct drm_device *dev,
int feature)
@@ -1279,7 +1259,6 @@ extern DRM_AGP_MEM *drm_agp_allocate_memory(struct agp_bridge_data *bridge, size
extern int drm_agp_free_memory(DRM_AGP_MEM * handle);
extern int drm_agp_bind_memory(DRM_AGP_MEM * handle, off_t start);
extern int drm_agp_unbind_memory(DRM_AGP_MEM * handle);
-extern struct drm_ttm_backend *drm_agp_init_ttm(struct drm_device *dev);
extern void drm_agp_chipset_flush(struct drm_device *dev);
/* Stub support (drm_stub.h) */
extern int drm_get_dev(struct pci_dev *pdev, const struct pci_device_id *ent,
diff --git a/linux-core/drm_agpsupport.c b/linux-core/drm_agpsupport.c
index 2abfac6..9f746a3 100644
--- a/linux-core/drm_agpsupport.c
+++ b/linux-core/drm_agpsupport.c
@@ -498,177 +498,6 @@ drm_agp_bind_pages(struct drm_device *dev,
}
EXPORT_SYMBOL(drm_agp_bind_pages);
-/*
- * AGP ttm backend interface.
- */
-
-#ifndef AGP_USER_TYPES
-#define AGP_USER_TYPES (1 << 16)
-#define AGP_USER_MEMORY (AGP_USER_TYPES)
-#define AGP_USER_CACHED_MEMORY (AGP_USER_TYPES + 1)
-#endif
-#define AGP_REQUIRED_MAJOR 0
-#define AGP_REQUIRED_MINOR 102
-
-static int drm_agp_needs_unbind_cache_adjust(struct drm_ttm_backend *backend)
-{
- return ((backend->flags & DRM_BE_FLAG_BOUND_CACHED) ? 0 : 1);
-}
-
-
-static int drm_agp_populate(struct drm_ttm_backend *backend,
- unsigned long num_pages, struct page **pages,
- struct page *dummy_read_page)
-{
- struct drm_agp_ttm_backend *agp_be =
- container_of(backend, struct drm_agp_ttm_backend, backend);
- struct page **cur_page, **last_page = pages + num_pages;
- DRM_AGP_MEM *mem;
- int dummy_page_count = 0;
-
- if (drm_alloc_memctl(num_pages * sizeof(void *)))
- return -1;
-
- DRM_DEBUG("drm_agp_populate_ttm\n");
- mem = drm_agp_allocate_memory(agp_be->bridge, num_pages, AGP_USER_MEMORY);
- if (!mem) {
- drm_free_memctl(num_pages * sizeof(void *));
- return -1;
- }
-
- DRM_DEBUG("Current page count is %ld\n", (long) mem->page_count);
- mem->page_count = 0;
- for (cur_page = pages; cur_page < last_page; ++cur_page) {
- struct page *page = *cur_page;
- if (!page) {
- page = dummy_read_page;
- ++dummy_page_count;
- }
- mem->memory[mem->page_count++] = phys_to_gart(page_to_phys(page));
- }
- if (dummy_page_count)
- DRM_DEBUG("Mapped %d dummy pages\n", dummy_page_count);
- agp_be->mem = mem;
- return 0;
-}
-
-static int drm_agp_bind_ttm(struct drm_ttm_backend *backend,
- struct drm_bo_mem_reg *bo_mem)
-{
- struct drm_agp_ttm_backend *agp_be =
- container_of(backend, struct drm_agp_ttm_backend, backend);
- DRM_AGP_MEM *mem = agp_be->mem;
- int ret;
- int snooped = (bo_mem->flags & DRM_BO_FLAG_CACHED) && !(bo_mem->flags & DRM_BO_FLAG_CACHED_MAPPED);
-
- DRM_DEBUG("drm_agp_bind_ttm\n");
- mem->is_flushed = true;
- mem->type = AGP_USER_MEMORY;
- /* CACHED MAPPED implies not snooped memory */
- if (snooped)
- mem->type = AGP_USER_CACHED_MEMORY;
-
- ret = drm_agp_bind_memory(mem, bo_mem->mm_node->start);
- if (ret)
- DRM_ERROR("AGP Bind memory failed\n");
-
- DRM_FLAG_MASKED(backend->flags, (bo_mem->flags & DRM_BO_FLAG_CACHED) ?
- DRM_BE_FLAG_BOUND_CACHED : 0,
- DRM_BE_FLAG_BOUND_CACHED);
- return ret;
-}
-
-static int drm_agp_unbind_ttm(struct drm_ttm_backend *backend)
-{
- struct drm_agp_ttm_backend *agp_be =
- container_of(backend, struct drm_agp_ttm_backend, backend);
-
- DRM_DEBUG("drm_agp_unbind_ttm\n");
- if (agp_be->mem->is_bound)
- return drm_agp_unbind_memory(agp_be->mem);
- else
- return 0;
-}
-
-static void drm_agp_clear_ttm(struct drm_ttm_backend *backend)
-{
- struct drm_agp_ttm_backend *agp_be =
- container_of(backend, struct drm_agp_ttm_backend, backend);
- DRM_AGP_MEM *mem = agp_be->mem;
-
- DRM_DEBUG("drm_agp_clear_ttm\n");
- if (mem) {
- unsigned long num_pages = mem->page_count;
- backend->func->unbind(backend);
- agp_free_memory(mem);
- drm_free_memctl(num_pages * sizeof(void *));
- }
- agp_be->mem = NULL;
-}
-
-static void drm_agp_destroy_ttm(struct drm_ttm_backend *backend)
-{
- struct drm_agp_ttm_backend *agp_be;
-
- if (backend) {
- DRM_DEBUG("drm_agp_destroy_ttm\n");
- agp_be = container_of(backend, struct drm_agp_ttm_backend, backend);
- if (agp_be) {
- if (agp_be->mem)
- backend->func->clear(backend);
- drm_ctl_free(agp_be, sizeof(*agp_be), DRM_MEM_TTM);
- }
- }
-}
-
-static struct drm_ttm_backend_func agp_ttm_backend = {
- .needs_ub_cache_adjust = drm_agp_needs_unbind_cache_adjust,
- .populate = drm_agp_populate,
- .clear = drm_agp_clear_ttm,
- .bind = drm_agp_bind_ttm,
- .unbind = drm_agp_unbind_ttm,
- .destroy = drm_agp_destroy_ttm,
-};
-
-struct drm_ttm_backend *drm_agp_init_ttm(struct drm_device *dev)
-{
-
- struct drm_agp_ttm_backend *agp_be;
- struct agp_kern_info *info;
-
- if (!dev->agp) {
- DRM_ERROR("AGP is not initialized.\n");
- return NULL;
- }
- info = &dev->agp->agp_info;
-
- if (info->version.major != AGP_REQUIRED_MAJOR ||
- info->version.minor < AGP_REQUIRED_MINOR) {
- DRM_ERROR("Wrong agpgart version %d.%d\n"
- "\tYou need at least version %d.%d.\n",
- info->version.major,
- info->version.minor,
- AGP_REQUIRED_MAJOR,
- AGP_REQUIRED_MINOR);
- return NULL;
- }
-
-
- agp_be = drm_ctl_calloc(1, sizeof(*agp_be), DRM_MEM_TTM);
- if (!agp_be)
- return NULL;
-
- agp_be->mem = NULL;
-
- agp_be->bridge = dev->agp->bridge;
- agp_be->populated = false;
- agp_be->backend.func = &agp_ttm_backend;
- agp_be->backend.dev = dev;
-
- return &agp_be->backend;
-}
-EXPORT_SYMBOL(drm_agp_init_ttm);
-
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,25)
void drm_agp_chipset_flush(struct drm_device *dev)
{
diff --git a/linux-core/drm_bo.c b/linux-core/drm_bo.c
deleted file mode 100644
index f43480c..0000000
--- a/linux-core/drm_bo.c
+++ /dev/null
@@ -1,2730 +0,0 @@
-/**************************************************************************
- *
- * Copyright (c) 2006-2007 Tungsten Graphics, Inc., Cedar Park, TX., USA
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
- * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
- * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
- * USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- **************************************************************************/
-/*
- * Authors: Thomas Hellström <thomas-at-tungstengraphics-dot-com>
- */
-
-#include "drmP.h"
-
-/*
- * Locking may look a bit complicated but isn't really:
- *
- * The buffer usage atomic_t needs to be protected by dev->struct_mutex
- * when there is a chance that it can be zero before or after the operation.
- *
- * dev->struct_mutex also protects all lists and list heads,
- * Hash tables and hash heads.
- *
- * bo->mutex protects the buffer object itself excluding the usage field.
- * bo->mutex does also protect the buffer list heads, so to manipulate those,
- * we need both the bo->mutex and the dev->struct_mutex.
- *
- * Locking order is bo->mutex, dev->struct_mutex. Therefore list traversal
- * is a bit complicated. When dev->struct_mutex is released to grab bo->mutex,
- * the list traversal will, in general, need to be restarted.
- *
- */
-
-static void drm_bo_destroy_locked(struct drm_buffer_object *bo);
-static int drm_bo_setup_vm_locked(struct drm_buffer_object *bo);
-static void drm_bo_takedown_vm_locked(struct drm_buffer_object *bo);
-static void drm_bo_unmap_virtual(struct drm_buffer_object *bo);
-
-static inline uint64_t drm_bo_type_flags(unsigned type)
-{
- return (1ULL << (24 + type));
-}
-
-/*
- * bo locked. dev->struct_mutex locked.
- */
-
-void drm_bo_add_to_pinned_lru(struct drm_buffer_object *bo)
-{
- struct drm_mem_type_manager *man;
-
- DRM_ASSERT_LOCKED(&bo->dev->struct_mutex);
- DRM_ASSERT_LOCKED(&bo->mutex);
-
- man = &bo->dev->bm.man[bo->pinned_mem_type];
- list_add_tail(&bo->pinned_lru, &man->pinned);
-}
-
-void drm_bo_add_to_lru(struct drm_buffer_object *bo)
-{
- struct drm_mem_type_manager *man;
-
- DRM_ASSERT_LOCKED(&bo->dev->struct_mutex);
-
- if (!(bo->mem.proposed_flags & (DRM_BO_FLAG_NO_MOVE | DRM_BO_FLAG_NO_EVICT))
- || bo->mem.mem_type != bo->pinned_mem_type) {
- man = &bo->dev->bm.man[bo->mem.mem_type];
- list_add_tail(&bo->lru, &man->lru);
- } else {
- INIT_LIST_HEAD(&bo->lru);
- }
-}
-
-static int drm_bo_vm_pre_move(struct drm_buffer_object *bo, int old_is_pci)
-{
- if (!bo->map_list.map)
- return 0;
-
- drm_bo_unmap_virtual(bo);
- return 0;
-}
-
-/*
- * Call bo->mutex locked.
- */
-
-static int drm_bo_add_ttm(struct drm_buffer_object *bo)
-{
- struct drm_device *dev = bo->dev;
- int ret = 0;
- uint32_t page_flags = 0;
-
- DRM_ASSERT_LOCKED(&bo->mutex);
- bo->ttm = NULL;
-
- if (bo->mem.proposed_flags & DRM_BO_FLAG_WRITE)
- page_flags |= DRM_TTM_PAGE_WRITE;
-
- switch (bo->type) {
- case drm_bo_type_device:
- case drm_bo_type_kernel:
- bo->ttm = drm_ttm_create(dev, bo->num_pages << PAGE_SHIFT,
- page_flags, dev->bm.dummy_read_page);
- if (!bo->ttm)
- ret = -ENOMEM;
- break;
- case drm_bo_type_user:
- bo->ttm = drm_ttm_create(dev, bo->num_pages << PAGE_SHIFT,
- page_flags | DRM_TTM_PAGE_USER,
- dev->bm.dummy_read_page);
- if (!bo->ttm)
- ret = -ENOMEM;
-
- ret = drm_ttm_set_user(bo->ttm, current,
- bo->buffer_start,
- bo->num_pages);
- if (ret)
- return ret;
-
- break;
- default:
- DRM_ERROR("Illegal buffer object type\n");
- ret = -EINVAL;
- break;
- }
-
- return ret;
-}
-
-static int drm_bo_handle_move_mem(struct drm_buffer_object *bo,
- struct drm_bo_mem_reg *mem,
- int evict, int no_wait)
-{
- struct drm_device *dev = bo->dev;
- struct drm_buffer_manager *bm = &dev->bm;
- int old_is_pci = drm_mem_reg_is_pci(dev, &bo->mem);
- int new_is_pci = drm_mem_reg_is_pci(dev, mem);
- struct drm_mem_type_manager *old_man = &bm->man[bo->mem.mem_type];
- struct drm_mem_type_manager *new_man = &bm->man[mem->mem_type];
- int ret = 0;
-
- if (old_is_pci || new_is_pci ||
- ((mem->flags ^ bo->mem.flags) & DRM_BO_FLAG_CACHED))
- ret = drm_bo_vm_pre_move(bo, old_is_pci);
- if (ret)
- return ret;
-
- /*
- * Create and bind a ttm if required.
- */
-
- if (!(new_man->flags & _DRM_FLAG_MEMTYPE_FIXED) && (bo->ttm == NULL)) {
- ret = drm_bo_add_ttm(bo);
- if (ret)
- goto out_err;
-
- if (mem->mem_type != DRM_BO_MEM_LOCAL) {
- ret = drm_ttm_bind(bo->ttm, mem);
- if (ret)
- goto out_err;
- }
-
- if (bo->mem.mem_type == DRM_BO_MEM_LOCAL) {
-
- struct drm_bo_mem_reg *old_mem = &bo->mem;
- uint64_t save_flags = old_mem->flags;
- uint64_t save_proposed_flags = old_mem->proposed_flags;
-
- *old_mem = *mem;
- mem->mm_node = NULL;
- old_mem->proposed_flags = save_proposed_flags;
- DRM_FLAG_MASKED(save_flags, mem->flags,
- DRM_BO_MASK_MEMTYPE);
- goto moved;
- }
-
- }
-
- if (!(old_man->flags & _DRM_FLAG_MEMTYPE_FIXED) &&
- !(new_man->flags & _DRM_FLAG_MEMTYPE_FIXED))
- ret = drm_bo_move_ttm(bo, evict, no_wait, mem);
- else if (dev->driver->bo_driver->move)
- ret = dev->driver->bo_driver->move(bo, evict, no_wait, mem);
- else
- ret = drm_bo_move_memcpy(bo, evict, no_wait, mem);
-
- if (ret)
- goto out_err;
-
-moved:
- if (bo->priv_flags & _DRM_BO_FLAG_EVICTED) {
- ret =
- dev->driver->bo_driver->invalidate_caches(dev,
- bo->mem.flags);
- if (ret)
- DRM_ERROR("Can not flush read caches\n");
- }
-
- DRM_FLAG_MASKED(bo->priv_flags,
- (evict) ? _DRM_BO_FLAG_EVICTED : 0,
- _DRM_BO_FLAG_EVICTED);
-
- if (bo->mem.mm_node)
- bo->offset = (bo->mem.mm_node->start << PAGE_SHIFT) +
- bm->man[bo->mem.mem_type].gpu_offset;
-
-
- return 0;
-
-out_err:
- new_man = &bm->man[bo->mem.mem_type];
- if ((new_man->flags & _DRM_FLAG_MEMTYPE_FIXED) && bo->ttm) {
- drm_ttm_unbind(bo->ttm);
- drm_ttm_destroy(bo->ttm);
- bo->ttm = NULL;
- }
-
- return ret;
-}
-
-/*
- * Call bo->mutex locked.
- * Returns -EBUSY if the buffer is currently rendered to or from. 0 otherwise.
- */
-
-static int drm_bo_busy(struct drm_buffer_object *bo, int check_unfenced)
-{
- struct drm_fence_object *fence = bo->fence;
-
- if (check_unfenced && (bo->priv_flags & _DRM_BO_FLAG_UNFENCED))
- return -EBUSY;
-
- if (fence) {
- if (drm_fence_object_signaled(fence, bo->fence_type)) {
- drm_fence_usage_deref_unlocked(&bo->fence);
- return 0;
- }
- drm_fence_object_flush(fence, DRM_FENCE_TYPE_EXE);
- if (drm_fence_object_signaled(fence, bo->fence_type)) {
- drm_fence_usage_deref_unlocked(&bo->fence);
- return 0;
- }
- return -EBUSY;
- }
- return 0;
-}
-
-static int drm_bo_check_unfenced(struct drm_buffer_object *bo)
-{
- int ret;
-
- mutex_lock(&bo->mutex);
- ret = (bo->priv_flags & _DRM_BO_FLAG_UNFENCED);
- mutex_unlock(&bo->mutex);
- return ret;
-}
-
-
-/*
- * Call bo->mutex locked.
- * Wait until the buffer is idle.
- */
-
-int drm_bo_wait(struct drm_buffer_object *bo, int lazy, int interruptible,
- int no_wait, int check_unfenced)
-{
- int ret;
-
- DRM_ASSERT_LOCKED(&bo->mutex);
- while(unlikely(drm_bo_busy(bo, check_unfenced))) {
- if (no_wait)
- return -EBUSY;
-
- if (check_unfenced && (bo->priv_flags & _DRM_BO_FLAG_UNFENCED)) {
- mutex_unlock(&bo->mutex);
- wait_event(bo->event_queue, !drm_bo_check_unfenced(bo));
- mutex_lock(&bo->mutex);
- bo->priv_flags |= _DRM_BO_FLAG_UNLOCKED;
- }
-
- if (bo->fence) {
- struct drm_fence_object *fence;
- uint32_t fence_type = bo->fence_type;
-
- drm_fence_reference_unlocked(&fence, bo->fence);
- mutex_unlock(&bo->mutex);
-
- ret = drm_fence_object_wait(fence, lazy, !interruptible,
- fence_type);
-
- drm_fence_usage_deref_unlocked(&fence);
- mutex_lock(&bo->mutex);
- bo->priv_flags |= _DRM_BO_FLAG_UNLOCKED;
- if (ret)
- return ret;
- }
-
- }
- return 0;
-}
-EXPORT_SYMBOL(drm_bo_wait);
-
-static int drm_bo_expire_fence(struct drm_buffer_object *bo, int allow_errors)
-{
- struct drm_device *dev = bo->dev;
- struct drm_buffer_manager *bm = &dev->bm;
-
- if (bo->fence) {
- if (bm->nice_mode) {
- unsigned long _end = jiffies + 3 * DRM_HZ;
- int ret;
- do {
- ret = drm_bo_wait(bo, 0, 0, 0, 0);
- if (ret && allow_errors)
- return ret;
-
- } while (ret && !time_after_eq(jiffies, _end));
-
- if (bo->fence) {
- bm->nice_mode = 0;
- DRM_ERROR("Detected GPU lockup or "
- "fence driver was taken down. "
- "Evicting buffer.\n");
- }
- }
- if (bo->fence)
- drm_fence_usage_deref_unlocked(&bo->fence);
- }
- return 0;
-}
-
-/*
- * Call dev->struct_mutex locked.
- * Attempts to remove all private references to a buffer by expiring its
- * fence object and removing from lru lists and memory managers.
- */
-
-static void drm_bo_cleanup_refs(struct drm_buffer_object *bo, int remove_all)
-{
- struct drm_device *dev = bo->dev;
- struct drm_buffer_manager *bm = &dev->bm;
-
- DRM_ASSERT_LOCKED(&dev->struct_mutex);
-
- atomic_inc(&bo->usage);
- mutex_unlock(&dev->struct_mutex);
- mutex_lock(&bo->mutex);
-
- DRM_FLAG_MASKED(bo->priv_flags, 0, _DRM_BO_FLAG_UNFENCED);
-
- if (bo->fence && drm_fence_object_signaled(bo->fence,
- bo->fence_type))
- drm_fence_usage_deref_unlocked(&bo->fence);
-
- if (bo->fence && remove_all)
- (void)drm_bo_expire_fence(bo, 0);
-
- mutex_lock(&dev->struct_mutex);
-
- if (!atomic_dec_and_test(&bo->usage))
- goto out;
-
- if (!bo->fence) {
- list_del_init(&bo->lru);
- if (bo->mem.mm_node) {
- drm_mm_put_block(bo->mem.mm_node);
- if (bo->pinned_node == bo->mem.mm_node)
- bo->pinned_node = NULL;
- bo->mem.mm_node = NULL;
- }
- list_del_init(&bo->pinned_lru);
- if (bo->pinned_node) {
- drm_mm_put_block(bo->pinned_node);
- bo->pinned_node = NULL;
- }
- list_del_init(&bo->ddestroy);
- mutex_unlock(&bo->mutex);
- drm_bo_destroy_locked(bo);
- return;
- }
-
- if (list_empty(&bo->ddestroy)) {
- drm_fence_object_flush(bo->fence, bo->fence_type);
- list_add_tail(&bo->ddestroy, &bm->ddestroy);
- schedule_delayed_work(&bm->wq,
- ((DRM_HZ / 100) < 1) ? 1 : DRM_HZ / 100);
- }
-
-out:
- mutex_unlock(&bo->mutex);
- return;
-}
-
-/*
- * Verify that refcount is 0 and that there are no internal references
- * to the buffer object. Then destroy it.
- */
-
-static void drm_bo_destroy_locked(struct drm_buffer_object *bo)
-{
- struct drm_device *dev = bo->dev;
- struct drm_buffer_manager *bm = &dev->bm;
-
- DRM_ASSERT_LOCKED(&dev->struct_mutex);
-
- if (list_empty(&bo->lru) && bo->mem.mm_node == NULL &&
- list_empty(&bo->pinned_lru) && bo->pinned_node == NULL &&
- list_empty(&bo->ddestroy) && atomic_read(&bo->usage) == 0) {
- if (bo->fence != NULL) {
- DRM_ERROR("Fence was non-zero.\n");
- drm_bo_cleanup_refs(bo, 0);
- return;
- }
-
- if (bo->ttm) {
- drm_ttm_unbind(bo->ttm);
- drm_ttm_destroy(bo->ttm);
- bo->ttm = NULL;
- }
-
- atomic_dec(&bm->count);
-
- drm_ctl_free(bo, sizeof(*bo), DRM_MEM_BUFOBJ);
-
- return;
- }
-
- /*
- * Some stuff is still trying to reference the buffer object.
- * Get rid of those references.
- */
-
- drm_bo_cleanup_refs(bo, 0);
-
- return;
-}
-
-/*
- * Call dev->struct_mutex locked.
- */
-
-static void drm_bo_delayed_delete(struct drm_device *dev, int remove_all)
-{
- struct drm_buffer_manager *bm = &dev->bm;
-
- struct drm_buffer_object *entry, *nentry;
- struct list_head *list, *next;
-
- list_for_each_safe(list, next, &bm->ddestroy) {
- entry = list_entry(list, struct drm_buffer_object, ddestroy);
-
- nentry = NULL;
- if (next != &bm->ddestroy) {
- nentry = list_entry(next, struct drm_buffer_object,
- ddestroy);
- atomic_inc(&nentry->usage);
- }
-
- drm_bo_cleanup_refs(entry, remove_all);
-
- if (nentry)
- atomic_dec(&nentry->usage);
- }
-}
-
-static void drm_bo_delayed_workqueue(struct work_struct *work)
-{
- struct drm_buffer_manager *bm =
- container_of(work, struct drm_buffer_manager, wq.work);
- struct drm_device *dev = container_of(bm, struct drm_device, bm);
-
- DRM_DEBUG("Delayed delete Worker\n");
-
- mutex_lock(&dev->struct_mutex);
- if (!bm->initialized) {
- mutex_unlock(&dev->struct_mutex);
- return;
- }
- drm_bo_delayed_delete(dev, 0);
- if (bm->initialized && !list_empty(&bm->ddestroy)) {
- schedule_delayed_work(&bm->wq,
- ((DRM_HZ / 100) < 1) ? 1 : DRM_HZ / 100);
- }
- mutex_unlock(&dev->struct_mutex);
-}
-
-void drm_bo_usage_deref_locked(struct drm_buffer_object **bo)
-{
- struct drm_buffer_object *tmp_bo = *bo;
- bo = NULL;
-
- DRM_ASSERT_LOCKED(&tmp_bo->dev->struct_mutex);
-
- if (atomic_dec_and_test(&tmp_bo->usage))
- drm_bo_destroy_locked(tmp_bo);
-}
-EXPORT_SYMBOL(drm_bo_usage_deref_locked);
-
-static void drm_bo_base_deref_locked(struct drm_file *file_priv,
- struct drm_user_object *uo)
-{
- struct drm_buffer_object *bo =
- drm_user_object_entry(uo, struct drm_buffer_object, base);
-
- DRM_ASSERT_LOCKED(&bo->dev->struct_mutex);
-
- drm_bo_takedown_vm_locked(bo);
- drm_bo_usage_deref_locked(&bo);
-}
-
-void drm_bo_usage_deref_unlocked(struct drm_buffer_object **bo)
-{
- struct drm_buffer_object *tmp_bo = *bo;
- struct drm_device *dev = tmp_bo->dev;
-
- *bo = NULL;
- if (atomic_dec_and_test(&tmp_bo->usage)) {
- mutex_lock(&dev->struct_mutex);
- if (atomic_read(&tmp_bo->usage) == 0)
- drm_bo_destroy_locked(tmp_bo);
- mutex_unlock(&dev->struct_mutex);
- }
-}
-EXPORT_SYMBOL(drm_bo_usage_deref_unlocked);
-
-void drm_putback_buffer_objects(struct drm_device *dev)
-{
- struct drm_buffer_manager *bm = &dev->bm;
- struct list_head *list = &bm->unfenced;
- struct drm_buffer_object *entry, *next;
-
- mutex_lock(&dev->struct_mutex);
- list_for_each_entry_safe(entry, next, list, lru) {
- atomic_inc(&entry->usage);
- mutex_unlock(&dev->struct_mutex);
-
- mutex_lock(&entry->mutex);
- BUG_ON(!(entry->priv_flags & _DRM_BO_FLAG_UNFENCED));
- mutex_lock(&dev->struct_mutex);
-
- list_del_init(&entry->lru);
- DRM_FLAG_MASKED(entry->priv_flags, 0, _DRM_BO_FLAG_UNFENCED);
- wake_up_all(&entry->event_queue);
-
- /*
- * FIXME: Might want to put back on head of list
- * instead of tail here.
- */
-
- drm_bo_add_to_lru(entry);
- mutex_unlock(&entry->mutex);
- drm_bo_usage_deref_locked(&entry);
- }
- mutex_unlock(&dev->struct_mutex);
-}
-EXPORT_SYMBOL(drm_putback_buffer_objects);
-
-
-/*
- * Note. The caller has to register (if applicable)
- * and deregister fence object usage.
- */
-
-int drm_fence_buffer_objects(struct drm_device *dev,
- struct list_head *list,
- uint32_t fence_flags,
- struct drm_fence_object *fence,
- struct drm_fence_object **used_fence)
-{
- struct drm_buffer_manager *bm = &dev->bm;
- struct drm_buffer_object *entry;
- uint32_t fence_type = 0;
- uint32_t fence_class = ~0;
- int count = 0;
- int ret = 0;
- struct list_head *l;
-
- mutex_lock(&dev->struct_mutex);
-
- if (!list)
- list = &bm->unfenced;
-
- if (fence)
- fence_class = fence->fence_class;
-
- list_for_each_entry(entry, list, lru) {
- BUG_ON(!(entry->priv_flags & _DRM_BO_FLAG_UNFENCED));
- fence_type |= entry->new_fence_type;
- if (fence_class == ~0)
- fence_class = entry->new_fence_class;
- else if (entry->new_fence_class != fence_class) {
- DRM_ERROR("Unmatching fence classes on unfenced list: "
- "%d and %d.\n",
- fence_class,
- entry->new_fence_class);
- ret = -EINVAL;
- goto out;
- }
- count++;
- }
-
- if (!count) {
- ret = -EINVAL;
- goto out;
- }
-
- if (fence) {
- if ((fence_type & fence->type) != fence_type ||
- (fence->fence_class != fence_class)) {
- DRM_ERROR("Given fence doesn't match buffers "
- "on unfenced list.\n");
- ret = -EINVAL;
- goto out;
- }
- } else {
- mutex_unlock(&dev->struct_mutex);
- ret = drm_fence_object_create(dev, fence_class, fence_type,
- fence_flags | DRM_FENCE_FLAG_EMIT,
- &fence);
- mutex_lock(&dev->struct_mutex);
- if (ret)
- goto out;
- }
-
- count = 0;
- l = list->next;
- while (l != list) {
- prefetch(l->next);
- entry = list_entry(l, struct drm_buffer_object, lru);
- atomic_inc(&entry->usage);
- mutex_unlock(&dev->struct_mutex);
- mutex_lock(&entry->mutex);
- mutex_lock(&dev->struct_mutex);
- list_del_init(l);
- if (entry->priv_flags & _DRM_BO_FLAG_UNFENCED) {
- count++;
- if (entry->fence)
- drm_fence_usage_deref_locked(&entry->fence);
- entry->fence = drm_fence_reference_locked(fence);
- entry->fence_class = entry->new_fence_class;
- entry->fence_type = entry->new_fence_type;
- DRM_FLAG_MASKED(entry->priv_flags, 0,
- _DRM_BO_FLAG_UNFENCED);
- wake_up_all(&entry->event_queue);
- drm_bo_add_to_lru(entry);
- }
- mutex_unlock(&entry->mutex);
- drm_bo_usage_deref_locked(&entry);
- l = list->next;
- }
- DRM_DEBUG("Fenced %d buffers\n", count);
-out:
- mutex_unlock(&dev->struct_mutex);
- *used_fence = fence;
- return ret;
-}
-EXPORT_SYMBOL(drm_fence_buffer_objects);
-
-/*
- * bo->mutex locked
- */
-
-static int drm_bo_evict(struct drm_buffer_object *bo, unsigned mem_type,
- int no_wait)
-{
- int ret = 0;
- struct drm_device *dev = bo->dev;
- struct drm_bo_mem_reg evict_mem;
-
- /*
- * Someone might have modified the buffer before we took the
- * buffer mutex.
- */
-
- do {
- bo->priv_flags &= ~_DRM_BO_FLAG_UNLOCKED;
-
- if (unlikely(bo->mem.flags &
- (DRM_BO_FLAG_NO_MOVE | DRM_BO_FLAG_NO_EVICT)))
- goto out_unlock;
- if (unlikely(bo->priv_flags & _DRM_BO_FLAG_UNFENCED))
- goto out_unlock;
- if (unlikely(bo->mem.mem_type != mem_type))
- goto out_unlock;
- ret = drm_bo_wait(bo, 0, 1, no_wait, 0);
- if (ret)
- goto out_unlock;
-
- } while(bo->priv_flags & _DRM_BO_FLAG_UNLOCKED);
-
- evict_mem = bo->mem;
- evict_mem.mm_node = NULL;
-
- evict_mem = bo->mem;
- evict_mem.proposed_flags = dev->driver->bo_driver->evict_flags(bo);
-
- mutex_lock(&dev->struct_mutex);
- list_del_init(&bo->lru);
- mutex_unlock(&dev->struct_mutex);
-
- ret = drm_bo_mem_space(bo, &evict_mem, no_wait);
-
- if (ret) {
- if (ret != -EAGAIN)
- DRM_ERROR("Failed to find memory space for "
- "buffer 0x%p eviction.\n", bo);
- goto out;
- }
-
- ret = drm_bo_handle_move_mem(bo, &evict_mem, 1, no_wait);
-
- if (ret) {
- if (ret != -EAGAIN)
- DRM_ERROR("Buffer eviction failed\n");
- goto out;
- }
-
- DRM_FLAG_MASKED(bo->priv_flags, _DRM_BO_FLAG_EVICTED,
- _DRM_BO_FLAG_EVICTED);
-
-out:
- mutex_lock(&dev->struct_mutex);
- if (evict_mem.mm_node) {
- if (evict_mem.mm_node != bo->pinned_node)
- drm_mm_put_block(evict_mem.mm_node);
- evict_mem.mm_node = NULL;
- }
- drm_bo_add_to_lru(bo);
- BUG_ON(bo->priv_flags & _DRM_BO_FLAG_UNLOCKED);
-out_unlock:
- mutex_unlock(&dev->struct_mutex);
-
- return ret;
-}
-
-/**
- * Repeatedly evict memory from the LRU for @mem_type until we create enough
- * space, or we've evicted everything and there isn't enough space.
- */
-static int drm_bo_mem_force_space(struct drm_device *dev,
- struct drm_bo_mem_reg *mem,
- uint32_t mem_type, int no_wait)
-{
- struct drm_mm_node *node;
- struct drm_buffer_manager *bm = &dev->bm;
- struct drm_buffer_object *entry;
- struct drm_mem_type_manager *man = &bm->man[mem_type];
- struct list_head *lru;
- unsigned long num_pages = mem->num_pages;
- int ret;
-
- mutex_lock(&dev->struct_mutex);
- do {
- node = drm_mm_search_free(&man->manager, num_pages,
- mem->page_alignment, 1);
- if (node)
- break;
-
- lru = &man->lru;
- if (lru->next == lru)
- break;
-
- entry = list_entry(lru->next, struct drm_buffer_object, lru);
- atomic_inc(&entry->usage);
- mutex_unlock(&dev->struct_mutex);
- mutex_lock(&entry->mutex);
- ret = drm_bo_evict(entry, mem_type, no_wait);
- mutex_unlock(&entry->mutex);
- drm_bo_usage_deref_unlocked(&entry);
- if (ret)
- return ret;
- mutex_lock(&dev->struct_mutex);
- } while (1);
-
- if (!node) {
- mutex_unlock(&dev->struct_mutex);
- return -ENOMEM;
- }
-
- node = drm_mm_get_block(node, num_pages, mem->page_alignment);
- if (unlikely(!node)) {
- mutex_unlock(&dev->struct_mutex);
- return -ENOMEM;
- }
-
- mutex_unlock(&dev->struct_mutex);
- mem->mm_node = node;
- mem->mem_type = mem_type;
- return 0;
-}
-
-static int drm_bo_mt_compatible(struct drm_mem_type_manager *man,
- int disallow_fixed,
- uint32_t mem_type,
- uint64_t mask, uint32_t *res_mask)
-{
- uint64_t cur_flags = drm_bo_type_flags(mem_type);
- uint64_t flag_diff;
-
- if ((man->flags & _DRM_FLAG_MEMTYPE_FIXED) && disallow_fixed)
- return 0;
- if (man->flags & _DRM_FLAG_MEMTYPE_CACHED)
- cur_flags |= DRM_BO_FLAG_CACHED;
- if (man->flags & _DRM_FLAG_MEMTYPE_MAPPABLE)
- cur_flags |= DRM_BO_FLAG_MAPPABLE;
- if (man->flags & _DRM_FLAG_MEMTYPE_CSELECT)
- DRM_FLAG_MASKED(cur_flags, mask, DRM_BO_FLAG_CACHED);
-
- if ((cur_flags & mask & DRM_BO_MASK_MEM) == 0)
- return 0;
-
- if (mem_type == DRM_BO_MEM_LOCAL) {
- *res_mask = cur_flags;
- return 1;
- }
-
- flag_diff = (mask ^ cur_flags);
- if (flag_diff & DRM_BO_FLAG_CACHED_MAPPED)
- cur_flags |= DRM_BO_FLAG_CACHED_MAPPED;
-
- if ((flag_diff & DRM_BO_FLAG_CACHED) &&
- (!(mask & DRM_BO_FLAG_CACHED) ||
- (mask & DRM_BO_FLAG_FORCE_CACHING)))
- return 0;
-
- if ((flag_diff & DRM_BO_FLAG_MAPPABLE) &&
- ((mask & DRM_BO_FLAG_MAPPABLE) ||
- (mask & DRM_BO_FLAG_FORCE_MAPPABLE)))
- return 0;
-
- *res_mask = cur_flags;
- return 1;
-}
-
-/**
- * Creates space for memory region @mem according to its type.
- *
- * This function first searches for free space in compatible memory types in
- * the priority order defined by the driver. If free space isn't found, then
- * drm_bo_mem_force_space is attempted in priority order to evict and find
- * space.
- */
-int drm_bo_mem_space(struct drm_buffer_object *bo,
- struct drm_bo_mem_reg *mem, int no_wait)
-{
- struct drm_device *dev = bo->dev;
- struct drm_buffer_manager *bm = &dev->bm;
- struct drm_mem_type_manager *man;
-
- uint32_t num_prios = dev->driver->bo_driver->num_mem_type_prio;
- const uint32_t *prios = dev->driver->bo_driver->mem_type_prio;
- uint32_t i;
- uint32_t mem_type = DRM_BO_MEM_LOCAL;
- uint32_t cur_flags;
- int type_found = 0;
- int type_ok = 0;
- int has_eagain = 0;
- struct drm_mm_node *node = NULL;
- int ret;
-
- mem->mm_node = NULL;
- for (i = 0; i < num_prios; ++i) {
- mem_type = prios[i];
- man = &bm->man[mem_type];
-
- type_ok = drm_bo_mt_compatible(man,
- bo->type == drm_bo_type_user,
- mem_type, mem->proposed_flags,
- &cur_flags);
-
- if (!type_ok)
- continue;
-
- if (mem_type == DRM_BO_MEM_LOCAL)
- break;
-
- if ((mem_type == bo->pinned_mem_type) &&
- (bo->pinned_node != NULL)) {
- node = bo->pinned_node;
- break;
- }
-
- mutex_lock(&dev->struct_mutex);
- if (man->has_type && man->use_type) {
- type_found = 1;
- node = drm_mm_search_free(&man->manager, mem->num_pages,
- mem->page_alignment, 1);
- if (node)
- node = drm_mm_get_block(node, mem->num_pages,
- mem->page_alignment);
- }
- mutex_unlock(&dev->struct_mutex);
- if (node)
- break;
- }
-
- if ((type_ok && (mem_type == DRM_BO_MEM_LOCAL)) || node) {
- mem->mm_node = node;
- mem->mem_type = mem_type;
- mem->flags = cur_flags;
- return 0;
- }
-
- if (!type_found)
- return -EINVAL;
-
- num_prios = dev->driver->bo_driver->num_mem_busy_prio;
- prios = dev->driver->bo_driver->mem_busy_prio;
-
- for (i = 0; i < num_prios; ++i) {
- mem_type = prios[i];
- man = &bm->man[mem_type];
-
- if (!man->has_type)
- continue;
-
- if (!drm_bo_mt_compatible(man,
- bo->type == drm_bo_type_user,
- mem_type,
- mem->proposed_flags,
- &cur_flags))
- continue;
-
- ret = drm_bo_mem_force_space(dev, mem, mem_type, no_wait);
-
- if (ret == 0 && mem->mm_node) {
- mem->flags = cur_flags;
- return 0;
- }
-
- if (ret == -EAGAIN)
- has_eagain = 1;
- }
-
- ret = (has_eagain) ? -EAGAIN : -ENOMEM;
- return ret;
-}
-EXPORT_SYMBOL(drm_bo_mem_space);
-
-/*
- * drm_bo_propose_flags:
- *
- * @bo: the buffer object getting new flags
- *
- * @new_flags: the new set of proposed flag bits
- *
- * @new_mask: the mask of bits changed in new_flags
- *
- * Modify the proposed_flag bits in @bo
- */
-static int drm_bo_modify_proposed_flags (struct drm_buffer_object *bo,
- uint64_t new_flags, uint64_t new_mask)
-{
- uint32_t new_access;
-
- /* Copy unchanging bits from existing proposed_flags */
- DRM_FLAG_MASKED(new_flags, bo->mem.proposed_flags, ~new_mask);
-
- if (bo->type == drm_bo_type_user &&
- ((new_flags & (DRM_BO_FLAG_CACHED | DRM_BO_FLAG_FORCE_CACHING)) !=
- (DRM_BO_FLAG_CACHED | DRM_BO_FLAG_FORCE_CACHING))) {
- DRM_ERROR("User buffers require cache-coherent memory.\n");
- return -EINVAL;
- }
-
- if (bo->type != drm_bo_type_kernel && (new_mask & DRM_BO_FLAG_NO_EVICT) && !DRM_SUSER(DRM_CURPROC)) {
- DRM_ERROR("DRM_BO_FLAG_NO_EVICT is only available to priviliged processes.\n");
- return -EPERM;
- }
-
- if (likely(new_mask & DRM_BO_MASK_MEM) &&
- (bo->mem.flags & DRM_BO_FLAG_NO_EVICT) &&
- !DRM_SUSER(DRM_CURPROC)) {
- if (likely(bo->mem.flags & new_flags & new_mask &
- DRM_BO_MASK_MEM))
- new_flags = (new_flags & ~DRM_BO_MASK_MEM) |
- (bo->mem.flags & DRM_BO_MASK_MEM);
- else {
- DRM_ERROR("Incompatible memory type specification "
- "for NO_EVICT buffer.\n");
- return -EPERM;
- }
- }
-
- if ((new_flags & DRM_BO_FLAG_NO_MOVE)) {
- DRM_ERROR("DRM_BO_FLAG_NO_MOVE is not properly implemented yet.\n");
- return -EPERM;
- }
-
- new_access = new_flags & (DRM_BO_FLAG_EXE | DRM_BO_FLAG_WRITE |
- DRM_BO_FLAG_READ);
-
- if (new_access == 0) {
- DRM_ERROR("Invalid buffer object rwx properties\n");
- return -EINVAL;
- }
-
- bo->mem.proposed_flags = new_flags;
- return 0;
-}
-
-/*
- * Call dev->struct_mutex locked.
- */
-
-struct drm_buffer_object *drm_lookup_buffer_object(struct drm_file *file_priv,
- uint32_t handle, int check_owner)
-{
- struct drm_user_object *uo;
- struct drm_buffer_object *bo;
-
- uo = drm_lookup_user_object(file_priv, handle);
-
- if (!uo || (uo->type != drm_buffer_type)) {
- DRM_ERROR("Could not find buffer object 0x%08x\n", handle);
- return NULL;
- }
-
- if (check_owner && file_priv != uo->owner) {
- if (!drm_lookup_ref_object(file_priv, uo, _DRM_REF_USE))
- return NULL;
- }
-
- bo = drm_user_object_entry(uo, struct drm_buffer_object, base);
- atomic_inc(&bo->usage);
- return bo;
-}
-EXPORT_SYMBOL(drm_lookup_buffer_object);
-
-/*
- * Call bo->mutex locked.
- * Returns -EBUSY if the buffer is currently rendered to or from. 0 otherwise.
- * Doesn't do any fence flushing as opposed to the drm_bo_busy function.
- */
-
-static int drm_bo_quick_busy(struct drm_buffer_object *bo, int check_unfenced)
-{
- struct drm_fence_object *fence = bo->fence;
-
- if (check_unfenced && (bo->priv_flags & _DRM_BO_FLAG_UNFENCED))
- return -EBUSY;
-
- if (fence) {
- if (drm_fence_object_signaled(fence, bo->fence_type)) {
- drm_fence_usage_deref_unlocked(&bo->fence);
- return 0;
- }
- return -EBUSY;
- }
- return 0;
-}
-
-int drm_bo_evict_cached(struct drm_buffer_object *bo)
-{
- int ret = 0;
-
- BUG_ON(bo->priv_flags & _DRM_BO_FLAG_UNFENCED);
- if (bo->mem.mm_node)
- ret = drm_bo_evict(bo, DRM_BO_MEM_TT, 1);
- return ret;
-}
-
-EXPORT_SYMBOL(drm_bo_evict_cached);
-/*
- * Wait until a buffer is unmapped.
- */
-
-static int drm_bo_wait_unmapped(struct drm_buffer_object *bo, int no_wait)
-{
- int ret = 0;
-
- if (likely(atomic_read(&bo->mapped)) == 0)
- return 0;
-
- if (unlikely(no_wait))
- return -EBUSY;
-
- do {
- mutex_unlock(&bo->mutex);
- ret = wait_event_interruptible(bo->event_queue,
- atomic_read(&bo->mapped) == 0);
- mutex_lock(&bo->mutex);
- bo->priv_flags |= _DRM_BO_FLAG_UNLOCKED;
-
- if (ret == -ERESTARTSYS)
- ret = -EAGAIN;
- } while((ret == 0) && atomic_read(&bo->mapped) > 0);
-
- return ret;
-}
-
-/*
- * Fill in the ioctl reply argument with buffer info.
- * Bo locked.
- */
-
-void drm_bo_fill_rep_arg(struct drm_buffer_object *bo,
- struct drm_bo_info_rep *rep)
-{
- if (!rep)
- return;
-
- rep->handle = bo->base.hash.key;
- rep->flags = bo->mem.flags;
- rep->size = bo->num_pages * PAGE_SIZE;
- rep->offset = bo->offset;
-
- /*
- * drm_bo_type_device buffers have user-visible
- * handles which can be used to share across
- * processes. Hand that back to the application
- */
- if (bo->type == drm_bo_type_device)
- rep->arg_handle = bo->map_list.user_token;
- else
- rep->arg_handle = 0;
-
- rep->proposed_flags = bo->mem.proposed_flags;
- rep->buffer_start = bo->buffer_start;
- rep->fence_flags = bo->fence_type;
- rep->rep_flags = 0;
- rep->page_alignment = bo->mem.page_alignment;
-
- if ((bo->priv_flags & _DRM_BO_FLAG_UNFENCED) || drm_bo_quick_busy(bo, 1)) {
- DRM_FLAG_MASKED(rep->rep_flags, DRM_BO_REP_BUSY,
- DRM_BO_REP_BUSY);
- }
-}
-EXPORT_SYMBOL(drm_bo_fill_rep_arg);
-
-/*
- * Wait for buffer idle and register that we've mapped the buffer.
- * Mapping is registered as a drm_ref_object with type _DRM_REF_TYPE1,
- * so that if the client dies, the mapping is automatically
- * unregistered.
- */
-
-static int drm_buffer_object_map(struct drm_file *file_priv, uint32_t handle,
- uint32_t map_flags, unsigned hint,
- struct drm_bo_info_rep *rep)
-{
- struct drm_buffer_object *bo;
- struct drm_device *dev = file_priv->minor->dev;
- int ret = 0;
- int no_wait = hint & DRM_BO_HINT_DONT_BLOCK;
-
- mutex_lock(&dev->struct_mutex);
- bo = drm_lookup_buffer_object(file_priv, handle, 1);
- mutex_unlock(&dev->struct_mutex);
-
- if (!bo)
- return -EINVAL;
-
- mutex_lock(&bo->mutex);
- do {
- bo->priv_flags &= ~_DRM_BO_FLAG_UNLOCKED;
-
- ret = drm_bo_wait(bo, 0, 1, no_wait, 1);
- if (unlikely(ret))
- goto out;
-
- if (bo->mem.flags & DRM_BO_FLAG_CACHED_MAPPED)
- drm_bo_evict_cached(bo);
-
- } while (unlikely(bo->priv_flags & _DRM_BO_FLAG_UNLOCKED));
-
- atomic_inc(&bo->mapped);
- mutex_lock(&dev->struct_mutex);
- ret = drm_add_ref_object(file_priv, &bo->base, _DRM_REF_TYPE1);
- mutex_unlock(&dev->struct_mutex);
- if (ret) {
- if (atomic_dec_and_test(&bo->mapped))
- wake_up_all(&bo->event_queue);
-
- } else
- drm_bo_fill_rep_arg(bo, rep);
-
- out:
- mutex_unlock(&bo->mutex);
- drm_bo_usage_deref_unlocked(&bo);
-
- return ret;
-}
-
-static int drm_buffer_object_unmap(struct drm_file *file_priv, uint32_t handle)
-{
- struct drm_device *dev = file_priv->minor->dev;
- struct drm_buffer_object *bo;
- struct drm_ref_object *ro;
- int ret = 0;
-
- mutex_lock(&dev->struct_mutex);
-
- bo = drm_lookup_buffer_object(file_priv, handle, 1);
- if (!bo) {
- ret = -EINVAL;
- goto out;
- }
-
- ro = drm_lookup_ref_object(file_priv, &bo->base, _DRM_REF_TYPE1);
- if (!ro) {
- ret = -EINVAL;
- goto out;
- }
-
- drm_remove_ref_object(file_priv, ro);
- drm_bo_usage_deref_locked(&bo);
-out:
- mutex_unlock(&dev->struct_mutex);
- return ret;
-}
-
-/*
- * Call struct-sem locked.
- */
-
-static void drm_buffer_user_object_unmap(struct drm_file *file_priv,
- struct drm_user_object *uo,
- enum drm_ref_type action)
-{
- struct drm_buffer_object *bo =
- drm_user_object_entry(uo, struct drm_buffer_object, base);
-
- /*
- * We DON'T want to take the bo->lock here, because we want to
- * hold it when we wait for unmapped buffer.
- */
-
- BUG_ON(action != _DRM_REF_TYPE1);
-
- if (atomic_dec_and_test(&bo->mapped))
- wake_up_all(&bo->event_queue);
-}
-
-/*
- * bo->mutex locked.
- * Note that new_mem_flags are NOT transferred to the bo->mem.proposed_flags.
- */
-
-int drm_bo_move_buffer(struct drm_buffer_object *bo, uint64_t new_mem_flags,
- int no_wait, int move_unfenced)
-{
- struct drm_device *dev = bo->dev;
- struct drm_buffer_manager *bm = &dev->bm;
- int ret = 0;
- struct drm_bo_mem_reg mem;
-
- BUG_ON(bo->fence != NULL);
-
- mem.num_pages = bo->num_pages;
- mem.size = mem.num_pages << PAGE_SHIFT;
- mem.proposed_flags = new_mem_flags;
- mem.page_alignment = bo->mem.page_alignment;
-
- mutex_lock(&bm->evict_mutex);
- mutex_lock(&dev->struct_mutex);
- list_del_init(&bo->lru);
- mutex_unlock(&dev->struct_mutex);
-
- /*
- * Determine where to move the buffer.
- */
- ret = drm_bo_mem_space(bo, &mem, no_wait);
- if (ret)
- goto out_unlock;
-
- ret = drm_bo_handle_move_mem(bo, &mem, 0, no_wait);
-
-out_unlock:
- mutex_lock(&dev->struct_mutex);
- if (ret || !move_unfenced) {
- if (mem.mm_node) {
- if (mem.mm_node != bo->pinned_node)
- drm_mm_put_block(mem.mm_node);
- mem.mm_node = NULL;
- }
- drm_bo_add_to_lru(bo);
- if (bo->priv_flags & _DRM_BO_FLAG_UNFENCED) {
- wake_up_all(&bo->event_queue);
- DRM_FLAG_MASKED(bo->priv_flags, 0,
- _DRM_BO_FLAG_UNFENCED);
- }
- } else {
- list_add_tail(&bo->lru, &bm->unfenced);
- DRM_FLAG_MASKED(bo->priv_flags, _DRM_BO_FLAG_UNFENCED,
- _DRM_BO_FLAG_UNFENCED);
- }
- mutex_unlock(&dev->struct_mutex);
- mutex_unlock(&bm->evict_mutex);
- return ret;
-}
-
-static int drm_bo_mem_compat(struct drm_bo_mem_reg *mem)
-{
- uint32_t flag_diff = (mem->proposed_flags ^ mem->flags);
-
- if ((mem->proposed_flags & mem->flags & DRM_BO_MASK_MEM) == 0)
- return 0;
- if ((flag_diff & DRM_BO_FLAG_CACHED) &&
- (/* !(mem->proposed_flags & DRM_BO_FLAG_CACHED) ||*/
- (mem->proposed_flags & DRM_BO_FLAG_FORCE_CACHING)))
- return 0;
-
- if ((flag_diff & DRM_BO_FLAG_MAPPABLE) &&
- ((mem->proposed_flags & DRM_BO_FLAG_MAPPABLE) ||
- (mem->proposed_flags & DRM_BO_FLAG_FORCE_MAPPABLE)))
- return 0;
- return 1;
-}
-
-/**
- * drm_buffer_object_validate:
- *
- * @bo: the buffer object to modify
- *
- * @fence_class: the new fence class covering this buffer
- *
- * @move_unfenced: a boolean indicating whether switching the
- * memory space of this buffer should cause the buffer to
- * be placed on the unfenced list.
- *
- * @no_wait: whether this function should return -EBUSY instead
- * of waiting.
- *
- * Change buffer access parameters. This can involve moving
- * the buffer to the correct memory type, pinning the buffer
- * or changing the class/type of fence covering this buffer
- *
- * Must be called with bo locked.
- */
-
-static int drm_buffer_object_validate(struct drm_buffer_object *bo,
- uint32_t fence_class,
- int move_unfenced, int no_wait,
- int move_buffer)
-{
- struct drm_device *dev = bo->dev;
- struct drm_buffer_manager *bm = &dev->bm;
- int ret;
-
- if (move_buffer) {
- ret = drm_bo_move_buffer(bo, bo->mem.proposed_flags, no_wait,
- move_unfenced);
- if (ret) {
- if (ret != -EAGAIN)
- DRM_ERROR("Failed moving buffer.\n");
- if (ret == -ENOMEM)
- DRM_ERROR("Out of aperture space or "
- "DRM memory quota.\n");
- return ret;
- }
- }
-
- /*
- * Pinned buffers.
- */
-
- if (bo->mem.proposed_flags & (DRM_BO_FLAG_NO_EVICT | DRM_BO_FLAG_NO_MOVE)) {
- bo->pinned_mem_type = bo->mem.mem_type;
- mutex_lock(&dev->struct_mutex);
- list_del_init(&bo->pinned_lru);
- drm_bo_add_to_pinned_lru(bo);
-
- if (bo->pinned_node != bo->mem.mm_node) {
- if (bo->pinned_node != NULL)
- drm_mm_put_block(bo->pinned_node);
- bo->pinned_node = bo->mem.mm_node;
- }
-
- mutex_unlock(&dev->struct_mutex);
-
- } else if (bo->pinned_node != NULL) {
-
- mutex_lock(&dev->struct_mutex);
-
- if (bo->pinned_node != bo->mem.mm_node)
- drm_mm_put_block(bo->pinned_node);
-
- list_del_init(&bo->pinned_lru);
- bo->pinned_node = NULL;
- mutex_unlock(&dev->struct_mutex);
-
- }
-
- /*
- * We might need to add a TTM.
- */
-
- if (bo->mem.mem_type == DRM_BO_MEM_LOCAL && bo->ttm == NULL) {
- ret = drm_bo_add_ttm(bo);
- if (ret)
- return ret;
- }
- /*
- * Validation has succeeded, move the access and other
- * non-mapping-related flag bits from the proposed flags to
- * the active flags
- */
-
- DRM_FLAG_MASKED(bo->mem.flags, bo->mem.proposed_flags, ~DRM_BO_MASK_MEMTYPE);
-
- /*
- * Finally, adjust lru to be sure.
- */
-
- mutex_lock(&dev->struct_mutex);
- list_del(&bo->lru);
- if (move_unfenced) {
- list_add_tail(&bo->lru, &bm->unfenced);
- DRM_FLAG_MASKED(bo->priv_flags, _DRM_BO_FLAG_UNFENCED,
- _DRM_BO_FLAG_UNFENCED);
- } else {
- drm_bo_add_to_lru(bo);
- if (bo->priv_flags & _DRM_BO_FLAG_UNFENCED) {
- wake_up_all(&bo->event_queue);
- DRM_FLAG_MASKED(bo->priv_flags, 0,
- _DRM_BO_FLAG_UNFENCED);
- }
- }
- mutex_unlock(&dev->struct_mutex);
-
- return 0;
-}
-
-/*
- * This function is called with bo->mutex locked, but may release it
- * temporarily to wait for events.
- */
-
-static int drm_bo_prepare_for_validate(struct drm_buffer_object *bo,
- uint64_t flags,
- uint64_t mask,
- uint32_t hint,
- uint32_t fence_class,
- int no_wait,
- int *move_buffer)
-{
- struct drm_device *dev = bo->dev;
- struct drm_bo_driver *driver = dev->driver->bo_driver;
- uint32_t ftype;
-
- int ret;
-
- DRM_DEBUG("Proposed flags 0x%016llx, Old flags 0x%016llx\n",
- (unsigned long long) bo->mem.proposed_flags,
- (unsigned long long) bo->mem.flags);
-
- ret = drm_bo_modify_proposed_flags (bo, flags, mask);
- if (ret)
- return ret;
-
- ret = drm_bo_wait_unmapped(bo, no_wait);
- if (ret)
- return ret;
-
- ret = driver->fence_type(bo, &fence_class, &ftype);
-
- if (ret) {
- DRM_ERROR("Driver did not support given buffer permissions.\n");
- return ret;
- }
-
- /*
- * We're switching command submission mechanism,
- * or cannot simply rely on the hardware serializing for us.
- * Insert a driver-dependant barrier or wait for buffer idle.
- */
-
- if ((fence_class != bo->fence_class) ||
- ((ftype ^ bo->fence_type) & bo->fence_type)) {
-
- ret = -EINVAL;
- if (driver->command_stream_barrier) {
- ret = driver->command_stream_barrier(bo,
- fence_class,
- ftype,
- no_wait);
- }
- if (ret && ret != -EAGAIN)
- ret = drm_bo_wait(bo, 0, 1, no_wait, 1);
-
- if (ret)
- return ret;
- }
-
- bo->new_fence_class = fence_class;
- bo->new_fence_type = ftype;
-
- /*
- * Check whether we need to move buffer.
- */
-
- *move_buffer = 0;
- if (!drm_bo_mem_compat(&bo->mem)) {
- *move_buffer = 1;
- ret = drm_bo_wait(bo, 0, 1, no_wait, 1);
- }
-
- return ret;
-}
-
-/**
- * drm_bo_do_validate:
- *
- * @bo: the buffer object
- *
- * @flags: access rights, mapping parameters and cacheability. See
- * the DRM_BO_FLAG_* values in drm.h
- *
- * @mask: Which flag values to change; this allows callers to modify
- * things without knowing the current state of other flags.
- *
- * @hint: changes the proceedure for this operation, see the DRM_BO_HINT_*
- * values in drm.h.
- *
- * @fence_class: a driver-specific way of doing fences. Presumably,
- * this would be used if the driver had more than one submission and
- * fencing mechanism. At this point, there isn't any use of this
- * from the user mode code.
- *
- * @rep: To be stuffed with the reply from validation
- *
- * 'validate' a buffer object. This changes where the buffer is
- * located, along with changing access modes.
- */
-
-int drm_bo_do_validate(struct drm_buffer_object *bo,
- uint64_t flags, uint64_t mask, uint32_t hint,
- uint32_t fence_class,
- struct drm_bo_info_rep *rep)
-{
- int ret;
- int no_wait = (hint & DRM_BO_HINT_DONT_BLOCK) != 0;
- int move_buffer;
-
- mutex_lock(&bo->mutex);
-
- do {
- bo->priv_flags &= ~_DRM_BO_FLAG_UNLOCKED;
-
- ret = drm_bo_prepare_for_validate(bo, flags, mask, hint,
- fence_class, no_wait,
- &move_buffer);
- if (ret)
- goto out;
-
- } while(unlikely(bo->priv_flags & _DRM_BO_FLAG_UNLOCKED));
-
- ret = drm_buffer_object_validate(bo,
- fence_class,
- !(hint & DRM_BO_HINT_DONT_FENCE),
- no_wait,
- move_buffer);
-
- BUG_ON(bo->priv_flags & _DRM_BO_FLAG_UNLOCKED);
-out:
- if (rep)
- drm_bo_fill_rep_arg(bo, rep);
-
- mutex_unlock(&bo->mutex);
-
- return ret;
-}
-EXPORT_SYMBOL(drm_bo_do_validate);
-
-/**
- * drm_bo_handle_validate
- *
- * @file_priv: the drm file private, used to get a handle to the user context
- *
- * @handle: the buffer object handle
- *
- * @flags: access rights, mapping parameters and cacheability. See
- * the DRM_BO_FLAG_* values in drm.h
- *
- * @mask: Which flag values to change; this allows callers to modify
- * things without knowing the current state of other flags.
- *
- * @hint: changes the proceedure for this operation, see the DRM_BO_HINT_*
- * values in drm.h.
- *
- * @fence_class: a driver-specific way of doing fences. Presumably,
- * this would be used if the driver had more than one submission and
- * fencing mechanism. At this point, there isn't any use of this
- * from the user mode code.
- *
- * @rep: To be stuffed with the reply from validation
- *
- * @bp_rep: To be stuffed with the buffer object pointer
- *
- * Perform drm_bo_do_validate on a buffer referenced by a user-space handle instead
- * of a pointer to a buffer object. Optionally return a pointer to the buffer object.
- * This is a convenience wrapper only.
- */
-
-int drm_bo_handle_validate(struct drm_file *file_priv, uint32_t handle,
- uint64_t flags, uint64_t mask,
- uint32_t hint,
- uint32_t fence_class,
- struct drm_bo_info_rep *rep,
- struct drm_buffer_object **bo_rep)
-{
- struct drm_device *dev = file_priv->minor->dev;
- struct drm_buffer_object *bo;
- int ret;
-
- mutex_lock(&dev->struct_mutex);
- bo = drm_lookup_buffer_object(file_priv, handle, 1);
- mutex_unlock(&dev->struct_mutex);
-
- if (!bo)
- return -EINVAL;
-
- if (bo->base.owner != file_priv)
- mask &= ~(DRM_BO_FLAG_NO_EVICT | DRM_BO_FLAG_NO_MOVE);
-
- ret = drm_bo_do_validate(bo, flags, mask, hint, fence_class, rep);
-
- if (!ret && bo_rep)
- *bo_rep = bo;
- else
- drm_bo_usage_deref_unlocked(&bo);
-
- return ret;
-}
-EXPORT_SYMBOL(drm_bo_handle_validate);
-
-
-static int drm_bo_handle_info(struct drm_file *file_priv, uint32_t handle,
- struct drm_bo_info_rep *rep)
-{
- struct drm_device *dev = file_priv->minor->dev;
- struct drm_buffer_object *bo;
-
- mutex_lock(&dev->struct_mutex);
- bo = drm_lookup_buffer_object(file_priv, handle, 1);
- mutex_unlock(&dev->struct_mutex);
-
- if (!bo)
- return -EINVAL;
-
- mutex_lock(&bo->mutex);
-
- /*
- * FIXME: Quick busy here?
- */
-
- drm_bo_busy(bo, 1);
- drm_bo_fill_rep_arg(bo, rep);
- mutex_unlock(&bo->mutex);
- drm_bo_usage_deref_unlocked(&bo);
- return 0;
-}
-
-static int drm_bo_handle_wait(struct drm_file *file_priv, uint32_t handle,
- uint32_t hint,
- struct drm_bo_info_rep *rep)
-{
- struct drm_device *dev = file_priv->minor->dev;
- struct drm_buffer_object *bo;
- int no_wait = hint & DRM_BO_HINT_DONT_BLOCK;
- int ret;
-
- mutex_lock(&dev->struct_mutex);
- bo = drm_lookup_buffer_object(file_priv, handle, 1);
- mutex_unlock(&dev->struct_mutex);
-
- if (!bo)
- return -EINVAL;
-
- mutex_lock(&bo->mutex);
- ret = drm_bo_wait(bo, hint & DRM_BO_HINT_WAIT_LAZY, 1, no_wait, 1);
- if (ret)
- goto out;
-
- drm_bo_fill_rep_arg(bo, rep);
-out:
- mutex_unlock(&bo->mutex);
- drm_bo_usage_deref_unlocked(&bo);
- return ret;
-}
-
-int drm_buffer_object_create(struct drm_device *dev,
- unsigned long size,
- enum drm_bo_type type,
- uint64_t flags,
- uint32_t hint,
- uint32_t page_alignment,
- unsigned long buffer_start,
- struct drm_buffer_object **buf_obj)
-{
- struct drm_buffer_manager *bm = &dev->bm;
- struct drm_buffer_object *bo;
- int ret = 0;
- unsigned long num_pages;
-
- size += buffer_start & ~PAGE_MASK;
- num_pages = (size + PAGE_SIZE - 1) >> PAGE_SHIFT;
- if (num_pages == 0) {
- DRM_ERROR("Illegal buffer object size.\n");
- return -EINVAL;
- }
-
- bo = drm_ctl_calloc(1, sizeof(*bo), DRM_MEM_BUFOBJ);
-
- if (!bo)
- return -ENOMEM;
-
- mutex_init(&bo->mutex);
- mutex_lock(&bo->mutex);
-
- atomic_set(&bo->usage, 1);
- atomic_set(&bo->mapped, 0);
- DRM_INIT_WAITQUEUE(&bo->event_queue);
- INIT_LIST_HEAD(&bo->lru);
- INIT_LIST_HEAD(&bo->pinned_lru);
- INIT_LIST_HEAD(&bo->ddestroy);
- bo->dev = dev;
- bo->type = type;
- bo->num_pages = num_pages;
- bo->mem.mem_type = DRM_BO_MEM_LOCAL;
- bo->mem.num_pages = bo->num_pages;
- bo->mem.mm_node = NULL;
- bo->mem.page_alignment = page_alignment;
- bo->buffer_start = buffer_start & PAGE_MASK;
- bo->priv_flags = 0;
- bo->mem.flags = (DRM_BO_FLAG_MEM_LOCAL | DRM_BO_FLAG_CACHED |
- DRM_BO_FLAG_MAPPABLE);
- bo->mem.proposed_flags = 0;
- atomic_inc(&bm->count);
- /*
- * Use drm_bo_modify_proposed_flags to error-check the proposed flags
- */
- ret = drm_bo_modify_proposed_flags (bo, flags, flags);
- if (ret)
- goto out_err;
-
- /*
- * For drm_bo_type_device buffers, allocate
- * address space from the device so that applications
- * can mmap the buffer from there
- */
- if (bo->type == drm_bo_type_device) {
- mutex_lock(&dev->struct_mutex);
- ret = drm_bo_setup_vm_locked(bo);
- mutex_unlock(&dev->struct_mutex);
- if (ret)
- goto out_err;
- }
-
- mutex_unlock(&bo->mutex);
- ret = drm_bo_do_validate(bo, 0, 0, hint | DRM_BO_HINT_DONT_FENCE,
- 0, NULL);
- if (ret)
- goto out_err_unlocked;
-
- *buf_obj = bo;
- return 0;
-
-out_err:
- mutex_unlock(&bo->mutex);
-out_err_unlocked:
- drm_bo_usage_deref_unlocked(&bo);
- return ret;
-}
-EXPORT_SYMBOL(drm_buffer_object_create);
-
-
-static int drm_bo_add_user_object(struct drm_file *file_priv,
- struct drm_buffer_object *bo, int shareable)
-{
- struct drm_device *dev = file_priv->minor->dev;
- int ret;
-
- mutex_lock(&dev->struct_mutex);
- ret = drm_add_user_object(file_priv, &bo->base, shareable);
- if (ret)
- goto out;
-
- bo->base.remove = drm_bo_base_deref_locked;
- bo->base.type = drm_buffer_type;
- bo->base.ref_struct_locked = NULL;
- bo->base.unref = drm_buffer_user_object_unmap;
-
-out:
- mutex_unlock(&dev->struct_mutex);
- return ret;
-}
-
-int drm_bo_create_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv)
-{
- struct drm_bo_create_arg *arg = data;
- struct drm_bo_create_req *req = &arg->d.req;
- struct drm_bo_info_rep *rep = &arg->d.rep;
- struct drm_buffer_object *entry;
- enum drm_bo_type bo_type;
- int ret = 0;
-
- DRM_DEBUG("drm_bo_create_ioctl: %dkb, %dkb align\n",
- (int)(req->size / 1024), req->page_alignment * 4);
-
- if (!dev->bm.initialized) {
- DRM_ERROR("Buffer object manager is not initialized.\n");
- return -EINVAL;
- }
-
- /*
- * If the buffer creation request comes in with a starting address,
- * that points at the desired user pages to map. Otherwise, create
- * a drm_bo_type_device buffer, which uses pages allocated from the kernel
- */
- bo_type = (req->buffer_start) ? drm_bo_type_user : drm_bo_type_device;
-
- /*
- * User buffers cannot be shared
- */
- if (bo_type == drm_bo_type_user)
- req->flags &= ~DRM_BO_FLAG_SHAREABLE;
-
- ret = drm_buffer_object_create(file_priv->minor->dev,
- req->size, bo_type, req->flags,
- req->hint, req->page_alignment,
- req->buffer_start, &entry);
- if (ret)
- goto out;
-
- ret = drm_bo_add_user_object(file_priv, entry,
- req->flags & DRM_BO_FLAG_SHAREABLE);
- if (ret) {
- drm_bo_usage_deref_unlocked(&entry);
- goto out;
- }
-
- mutex_lock(&entry->mutex);
- drm_bo_fill_rep_arg(entry, rep);
- mutex_unlock(&entry->mutex);
-
-out:
- return ret;
-}
-
-int drm_bo_setstatus_ioctl(struct drm_device *dev,
- void *data, struct drm_file *file_priv)
-{
- struct drm_bo_map_wait_idle_arg *arg = data;
- struct drm_bo_info_req *req = &arg->d.req;
- struct drm_bo_info_rep *rep = &arg->d.rep;
- struct drm_buffer_object *bo;
- int ret;
-
- if (!dev->bm.initialized) {
- DRM_ERROR("Buffer object manager is not initialized.\n");
- return -EINVAL;
- }
-
- ret = drm_bo_read_lock(&dev->bm.bm_lock, 1);
- if (ret)
- return ret;
-
- mutex_lock(&dev->struct_mutex);
- bo = drm_lookup_buffer_object(file_priv, req->handle, 1);
- mutex_unlock(&dev->struct_mutex);
-
- if (!bo)
- return -EINVAL;
-
- if (bo->base.owner != file_priv)
- req->mask &= ~(DRM_BO_FLAG_NO_EVICT | DRM_BO_FLAG_NO_MOVE);
-
- ret = drm_bo_do_validate(bo, req->flags, req->mask,
- req->hint | DRM_BO_HINT_DONT_FENCE,
- bo->fence_class, rep);
-
- drm_bo_usage_deref_unlocked(&bo);
-
- (void) drm_bo_read_unlock(&dev->bm.bm_lock);
-
- return ret;
-}
-
-int drm_bo_map_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv)
-{
- struct drm_bo_map_wait_idle_arg *arg = data;
- struct drm_bo_info_req *req = &arg->d.req;
- struct drm_bo_info_rep *rep = &arg->d.rep;
- int ret;
- if (!dev->bm.initialized) {
- DRM_ERROR("Buffer object manager is not initialized.\n");
- return -EINVAL;
- }
-
- ret = drm_buffer_object_map(file_priv, req->handle, req->mask,
- req->hint, rep);
- if (ret)
- return ret;
-
- return 0;
-}
-
-int drm_bo_unmap_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv)
-{
- struct drm_bo_handle_arg *arg = data;
- int ret;
- if (!dev->bm.initialized) {
- DRM_ERROR("Buffer object manager is not initialized.\n");
- return -EINVAL;
- }
-
- ret = drm_buffer_object_unmap(file_priv, arg->handle);
- return ret;
-}
-
-
-int drm_bo_reference_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv)
-{
- struct drm_bo_reference_info_arg *arg = data;
- struct drm_bo_handle_arg *req = &arg->d.req;
- struct drm_b...
[truncated message content] |
|
From: <jb...@ke...> - 2009-06-22 19:28:15
|
tests/modetest/modetest.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
New commits:
commit 81644198aeced288d26e17fadd8e5eb19798352f
Author: Jesse Barnes <jb...@vi...>
Date: Mon Jun 22 12:27:49 2009 -0700
modetest: use gtt unmap for object
Match gtt map/unmap for correctness.
diff --git a/tests/modetest/modetest.c b/tests/modetest/modetest.c
index 58e0e4c..6c69a57 100644
--- a/tests/modetest/modetest.c
+++ b/tests/modetest/modetest.c
@@ -447,7 +447,7 @@ create_test_buffer(drm_intel_bufmgr *bufmgr,
d = div(i, width);
fb_ptr[i] = 0x00130502 * (d.quot >> 6) + 0x000a1120 * (d.rem >> 6);
}
- drm_intel_bo_unmap(bo);
+ drm_intel_gem_bo_unmap_gtt(bo);
*bo_out = bo;
*stride_out = stride;
|
|
From: <ai...@ke...> - 2009-06-17 07:48:35
|
configure.ac | 9
libdrm/Makefile.am | 6
libdrm/radeon/Makefile.am | 53 +++
libdrm/radeon/libdrm_radeon.pc.in | 10
libdrm/radeon/radeon_bo.h | 179 ++++++++++++
libdrm/radeon/radeon_bo_gem.c | 254 +++++++++++++++++
libdrm/radeon/radeon_bo_gem.h | 42 ++
libdrm/radeon/radeon_cs.h | 208 ++++++++++++++
libdrm/radeon/radeon_cs_gem.c | 544 ++++++++++++++++++++++++++++++++++++++
libdrm/radeon/radeon_cs_gem.h | 41 ++
libdrm/radeon/radeon_track.c | 140 +++++++++
libdrm/radeon/radeon_track.h | 64 ++++
shared-core/radeon_drm.h | 131 +++++++++
13 files changed, 1679 insertions(+), 2 deletions(-)
New commits:
commit 2fa2db138ba989bfa1a8cd9ab66d83fb7369249e
Author: Dave Airlie <ai...@li...>
Date: Wed Jun 17 17:47:42 2009 +1000
libdrm/radeon: add initial libdrm_radeon
requires --enable-radeon-experimental-api for now
diff --git a/configure.ac b/configure.ac
index 9d1a8ef..be2fbbf 100644
--- a/configure.ac
+++ b/configure.ac
@@ -47,6 +47,11 @@ AC_ARG_ENABLE(nouveau-experimental-api,
[Enable support for nouveau's experimental API (default: disabled)]),
[NOUVEAU=$enableval], [NOUVEAU=no])
+AC_ARG_ENABLE(radeon-experimental-api,
+ AS_HELP_STRING([--enable-radeon-experimental-api],
+ [Enable support for radeon's KMS API (default: disabled)]),
+ [RADEON=$enableval], [RADEON=no])
+
dnl ===========================================================================
dnl check compiler flags
AC_DEFUN([LIBDRM_CC_TRY_FLAG], [
@@ -125,6 +130,8 @@ fi
AM_CONDITIONAL(HAVE_NOUVEAU, [test "x$NOUVEAU" = xyes])
+AM_CONDITIONAL(HAVE_RADEON, [test "x$RADEON" = xyes])
+
PKG_CHECK_MODULES(CAIRO, cairo, [HAVE_CAIRO=yes], [HAVE_CAIRO=no])
if test "x$HAVE_CAIRO" = xyes; then
AC_DEFINE(HAVE_CAIRO, 1, [Have cairo support])
@@ -144,6 +151,8 @@ AC_OUTPUT([
Makefile
libdrm/Makefile
libdrm/intel/Makefile
+ libdrm/radeon/Makefile
+ libdrm/radeon/libdrm_radeon.pc
libdrm/nouveau/Makefile
libdrm/nouveau/libdrm_nouveau.pc
shared-core/Makefile
diff --git a/libdrm/Makefile.am b/libdrm/Makefile.am
index 458420a..0c07220 100644
--- a/libdrm/Makefile.am
+++ b/libdrm/Makefile.am
@@ -22,7 +22,11 @@ if HAVE_NOUVEAU
NOUVEAU_SUBDIR = nouveau
endif
-SUBDIRS = . intel $(NOUVEAU_SUBDIR)
+if HAVE_RADEON
+RADEON_SUBDIR = radeon
+endif
+
+SUBDIRS = . intel $(NOUVEAU_SUBDIR) $(RADEON_SUBDIR)
libdrm_la_LTLIBRARIES = libdrm.la
libdrm_ladir = $(libdir)
diff --git a/libdrm/radeon/Makefile.am b/libdrm/radeon/Makefile.am
new file mode 100644
index 0000000..bc8a5b8
--- /dev/null
+++ b/libdrm/radeon/Makefile.am
@@ -0,0 +1,53 @@
+# Copyright © 2008 Jérôme Glisse
+#
+# Permission is hereby granted, free of charge, to any person obtaining a
+# copy of this software and associated documentation files (the "Software"),
+# to deal in the Software without restriction, including without limitation
+# the rights to use, copy, modify, merge, publish, distribute, sublicense,
+# and/or sell copies of the Software, and to permit persons to whom the
+# Software is furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice (including the next
+# paragraph) shall be included in all copies or substantial portions of the
+# Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+# IN THE SOFTWARE.
+#
+# Authors:
+# Jérôme Glisse <gl...@fr...>
+
+AM_CFLAGS = \
+ $(WARN_CFLAGS) \
+ -I$(top_srcdir)/libdrm \
+ -I$(top_srcdir)/libdrm/radeon \
+ $(PTHREADSTUBS_CFLAGS) \
+ -I$(top_srcdir)/shared-core
+
+libdrm_radeon_la_LTLIBRARIES = libdrm_radeon.la
+libdrm_radeon_ladir = $(libdir)
+libdrm_radeon_la_LDFLAGS = -version-number 1:0:0 -no-undefined
+libdrm_radeon_la_LIBADD = ../libdrm.la @PTHREADSTUBS_LIBS@
+
+libdrm_radeon_la_SOURCES = \
+ radeon_bo_gem.c \
+ radeon_cs_gem.c \
+ radeon_track.c
+
+libdrm_radeonincludedir = ${includedir}/drm
+libdrm_radeoninclude_HEADERS = \
+ radeon_bo.h \
+ radeon_cs.h \
+ radeon_bo_gem.h \
+ radeon_cs_gem.h \
+ radeon_track.h
+
+pkgconfigdir = @pkgconfigdir@
+pkgconfig_DATA = libdrm_radeon.pc
+
+EXTRA_DIST = libdrm_radeon.pc.in
diff --git a/libdrm/radeon/libdrm_radeon.pc.in b/libdrm/radeon/libdrm_radeon.pc.in
new file mode 100644
index 0000000..3306844
--- /dev/null
+++ b/libdrm/radeon/libdrm_radeon.pc.in
@@ -0,0 +1,10 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: libdrm_radeon
+Description: Userspace interface to kernel DRM services for radeon
+Version: 1.0.1
+Libs: -L${libdir} -ldrm_radeon
+Cflags: -I${includedir} -I${includedir}/drm
diff --git a/libdrm/radeon/radeon_bo.h b/libdrm/radeon/radeon_bo.h
new file mode 100644
index 0000000..3cabdfc
--- /dev/null
+++ b/libdrm/radeon/radeon_bo.h
@@ -0,0 +1,179 @@
+/*
+ * Copyright © 2008 Jérôme Glisse
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS, AUTHORS
+ * AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ */
+/*
+ * Authors:
+ * Jérôme Glisse <gl...@fr...>
+ */
+#ifndef RADEON_BO_H
+#define RADEON_BO_H
+
+#include <stdio.h>
+#include <stdint.h>
+#include "radeon_track.h"
+
+/* bo object */
+#define RADEON_BO_FLAGS_MACRO_TILE 1
+#define RADEON_BO_FLAGS_MICRO_TILE 2
+
+struct radeon_bo_manager;
+
+struct radeon_bo {
+ uint32_t alignment;
+ uint32_t handle;
+ uint32_t size;
+ uint32_t domains;
+ uint32_t flags;
+ unsigned cref;
+#ifdef RADEON_BO_TRACK
+ struct radeon_track *track;
+#endif
+ void *ptr;
+ struct radeon_bo_manager *bom;
+ uint32_t space_accounted;
+};
+
+/* bo functions */
+struct radeon_bo_funcs {
+ struct radeon_bo *(*bo_open)(struct radeon_bo_manager *bom,
+ uint32_t handle,
+ uint32_t size,
+ uint32_t alignment,
+ uint32_t domains,
+ uint32_t flags);
+ void (*bo_ref)(struct radeon_bo *bo);
+ struct radeon_bo *(*bo_unref)(struct radeon_bo *bo);
+ int (*bo_map)(struct radeon_bo *bo, int write);
+ int (*bo_unmap)(struct radeon_bo *bo);
+ int (*bo_wait)(struct radeon_bo *bo);
+};
+
+struct radeon_bo_manager {
+ struct radeon_bo_funcs *funcs;
+ int fd;
+ struct radeon_tracker tracker;
+};
+
+static inline void _radeon_bo_debug(struct radeon_bo *bo,
+ const char *op,
+ const char *file,
+ const char *func,
+ int line)
+{
+ fprintf(stderr, "%s %p 0x%08X 0x%08X 0x%08X [%s %s %d]\n",
+ op, bo, bo->handle, bo->size, bo->cref, file, func, line);
+}
+
+static inline struct radeon_bo *_radeon_bo_open(struct radeon_bo_manager *bom,
+ uint32_t handle,
+ uint32_t size,
+ uint32_t alignment,
+ uint32_t domains,
+ uint32_t flags,
+ const char *file,
+ const char *func,
+ int line)
+{
+ struct radeon_bo *bo;
+
+ bo = bom->funcs->bo_open(bom, handle, size, alignment, domains, flags);
+#ifdef RADEON_BO_TRACK
+ if (bo) {
+ bo->track = radeon_tracker_add_track(&bom->tracker, bo->handle);
+ radeon_track_add_event(bo->track, file, func, "open", line);
+ }
+#endif
+ return bo;
+}
+
+static inline void _radeon_bo_ref(struct radeon_bo *bo,
+ const char *file,
+ const char *func,
+ int line)
+{
+ bo->cref++;
+#ifdef RADEON_BO_TRACK
+ radeon_track_add_event(bo->track, file, func, "ref", line);
+#endif
+ bo->bom->funcs->bo_ref(bo);
+}
+
+static inline struct radeon_bo *_radeon_bo_unref(struct radeon_bo *bo,
+ const char *file,
+ const char *func,
+ int line)
+{
+ bo->cref--;
+#ifdef RADEON_BO_TRACK
+ radeon_track_add_event(bo->track, file, func, "unref", line);
+ if (bo->cref <= 0) {
+ radeon_tracker_remove_track(&bo->bom->tracker, bo->track);
+ bo->track = NULL;
+ }
+#endif
+ return bo->bom->funcs->bo_unref(bo);
+}
+
+static inline int _radeon_bo_map(struct radeon_bo *bo,
+ int write,
+ const char *file,
+ const char *func,
+ int line)
+{
+ return bo->bom->funcs->bo_map(bo, write);
+}
+
+static inline int _radeon_bo_unmap(struct radeon_bo *bo,
+ const char *file,
+ const char *func,
+ int line)
+{
+ return bo->bom->funcs->bo_unmap(bo);
+}
+
+static inline int _radeon_bo_wait(struct radeon_bo *bo,
+ const char *file,
+ const char *func,
+ int line)
+{
+ return bo->bom->funcs->bo_wait(bo);
+}
+
+#define radeon_bo_open(bom, h, s, a, d, f)\
+ _radeon_bo_open(bom, h, s, a, d, f, __FILE__, __FUNCTION__, __LINE__)
+#define radeon_bo_ref(bo)\
+ _radeon_bo_ref(bo, __FILE__, __FUNCTION__, __LINE__)
+#define radeon_bo_unref(bo)\
+ _radeon_bo_unref(bo, __FILE__, __FUNCTION__, __LINE__)
+#define radeon_bo_map(bo, w)\
+ _radeon_bo_map(bo, w, __FILE__, __FUNCTION__, __LINE__)
+#define radeon_bo_unmap(bo)\
+ _radeon_bo_unmap(bo, __FILE__, __FUNCTION__, __LINE__)
+#define radeon_bo_debug(bo, opcode)\
+ _radeon_bo_debug(bo, opcode, __FILE__, __FUNCTION__, __LINE__)
+#define radeon_bo_wait(bo) \
+ _radeon_bo_wait(bo, __FILE__, __func__, __LINE__)
+
+#endif
diff --git a/libdrm/radeon/radeon_bo_gem.c b/libdrm/radeon/radeon_bo_gem.c
new file mode 100644
index 0000000..78439b2
--- /dev/null
+++ b/libdrm/radeon/radeon_bo_gem.c
@@ -0,0 +1,254 @@
+/*
+ * Copyright © 2008 Dave Airlie
+ * Copyright © 2008 Jérôme Glisse
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS, AUTHORS
+ * AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ */
+/*
+ * Authors:
+ * Dave Airlie
+ * Jérôme Glisse <gl...@fr...>
+ */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/mman.h>
+#include <sys/ioctl.h>
+#include <errno.h>
+#include "xf86drm.h"
+#include "drm.h"
+#include "radeon_drm.h"
+#include "radeon_bo.h"
+#include "radeon_bo_gem.h"
+
+struct radeon_bo_gem {
+ struct radeon_bo base;
+ uint32_t name;
+ int map_count;
+};
+
+struct bo_manager_gem {
+ struct radeon_bo_manager base;
+};
+
+static struct radeon_bo *bo_open(struct radeon_bo_manager *bom,
+ uint32_t handle,
+ uint32_t size,
+ uint32_t alignment,
+ uint32_t domains,
+ uint32_t flags)
+{
+ struct radeon_bo_gem *bo;
+ int r;
+
+ bo = (struct radeon_bo_gem*)calloc(1, sizeof(struct radeon_bo_gem));
+ if (bo == NULL) {
+ return NULL;
+ }
+
+ bo->base.bom = bom;
+ bo->base.handle = 0;
+ bo->base.size = size;
+ bo->base.alignment = alignment;
+ bo->base.domains = domains;
+ bo->base.flags = flags;
+ bo->base.ptr = NULL;
+ bo->map_count = 0;
+ if (handle) {
+ struct drm_gem_open open_arg;
+
+ memset(&open_arg, 0, sizeof(open_arg));
+ open_arg.name = handle;
+ r = ioctl(bom->fd, DRM_IOCTL_GEM_OPEN, &open_arg);
+ if (r != 0) {
+ free(bo);
+ return NULL;
+ }
+ bo->base.handle = open_arg.handle;
+ bo->base.size = open_arg.size;
+ bo->name = handle;
+ } else {
+ struct drm_radeon_gem_create args;
+
+ args.size = size;
+ args.alignment = alignment;
+ args.initial_domain = bo->base.domains;
+ args.flags = 0;
+ args.handle = 0;
+ r = drmCommandWriteRead(bom->fd, DRM_RADEON_GEM_CREATE,
+ &args, sizeof(args));
+ bo->base.handle = args.handle;
+ if (r) {
+ fprintf(stderr, "Failed to allocate :\n");
+ fprintf(stderr, " size : %d bytes\n", size);
+ fprintf(stderr, " alignment : %d bytes\n", alignment);
+ fprintf(stderr, " domains : %d\n", bo->base.domains);
+ free(bo);
+ return NULL;
+ }
+ }
+ radeon_bo_ref((struct radeon_bo*)bo);
+ return (struct radeon_bo*)bo;
+}
+
+static void bo_ref(struct radeon_bo *bo)
+{
+}
+
+static struct radeon_bo *bo_unref(struct radeon_bo *bo)
+{
+ struct radeon_bo_gem *bo_gem = (struct radeon_bo_gem*)bo;
+ struct drm_gem_close args;
+
+ if (bo == NULL) {
+ return NULL;
+ }
+ if (bo->cref) {
+ return bo;
+ }
+ if (bo_gem->map_count) {
+ munmap(bo->ptr, bo->size);
+ }
+
+ /* close object */
+ args.handle = bo->handle;
+ ioctl(bo->bom->fd, DRM_IOCTL_GEM_CLOSE, &args);
+ memset(bo_gem, 0, sizeof(struct radeon_bo_gem));
+ free(bo_gem);
+ return NULL;
+}
+
+static int bo_map(struct radeon_bo *bo, int write)
+{
+ struct radeon_bo_gem *bo_gem = (struct radeon_bo_gem*)bo;
+ struct drm_radeon_gem_mmap args;
+ int r;
+ void *ptr;
+
+ if (bo_gem->map_count++ != 0) {
+ return 0;
+ }
+ bo->ptr = NULL;
+ args.handle = bo->handle;
+ args.offset = 0;
+ args.size = (uint64_t)bo->size;
+ r = drmCommandWriteRead(bo->bom->fd,
+ DRM_RADEON_GEM_MMAP,
+ &args,
+ sizeof(args));
+ if (r) {
+ fprintf(stderr, "error mapping %p 0x%08X (error = %d)\n",
+ bo, bo->handle, r);
+ return r;
+ }
+ ptr = mmap(0, args.size, PROT_READ|PROT_WRITE, MAP_SHARED, bo->bom->fd, args.addr_ptr);
+ if (ptr == MAP_FAILED)
+ return -errno;
+ bo->ptr = ptr;
+
+ return r;
+}
+
+static int bo_unmap(struct radeon_bo *bo)
+{
+ struct radeon_bo_gem *bo_gem = (struct radeon_bo_gem*)bo;
+
+ if (--bo_gem->map_count > 0) {
+ return 0;
+ }
+ munmap(bo->ptr, bo->size);
+ bo->ptr = NULL;
+ return 0;
+}
+
+static int bo_wait(struct radeon_bo *bo)
+{
+ struct drm_radeon_gem_wait_idle args;
+ int ret;
+
+ args.handle = bo->handle;
+ do {
+ ret = drmCommandWriteRead(bo->bom->fd, DRM_RADEON_GEM_WAIT_IDLE,
+ &args, sizeof(args));
+ } while (ret == -EBUSY);
+ return ret;
+}
+
+static struct radeon_bo_funcs bo_gem_funcs = {
+ bo_open,
+ bo_ref,
+ bo_unref,
+ bo_map,
+ bo_unmap,
+ bo_wait
+};
+
+struct radeon_bo_manager *radeon_bo_manager_gem_ctor(int fd)
+{
+ struct bo_manager_gem *bomg;
+
+ bomg = (struct bo_manager_gem*)calloc(1, sizeof(struct bo_manager_gem));
+ if (bomg == NULL) {
+ return NULL;
+ }
+ bomg->base.funcs = &bo_gem_funcs;
+ bomg->base.fd = fd;
+ return (struct radeon_bo_manager*)bomg;
+}
+
+void radeon_bo_manager_gem_dtor(struct radeon_bo_manager *bom)
+{
+ struct bo_manager_gem *bomg = (struct bo_manager_gem*)bom;
+
+ if (bom == NULL) {
+ return;
+ }
+ free(bomg);
+}
+
+uint32_t radeon_gem_name_bo(struct radeon_bo *bo)
+{
+ struct radeon_bo_gem *bo_gem = (struct radeon_bo_gem*)bo;
+ return bo_gem->name;
+}
+
+int radeon_gem_set_domain(struct radeon_bo *bo, uint32_t read_domains, uint32_t write_domain)
+{
+ struct radeon_bo_gem *bo_gem = (struct radeon_bo_gem*)bo;
+ struct drm_radeon_gem_set_domain args;
+ int r;
+
+ args.handle = bo->handle;
+ args.read_domains = read_domains;
+ args.write_domain = write_domain;
+
+ r = drmCommandWriteRead(bo->bom->fd,
+ DRM_RADEON_GEM_SET_DOMAIN,
+ &args,
+ sizeof(args));
+ return r;
+}
diff --git a/libdrm/radeon/radeon_bo_gem.h b/libdrm/radeon/radeon_bo_gem.h
new file mode 100644
index 0000000..9d9ce02
--- /dev/null
+++ b/libdrm/radeon/radeon_bo_gem.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright © 2008 Dave Airlie
+ * Copyright © 2008 Jérôme Glisse
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS, AUTHORS
+ * AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ */
+/*
+ * Authors:
+ * Dave Airlie
+ * Jérôme Glisse <gl...@fr...>
+ */
+#ifndef RADEON_BO_GEM_H
+#define RADEON_BO_GEM_H
+
+#include "radeon_bo.h"
+
+struct radeon_bo_manager *radeon_bo_manager_gem_ctor(int fd);
+void radeon_bo_manager_gem_dtor(struct radeon_bo_manager *bom);
+
+uint32_t radeon_gem_name_bo(struct radeon_bo *bo);
+int radeon_gem_set_domain(struct radeon_bo *bo, uint32_t read_domains, uint32_t write_domain);
+#endif
diff --git a/libdrm/radeon/radeon_cs.h b/libdrm/radeon/radeon_cs.h
new file mode 100644
index 0000000..d870961
--- /dev/null
+++ b/libdrm/radeon/radeon_cs.h
@@ -0,0 +1,208 @@
+/*
+ * Copyright © 2008 Nicolai Haehnle
+ * Copyright © 2008 Jérôme Glisse
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ */
+/*
+ * Authors:
+ * Aapo Tahkola <ae...@ra...>
+ * Nicolai Haehnle <pre...@gm...>
+ * Jérôme Glisse <gl...@fr...>
+ */
+#ifndef RADEON_CS_H
+#define RADEON_CS_H
+
+#include <stdint.h>
+#include <string.h>
+#include "drm.h"
+#include "radeon_drm.h"
+#include "radeon_bo.h"
+
+struct radeon_cs_reloc {
+ struct radeon_bo *bo;
+ uint32_t read_domain;
+ uint32_t write_domain;
+ uint32_t flags;
+};
+
+
+#define RADEON_CS_SPACE_OK 0
+#define RADEON_CS_SPACE_OP_TO_BIG 1
+#define RADEON_CS_SPACE_FLUSH 2
+
+struct radeon_cs_space_check {
+ struct radeon_bo *bo;
+ uint32_t read_domains;
+ uint32_t write_domain;
+ uint32_t new_accounted;
+};
+
+struct radeon_cs_manager;
+
+struct radeon_cs {
+ struct radeon_cs_manager *csm;
+ void *relocs;
+ uint32_t *packets;
+ unsigned crelocs;
+ unsigned relocs_total_size;
+ unsigned cdw;
+ unsigned ndw;
+ int section;
+ unsigned section_ndw;
+ unsigned section_cdw;
+ const char *section_file;
+ const char *section_func;
+ int section_line;
+
+};
+
+/* cs functions */
+struct radeon_cs_funcs {
+ struct radeon_cs *(*cs_create)(struct radeon_cs_manager *csm,
+ uint32_t ndw);
+ int (*cs_write_reloc)(struct radeon_cs *cs,
+ struct radeon_bo *bo,
+ uint32_t read_domain,
+ uint32_t write_domain,
+ uint32_t flags);
+ int (*cs_begin)(struct radeon_cs *cs,
+ uint32_t ndw,
+ const char *file,
+ const char *func,
+ int line);
+ int (*cs_end)(struct radeon_cs *cs,
+ const char *file,
+ const char *func,
+ int line);
+ int (*cs_emit)(struct radeon_cs *cs);
+ int (*cs_destroy)(struct radeon_cs *cs);
+ int (*cs_erase)(struct radeon_cs *cs);
+ int (*cs_need_flush)(struct radeon_cs *cs);
+ void (*cs_print)(struct radeon_cs *cs, FILE *file);
+ int (*cs_space_check)(struct radeon_cs *cs, struct radeon_cs_space_check *bos,
+ int num_bo);
+};
+
+struct radeon_cs_manager {
+ struct radeon_cs_funcs *funcs;
+ int fd;
+ uint32_t vram_limit, gart_limit;
+ uint32_t vram_write_used, gart_write_used;
+ uint32_t read_used;
+};
+
+static inline struct radeon_cs *radeon_cs_create(struct radeon_cs_manager *csm,
+ uint32_t ndw)
+{
+ return csm->funcs->cs_create(csm, ndw);
+}
+
+static inline int radeon_cs_write_reloc(struct radeon_cs *cs,
+ struct radeon_bo *bo,
+ uint32_t read_domain,
+ uint32_t write_domain,
+ uint32_t flags)
+{
+ return cs->csm->funcs->cs_write_reloc(cs,
+ bo,
+ read_domain,
+ write_domain,
+ flags);
+}
+
+static inline int radeon_cs_begin(struct radeon_cs *cs,
+ uint32_t ndw,
+ const char *file,
+ const char *func,
+ int line)
+{
+ return cs->csm->funcs->cs_begin(cs, ndw, file, func, line);
+}
+
+static inline int radeon_cs_end(struct radeon_cs *cs,
+ const char *file,
+ const char *func,
+ int line)
+{
+ return cs->csm->funcs->cs_end(cs, file, func, line);
+}
+
+static inline int radeon_cs_emit(struct radeon_cs *cs)
+{
+ return cs->csm->funcs->cs_emit(cs);
+}
+
+static inline int radeon_cs_destroy(struct radeon_cs *cs)
+{
+ return cs->csm->funcs->cs_destroy(cs);
+}
+
+static inline int radeon_cs_erase(struct radeon_cs *cs)
+{
+ return cs->csm->funcs->cs_erase(cs);
+}
+
+static inline int radeon_cs_need_flush(struct radeon_cs *cs)
+{
+ return cs->csm->funcs->cs_need_flush(cs);
+}
+
+static inline void radeon_cs_print(struct radeon_cs *cs, FILE *file)
+{
+ cs->csm->funcs->cs_print(cs, file);
+}
+
+static inline int radeon_cs_space_check(struct radeon_cs *cs,
+ struct radeon_cs_space_check *bos,
+ int num_bo)
+{
+ return cs->csm->funcs->cs_space_check(cs, bos, num_bo);
+}
+
+static inline void radeon_cs_set_limit(struct radeon_cs *cs, uint32_t domain, uint32_t limit)
+{
+
+ if (domain == RADEON_GEM_DOMAIN_VRAM)
+ cs->csm->vram_limit = limit;
+ else
+ cs->csm->gart_limit = limit;
+}
+
+static inline void radeon_cs_write_dword(struct radeon_cs *cs, uint32_t dword)
+{
+ cs->packets[cs->cdw++] = dword;
+ if (cs->section) {
+ cs->section_cdw++;
+ }
+}
+
+static inline void radeon_cs_write_qword(struct radeon_cs *cs, uint64_t qword)
+{
+ memcpy(cs->packets + cs->cdw, &qword, sizeof(uint64_t));
+ cs->cdw += 2;
+ if (cs->section) {
+ cs->section_cdw += 2;
+ }
+}
+
+#endif
diff --git a/libdrm/radeon/radeon_cs_gem.c b/libdrm/radeon/radeon_cs_gem.c
new file mode 100644
index 0000000..b9f6f4b
--- /dev/null
+++ b/libdrm/radeon/radeon_cs_gem.c
@@ -0,0 +1,544 @@
+/*
+ * Copyright © 2008 Jérôme Glisse
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS, AUTHORS
+ * AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ */
+/*
+ * Authors:
+ * Aapo Tahkola <ae...@ra...>
+ * Nicolai Haehnle <pre...@gm...>
+ * Jérôme Glisse <gl...@fr...>
+ */
+#include <assert.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <sys/mman.h>
+#include <sys/ioctl.h>
+#include "radeon_cs.h"
+#include "radeon_cs_gem.h"
+#include "radeon_bo_gem.h"
+#include "drm.h"
+#include "xf86drm.h"
+#include "radeon_drm.h"
+
+#pragma pack(1)
+struct cs_reloc_gem {
+ uint32_t handle;
+ uint32_t read_domain;
+ uint32_t write_domain;
+ uint32_t flags;
+};
+
+#pragma pack()
+#define RELOC_SIZE (sizeof(struct cs_reloc_gem) / sizeof(uint32_t))
+
+struct cs_gem {
+ struct radeon_cs base;
+ struct drm_radeon_cs cs;
+ struct drm_radeon_cs_chunk chunks[2];
+ unsigned nrelocs;
+ uint32_t *relocs;
+ struct radeon_bo **relocs_bo;
+};
+
+static struct radeon_cs *cs_gem_create(struct radeon_cs_manager *csm,
+ uint32_t ndw)
+{
+ struct cs_gem *csg;
+
+ /* max cmd buffer size is 64Kb */
+ if (ndw > (64 * 1024 / 4)) {
+ return NULL;
+ }
+ csg = (struct cs_gem*)calloc(1, sizeof(struct cs_gem));
+ if (csg == NULL) {
+ return NULL;
+ }
+ csg->base.csm = csm;
+ csg->base.ndw = 64 * 1024 / 4;
+ csg->base.packets = (uint32_t*)calloc(1, 64 * 1024);
+ if (csg->base.packets == NULL) {
+ free(csg);
+ return NULL;
+ }
+ csg->base.relocs_total_size = 0;
+ csg->base.crelocs = 0;
+ csg->nrelocs = 4096 / (4 * 4) ;
+ csg->relocs_bo = (struct radeon_bo**)calloc(1,
+ csg->nrelocs*sizeof(void*));
+ if (csg->relocs_bo == NULL) {
+ free(csg->base.packets);
+ free(csg);
+ return NULL;
+ }
+ csg->base.relocs = csg->relocs = (uint32_t*)calloc(1, 4096);
+ if (csg->relocs == NULL) {
+ free(csg->relocs_bo);
+ free(csg->base.packets);
+ free(csg);
+ return NULL;
+ }
+ csg->chunks[0].chunk_id = RADEON_CHUNK_ID_IB;
+ csg->chunks[0].length_dw = 0;
+ csg->chunks[0].chunk_data = (uint64_t)(intptr_t)csg->base.packets;
+ csg->chunks[1].chunk_id = RADEON_CHUNK_ID_RELOCS;
+ csg->chunks[1].length_dw = 0;
+ csg->chunks[1].chunk_data = (uint64_t)(intptr_t)csg->relocs;
+ return (struct radeon_cs*)csg;
+}
+
+static int cs_gem_write_reloc(struct radeon_cs *cs,
+ struct radeon_bo *bo,
+ uint32_t read_domain,
+ uint32_t write_domain,
+ uint32_t flags)
+{
+ struct cs_gem *csg = (struct cs_gem*)cs;
+ struct cs_reloc_gem *reloc;
+ uint32_t idx;
+ unsigned i;
+
+ assert(bo->space_accounted);
+
+ /* check domains */
+ if ((read_domain && write_domain) || (!read_domain && !write_domain)) {
+ /* in one CS a bo can only be in read or write domain but not
+ * in read & write domain at the same sime
+ */
+ return -EINVAL;
+ }
+ if (read_domain == RADEON_GEM_DOMAIN_CPU) {
+ return -EINVAL;
+ }
+ if (write_domain == RADEON_GEM_DOMAIN_CPU) {
+ return -EINVAL;
+ }
+ /* check if bo is already referenced */
+ for(i = 0; i < cs->crelocs; i++) {
+ idx = i * RELOC_SIZE;
+ reloc = (struct cs_reloc_gem*)&csg->relocs[idx];
+ if (reloc->handle == bo->handle) {
+ /* Check domains must be in read or write. As we check already
+ * checked that in argument one of the read or write domain was
+ * set we only need to check that if previous reloc as the read
+ * domain set then the read_domain should also be set for this
+ * new relocation.
+ */
+ if (reloc->read_domain && !read_domain) {
+ return -EINVAL;
+ }
+ if (reloc->write_domain && !write_domain) {
+ return -EINVAL;
+ }
+ reloc->read_domain |= read_domain;
+ reloc->write_domain |= write_domain;
+ /* update flags */
+ reloc->flags |= (flags & reloc->flags);
+ /* write relocation packet */
+ radeon_cs_write_dword(cs, 0xc0001000);
+ radeon_cs_write_dword(cs, idx);
+ return 0;
+ }
+ }
+ /* new relocation */
+ if (csg->base.crelocs >= csg->nrelocs) {
+ /* allocate more memory (TODO: should use a slab allocatore maybe) */
+ uint32_t *tmp, size;
+ size = ((csg->nrelocs + 1) * sizeof(struct radeon_bo*));
+ tmp = (uint32_t*)realloc(csg->relocs_bo, size);
+ if (tmp == NULL) {
+ return -ENOMEM;
+ }
+ csg->relocs_bo = (struct radeon_bo**)tmp;
+ size = ((csg->nrelocs + 1) * RELOC_SIZE * 4);
+ tmp = (uint32_t*)realloc(csg->relocs, size);
+ if (tmp == NULL) {
+ return -ENOMEM;
+ }
+ cs->relocs = csg->relocs = tmp;
+ csg->nrelocs += 1;
+ csg->chunks[1].chunk_data = (uint64_t)(intptr_t)csg->relocs;
+ }
+ csg->relocs_bo[csg->base.crelocs] = bo;
+ idx = (csg->base.crelocs++) * RELOC_SIZE;
+ reloc = (struct cs_reloc_gem*)&csg->relocs[idx];
+ reloc->handle = bo->handle;
+ reloc->read_domain = read_domain;
+ reloc->write_domain = write_domain;
+ reloc->flags = flags;
+ csg->chunks[1].length_dw += RELOC_SIZE;
+ radeon_bo_ref(bo);
+ cs->relocs_total_size += bo->size;
+ radeon_cs_write_dword(cs, 0xc0001000);
+ radeon_cs_write_dword(cs, idx);
+ return 0;
+}
+
+static int cs_gem_begin(struct radeon_cs *cs,
+ uint32_t ndw,
+ const char *file,
+ const char *func,
+ int line)
+{
+
+ if (cs->section) {
+ fprintf(stderr, "CS already in a section(%s,%s,%d)\n",
+ cs->section_file, cs->section_func, cs->section_line);
+ fprintf(stderr, "CS can't start section(%s,%s,%d)\n",
+ file, func, line);
+ return -EPIPE;
+ }
+ cs->section = 1;
+ cs->section_ndw = ndw;
+ cs->section_cdw = 0;
+ cs->section_file = file;
+ cs->section_func = func;
+ cs->section_line = line;
+
+
+ if (cs->cdw + ndw > cs->ndw) {
+ uint32_t tmp, *ptr;
+ int num = (ndw > 0x3FF) ? ndw : 0x3FF;
+
+ tmp = (cs->cdw + 1 + num) & (~num);
+ ptr = (uint32_t*)realloc(cs->packets, 4 * tmp);
+ if (ptr == NULL) {
+ return -ENOMEM;
+ }
+ cs->packets = ptr;
+ cs->ndw = tmp;
+ }
+
+ return 0;
+}
+
+static int cs_gem_end(struct radeon_cs *cs,
+ const char *file,
+ const char *func,
+ int line)
+
+{
+ if (!cs->section) {
+ fprintf(stderr, "CS no section to end at (%s,%s,%d)\n",
+ file, func, line);
+ return -EPIPE;
+ }
+ cs->section = 0;
+ if (cs->section_ndw != cs->section_cdw) {
+ fprintf(stderr, "CS section size missmatch start at (%s,%s,%d) %d vs %d\n",
+ cs->section_file, cs->section_func, cs->section_line, cs->section_ndw, cs->section_cdw);
+ fprintf(stderr, "CS section end at (%s,%s,%d)\n",
+ file, func, line);
+ return -EPIPE;
+ }
+ return 0;
+}
+
+static int cs_gem_emit(struct radeon_cs *cs)
+{
+ struct cs_gem *csg = (struct cs_gem*)cs;
+ uint64_t chunk_array[2];
+ unsigned i;
+ int r;
+
+ csg->chunks[0].length_dw = cs->cdw;
+
+ chunk_array[0] = (uint64_t)(intptr_t)&csg->chunks[0];
+ chunk_array[1] = (uint64_t)(intptr_t)&csg->chunks[1];
+
+ csg->cs.num_chunks = 2;
+ csg->cs.chunks = (uint64_t)(intptr_t)chunk_array;
+
+ r = drmCommandWriteRead(cs->csm->fd, DRM_RADEON_CS,
+ &csg->cs, sizeof(struct drm_radeon_cs));
+ for (i = 0; i < csg->base.crelocs; i++) {
+ csg->relocs_bo[i]->space_accounted = 0;
+ radeon_bo_unref(csg->relocs_bo[i]);
+ csg->relocs_bo[i] = NULL;
+ }
+
+ cs->csm->read_used = 0;
+ cs->csm->vram_write_used = 0;
+ cs->csm->gart_write_used = 0;
+ return r;
+}
+
+static int cs_gem_destroy(struct radeon_cs *cs)
+{
+ struct cs_gem *csg = (struct cs_gem*)cs;
+
+ free(csg->relocs_bo);
+ free(cs->relocs);
+ free(cs->packets);
+ free(cs);
+ return 0;
+}
+
+static int cs_gem_erase(struct radeon_cs *cs)
+{
+ struct cs_gem *csg = (struct cs_gem*)cs;
+ unsigned i;
+
+ if (csg->relocs_bo) {
+ for (i = 0; i < csg->base.crelocs; i++) {
+ if (csg->relocs_bo[i]) {
+ radeon_bo_unref(csg->relocs_bo[i]);
+ csg->relocs_bo[i] = NULL;
+ }
+ }
+ }
+ cs->relocs_total_size = 0;
+ cs->cdw = 0;
+ cs->section = 0;
+ cs->crelocs = 0;
+ csg->chunks[0].length_dw = 0;
+ csg->chunks[1].length_dw = 0;
+ return 0;
+}
+
+static int cs_gem_need_flush(struct radeon_cs *cs)
+{
+ return 0; //(cs->relocs_total_size > (32*1024*1024));
+}
+
+#define PACKET_TYPE0 0
+#define PACKET_TYPE1 1
+#define PACKET_TYPE2 2
+#define PACKET_TYPE3 3
+
+#define PACKET3_NOP 0x10
+#define PACKET3_SET_SCISSORS 0x1E
+#define PACKET3_3D_DRAW_VBUF 0x28
+#define PACKET3_3D_DRAW_IMMD 0x29
+#define PACKET3_3D_DRAW_INDX 0x2A
+#define PACKET3_3D_LOAD_VBPNTR 0x2F
+#define PACKET3_INDX_BUFFER 0x33
+#define PACKET3_3D_DRAW_VBUF_2 0x34
+#define PACKET3_3D_DRAW_IMMD_2 0x35
+#define PACKET3_3D_DRAW_INDX_2 0x36
+
+#define CP_PACKET_GET_TYPE(h) (((h) >> 30) & 3)
+#define CP_PACKET_GET_COUNT(h) (((h) >> 16) & 0x3FFF)
+#define CP_PACKET0_GET_REG(h) (((h) & 0x1FFF) << 2)
+#define CP_PACKET0_GET_ONE_REG_WR(h) (((h) >> 15) & 1)
+#define CP_PACKET3_GET_OPCODE(h) (((h) >> 8) & 0xFF)
+
+static void cs_gem_print(struct radeon_cs *cs, FILE *file)
+{
+ unsigned opcode;
+ unsigned reg;
+ unsigned cnt;
+ int i, j;
+
+ for (i = 0; i < cs->cdw;) {
+ cnt = CP_PACKET_GET_COUNT(cs->packets[i]);
+ switch (CP_PACKET_GET_TYPE(cs->packets[i])) {
+ case PACKET_TYPE0:
+ fprintf(file, "Pkt0 at %d (%d dwords):\n", i, cnt + 1);
+ reg = CP_PACKET0_GET_REG(cs->packets[i]);
+ if (CP_PACKET0_GET_ONE_REG_WR(cs->packets[i++])) {
+ for (j = 0; j <= cnt; j++) {
+ fprintf(file, " 0x%08X -> 0x%04X\n",
+ cs->packets[i++], reg);
+ }
+ } else {
+ for (j = 0; j <= cnt; j++) {
+ fprintf(file, " 0x%08X -> 0x%04X\n",
+ cs->packets[i++], reg);
+ reg += 4;
+ }
+ }
+ break;
+ case PACKET_TYPE3:
+ fprintf(file, "Pkt3 at %d :\n", i);
+ opcode = CP_PACKET3_GET_OPCODE(cs->packets[i++]);
+ switch (opcode) {
+ case PACKET3_NOP:
+ fprintf(file, " PACKET3_NOP:\n");
+ break;
+ case PACKET3_3D_DRAW_VBUF:
+ fprintf(file, " PACKET3_3D_DRAW_VBUF:\n");
+ break;
+ case PACKET3_3D_DRAW_IMMD:
+ fprintf(file, " PACKET3_3D_DRAW_IMMD:\n");
+ break;
+ case PACKET3_3D_DRAW_INDX:
+ fprintf(file, " PACKET3_3D_DRAW_INDX:\n");
+ break;
+ case PACKET3_3D_LOAD_VBPNTR:
+ fprintf(file, " PACKET3_3D_LOAD_VBPNTR:\n");
+ break;
+ case PACKET3_INDX_BUFFER:
+ fprintf(file, " PACKET3_INDX_BUFFER:\n");
+ break;
+ case PACKET3_3D_DRAW_VBUF_2:
+ fprintf(file, " PACKET3_3D_DRAW_VBUF_2:\n");
+ break;
+ case PACKET3_3D_DRAW_IMMD_2:
+ fprintf(file, " PACKET3_3D_DRAW_IMMD_2:\n");
+ break;
+ case PACKET3_3D_DRAW_INDX_2:
+ fprintf(file, " PACKET3_3D_DRAW_INDX_2:\n");
+ break;
+ default:
+ fprintf(file, "Unknow opcode 0x%02X at %d\n", opcode, i);
+ return;
+ }
+ for (j = 0; j <= cnt; j++) {
+ fprintf(file, " 0x%08X\n", cs->packets[i++]);
+ }
+ break;
+ case PACKET_TYPE1:
+ case PACKET_TYPE2:
+ default:
+ fprintf(file, "Unknow packet 0x%08X at %d\n", cs->packets[i], i);
+ return;
+ }
+ }
+}
+
+static int cs_gem_check_space(struct radeon_cs *cs, struct radeon_cs_space_check *bos, int num_bo)
+{
+ struct radeon_cs_manager *csm = cs->csm;
+ int this_op_read = 0, this_op_gart_write = 0, this_op_vram_write = 0;
+ uint32_t read_domains, write_domain;
+ int i;
+ struct radeon_bo *bo;
+
+ /* check the totals for this operation */
+
+ if (num_bo == 0)
+ return 0;
+
+ /* prepare */
+ for (i = 0; i < num_bo; i++) {
+ bo = bos[i].bo;
+
+ bos[i].new_accounted = 0;
+ read_domains = bos[i].read_domains;
+ write_domain = bos[i].write_domain;
+
+ /* already accounted this bo */
+ if (write_domain && (write_domain == bo->space_accounted)) {
+ bos[i].new_accounted = bo->space_accounted;
+ continue;
+ }
+ if (read_domains && ((read_domains << 16) == bo->space_accounted)) {
+ bos[i].new_accounted = bo->space_accounted;
+ continue;
+ }
+
+ if (bo->space_accounted == 0) {
+ if (write_domain == RADEON_GEM_DOMAIN_VRAM)
+ this_op_vram_write += bo->size;
+ else if (write_domain == RADEON_GEM_DOMAIN_GTT)
+ this_op_gart_write += bo->size;
+ else
+ this_op_read += bo->size;
+ bos[i].new_accounted = (read_domains << 16) | write_domain;
+ } else {
+ uint16_t old_read, old_write;
+
+ old_read = bo->space_accounted >> 16;
+ old_write = bo->space_accounted & 0xffff;
+
+ if (write_domain && (old_read & write_domain)) {
+ bos[i].new_accounted = write_domain;
+ /* moving from read to a write domain */
+ if (write_domain == RADEON_GEM_DOMAIN_VRAM) {
+ this_op_read -= bo->size;
+ this_op_vram_write += bo->size;
+ } else if (write_domain == RADEON_GEM_DOMAIN_VRAM) {
+ this_op_read -= bo->size;
+ this_op_gart_write += bo->size;
+ }
+ } else if (read_domains & old_write) {
+ bos[i].new_accounted = bo->space_accounted & 0xffff;
+ } else {
+ /* rewrite the domains */
+ if (write_domain != old_write)
+ fprintf(stderr,"WRITE DOMAIN RELOC FAILURE 0x%x %d %d\n", bo->handle, write_domain, old_write);
+ if (read_domains != old_read)
+ fprintf(stderr,"READ DOMAIN RELOC FAILURE 0x%x %d %d\n", bo->handle, read_domains, old_read);
+ return RADEON_CS_SPACE_FLUSH;
+ }
+ }
+ }
+
+ if (this_op_read < 0)
+ this_op_read = 0;
+
+ /* check sizes - operation first */
+ if ((this_op_read + this_op_gart_write > csm->gart_limit) ||
+ (this_op_vram_write > csm->vram_limit)) {
+ return RADEON_CS_SPACE_OP_TO_BIG;
+ }
+
+ if (((csm->vram_write_used + this_op_vram_write) > csm->vram_limit) ||
+ ((csm->read_used + csm->gart_write_used + this_op_gart_write + this_op_read) > csm->gart_limit)) {
+ return RADEON_CS_SPACE_FLUSH;
+ }
+
+ csm->gart_write_used += this_op_gart_write;
+ csm->vram_write_used += this_op_vram_write;
+ csm->read_used += this_op_read;
+ /* commit */
+ for (i = 0; i < num_bo; i++) {
+ bo = bos[i].bo;
+ bo->space_accounted = bos[i].new_accounted;
+ }
+
+ return RADEON_CS_SPACE_OK;
+}
+
+static struct radeon_cs_funcs radeon_cs_gem_funcs = {
+ cs_gem_create,
+ cs_gem_write_reloc,
+ cs_gem_begin,
+ cs_gem_end,
+ cs_gem_emit,
+ cs_gem_destroy,
+ cs_gem_erase,
+ cs_gem_need_flush,
+ cs_gem_print,
+ cs_gem_check_space,
+};
+
+struct radeon_cs_manager *radeon_cs_manager_gem_ctor(int fd)
+{
+ struct radeon_cs_manager *csm;
+
+ csm = (struct radeon_cs_manager*)calloc(1,
+ sizeof(struct radeon_cs_manager));
+ if (csm == NULL) {
+ return NULL;
+ }
+ csm->funcs = &radeon_cs_gem_funcs;
+ csm->fd = fd;
+ return csm;
+}
+
+void radeon_cs_manager_gem_dtor(struct radeon_cs_manager *csm)
+{
+ free(csm);
+}
diff --git a/libdrm/radeon/radeon_cs_gem.h b/libdrm/radeon/radeon_cs_gem.h
new file mode 100644
index 0000000..5efd146
--- /dev/null
+++ b/libdrm/radeon/radeon_cs_gem.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright © 2008 Nicolai Haehnle
+ * Copyright © 2008 Jérôme Glisse
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS, AUTHORS
+ * AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ */
+/*
+ * Authors:
+ * Aapo Tahkola <ae...@ra...>
+ * Nicolai Haehnle <pre...@gm...>
+ * Jérôme Glisse <gl...@fr...>
+ */
+#ifndef RADEON_CS_GEM_H
+#define RADEON_CS_GEM_H
+
+#include "radeon_cs.h"
+
+struct radeon_cs_manager *radeon_cs_manager_gem_ctor(int fd);
+void radeon_cs_manager_gem_dtor(struct radeon_cs_manager *csm);
+
+#endif
diff --git a/libdrm/radeon/radeon_track.c b/libdrm/radeon/radeon_track.c
new file mode 100644
index 0000000..1623906
--- /dev/null
+++ b/libdrm/radeon/radeon_track.c
@@ -0,0 +1,140 @@
+/*
+ * Copyright © 2008 Jérôme Glisse
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS, AUTHORS
+ * AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ */
+/*
+ * Authors:
+ * Jérôme Glisse <gl...@fr...>
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "radeon_track.h"
+
+void radeon_track_add_event(struct radeon_track *track,
+ const char *file,
+ const char *func,
+ const char *op,
+ unsigned line)
+{
+ struct radeon_track_event *event;
+
+ if (track == NULL) {
+ return;
+ }
+ event = (void*)calloc(1,sizeof(struct radeon_track_event));
+ if (event == NULL) {
+ return;
+ }
+ event->line = line;
+ event->file = strdup(file);
+ event->func = strdup(func);
+ event->op = strdup(op);
+ if (event->file == NULL || event->func == NULL || event->op == NULL) {
+ free(event->file);
+ free(event->func);
+ free(event->op);
+ free(event);
+ return;
+ }
+ event->next = track->events;
+ track->events = event;
+}
+
+struct radeon_track *radeon_tracker_add_track(struct radeon_tracker *tracker,
+ unsigned key)
+{
+ struct radeon_track *track;
+
+ track = (struct radeon_track*)calloc(1, sizeof(struct radeon_track));
+ if (track) {
+ track->next = tracker->tracks.next;
+ track->prev = &tracker->tracks;
+ tracker->tracks.next = track;
+ if (track->next) {
+ track->next->prev = track;
+ }
+ track->key = key;
+ track->events = NULL;
+ }
+ return track;
+}
+
+void radeon_tracker_remove_track(struct radeon_tracker *tracker,
+ struct radeon_track *track)
+{
+ struct radeon_track_event *event;
+ void *tmp;
+
+ if (track == NULL) {
+ return;
+ }
+ track->prev->next = track->next;
+ if (track->next) {
+ track->next->prev = track->prev;
+ }
+ track->next = track->prev = NULL;
+ event = track->events;
+ while (event) {
+ tmp = event;
+ free(event->file);
+ free(event->func);
+ free(event->op);
+ event = event->next;
+ free(tmp);
+ }
+ track->events = NULL;
+ free(track);
+}
+
+void radeon_tracker_print(struct radeon_tracker *tracker, FILE *file)
+{
+ struct radeon_track *track;
+ struct radeon_track_event *event;
+ void *tmp;
+
+ track = tracker->tracks.next;
+ while (track) {
+ event = track->events;
+ fprintf(file, "[0x%08X] :\n", track->key);
+ while (event) {
+ tmp = event;
+ fprintf(file, " [0x%08X:%s](%s:%s:%d)\n",
+ track->key, event->op, event->file,
+ event->func, event->line);
+ free(event->file);
+ free(event->func);
+ free(event->op);
+ event->file = NULL;
+ event->func = NULL;
+ event->op = NULL;
+ event = event->next;
+ free(tmp);
+ }
+ track->events = NULL;
+ tmp = track;
+ track = track->next;
+ free(tmp);
+ }
+}
diff --git a/libdrm/radeon/radeon_track.h b/libdrm/radeon/radeon_track.h
new file mode 100644
index 0000000..838d1f3
--- /dev/null
+++ b/libdrm/radeon/radeon_track.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright © 2008 Jérôme Glisse
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS, AUTHORS
+ * AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ */
+/*
+ * Authors:
+ * Jérôme Glisse <gl...@fr...>
+ */
+#ifndef RADEON_TRACK_H
+#define RADEON_TRACK_H
+
+struct radeon_track_event {
+ struct radeon_track_event *next;
+ char *file;
+ char *func;
+ char *op;
+ unsigned line;
+};
+
+struct radeon_track {
+ struct radeon_track *next;
+ struct radeon_track *prev;
+ unsigned key;
+ struct radeon_track_event *events;
+};
+
+struct radeon_tracker {
+ struct radeon_track tracks;
+};
+
+void radeon_track_add_event(struct radeon_track *track,
+ const char *file,
+ const char *func,
+ const char *op,
+ unsigned line);
+struct radeon_track *radeon_tracker_add_track(struct radeon_tracker *tracker,
+ unsigned key);
+void radeon_tracker_remove_track(struct radeon_tracker *tracker,
+ struct radeon_track *track);
+void radeon_tracker_print(struct radeon_tracker *tracker,
+ FILE *file);
+
+#endif
diff --git a/shared-core/radeon_drm.h b/shared-core/radeon_drm.h
index ffaa46e..e9f2afa 100644
--- a/shared-core/radeon_drm.h
+++ b/shared-core/radeon_drm.h
@@ -492,6 +492,16 @@ typedef struct {
#define DRM_RADEON_SETPARAM 0x19
#define DRM_RADEON_SURF_ALLOC 0x1a
#define DRM_RADEON_SURF_FREE 0x1b
+/* KMS ioctl */
+#define DRM_RADEON_GEM_INFO 0x1c
+#define DRM_RADEON_GEM_CREATE 0x1d
+#define DRM_RADEON_GEM_MMAP 0x1e
+#define DRM_RADEON_GEM_PREAD 0x21
+#define DRM_RADEON_GEM_PWRITE 0x22
+#define DRM_RADEON_GEM_SET_DOMAIN 0x23
+#define DRM_RADEON_GEM_WAIT_IDLE 0x24
+#define DRM_RADEON_CS 0x26
+#define DRM_RADEON_INFO 0x27
#define DRM_IOCTL_RADEON_CP_INIT DRM_IOW( DRM_COMMAND_BASE + DRM_RADEON_CP_INIT, drm_radeon_init_t)
#define DRM_IOCTL_RADEON_CP_START DRM_IO( DRM_COMMAND_BASE + DRM_RADEON_CP_START)
@@ -521,6 +531,17 @@ typedef struct {
#define DRM_IOCTL_RADEON_SURF_ALLOC DRM_IOW( DRM_COMMAND_BASE + DRM_RADEON_SURF_ALLOC, drm_radeon_surface_alloc_t)
#define DRM_IOCTL_RADEON_SURF_FREE DRM_IOW( DRM_COMMAND_BASE + DRM_RADEON_SURF_FREE, drm_radeon_surface_free_t)
+#define DRM_IOCTL_RADEON_GEM_INFO DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_GEM_INFO, struct drm_radeon_gem_info)
+#define DRM_IOCTL_RADEON_GEM_CREATE DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_GEM_CREATE, struct drm_radeon_gem_create)
+#define DRM_IOCTL_RADEON_GEM_MMAP DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_GEM_MMAP, struct drm_radeon_gem_mmap)
+#define DRM_IOCTL_RADEON_GEM_PIN DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_GEM_PIN, struct drm_radeon_gem_pin)
+#define DRM_IOCTL_RADEON_GEM_UNPIN DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_GEM_UNPIN, struct drm_radeon_gem_unpin)
+#define DRM_IOCTL_RADEON_GEM_PREAD DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_GEM_PREAD, struct drm_radeon_gem_pread)
+#define DRM_IOCTL_RADEON_GEM_PWRITE DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_GEM_PWRITE, struct drm_radeon_gem_pwrite)
+#define DRM_IOCTL_RADEON_GEM_SET_DOMAIN DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_GEM_SET_DOMAIN, struct drm_radeon_gem_set_domain)
+#define DRM_IOCTL_RADEON_GEM_WAIT_RENDERING DRM_IOW(DRM_COMMAND_BASE + DRM_RADEON_GEM_WAIT_RENDERING, struct drm_radeon_gem_wait_rendering)
+#define DRM_IOCTL_RADEON_CS DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_CS, struct drm_radeon_cs)
+
typedef struct drm_radeon_init {
enum {
RADEON_INIT_CP = 0x01,
@@ -677,6 +698,7 @@ typedef struct drm_radeon_indirect {
#define RADEON_PARAM_VBLANK_CRTC 13 /* VBLANK CRTC */
#define RADEON_PARAM_FB_LOCATION 14 /* FB location */
#define RADEON_PARAM_NUM_GB_PIPES 15 /* num GB pipes */
+#define RADEON_PARAM_DEVICE_ID 16
typedef struct drm_radeon_getparam {
int param;
@@ -728,7 +750,6 @@ typedef struct drm_radeon_setparam {
#define RADEON_SETPARAM_FB_LOCATION 1 /* determined framebuffer location */
#define RADEON_SETPARAM_SWITCH_TILING 2 /* enable/disable color tiling */
#define RADEON_SETPARAM_PCIGART_LOCATION 3 /* PCI Gart Location */
-
#define RADEON_SETPARAM_NEW_MEMMAP 4 /* Use new memory map */
#define RADEON_SETPARAM_PCIGART_TABLE_SIZE 5 /* PCI GART Table Size */
#define RADEON_SETPARAM_VBLANK_CRTC 6 /* VBLANK CRTC */
@@ -747,4 +768,112 @@ typedef struct drm_radeon_surface_free {
#define DRM_RADEON_VBLANK_CRTC1 1
#define DRM_RADEON_VBLANK_CRTC2 2
+/*
+ * Kernel modesetting world below.
+ */
+#define RADEON_GEM_DOMAIN_CPU 0x1
+#define RADEON_GEM_DOMAIN_GTT 0x2
+#define RADEON_GEM_DOMAIN_VRAM 0x4
+
+struct drm_radeon_gem_info {
+ uint64_t gart_size;
+ uint64_t vram_size;
+ uint64_t vram_visible;
+};
+
+#define RADEON_GEM_NO_BACKING_STORE 1
+
+struct drm_radeon_gem_create {
+ uint64_t size;
+ uint64_t alignment;
+ uint32_t handle;
+ uint32_t initial_domain;
+ uint32_t flags;
+};
+
+struct drm_radeon_gem_mmap {
+ uint32_t handle;
+ uint32_t pad;
+ uint64_t offset;
+ uint64_t size;
+ uint64_t addr_ptr;
+};
+
+struct drm_radeon_gem_set_domain {
+ uint32_t handle;
+ uint32_t read_domains;
+ uint32_t write_domain;
+};
+
+struct drm_radeon_gem_wait_idle {
+ uint32_t handle;
+ uint32_t pad;
+};
+
+struct drm_radeon_gem_busy {
+ uint32_t handle;
+ uint32_t busy;
+};
+
+struct drm_radeon_gem_pread {
+ /** Handle for the object being read. */
+ uint32_t handle;
+ uint32_t pad;
+ /** Offset into the object to read from */
+ uint64_t offset;
+ /** Length of data to read */
+ uint64_t size;
+ /** Pointer to write the data into. */
+ /* void *, but pointers are not 32/64 compatible */
+ uint64_t data_ptr;
+};
+
+struct drm_radeon_gem_pwrite {
+ /** Handle for the object being written to. */
+ uint32_t handle;
+ uint32_t pad;
+ /** Offset into the object to write to */
+ uint64_t offset;
+ /** Length of data to write */
+ uint64_t size;
+ /** Pointer to read the data from. */
+ /* void *, but pointers are not 32/64 compatible */
+ uint64_t data_ptr;
+};
+
+#define RADEON_CHUNK_ID_RELOCS 0x01
+#define RADEON_CHUNK_ID_IB 0x02
+
+struct drm_radeon_cs_chunk {
+ uint32_t chunk_id;
+ uint32_t length_dw;
+ uint64_t chunk_data;
+};
+
+struct drm_radeon_cs_reloc {
+ uint32_t handle;
+ uint32_t read_domains;
+ uint32_t write_domain;
+ uint32_t flags;
+};
+
+struct drm_radeon_cs {
+ uint32_t num_chunks;
+ uint32_t cs_id;
+ /* this points to uint64_t * which point to cs chunks */
+ uint64_t chunks;
+ /* updates to the limits after this CS ioctl */
+ uint64_t gart_limit;
+ uint64_t vram_limit;
+};
+
+#define RADEON_INFO_DEVICE_ID 0x00
+#define RADEON_INFO_NUM_GB_PIPES 0x01
+
+struct drm_radeon_info {
+ uint32_t request;
+ uint32_t pad;
+ uint64_t value;
+};
+
#endif
|
|
From: <dar...@ke...> - 2009-06-05 04:40:02
|
libdrm/nouveau/libdrm_nouveau.pc.in | 2
libdrm/nouveau/nouveau_bo.c | 78 +++++++++++++++++++++---------------
libdrm/nouveau/nouveau_bo.h | 19 ++++++++
libdrm/nouveau/nouveau_device.c | 2
libdrm/nouveau/nouveau_pushbuf.c | 4 -
libdrm/nouveau/nouveau_pushbuf.h | 23 +++++++++-
shared-core/nouveau_drm.h | 6 +-
shared-core/nouveau_drv.h | 2
8 files changed, 93 insertions(+), 43 deletions(-)
New commits:
commit 3d4bfe8c893d016ef43d1ebf28e4607aa1f540a4
Author: Ben Skeggs <bs...@re...>
Date: Wed Jun 3 13:54:43 2009 +1000
nouveau: 0.0.14 + extend bo interface to support subrange mapping
Normal map() should operate as before, and map_range()/map_flush() should
give correct results but lacking any performance difference from map().
Nothing exiting being done here yet, but the interface is a good start.
diff --git a/libdrm/nouveau/libdrm_nouveau.pc.in b/libdrm/nouveau/libdrm_nouveau.pc.in
index 9e67a23..7ef49e5 100644
--- a/libdrm/nouveau/libdrm_nouveau.pc.in
+++ b/libdrm/nouveau/libdrm_nouveau.pc.in
@@ -5,6 +5,6 @@ includedir=@includedir@
Name: libdrm_nouveau
Description: Userspace interface to nouveau kernel DRM services
-Version: 0.5
+Version: 0.6
Libs: -L${libdir} -ldrm_nouveau
Cflags: -I${includedir} -I${includedir}/drm -I${includedir}/nouveau
diff --git a/libdrm/nouveau/nouveau_bo.c b/libdrm/nouveau/nouveau_bo.c
index 55d0575..e68533b 100644
--- a/libdrm/nouveau/nouveau_bo.c
+++ b/libdrm/nouveau/nouveau_bo.c
@@ -52,15 +52,8 @@ nouveau_bo_info(struct nouveau_bo_priv *nvbo, struct drm_nouveau_gem_info *arg)
nvbo->size = nvbo->base.size = arg->size;
nvbo->offset = arg->offset;
nvbo->map_handle = arg->map_handle;
-
- if (nvbo->domain & NOUVEAU_GEM_DOMAIN_TILE) {
- nvbo->base.tiled = 1;
- if (nvbo->domain & NOUVEAU_GEM_DOMAIN_TILE_ZETA)
- nvbo->base.tiled |= 2;
- } else {
- nvbo->base.tiled = 0;
- }
-
+ nvbo->base.tile_mode = arg->tile_mode;
+ nvbo->base.tile_flags = arg->tile_flags;
return 0;
}
@@ -215,18 +208,15 @@ nouveau_bo_kalloc(struct nouveau_bo_priv *nvbo, struct nouveau_channel *chan)
info->domain |= NOUVEAU_GEM_DOMAIN_GART;
if (!info->domain) {
info->domain |= (NOUVEAU_GEM_DOMAIN_VRAM |
- NOUVEAU_GEM_DOMAIN_GART);
- }
-
- if (nvbo->flags & NOUVEAU_BO_TILED) {
- info->domain |= NOUVEAU_GEM_DOMAIN_TILE;
- if (nvbo->flags & NOUVEAU_BO_ZTILE)
- info->domain |= NOUVEAU_GEM_DOMAIN_TILE_ZETA;
+ NOUVEAU_GEM_DOMAIN_GART);
}
if (nvbo->flags & NOUVEAU_BO_MAP)
info->domain |= NOUVEAU_GEM_DOMAIN_MAPPABLE;
+ info->tile_mode = nvbo->base.tile_mode;
+ info->tile_flags = nvbo->base.tile_flags;
+
ret = drmCommandWriteRead(nvdev->fd, DRM_NOUVEAU_GEM_NEW,
&req, sizeof(req));
if (ret)
@@ -276,8 +266,9 @@ nouveau_bo_kmap(struct nouveau_bo_priv *nvbo)
}
int
-nouveau_bo_new(struct nouveau_device *dev, uint32_t flags, int align,
- int size, struct nouveau_bo **bo)
+nouveau_bo_new_tile(struct nouveau_device *dev, uint32_t flags, int align,
+ int size, uint32_t tile_mode, uint32_t tile_flags,
+ struct nouveau_bo **bo)
{
struct nouveau_bo_priv *nvbo;
int ret;
@@ -290,6 +281,8 @@ nouveau_bo_new(struct nouveau_device *dev, uint32_t flags, int align,
return -ENOMEM;
nvbo->base.device = dev;
nvbo->base.size = size;
+ nvbo->base.tile_mode = tile_mode;
+ nvbo->base.tile_flags = tile_flags;
nvbo->refcount = 1;
/* Don't set NOUVEAU_BO_PIN here, or nouveau_bo_allocated() will
@@ -300,13 +293,6 @@ nouveau_bo_new(struct nouveau_device *dev, uint32_t flags, int align,
nvbo->size = size;
nvbo->align = align;
- /*XXX: murder me violently */
- if (flags & NOUVEAU_BO_TILED) {
- nvbo->base.tiled = 1;
- if (flags & NOUVEAU_BO_ZTILE)
- nvbo->base.tiled |= 2;
- }
-
if (flags & NOUVEAU_BO_PIN) {
ret = nouveau_bo_pin((void *)nvbo, nvbo->flags);
if (ret) {
@@ -320,6 +306,22 @@ nouveau_bo_new(struct nouveau_device *dev, uint32_t flags, int align,
}
int
+nouveau_bo_new(struct nouveau_device *dev, uint32_t flags, int align,
+ int size, struct nouveau_bo **bo)
+{
+ uint32_t tile_flags = 0;
+
+ if (flags & NOUVEAU_BO_TILED) {
+ if (flags & NOUVEAU_BO_ZTILE)
+ tile_flags = 0x2800;
+ else
+ tile_flags = 0x7000;
+ }
+
+ return nouveau_bo_new_tile(dev, flags, align, size, 0, tile_flags, bo);
+}
+
+int
nouveau_bo_user(struct nouveau_device *dev, void *ptr, int size,
struct nouveau_bo **bo)
{
@@ -575,7 +577,8 @@ nouveau_bo_wait(struct nouveau_bo *bo, int cpu_write)
}
int
-nouveau_bo_map(struct nouveau_bo *bo, uint32_t flags)
+nouveau_bo_map_range(struct nouveau_bo *bo, uint32_t delta, uint32_t size,
+ uint32_t flags)
{
struct nouveau_bo_priv *nvbo = nouveau_bo(bo);
int ret;
@@ -598,23 +601,36 @@ nouveau_bo_map(struct nouveau_bo *bo, uint32_t flags)
}
if (nvbo->sysmem) {
- bo->map = nvbo->sysmem;
+ bo->map = (char *)nvbo->sysmem + delta;
} else {
ret = nouveau_bo_kmap(nvbo);
if (ret)
return ret;
- ret = nouveau_bo_wait(bo, (flags & NOUVEAU_BO_WR));
- if (ret)
- return ret;
+ if (!(flags & NOUVEAU_BO_NOSYNC)) {
+ ret = nouveau_bo_wait(bo, (flags & NOUVEAU_BO_WR));
+ if (ret)
+ return ret;
+ }
- bo->map = nvbo->map;
+ bo->map = (char *)nvbo->map + delta;
}
return 0;
}
void
+nouveau_bo_map_flush(struct nouveau_bo *bo, uint32_t delta, uint32_t size)
+{
+}
+
+int
+nouveau_bo_map(struct nouveau_bo *bo, uint32_t flags)
+{
+ return nouveau_bo_map_range(bo, 0, bo->size, flags);
+}
+
+void
nouveau_bo_unmap(struct nouveau_bo *bo)
{
struct nouveau_device_priv *nvdev = nouveau_device(bo->device);
diff --git a/libdrm/nouveau/nouveau_bo.h b/libdrm/nouveau/nouveau_bo.h
index f0ae09b..9b1feff 100644
--- a/libdrm/nouveau/nouveau_bo.h
+++ b/libdrm/nouveau/nouveau_bo.h
@@ -37,6 +37,10 @@
#define NOUVEAU_BO_LOCAL (1 << 9)
#define NOUVEAU_BO_TILED (1 << 10)
#define NOUVEAU_BO_ZTILE (1 << 11)
+#define NOUVEAU_BO_INVAL (1 << 12)
+#define NOUVEAU_BO_NOSYNC (1 << 13)
+#define NOUVEAU_BO_NOWAIT (1 << 14)
+#define NOUVEAU_BO_IFLUSH (1 << 15)
#define NOUVEAU_BO_DUMMY (1 << 31)
struct nouveau_bo {
@@ -46,7 +50,8 @@ struct nouveau_bo {
uint64_t size;
void *map;
- int tiled;
+ uint32_t tile_mode;
+ uint32_t tile_flags;
/* Available when buffer is pinned *only* */
uint32_t flags;
@@ -58,6 +63,11 @@ nouveau_bo_new(struct nouveau_device *, uint32_t flags, int align, int size,
struct nouveau_bo **);
int
+nouveau_bo_new_tile(struct nouveau_device *, uint32_t flags, int align,
+ int size, uint32_t tile_mode, uint32_t tile_flags,
+ struct nouveau_bo **);
+
+int
nouveau_bo_user(struct nouveau_device *, void *ptr, int size,
struct nouveau_bo **);
@@ -79,6 +89,13 @@ int
nouveau_bo_ref(struct nouveau_bo *, struct nouveau_bo **);
int
+nouveau_bo_map_range(struct nouveau_bo *, uint32_t delta, uint32_t size,
+ uint32_t flags);
+
+void
+nouveau_bo_map_flush(struct nouveau_bo *, uint32_t delta, uint32_t size);
+
+int
nouveau_bo_map(struct nouveau_bo *, uint32_t flags);
void
diff --git a/libdrm/nouveau/nouveau_device.c b/libdrm/nouveau/nouveau_device.c
index 48db23d..6b99e36 100644
--- a/libdrm/nouveau/nouveau_device.c
+++ b/libdrm/nouveau/nouveau_device.c
@@ -26,7 +26,7 @@
#include "nouveau_private.h"
-#if NOUVEAU_DRM_HEADER_PATCHLEVEL != 13
+#if NOUVEAU_DRM_HEADER_PATCHLEVEL != 14
#error nouveau_drm.h does not match expected patchlevel, update libdrm.
#endif
diff --git a/libdrm/nouveau/nouveau_pushbuf.c b/libdrm/nouveau/nouveau_pushbuf.c
index 5b8d18b..fded21b 100644
--- a/libdrm/nouveau/nouveau_pushbuf.c
+++ b/libdrm/nouveau/nouveau_pushbuf.c
@@ -60,8 +60,8 @@ nouveau_pushbuf_calc_reloc(struct drm_nouveau_gem_pushbuf_bo *pbbo,
int
nouveau_pushbuf_emit_reloc(struct nouveau_channel *chan, void *ptr,
- struct nouveau_bo *bo, uint32_t data, uint32_t flags,
- uint32_t vor, uint32_t tor)
+ struct nouveau_bo *bo, uint32_t data, uint32_t data2,
+ uint32_t flags, uint32_t vor, uint32_t tor)
{
struct nouveau_device_priv *nvdev = nouveau_device(chan->device);
struct nouveau_pushbuf_priv *nvpb = nouveau_pushbuf(chan->pushbuf);
diff --git a/libdrm/nouveau/nouveau_pushbuf.h b/libdrm/nouveau/nouveau_pushbuf.h
index 414ad2d..3c746ed 100644
--- a/libdrm/nouveau/nouveau_pushbuf.h
+++ b/libdrm/nouveau/nouveau_pushbuf.h
@@ -41,8 +41,8 @@ nouveau_pushbuf_flush(struct nouveau_channel *, unsigned min);
int
nouveau_pushbuf_emit_reloc(struct nouveau_channel *, void *ptr,
- struct nouveau_bo *, uint32_t data, uint32_t flags,
- uint32_t vor, uint32_t tor);
+ struct nouveau_bo *, uint32_t data, uint32_t data2,
+ uint32_t flags, uint32_t vor, uint32_t tor);
/* Push buffer access macros */
static __inline__ void
@@ -121,7 +121,16 @@ OUT_RELOC(struct nouveau_channel *chan, struct nouveau_bo *bo,
unsigned data, unsigned flags, unsigned vor, unsigned tor)
{
nouveau_pushbuf_emit_reloc(chan, chan->pushbuf->cur++, bo,
- data, flags, vor, tor);
+ data, 0, flags, vor, tor);
+}
+
+static __inline__ void
+OUT_RELOC2(struct nouveau_channel *chan, struct nouveau_bo *bo,
+ unsigned data, unsigned data2, unsigned flags,
+ unsigned vor, unsigned tor)
+{
+ nouveau_pushbuf_emit_reloc(chan, chan->pushbuf->cur++, bo,
+ data, data2, flags, vor, tor);
}
/* Raw data + flags depending on FB/TT buffer */
@@ -149,6 +158,14 @@ OUT_RELOCl(struct nouveau_channel *chan, struct nouveau_bo *bo,
OUT_RELOC(chan, bo, delta, flags | NOUVEAU_BO_LOW, 0, 0);
}
+/* Low 32-bits of offset + GPU linear access range info */
+static __inline__ void
+OUT_RELOCr(struct nouveau_channel *chan, struct nouveau_bo *bo,
+ unsigned delta, unsigned size, unsigned flags)
+{
+ OUT_RELOC2(chan, bo, delta, size, flags | NOUVEAU_BO_LOW, 0, 0);
+}
+
/* High 32-bits of offset */
static __inline__ void
OUT_RELOCh(struct nouveau_channel *chan, struct nouveau_bo *bo,
diff --git a/shared-core/nouveau_drm.h b/shared-core/nouveau_drm.h
index e999d20..dc6a194 100644
--- a/shared-core/nouveau_drm.h
+++ b/shared-core/nouveau_drm.h
@@ -25,7 +25,7 @@
#ifndef __NOUVEAU_DRM_H__
#define __NOUVEAU_DRM_H__
-#define NOUVEAU_DRM_HEADER_PATCHLEVEL 13
+#define NOUVEAU_DRM_HEADER_PATCHLEVEL 14
struct drm_nouveau_channel_alloc {
uint32_t fb_ctxdma_handle;
@@ -154,8 +154,6 @@ struct drm_nouveau_setparam {
#define NOUVEAU_GEM_DOMAIN_VRAM (1 << 1)
#define NOUVEAU_GEM_DOMAIN_GART (1 << 2)
#define NOUVEAU_GEM_DOMAIN_MAPPABLE (1 << 3)
-#define NOUVEAU_GEM_DOMAIN_TILE (1 << 30)
-#define NOUVEAU_GEM_DOMAIN_TILE_ZETA (1 << 31)
struct drm_nouveau_gem_info {
uint32_t handle;
@@ -163,6 +161,8 @@ struct drm_nouveau_gem_info {
uint64_t size;
uint64_t offset;
uint64_t map_handle;
+ uint32_t tile_mode;
+ uint32_t tile_flags;
};
struct drm_nouveau_gem_new {
diff --git a/shared-core/nouveau_drv.h b/shared-core/nouveau_drv.h
index ce52ce2..841cbf5 100644
--- a/shared-core/nouveau_drv.h
+++ b/shared-core/nouveau_drv.h
@@ -34,7 +34,7 @@
#define DRIVER_MAJOR 0
#define DRIVER_MINOR 0
-#define DRIVER_PATCHLEVEL 13
+#define DRIVER_PATCHLEVEL 14
#define NOUVEAU_FAMILY 0x0000FFFF
#define NOUVEAU_FLAGS 0xFFFF0000
|
|
From: <dar...@ke...> - 2009-06-03 23:06:33
|
libdrm/nouveau/nouveau_bo.c | 3 +++
1 file changed, 3 insertions(+)
New commits:
commit 2cb4c64d7310904b354365c2cbc263211e9eb4a1
Author: Ben Skeggs <bs...@re...>
Date: Thu Jun 4 08:59:53 2009 +1000
nouveau: fix bo mapping issue
diff --git a/libdrm/nouveau/nouveau_bo.c b/libdrm/nouveau/nouveau_bo.c
index 8832a0d..55d0575 100644
--- a/libdrm/nouveau/nouveau_bo.c
+++ b/libdrm/nouveau/nouveau_bo.c
@@ -20,6 +20,9 @@
* SOFTWARE.
*/
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
#include <stdint.h>
#include <stdlib.h>
#include <errno.h>
|
|
From: <pq...@ke...> - 2009-06-03 19:33:10
|
linux-core/drm_os_linux.h | 17 +++--------------
1 file changed, 3 insertions(+), 14 deletions(-)
New commits:
commit d7c42ff4c445ed2cb23f4eb3a45858c110184773
Author: Pekka Paalanen <pq...@ik...>
Date: Wed Jun 3 22:26:43 2009 +0300
Fix build on kernels < 2.6.26
The commit 651e3dc6dd58a79c90db7513ee2fb28360a4560d, "drm: Fix
compilation on 2.6.30" broke all builds on kernels before 2.6.26.
Variadic functions cannot be inlined.
The variadic inline function is replaced with a variadic macro.
Also, the function dev_name() added by that same commit is never used,
so it is removed.
Signed-off-by: Pekka Paalanen <pq...@ik...>
diff --git a/linux-core/drm_os_linux.h b/linux-core/drm_os_linux.h
index be5e099..2293711 100644
--- a/linux-core/drm_os_linux.h
+++ b/linux-core/drm_os_linux.h
@@ -39,20 +39,9 @@ typedef void irqreturn_t;
#endif
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,25)
-static inline const char *dev_name(const struct device *dev)
-{
- return dev->bus_id;
-}
-static inline int dev_set_name(struct device *dev, const char *name, ...)
-{
- va_list vargs;
-
- va_start(vargs, name);
- vsnprintf(dev->bus_id, sizeof(dev->bus_id), name, vargs);
- va_end(vargs);
-
- return 0;
-}
+#define dev_set_name(dev, name, ...) ({ \
+ snprintf((dev)->bus_id, BUS_ID_SIZE, (name), __VA_ARGS__); \
+ 0; })
#endif
/** AGP types */
|
|
From: <dar...@ke...> - 2009-06-03 00:57:44
|
libdrm/nouveau/nouveau_bo.c | 9 +++++++++
1 file changed, 9 insertions(+)
New commits:
commit 00fae87f96e1fc5198311feec81866bf9c53d0e1
Author: Ben Skeggs <bs...@re...>
Date: Wed Jun 3 10:24:30 2009 +1000
nouveau: fill in bo->tiled field for referenced buffers
Fixes the dri1 gallium driver if the front buffer happens to be non-linear.
diff --git a/libdrm/nouveau/nouveau_bo.c b/libdrm/nouveau/nouveau_bo.c
index 1bf6612..8832a0d 100644
--- a/libdrm/nouveau/nouveau_bo.c
+++ b/libdrm/nouveau/nouveau_bo.c
@@ -49,6 +49,15 @@ nouveau_bo_info(struct nouveau_bo_priv *nvbo, struct drm_nouveau_gem_info *arg)
nvbo->size = nvbo->base.size = arg->size;
nvbo->offset = arg->offset;
nvbo->map_handle = arg->map_handle;
+
+ if (nvbo->domain & NOUVEAU_GEM_DOMAIN_TILE) {
+ nvbo->base.tiled = 1;
+ if (nvbo->domain & NOUVEAU_GEM_DOMAIN_TILE_ZETA)
+ nvbo->base.tiled |= 2;
+ } else {
+ nvbo->base.tiled = 0;
+ }
+
return 0;
}
|
|
From: <dar...@ke...> - 2009-06-02 07:16:24
|
shared-core/nv50_graph.c | 1 +
1 file changed, 1 insertion(+)
New commits:
commit dbffeadcfca7cb4e3905ec0b8573d10e0418295e
Author: Ben Skeggs <bs...@re...>
Date: Tue Jun 2 17:06:34 2009 +1000
nv50: magic fix for "3d busted without the binary driver first" issue
No idea what this reg does.. NVIDIA put 0x802 into it on some chips, the
criteria aren't too clear on when they do that however. Hopefully 0x800
will work everywhere...
diff --git a/shared-core/nv50_graph.c b/shared-core/nv50_graph.c
index cbf6fd6..43f35e0 100644
--- a/shared-core/nv50_graph.c
+++ b/shared-core/nv50_graph.c
@@ -82,6 +82,7 @@ nv50_graph_init_regs(struct drm_device *dev)
DRM_DEBUG("\n");
NV_WRITE(NV04_PGRAPH_DEBUG_3, (1<<2) /* HW_CONTEXT_SWITCH_ENABLED */);
+ NV_WRITE(0x402ca8, 0x800);
}
static int
|