From 321c029396348f743537824bde13f4b161002222 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Thu, 5 Feb 2009 00:52:26 +0000 Subject: [PATCH] - update with more libdrm/radeon upstream fixes --- libdrm-radeon-update.patch | 309 ---- libdrm-radeon.patch | 2848 +++++++++++++++++++----------------- libdrm.spec | 7 +- 3 files changed, 1528 insertions(+), 1636 deletions(-) delete mode 100644 libdrm-radeon-update.patch diff --git a/libdrm-radeon-update.patch b/libdrm-radeon-update.patch deleted file mode 100644 index 74d3cf3..0000000 --- a/libdrm-radeon-update.patch +++ /dev/null @@ -1,309 +0,0 @@ -diff --git a/libdrm/radeon/radeon_bo.h b/libdrm/radeon/radeon_bo.h -index 44dc090..3cabdfc 100644 ---- a/libdrm/radeon/radeon_bo.h -+++ b/libdrm/radeon/radeon_bo.h -@@ -52,6 +52,7 @@ struct radeon_bo { - #endif - void *ptr; - struct radeon_bo_manager *bom; -+ uint32_t space_accounted; - }; - - /* bo functions */ -@@ -66,6 +67,7 @@ struct radeon_bo_funcs { - 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 { -@@ -151,6 +153,14 @@ static inline int _radeon_bo_unmap(struct radeon_bo *bo, - 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)\ -@@ -163,5 +173,7 @@ static inline int _radeon_bo_unmap(struct radeon_bo *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 -index fdf852a..932afeb 100644 ---- a/libdrm/radeon/radeon_bo_gem.c -+++ b/libdrm/radeon/radeon_bo_gem.c -@@ -35,6 +35,7 @@ - #include - #include - #include -+#include - #include "xf86drm.h" - #include "drm.h" - #include "radeon_drm.h" -@@ -176,12 +177,26 @@ static int bo_unmap(struct radeon_bo *bo) - return 0; - } - -+static int bo_wait(struct radeon_bo *bo) -+{ -+ struct drm_radeon_gem_wait_rendering args; -+ int ret; -+ -+ args.handle = bo->handle; -+ do { -+ ret = drmCommandWriteRead(bo->bom->fd, DRM_RADEON_GEM_WAIT_RENDERING, -+ &args, sizeof(args)); -+ } while (ret == -EAGAIN); -+ return ret; -+} -+ - static struct radeon_bo_funcs bo_gem_funcs = { - bo_open, - bo_ref, - bo_unref, - bo_map, -- bo_unmap -+ bo_unmap, -+ bo_wait - }; - - struct radeon_bo_manager *radeon_bo_manager_gem_ctor(int fd) -diff --git a/libdrm/radeon/radeon_cs.h b/libdrm/radeon/radeon_cs.h -index 8b1a999..8b5a2a9 100644 ---- a/libdrm/radeon/radeon_cs.h -+++ b/libdrm/radeon/radeon_cs.h -@@ -33,6 +33,8 @@ - #define RADEON_CS_H - - #include -+#include "drm.h" -+#include "radeon_drm.h" - #include "radeon_bo.h" - - struct radeon_cs_reloc { -@@ -42,6 +44,18 @@ struct radeon_cs_reloc { - 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 { -@@ -58,6 +72,7 @@ struct radeon_cs { - const char *section_file; - const char *section_func; - int section_line; -+ - }; - - /* cs functions */ -@@ -84,11 +99,16 @@ struct radeon_cs_funcs { - 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, -@@ -157,4 +177,19 @@ 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; -+} - #endif -diff --git a/libdrm/radeon/radeon_cs_gem.c b/libdrm/radeon/radeon_cs_gem.c -index bfc5aca..c9cf345 100644 ---- a/libdrm/radeon/radeon_cs_gem.c -+++ b/libdrm/radeon/radeon_cs_gem.c -@@ -229,6 +229,16 @@ static int cs_gem_end(struct radeon_cs *cs, - return 0; - } - -+ -+static void dump_cmdbuf(struct radeon_cs *cs) -+{ -+ int i; -+ for (i = 0; i < cs->cdw; i++){ -+ fprintf(stderr,"%x: %08x\n", i, cs->packets[i]); -+ } -+ -+} -+ - static int cs_gem_emit(struct radeon_cs *cs) - { - struct cs_gem *csg = (struct cs_gem*)cs; -@@ -236,6 +246,7 @@ static int cs_gem_emit(struct radeon_cs *cs) - unsigned i; - int r; - -+ dump_cmdbuf(cs); - csg->chunks[0].length_dw = cs->cdw; - - chunk_array[0] = (uint64_t)(intptr_t)&csg->chunks[0]; -@@ -387,6 +398,97 @@ static void cs_gem_print(struct radeon_cs *cs, FILE *file) - } - } - -+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)) -+ continue; -+ -+ if (read_domains && ((read_domains << 16) == 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_dword, -@@ -397,7 +499,8 @@ static struct radeon_cs_funcs radeon_cs_gem_funcs = { - cs_gem_destroy, - cs_gem_erase, - cs_gem_need_flush, -- cs_gem_print -+ cs_gem_print, -+ cs_gem_check_space, - }; - - struct radeon_cs_manager *radeon_cs_manager_gem_ctor(int fd) -diff --git a/shared-core/radeon_drm.h b/shared-core/radeon_drm.h -index fd26eee..b989649 100644 ---- a/shared-core/radeon_drm.h -+++ b/shared-core/radeon_drm.h -@@ -711,6 +711,7 @@ typedef struct drm_radeon_indirect { - #define RADEON_PARAM_FB_LOCATION 14 /* FB location */ - #define RADEON_PARAM_NUM_GB_PIPES 15 /* num GB pipes */ - #define RADEON_PARAM_KERNEL_MM 16 -+#define RADEON_PARAM_DEVICE_ID 17 - - typedef struct drm_radeon_getparam { - int param; diff --git a/libdrm-radeon.patch b/libdrm-radeon.patch index b077b84..73c372b 100644 --- a/libdrm-radeon.patch +++ b/libdrm-radeon.patch @@ -21,1330 +21,6 @@ diff -up libdrm-2.4.3/libdrm/Makefile.am.dave libdrm-2.4.3/libdrm/Makefile.am libdrm_la_LTLIBRARIES = libdrm.la libdrm_ladir = $(libdir) -diff -up /dev/null libdrm-2.4.3/libdrm/radeon/Makefile.am ---- /dev/null 2008-12-18 14:22:13.823022429 +1000 -+++ libdrm-2.4.3/libdrm/radeon/Makefile.am 2008-12-22 12:05:48.000000000 +1000 -@@ -0,0 +1,48 @@ -+# 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 -+ -+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 -diff -up /dev/null libdrm-2.4.3/libdrm/radeon/radeon_bo_gem.c ---- /dev/null 2008-12-18 14:22:13.823022429 +1000 -+++ libdrm-2.4.3/libdrm/radeon/radeon_bo_gem.c 2008-12-22 12:05:48.000000000 +1000 -@@ -0,0 +1,208 @@ -+/* -+ * 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 -+ */ -+#include -+#include -+#include -+#include -+#include -+#include -+#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.no_backing_store = 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; -+ -+ 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) { -+ bo->ptr = (void *)(unsigned long)args.addr_ptr; -+ } else { -+ fprintf(stderr, "error mapping %p 0x%08X (error = %d)\n", -+ bo, bo->handle, r); -+ } -+ 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 struct radeon_bo_funcs bo_gem_funcs = { -+ bo_open, -+ bo_ref, -+ bo_unref, -+ bo_map, -+ bo_unmap -+}; -+ -+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); -+} -diff -up /dev/null libdrm-2.4.3/libdrm/radeon/radeon_bo_gem.h ---- /dev/null 2008-12-18 14:22:13.823022429 +1000 -+++ libdrm-2.4.3/libdrm/radeon/radeon_bo_gem.h 2008-12-22 12:05:48.000000000 +1000 -@@ -0,0 +1,40 @@ -+/* -+ * 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 -+ */ -+#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); -+ -+#endif -diff -up /dev/null libdrm-2.4.3/libdrm/radeon/radeon_bo.h ---- /dev/null 2008-12-18 14:22:13.823022429 +1000 -+++ libdrm-2.4.3/libdrm/radeon/radeon_bo.h 2008-12-22 12:05:48.000000000 +1000 -@@ -0,0 +1,167 @@ -+/* -+ * 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 -+ */ -+#ifndef RADEON_BO_H -+#define RADEON_BO_H -+ -+#include -+#include -+#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; -+}; -+ -+/* 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); -+}; -+ -+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); -+} -+ -+#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__) -+ -+#endif -diff -up /dev/null libdrm-2.4.3/libdrm/radeon/radeon_cs_gem.c ---- /dev/null 2008-12-18 14:22:13.823022429 +1000 -+++ libdrm-2.4.3/libdrm/radeon/radeon_cs_gem.c 2008-12-22 12:05:48.000000000 +1000 -@@ -0,0 +1,420 @@ -+/* -+ * 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 -+ * Nicolai Haehnle -+ * Jérôme Glisse -+ */ -+#include -+#include -+#include -+#include -+#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_dword(struct radeon_cs *cs, uint32_t dword) -+{ -+ struct cs_gem *csg = (struct cs_gem*)cs; -+ if (cs->cdw >= cs->ndw) { -+ uint32_t tmp, *ptr; -+ tmp = (cs->cdw + 1 + 0x3FF) & (~0x3FF); -+ ptr = (uint32_t*)realloc(cs->packets, 4 * tmp); -+ if (ptr == NULL) { -+ return -ENOMEM; -+ } -+ cs->packets = ptr; -+ cs->ndw = tmp; -+ csg->chunks[0].chunk_data = (uint64_t)(intptr_t)csg->base.packets; -+ } -+ cs->packets[cs->cdw++] = dword; -+ csg->chunks[0].length_dw += 1; -+ return 0; -+} -+ -+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; -+ -+ /* 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 */ -+ cs_gem_write_dword(cs, 0xc0001000); -+ cs_gem_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; -+ cs_gem_write_dword(cs, 0xc0001000); -+ cs_gem_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) -+{ -+ return 0; -+} -+ -+static int cs_gem_end(struct radeon_cs *cs, -+ const char *file, -+ const char *func, -+ int line) -+ -+{ -+ cs->section = 0; -+ 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++) { -+ radeon_bo_unref(csg->relocs_bo[i]); -+ csg->relocs_bo[i] = NULL; -+ } -+ 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 (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 struct radeon_cs_funcs radeon_cs_gem_funcs = { -+ cs_gem_create, -+ cs_gem_write_dword, -+ 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 -+}; -+ -+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 -up /dev/null libdrm-2.4.3/libdrm/radeon/radeon_cs_gem.h ---- /dev/null 2008-12-18 14:22:13.823022429 +1000 -+++ libdrm-2.4.3/libdrm/radeon/radeon_cs_gem.h 2008-12-22 12:05:48.000000000 +1000 -@@ -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 -+ * Nicolai Haehnle -+ * Jérôme Glisse -+ */ -+#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 -up /dev/null libdrm-2.4.3/libdrm/radeon/radeon_cs.h ---- /dev/null 2008-12-18 14:22:13.823022429 +1000 -+++ libdrm-2.4.3/libdrm/radeon/radeon_cs.h 2008-12-22 12:05:48.000000000 +1000 -@@ -0,0 +1,160 @@ -+/* -+ * 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 -+ * Nicolai Haehnle -+ * Jérôme Glisse -+ */ -+#ifndef RADEON_CS_H -+#define RADEON_CS_H -+ -+#include -+#include "radeon_bo.h" -+ -+struct radeon_cs_reloc { -+ struct radeon_bo *bo; -+ uint32_t read_domain; -+ uint32_t write_domain; -+ uint32_t flags; -+}; -+ -+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_dword)(struct radeon_cs *cs, uint32_t dword); -+ 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); -+}; -+ -+struct radeon_cs_manager { -+ struct radeon_cs_funcs *funcs; -+ int fd; -+}; -+ -+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_dword(struct radeon_cs *cs, uint32_t dword) -+{ -+ return cs->csm->funcs->cs_write_dword(cs, dword); -+} -+ -+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); -+} -+ -+#endif -diff -up /dev/null libdrm-2.4.3/libdrm/radeon/radeon_track.c ---- /dev/null 2008-12-18 14:22:13.823022429 +1000 -+++ libdrm-2.4.3/libdrm/radeon/radeon_track.c 2008-12-22 12:05:48.000000000 +1000 -@@ -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 -+ */ -+#include -+#include -+#include -+#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 -up /dev/null libdrm-2.4.3/libdrm/radeon/radeon_track.h ---- /dev/null 2008-12-18 14:22:13.823022429 +1000 -+++ libdrm-2.4.3/libdrm/radeon/radeon_track.h 2008-12-22 12:05:48.000000000 +1000 -@@ -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 -+ */ -+#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 -up libdrm-2.4.3/shared-core/radeon_drm.h.dave libdrm-2.4.3/shared-core/radeon_drm.h --- libdrm-2.4.3/shared-core/radeon_drm.h.dave 2008-12-19 14:33:38.000000000 +1000 +++ libdrm-2.4.3/shared-core/radeon_drm.h 2008-12-22 12:05:48.000000000 +1000 @@ -1527,3 +203,1527 @@ diff -up libdrm-2.4.3/shared-core/radeon_drm.h.dave libdrm-2.4.3/shared-core/rad + + #endif +diff --git a/libdrm/radeon/Makefile.am b/libdrm/radeon/Makefile.am +new file mode 100644 +index 0000000..32ca559 +--- /dev/null ++++ b/libdrm/radeon/Makefile.am +@@ -0,0 +1,48 @@ ++# 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 ++ ++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 +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 ++ */ ++#ifndef RADEON_BO_H ++#define RADEON_BO_H ++ ++#include ++#include ++#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..932afeb +--- /dev/null ++++ b/libdrm/radeon/radeon_bo_gem.c +@@ -0,0 +1,223 @@ ++/* ++ * 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 ++ */ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#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.no_backing_store = 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; ++ ++ 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) { ++ bo->ptr = (void *)(unsigned long)args.addr_ptr; ++ } else { ++ fprintf(stderr, "error mapping %p 0x%08X (error = %d)\n", ++ bo, bo->handle, r); ++ } ++ 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_rendering args; ++ int ret; ++ ++ args.handle = bo->handle; ++ do { ++ ret = drmCommandWriteRead(bo->bom->fd, DRM_RADEON_GEM_WAIT_RENDERING, ++ &args, sizeof(args)); ++ } while (ret == -EAGAIN); ++ 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); ++} +diff --git a/libdrm/radeon/radeon_bo_gem.h b/libdrm/radeon/radeon_bo_gem.h +new file mode 100644 +index 0000000..c0f68e6 +--- /dev/null ++++ b/libdrm/radeon/radeon_bo_gem.h +@@ -0,0 +1,40 @@ ++/* ++ * 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 ++ */ ++#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); ++ ++#endif +diff --git a/libdrm/radeon/radeon_cs.h b/libdrm/radeon/radeon_cs.h +new file mode 100644 +index 0000000..7cc75d4 +--- /dev/null ++++ b/libdrm/radeon/radeon_cs.h +@@ -0,0 +1,198 @@ ++/* ++ * 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 ++ * Nicolai Haehnle ++ * Jérôme Glisse ++ */ ++#ifndef RADEON_CS_H ++#define RADEON_CS_H ++ ++#include ++#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++; ++ } ++} ++ ++#endif +diff --git a/libdrm/radeon/radeon_cs_gem.c b/libdrm/radeon/radeon_cs_gem.c +new file mode 100644 +index 0000000..dc14a8a +--- /dev/null ++++ b/libdrm/radeon/radeon_cs_gem.c +@@ -0,0 +1,537 @@ ++/* ++ * 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 ++ * Nicolai Haehnle ++ * Jérôme Glisse ++ */ ++#include ++#include ++#include ++#include ++#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; ++ ++ /* 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++) { ++ 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 (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)) ++ continue; ++ ++ if (read_domains && ((read_domains << 16) == 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 ++ * Nicolai Haehnle ++ * Jérôme Glisse ++ */ ++#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 ++ */ ++#include ++#include ++#include ++#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 ++ */ ++#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/libdrm.spec b/libdrm.spec index 173dc42..e3e0c86 100644 --- a/libdrm.spec +++ b/libdrm.spec @@ -3,7 +3,7 @@ Summary: Direct Rendering Manager runtime library Name: libdrm Version: 2.4.4 -Release: 2%{?dist} +Release: 3%{?dist} License: MIT Group: System Environment/Libraries URL: http://dri.sourceforge.net @@ -28,7 +28,6 @@ Patch3: libdrm-make-dri-perms-okay.patch Patch4: libdrm-2.4.0-no-bc.patch # radeon libdrm patches from modesetting-gem branch of upstream Patch8: libdrm-radeon.patch -Patch9: libdrm-radeon-update.patch %description Direct Rendering Manager runtime library @@ -48,7 +47,6 @@ Direct Rendering Manager development package %patch3 -p1 -b .forceperms %patch4 -p1 -b .no-bc %patch8 -p1 -b .radeon -%patch9 -p1 -b .radeon2 %build autoreconf -v --install || exit 1 @@ -100,6 +98,9 @@ rm -rf $RPM_BUILD_ROOT %{_libdir}/pkgconfig/libdrm.pc %changelog +* Thu Feb 05 2009 Dave Airlie 2.4.4-3 +- update with more libdrm/radeon upstream fixes + * Sun Feb 01 2009 Dave Airlie 2.4.4-2 - update specfile with review changes