diff --git a/packages/graphics/libdrm/build b/packages/graphics/libdrm/build index 9ce4ea3d1d..cc7fc55232 100755 --- a/packages/graphics/libdrm/build +++ b/packages/graphics/libdrm/build @@ -18,10 +18,13 @@ cd $BUILD/$1* --enable-shared \ --enable-udev \ --enable-largefile \ + --enable-nouveau-experimental-api $MAKE $STRIP libdrm/.libs/libdrm.so* -$STRIP libdrm/intel/.libs/libdrm_intel.so* +$STRIP libdrm/intel/.libs/*.so* +$STRIP libdrm/nouveau/.libs/*.so* +$STRIP libdrm/radeon/.libs/*.so* $MAKEINSTALL diff --git a/packages/graphics/libdrm/install b/packages/graphics/libdrm/install index 6493a129f2..fb46a72a00 100755 --- a/packages/graphics/libdrm/install +++ b/packages/graphics/libdrm/install @@ -4,4 +4,12 @@ mkdir -p $INSTALL/usr/lib cp -PR $BUILD/$1*/libdrm/.libs/libdrm.so* $INSTALL/usr/lib -cp -PR $BUILD/$1*/libdrm/intel/.libs/libdrm_intel.so* $INSTALL/usr/lib + +cp -PR $BUILD/$1*/libdrm/intel/.libs/libdrm_intel*.so* $INSTALL/usr/lib +rm -rf $INSTALL/usr/lib/libdrm_intel*.so*T + +cp -PR $BUILD/$1*/libdrm/nouveau/.libs/libdrm_nouveau*.so* $INSTALL/usr/lib +rm -rf $INSTALL/usr/lib/libdrm_nouveau*.so*T + +cp -PR $BUILD/$1*/libdrm/radeon/.libs/libdrm_radeon*.so* $INSTALL/usr/lib +rm -rf $INSTALL/usr/lib/libdrm_radeon*.so*T diff --git a/packages/graphics/libdrm/patches/libdrm-2.4.0-no-bc.diff b/packages/graphics/libdrm/patches/libdrm-2.4.0-no-bc.diff new file mode 100644 index 0000000000..c09acc587a --- /dev/null +++ b/packages/graphics/libdrm/patches/libdrm-2.4.0-no-bc.diff @@ -0,0 +1,54 @@ +diff -up libdrm-20080814/libdrm/xf86drm.c.no-bc libdrm-20080814/libdrm/xf86drm.c +--- libdrm-20080814/libdrm/xf86drm.c.no-bc 2008-08-14 15:43:09.000000000 +1000 ++++ libdrm-20080814/libdrm/xf86drm.c 2008-08-14 15:45:09.000000000 +1000 +@@ -396,11 +396,6 @@ int drmAvailable(void) + int fd; + + if ((fd = drmOpenMinor(0, 1, DRM_NODE_RENDER)) < 0) { +-#ifdef __linux__ +- /* Try proc for backward Linux compatibility */ +- if (!access("/proc/dri/0", R_OK)) +- return 1; +-#endif + return 0; + } + +@@ -519,38 +514,6 @@ static int drmOpenByName(const char *nam + } + } + +-#ifdef __linux__ +- /* Backward-compatibility /proc support */ +- for (i = 0; i < 8; i++) { +- char proc_name[64], buf[512]; +- char *driver, *pt, *devstring; +- int retcode; +- +- sprintf(proc_name, "/proc/dri/%d/name", i); +- if ((fd = open(proc_name, 0, 0)) >= 0) { +- retcode = read(fd, buf, sizeof(buf)-1); +- close(fd); +- if (retcode) { +- buf[retcode-1] = '\0'; +- for (driver = pt = buf; *pt && *pt != ' '; ++pt) +- ; +- if (*pt) { /* Device is next */ +- *pt = '\0'; +- if (!strcmp(driver, name)) { /* Match */ +- for (devstring = ++pt; *pt && *pt != ' '; ++pt) +- ; +- if (*pt) { /* Found busid */ +- return drmOpenByBusid(++pt); +- } else { /* No busid */ +- return drmOpenDevice(strtol(devstring, NULL, 0),i, DRM_NODE_RENDER); +- } +- } +- } +- } +- } +- } +-#endif +- + return -1; + } + diff --git a/packages/graphics/libdrm/patches/libdrm-make-dri-perms-okay.diff b/packages/graphics/libdrm/patches/libdrm-make-dri-perms-okay.diff new file mode 100644 index 0000000000..d9913c4905 --- /dev/null +++ b/packages/graphics/libdrm/patches/libdrm-make-dri-perms-okay.diff @@ -0,0 +1,12 @@ +diff -up libdrm-20080303/libdrm/xf86drm.h.da libdrm-20080303/libdrm/xf86drm.h +--- libdrm-20080303/libdrm/xf86drm.h.da 2008-03-19 15:26:31.000000000 +1000 ++++ libdrm-20080303/libdrm/xf86drm.h 2008-03-19 15:26:46.000000000 +1000 +@@ -45,7 +45,7 @@ + /* Default /dev/dri directory permissions 0755 */ + #define DRM_DEV_DIRMODE \ + (S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH) +-#define DRM_DEV_MODE (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP) ++#define DRM_DEV_MODE (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH) + + #define DRM_DIR_NAME "/dev/dri" + #define DRM_DEV_NAME "%s/card%d" diff --git a/packages/graphics/libdrm/patches/libdrm-radeon.diff b/packages/graphics/libdrm/patches/libdrm-radeon.diff new file mode 100644 index 0000000000..2eec60fdc4 --- /dev/null +++ b/packages/graphics/libdrm/patches/libdrm-radeon.diff @@ -0,0 +1,1769 @@ +diff -up libdrm-2.4.4/configure.ac.radeon libdrm-2.4.4/configure.ac +--- libdrm-2.4.4/configure.ac.radeon 2009-01-15 10:12:09.000000000 +1000 ++++ libdrm-2.4.4/configure.ac 2009-02-18 09:29:20.000000000 +1000 +@@ -124,6 +124,8 @@ AC_OUTPUT([ + Makefile + libdrm/Makefile + libdrm/intel/Makefile ++ libdrm/radeon/Makefile ++ libdrm/radeon/libdrm_radeon.pc + libdrm/nouveau/Makefile + libdrm/nouveau/libdrm_nouveau.pc + shared-core/Makefile +diff -up libdrm-2.4.4/libdrm/Makefile.am.radeon libdrm-2.4.4/libdrm/Makefile.am +--- libdrm-2.4.4/libdrm/Makefile.am.radeon 2009-01-10 11:08:29.000000000 +1000 ++++ libdrm-2.4.4/libdrm/Makefile.am 2009-02-18 09:27:49.000000000 +1000 +@@ -18,7 +18,7 @@ + NOUVEAU_SUBDIR = nouveau + endif + +-SUBDIRS = . intel $(NOUVEAU_SUBDIR) ++SUBDIRS = . intel radeon $(NOUVEAU_SUBDIR) + + libdrm_la_LTLIBRARIES = libdrm.la + libdrm_ladir = $(libdir) +diff --git a/libdrm/radeon/Makefile.am b/libdrm/radeon/Makefile.am +new file mode 100644 +index 0000000..bc8a5b8 +--- /dev/null ++++ b/libdrm/radeon/Makefile.am +@@ -0,0 +1,53 @@ ++# Copyright © 2008 Jérôme Glisse ++# ++# Permission is hereby granted, free of charge, to any person obtaining a ++# copy of this software and associated documentation files (the "Software"), ++# to deal in the Software without restriction, including without limitation ++# the rights to use, copy, modify, merge, publish, distribute, sublicense, ++# and/or sell copies of the Software, and to permit persons to whom the ++# Software is furnished to do so, subject to the following conditions: ++# ++# The above copyright notice and this permission notice (including the next ++# paragraph) shall be included in all copies or substantial portions of the ++# Software. ++# ++# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ++# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER ++# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING ++# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS ++# IN THE SOFTWARE. ++# ++# Authors: ++# Jérôme Glisse ++ ++AM_CFLAGS = \ ++ $(WARN_CFLAGS) \ ++ -I$(top_srcdir)/libdrm \ ++ -I$(top_srcdir)/libdrm/radeon \ ++ $(PTHREADSTUBS_CFLAGS) \ ++ -I$(top_srcdir)/shared-core ++ ++libdrm_radeon_la_LTLIBRARIES = libdrm_radeon.la ++libdrm_radeon_ladir = $(libdir) ++libdrm_radeon_la_LDFLAGS = -version-number 1:0:0 -no-undefined ++libdrm_radeon_la_LIBADD = ../libdrm.la @PTHREADSTUBS_LIBS@ ++ ++libdrm_radeon_la_SOURCES = \ ++ radeon_bo_gem.c \ ++ radeon_cs_gem.c \ ++ radeon_track.c ++ ++libdrm_radeonincludedir = ${includedir}/drm ++libdrm_radeoninclude_HEADERS = \ ++ radeon_bo.h \ ++ radeon_cs.h \ ++ radeon_bo_gem.h \ ++ radeon_cs_gem.h \ ++ radeon_track.h ++ ++pkgconfigdir = @pkgconfigdir@ ++pkgconfig_DATA = libdrm_radeon.pc ++ ++EXTRA_DIST = libdrm_radeon.pc.in +diff --git a/libdrm/radeon/libdrm_radeon.pc.in b/libdrm/radeon/libdrm_radeon.pc.in +new file mode 100644 +index 0000000..3306844 +--- /dev/null ++++ b/libdrm/radeon/libdrm_radeon.pc.in +@@ -0,0 +1,10 @@ ++prefix=@prefix@ ++exec_prefix=@exec_prefix@ ++libdir=@libdir@ ++includedir=@includedir@ ++ ++Name: libdrm_radeon ++Description: Userspace interface to kernel DRM services for radeon ++Version: 1.0.1 ++Libs: -L${libdir} -ldrm_radeon ++Cflags: -I${includedir} -I${includedir}/drm +diff --git a/libdrm/radeon/radeon_bo.h b/libdrm/radeon/radeon_bo.h +new file mode 100644 +index 0000000..3cabdfc +--- /dev/null ++++ b/libdrm/radeon/radeon_bo.h +@@ -0,0 +1,179 @@ ++/* ++ * Copyright © 2008 Jérôme Glisse ++ * All Rights Reserved. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining ++ * a copy of this software and associated documentation files (the ++ * "Software"), to deal in the Software without restriction, including ++ * without limitation the rights to use, copy, modify, merge, publish, ++ * distribute, sub license, and/or sell copies of the Software, and to ++ * permit persons to whom the Software is furnished to do so, subject to ++ * the following conditions: ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, ++ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES ++ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND ++ * NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS, AUTHORS ++ * AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER ++ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ++ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE ++ * USE OR OTHER DEALINGS IN THE SOFTWARE. ++ * ++ * The above copyright notice and this permission notice (including the ++ * next paragraph) shall be included in all copies or substantial portions ++ * of the Software. ++ */ ++/* ++ * Authors: ++ * Jérôme Glisse ++ */ ++#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..70f4b6b +--- /dev/null ++++ b/libdrm/radeon/radeon_bo_gem.c +@@ -0,0 +1,237 @@ ++/* ++ * 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 ++ */ ++#ifdef HAVE_CONFIG_H ++#include ++#endif ++#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.flags = 0; ++ args.handle = 0; ++ r = drmCommandWriteRead(bom->fd, DRM_RADEON_GEM_CREATE, ++ &args, sizeof(args)); ++ bo->base.handle = args.handle; ++ if (r) { ++ fprintf(stderr, "Failed to allocate :\n"); ++ fprintf(stderr, " size : %d bytes\n", size); ++ fprintf(stderr, " alignment : %d bytes\n", alignment); ++ fprintf(stderr, " domains : %d\n", bo->base.domains); ++ free(bo); ++ return NULL; ++ } ++ } ++ radeon_bo_ref((struct radeon_bo*)bo); ++ return (struct radeon_bo*)bo; ++} ++ ++static void bo_ref(struct radeon_bo *bo) ++{ ++} ++ ++static struct radeon_bo *bo_unref(struct radeon_bo *bo) ++{ ++ struct radeon_bo_gem *bo_gem = (struct radeon_bo_gem*)bo; ++ struct drm_gem_close args; ++ ++ if (bo == NULL) { ++ return NULL; ++ } ++ if (bo->cref) { ++ return bo; ++ } ++ if (bo_gem->map_count) { ++ munmap(bo->ptr, bo->size); ++ } ++ ++ /* close object */ ++ args.handle = bo->handle; ++ ioctl(bo->bom->fd, DRM_IOCTL_GEM_CLOSE, &args); ++ memset(bo_gem, 0, sizeof(struct radeon_bo_gem)); ++ free(bo_gem); ++ return NULL; ++} ++ ++static int bo_map(struct radeon_bo *bo, int write) ++{ ++ struct radeon_bo_gem *bo_gem = (struct radeon_bo_gem*)bo; ++ struct drm_radeon_gem_mmap args; ++ int r; ++ void *ptr; ++ ++ if (bo_gem->map_count++ != 0) { ++ return 0; ++ } ++ bo->ptr = NULL; ++ args.handle = bo->handle; ++ args.offset = 0; ++ args.size = (uint64_t)bo->size; ++ r = drmCommandWriteRead(bo->bom->fd, ++ DRM_RADEON_GEM_MMAP, ++ &args, ++ sizeof(args)); ++ if (r) { ++ fprintf(stderr, "error mapping %p 0x%08X (error = %d)\n", ++ bo, bo->handle, r); ++ return r; ++ } ++ ptr = mmap(0, args.size, PROT_READ|PROT_WRITE, MAP_SHARED, bo->bom->fd, args.addr_ptr); ++ if (ptr == MAP_FAILED) ++ return -errno; ++ bo->ptr = ptr; ++ ++ return r; ++} ++ ++static int bo_unmap(struct radeon_bo *bo) ++{ ++ struct radeon_bo_gem *bo_gem = (struct radeon_bo_gem*)bo; ++ ++ if (--bo_gem->map_count > 0) { ++ return 0; ++ } ++ munmap(bo->ptr, bo->size); ++ bo->ptr = NULL; ++ return 0; ++} ++ ++static int bo_wait(struct radeon_bo *bo) ++{ ++ struct drm_radeon_gem_wait_idle args; ++ int ret; ++ ++ args.handle = bo->handle; ++ do { ++ ret = drmCommandWriteRead(bo->bom->fd, DRM_RADEON_GEM_WAIT_IDLE, ++ &args, sizeof(args)); ++ } while (ret == -EBUSY); ++ return ret; ++} ++ ++static struct radeon_bo_funcs bo_gem_funcs = { ++ bo_open, ++ bo_ref, ++ bo_unref, ++ bo_map, ++ bo_unmap, ++ bo_wait ++}; ++ ++struct radeon_bo_manager *radeon_bo_manager_gem_ctor(int fd) ++{ ++ struct bo_manager_gem *bomg; ++ ++ bomg = (struct bo_manager_gem*)calloc(1, sizeof(struct bo_manager_gem)); ++ if (bomg == NULL) { ++ return NULL; ++ } ++ bomg->base.funcs = &bo_gem_funcs; ++ bomg->base.fd = fd; ++ return (struct radeon_bo_manager*)bomg; ++} ++ ++void radeon_bo_manager_gem_dtor(struct radeon_bo_manager *bom) ++{ ++ struct bo_manager_gem *bomg = (struct bo_manager_gem*)bom; ++ ++ if (bom == NULL) { ++ return; ++ } ++ free(bomg); ++} ++ ++uint32_t radeon_gem_name_bo(struct radeon_bo *bo) ++{ ++ struct radeon_bo_gem *bo_gem = (struct radeon_bo_gem*)bo; ++ return bo_gem->name; ++} +diff --git a/libdrm/radeon/radeon_bo_gem.h b/libdrm/radeon/radeon_bo_gem.h +new file mode 100644 +index 0000000..980a6a4 +--- /dev/null ++++ b/libdrm/radeon/radeon_bo_gem.h +@@ -0,0 +1,41 @@ ++/* ++ * 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); ++ ++uint32_t radeon_gem_name_bo(struct radeon_bo *bo); ++#endif +diff --git a/libdrm/radeon/radeon_cs.h b/libdrm/radeon/radeon_cs.h +new file mode 100644 +index 0000000..d870961 +--- /dev/null ++++ b/libdrm/radeon/radeon_cs.h +@@ -0,0 +1,208 @@ ++/* ++ * Copyright © 2008 Nicolai Haehnle ++ * Copyright © 2008 Jérôme Glisse ++ * All Rights Reserved. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining a ++ * copy of this software and associated documentation files (the ++ * "Software"), to deal in the Software without restriction, including ++ * without limitation the rights to use, copy, modify, merge, publish, ++ * distribute, sub license, and/or sell copies of the Software, and to ++ * permit persons to whom the Software is furnished to do so, subject to ++ * the following conditions: ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL ++ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, ++ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR ++ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE ++ * USE OR OTHER DEALINGS IN THE SOFTWARE. ++ * ++ * The above copyright notice and this permission notice (including the ++ * next paragraph) shall be included in all copies or substantial portions ++ * of the Software. ++ */ ++/* ++ * Authors: ++ * Aapo Tahkola ++ * Nicolai Haehnle ++ * Jérôme Glisse ++ */ ++#ifndef RADEON_CS_H ++#define RADEON_CS_H ++ ++#include ++#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++; ++ } ++} ++ ++static inline void radeon_cs_write_qword(struct radeon_cs *cs, uint64_t qword) ++{ ++ memcpy(cs->packets + cs->cdw, &qword, sizeof(uint64_t)); ++ cs->cdw += 2; ++ if (cs->section) { ++ cs->section_cdw += 2; ++ } ++} ++ ++#endif +diff --git a/libdrm/radeon/radeon_cs_gem.c b/libdrm/radeon/radeon_cs_gem.c +new file mode 100644 +index 0000000..b9f6f4b +--- /dev/null ++++ b/libdrm/radeon/radeon_cs_gem.c +@@ -0,0 +1,544 @@ ++/* ++ * Copyright © 2008 Jérôme Glisse ++ * All Rights Reserved. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining ++ * a copy of this software and associated documentation files (the ++ * "Software"), to deal in the Software without restriction, including ++ * without limitation the rights to use, copy, modify, merge, publish, ++ * distribute, sub license, and/or sell copies of the Software, and to ++ * permit persons to whom the Software is furnished to do so, subject to ++ * the following conditions: ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, ++ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES ++ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND ++ * NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS, AUTHORS ++ * AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER ++ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ++ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE ++ * USE OR OTHER DEALINGS IN THE SOFTWARE. ++ * ++ * The above copyright notice and this permission notice (including the ++ * next paragraph) shall be included in all copies or substantial portions ++ * of the Software. ++ */ ++/* ++ * Authors: ++ * Aapo Tahkola ++ * Nicolai Haehnle ++ * Jérôme Glisse ++ */ ++#include ++#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; ++ ++ assert(bo->space_accounted); ++ ++ /* check domains */ ++ if ((read_domain && write_domain) || (!read_domain && !write_domain)) { ++ /* in one CS a bo can only be in read or write domain but not ++ * in read & write domain at the same sime ++ */ ++ return -EINVAL; ++ } ++ if (read_domain == RADEON_GEM_DOMAIN_CPU) { ++ return -EINVAL; ++ } ++ if (write_domain == RADEON_GEM_DOMAIN_CPU) { ++ return -EINVAL; ++ } ++ /* check if bo is already referenced */ ++ for(i = 0; i < cs->crelocs; i++) { ++ idx = i * RELOC_SIZE; ++ reloc = (struct cs_reloc_gem*)&csg->relocs[idx]; ++ if (reloc->handle == bo->handle) { ++ /* Check domains must be in read or write. As we check already ++ * checked that in argument one of the read or write domain was ++ * set we only need to check that if previous reloc as the read ++ * domain set then the read_domain should also be set for this ++ * new relocation. ++ */ ++ if (reloc->read_domain && !read_domain) { ++ return -EINVAL; ++ } ++ if (reloc->write_domain && !write_domain) { ++ return -EINVAL; ++ } ++ reloc->read_domain |= read_domain; ++ reloc->write_domain |= write_domain; ++ /* update flags */ ++ reloc->flags |= (flags & reloc->flags); ++ /* write relocation packet */ ++ radeon_cs_write_dword(cs, 0xc0001000); ++ radeon_cs_write_dword(cs, idx); ++ return 0; ++ } ++ } ++ /* new relocation */ ++ if (csg->base.crelocs >= csg->nrelocs) { ++ /* allocate more memory (TODO: should use a slab allocatore maybe) */ ++ uint32_t *tmp, size; ++ size = ((csg->nrelocs + 1) * sizeof(struct radeon_bo*)); ++ tmp = (uint32_t*)realloc(csg->relocs_bo, size); ++ if (tmp == NULL) { ++ return -ENOMEM; ++ } ++ csg->relocs_bo = (struct radeon_bo**)tmp; ++ size = ((csg->nrelocs + 1) * RELOC_SIZE * 4); ++ tmp = (uint32_t*)realloc(csg->relocs, size); ++ if (tmp == NULL) { ++ return -ENOMEM; ++ } ++ cs->relocs = csg->relocs = tmp; ++ csg->nrelocs += 1; ++ csg->chunks[1].chunk_data = (uint64_t)(intptr_t)csg->relocs; ++ } ++ csg->relocs_bo[csg->base.crelocs] = bo; ++ idx = (csg->base.crelocs++) * RELOC_SIZE; ++ reloc = (struct cs_reloc_gem*)&csg->relocs[idx]; ++ reloc->handle = bo->handle; ++ reloc->read_domain = read_domain; ++ reloc->write_domain = write_domain; ++ reloc->flags = flags; ++ csg->chunks[1].length_dw += RELOC_SIZE; ++ radeon_bo_ref(bo); ++ cs->relocs_total_size += bo->size; ++ radeon_cs_write_dword(cs, 0xc0001000); ++ radeon_cs_write_dword(cs, idx); ++ return 0; ++} ++ ++static int cs_gem_begin(struct radeon_cs *cs, ++ uint32_t ndw, ++ const char *file, ++ const char *func, ++ int line) ++{ ++ ++ if (cs->section) { ++ fprintf(stderr, "CS already in a section(%s,%s,%d)\n", ++ cs->section_file, cs->section_func, cs->section_line); ++ fprintf(stderr, "CS can't start section(%s,%s,%d)\n", ++ file, func, line); ++ return -EPIPE; ++ } ++ cs->section = 1; ++ cs->section_ndw = ndw; ++ cs->section_cdw = 0; ++ cs->section_file = file; ++ cs->section_func = func; ++ cs->section_line = line; ++ ++ ++ if (cs->cdw + ndw > cs->ndw) { ++ uint32_t tmp, *ptr; ++ int num = (ndw > 0x3FF) ? ndw : 0x3FF; ++ ++ tmp = (cs->cdw + 1 + num) & (~num); ++ ptr = (uint32_t*)realloc(cs->packets, 4 * tmp); ++ if (ptr == NULL) { ++ return -ENOMEM; ++ } ++ cs->packets = ptr; ++ cs->ndw = tmp; ++ } ++ ++ return 0; ++} ++ ++static int cs_gem_end(struct radeon_cs *cs, ++ const char *file, ++ const char *func, ++ int line) ++ ++{ ++ if (!cs->section) { ++ fprintf(stderr, "CS no section to end at (%s,%s,%d)\n", ++ file, func, line); ++ return -EPIPE; ++ } ++ cs->section = 0; ++ if (cs->section_ndw != cs->section_cdw) { ++ fprintf(stderr, "CS section size missmatch start at (%s,%s,%d) %d vs %d\n", ++ cs->section_file, cs->section_func, cs->section_line, cs->section_ndw, cs->section_cdw); ++ fprintf(stderr, "CS section end at (%s,%s,%d)\n", ++ file, func, line); ++ return -EPIPE; ++ } ++ return 0; ++} ++ ++static int cs_gem_emit(struct radeon_cs *cs) ++{ ++ struct cs_gem *csg = (struct cs_gem*)cs; ++ uint64_t chunk_array[2]; ++ unsigned i; ++ int r; ++ ++ csg->chunks[0].length_dw = cs->cdw; ++ ++ chunk_array[0] = (uint64_t)(intptr_t)&csg->chunks[0]; ++ chunk_array[1] = (uint64_t)(intptr_t)&csg->chunks[1]; ++ ++ csg->cs.num_chunks = 2; ++ csg->cs.chunks = (uint64_t)(intptr_t)chunk_array; ++ ++ r = drmCommandWriteRead(cs->csm->fd, DRM_RADEON_CS, ++ &csg->cs, sizeof(struct drm_radeon_cs)); ++ for (i = 0; i < csg->base.crelocs; i++) { ++ csg->relocs_bo[i]->space_accounted = 0; ++ radeon_bo_unref(csg->relocs_bo[i]); ++ csg->relocs_bo[i] = NULL; ++ } ++ ++ cs->csm->read_used = 0; ++ cs->csm->vram_write_used = 0; ++ cs->csm->gart_write_used = 0; ++ return r; ++} ++ ++static int cs_gem_destroy(struct radeon_cs *cs) ++{ ++ struct cs_gem *csg = (struct cs_gem*)cs; ++ ++ free(csg->relocs_bo); ++ free(cs->relocs); ++ free(cs->packets); ++ free(cs); ++ return 0; ++} ++ ++static int cs_gem_erase(struct radeon_cs *cs) ++{ ++ struct cs_gem *csg = (struct cs_gem*)cs; ++ unsigned i; ++ ++ if (csg->relocs_bo) { ++ for (i = 0; i < csg->base.crelocs; i++) { ++ if (csg->relocs_bo[i]) { ++ radeon_bo_unref(csg->relocs_bo[i]); ++ csg->relocs_bo[i] = NULL; ++ } ++ } ++ } ++ cs->relocs_total_size = 0; ++ cs->cdw = 0; ++ cs->section = 0; ++ cs->crelocs = 0; ++ csg->chunks[0].length_dw = 0; ++ csg->chunks[1].length_dw = 0; ++ return 0; ++} ++ ++static int cs_gem_need_flush(struct radeon_cs *cs) ++{ ++ return 0; //(cs->relocs_total_size > (32*1024*1024)); ++} ++ ++#define PACKET_TYPE0 0 ++#define PACKET_TYPE1 1 ++#define PACKET_TYPE2 2 ++#define PACKET_TYPE3 3 ++ ++#define PACKET3_NOP 0x10 ++#define PACKET3_SET_SCISSORS 0x1E ++#define PACKET3_3D_DRAW_VBUF 0x28 ++#define PACKET3_3D_DRAW_IMMD 0x29 ++#define PACKET3_3D_DRAW_INDX 0x2A ++#define PACKET3_3D_LOAD_VBPNTR 0x2F ++#define PACKET3_INDX_BUFFER 0x33 ++#define PACKET3_3D_DRAW_VBUF_2 0x34 ++#define PACKET3_3D_DRAW_IMMD_2 0x35 ++#define PACKET3_3D_DRAW_INDX_2 0x36 ++ ++#define CP_PACKET_GET_TYPE(h) (((h) >> 30) & 3) ++#define CP_PACKET_GET_COUNT(h) (((h) >> 16) & 0x3FFF) ++#define CP_PACKET0_GET_REG(h) (((h) & 0x1FFF) << 2) ++#define CP_PACKET0_GET_ONE_REG_WR(h) (((h) >> 15) & 1) ++#define CP_PACKET3_GET_OPCODE(h) (((h) >> 8) & 0xFF) ++ ++static void cs_gem_print(struct radeon_cs *cs, FILE *file) ++{ ++ unsigned opcode; ++ unsigned reg; ++ unsigned cnt; ++ int i, j; ++ ++ for (i = 0; i < cs->cdw;) { ++ cnt = CP_PACKET_GET_COUNT(cs->packets[i]); ++ switch (CP_PACKET_GET_TYPE(cs->packets[i])) { ++ case PACKET_TYPE0: ++ fprintf(file, "Pkt0 at %d (%d dwords):\n", i, cnt + 1); ++ reg = CP_PACKET0_GET_REG(cs->packets[i]); ++ if (CP_PACKET0_GET_ONE_REG_WR(cs->packets[i++])) { ++ for (j = 0; j <= cnt; j++) { ++ fprintf(file, " 0x%08X -> 0x%04X\n", ++ cs->packets[i++], reg); ++ } ++ } else { ++ for (j = 0; j <= cnt; j++) { ++ fprintf(file, " 0x%08X -> 0x%04X\n", ++ cs->packets[i++], reg); ++ reg += 4; ++ } ++ } ++ break; ++ case PACKET_TYPE3: ++ fprintf(file, "Pkt3 at %d :\n", i); ++ opcode = CP_PACKET3_GET_OPCODE(cs->packets[i++]); ++ switch (opcode) { ++ case PACKET3_NOP: ++ fprintf(file, " PACKET3_NOP:\n"); ++ break; ++ case PACKET3_3D_DRAW_VBUF: ++ fprintf(file, " PACKET3_3D_DRAW_VBUF:\n"); ++ break; ++ case PACKET3_3D_DRAW_IMMD: ++ fprintf(file, " PACKET3_3D_DRAW_IMMD:\n"); ++ break; ++ case PACKET3_3D_DRAW_INDX: ++ fprintf(file, " PACKET3_3D_DRAW_INDX:\n"); ++ break; ++ case PACKET3_3D_LOAD_VBPNTR: ++ fprintf(file, " PACKET3_3D_LOAD_VBPNTR:\n"); ++ break; ++ case PACKET3_INDX_BUFFER: ++ fprintf(file, " PACKET3_INDX_BUFFER:\n"); ++ break; ++ case PACKET3_3D_DRAW_VBUF_2: ++ fprintf(file, " PACKET3_3D_DRAW_VBUF_2:\n"); ++ break; ++ case PACKET3_3D_DRAW_IMMD_2: ++ fprintf(file, " PACKET3_3D_DRAW_IMMD_2:\n"); ++ break; ++ case PACKET3_3D_DRAW_INDX_2: ++ fprintf(file, " PACKET3_3D_DRAW_INDX_2:\n"); ++ break; ++ default: ++ fprintf(file, "Unknow opcode 0x%02X at %d\n", opcode, i); ++ return; ++ } ++ for (j = 0; j <= cnt; j++) { ++ fprintf(file, " 0x%08X\n", cs->packets[i++]); ++ } ++ break; ++ case PACKET_TYPE1: ++ case PACKET_TYPE2: ++ default: ++ fprintf(file, "Unknow packet 0x%08X at %d\n", cs->packets[i], i); ++ return; ++ } ++ } ++} ++ ++static int cs_gem_check_space(struct radeon_cs *cs, struct radeon_cs_space_check *bos, int num_bo) ++{ ++ struct radeon_cs_manager *csm = cs->csm; ++ int this_op_read = 0, this_op_gart_write = 0, this_op_vram_write = 0; ++ uint32_t read_domains, write_domain; ++ int i; ++ struct radeon_bo *bo; ++ ++ /* check the totals for this operation */ ++ ++ if (num_bo == 0) ++ return 0; ++ ++ /* prepare */ ++ for (i = 0; i < num_bo; i++) { ++ bo = bos[i].bo; ++ ++ bos[i].new_accounted = 0; ++ read_domains = bos[i].read_domains; ++ write_domain = bos[i].write_domain; ++ ++ /* already accounted this bo */ ++ if (write_domain && (write_domain == bo->space_accounted)) { ++ bos[i].new_accounted = bo->space_accounted; ++ continue; ++ } ++ if (read_domains && ((read_domains << 16) == bo->space_accounted)) { ++ bos[i].new_accounted = bo->space_accounted; ++ continue; ++ } ++ ++ if (bo->space_accounted == 0) { ++ if (write_domain == RADEON_GEM_DOMAIN_VRAM) ++ this_op_vram_write += bo->size; ++ else if (write_domain == RADEON_GEM_DOMAIN_GTT) ++ this_op_gart_write += bo->size; ++ else ++ this_op_read += bo->size; ++ bos[i].new_accounted = (read_domains << 16) | write_domain; ++ } else { ++ uint16_t old_read, old_write; ++ ++ old_read = bo->space_accounted >> 16; ++ old_write = bo->space_accounted & 0xffff; ++ ++ if (write_domain && (old_read & write_domain)) { ++ bos[i].new_accounted = write_domain; ++ /* moving from read to a write domain */ ++ if (write_domain == RADEON_GEM_DOMAIN_VRAM) { ++ this_op_read -= bo->size; ++ this_op_vram_write += bo->size; ++ } else if (write_domain == RADEON_GEM_DOMAIN_VRAM) { ++ this_op_read -= bo->size; ++ this_op_gart_write += bo->size; ++ } ++ } else if (read_domains & old_write) { ++ bos[i].new_accounted = bo->space_accounted & 0xffff; ++ } else { ++ /* rewrite the domains */ ++ if (write_domain != old_write) ++ fprintf(stderr,"WRITE DOMAIN RELOC FAILURE 0x%x %d %d\n", bo->handle, write_domain, old_write); ++ if (read_domains != old_read) ++ fprintf(stderr,"READ DOMAIN RELOC FAILURE 0x%x %d %d\n", bo->handle, read_domains, old_read); ++ return RADEON_CS_SPACE_FLUSH; ++ } ++ } ++ } ++ ++ if (this_op_read < 0) ++ this_op_read = 0; ++ ++ /* check sizes - operation first */ ++ if ((this_op_read + this_op_gart_write > csm->gart_limit) || ++ (this_op_vram_write > csm->vram_limit)) { ++ return RADEON_CS_SPACE_OP_TO_BIG; ++ } ++ ++ if (((csm->vram_write_used + this_op_vram_write) > csm->vram_limit) || ++ ((csm->read_used + csm->gart_write_used + this_op_gart_write + this_op_read) > csm->gart_limit)) { ++ return RADEON_CS_SPACE_FLUSH; ++ } ++ ++ csm->gart_write_used += this_op_gart_write; ++ csm->vram_write_used += this_op_vram_write; ++ csm->read_used += this_op_read; ++ /* commit */ ++ for (i = 0; i < num_bo; i++) { ++ bo = bos[i].bo; ++ bo->space_accounted = bos[i].new_accounted; ++ } ++ ++ return RADEON_CS_SPACE_OK; ++} ++ ++static struct radeon_cs_funcs radeon_cs_gem_funcs = { ++ cs_gem_create, ++ cs_gem_write_reloc, ++ cs_gem_begin, ++ cs_gem_end, ++ cs_gem_emit, ++ cs_gem_destroy, ++ cs_gem_erase, ++ cs_gem_need_flush, ++ cs_gem_print, ++ cs_gem_check_space, ++}; ++ ++struct radeon_cs_manager *radeon_cs_manager_gem_ctor(int fd) ++{ ++ struct radeon_cs_manager *csm; ++ ++ csm = (struct radeon_cs_manager*)calloc(1, ++ sizeof(struct radeon_cs_manager)); ++ if (csm == NULL) { ++ return NULL; ++ } ++ csm->funcs = &radeon_cs_gem_funcs; ++ csm->fd = fd; ++ return csm; ++} ++ ++void radeon_cs_manager_gem_dtor(struct radeon_cs_manager *csm) ++{ ++ free(csm); ++} +diff --git a/libdrm/radeon/radeon_cs_gem.h b/libdrm/radeon/radeon_cs_gem.h +new file mode 100644 +index 0000000..5efd146 +--- /dev/null ++++ b/libdrm/radeon/radeon_cs_gem.h +@@ -0,0 +1,41 @@ ++/* ++ * Copyright © 2008 Nicolai Haehnle ++ * Copyright © 2008 Jérôme Glisse ++ * All Rights Reserved. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining ++ * a copy of this software and associated documentation files (the ++ * "Software"), to deal in the Software without restriction, including ++ * without limitation the rights to use, copy, modify, merge, publish, ++ * distribute, sub license, and/or sell copies of the Software, and to ++ * permit persons to whom the Software is furnished to do so, subject to ++ * the following conditions: ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, ++ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES ++ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND ++ * NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS, AUTHORS ++ * AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER ++ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ++ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE ++ * USE OR OTHER DEALINGS IN THE SOFTWARE. ++ * ++ * The above copyright notice and this permission notice (including the ++ * next paragraph) shall be included in all copies or substantial portions ++ * of the Software. ++ */ ++/* ++ * Authors: ++ * Aapo Tahkola ++ * 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/shared-core/radeon_drm.h b/shared-core/radeon_drm.h +index ffaa46e..e9f2afa 100644 +--- a/shared-core/radeon_drm.h ++++ b/shared-core/radeon_drm.h +@@ -492,6 +492,16 @@ typedef struct { + #define DRM_RADEON_SETPARAM 0x19 + #define DRM_RADEON_SURF_ALLOC 0x1a + #define DRM_RADEON_SURF_FREE 0x1b ++/* KMS ioctl */ ++#define DRM_RADEON_GEM_INFO 0x1c ++#define DRM_RADEON_GEM_CREATE 0x1d ++#define DRM_RADEON_GEM_MMAP 0x1e ++#define DRM_RADEON_GEM_PREAD 0x21 ++#define DRM_RADEON_GEM_PWRITE 0x22 ++#define DRM_RADEON_GEM_SET_DOMAIN 0x23 ++#define DRM_RADEON_GEM_WAIT_IDLE 0x24 ++#define DRM_RADEON_CS 0x26 ++#define DRM_RADEON_INFO 0x27 + + #define DRM_IOCTL_RADEON_CP_INIT DRM_IOW( DRM_COMMAND_BASE + DRM_RADEON_CP_INIT, drm_radeon_init_t) + #define DRM_IOCTL_RADEON_CP_START DRM_IO( DRM_COMMAND_BASE + DRM_RADEON_CP_START) +@@ -521,6 +531,17 @@ typedef struct { + #define DRM_IOCTL_RADEON_SURF_ALLOC DRM_IOW( DRM_COMMAND_BASE + DRM_RADEON_SURF_ALLOC, drm_radeon_surface_alloc_t) + #define DRM_IOCTL_RADEON_SURF_FREE DRM_IOW( DRM_COMMAND_BASE + DRM_RADEON_SURF_FREE, drm_radeon_surface_free_t) + ++#define DRM_IOCTL_RADEON_GEM_INFO DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_GEM_INFO, struct drm_radeon_gem_info) ++#define DRM_IOCTL_RADEON_GEM_CREATE DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_GEM_CREATE, struct drm_radeon_gem_create) ++#define DRM_IOCTL_RADEON_GEM_MMAP DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_GEM_MMAP, struct drm_radeon_gem_mmap) ++#define DRM_IOCTL_RADEON_GEM_PIN DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_GEM_PIN, struct drm_radeon_gem_pin) ++#define DRM_IOCTL_RADEON_GEM_UNPIN DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_GEM_UNPIN, struct drm_radeon_gem_unpin) ++#define DRM_IOCTL_RADEON_GEM_PREAD DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_GEM_PREAD, struct drm_radeon_gem_pread) ++#define DRM_IOCTL_RADEON_GEM_PWRITE DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_GEM_PWRITE, struct drm_radeon_gem_pwrite) ++#define DRM_IOCTL_RADEON_GEM_SET_DOMAIN DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_GEM_SET_DOMAIN, struct drm_radeon_gem_set_domain) ++#define DRM_IOCTL_RADEON_GEM_WAIT_RENDERING DRM_IOW(DRM_COMMAND_BASE + DRM_RADEON_GEM_WAIT_RENDERING, struct drm_radeon_gem_wait_rendering) ++#define DRM_IOCTL_RADEON_CS DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_CS, struct drm_radeon_cs) ++ + typedef struct drm_radeon_init { + enum { + RADEON_INIT_CP = 0x01, +@@ -677,6 +698,7 @@ typedef struct drm_radeon_indirect { + #define RADEON_PARAM_VBLANK_CRTC 13 /* VBLANK CRTC */ + #define RADEON_PARAM_FB_LOCATION 14 /* FB location */ + #define RADEON_PARAM_NUM_GB_PIPES 15 /* num GB pipes */ ++#define RADEON_PARAM_DEVICE_ID 16 + + typedef struct drm_radeon_getparam { + int param; +@@ -728,7 +750,6 @@ typedef struct drm_radeon_setparam { + #define RADEON_SETPARAM_FB_LOCATION 1 /* determined framebuffer location */ + #define RADEON_SETPARAM_SWITCH_TILING 2 /* enable/disable color tiling */ + #define RADEON_SETPARAM_PCIGART_LOCATION 3 /* PCI Gart Location */ +- + #define RADEON_SETPARAM_NEW_MEMMAP 4 /* Use new memory map */ + #define RADEON_SETPARAM_PCIGART_TABLE_SIZE 5 /* PCI GART Table Size */ + #define RADEON_SETPARAM_VBLANK_CRTC 6 /* VBLANK CRTC */ +@@ -747,4 +768,112 @@ typedef struct drm_radeon_surface_free { + #define DRM_RADEON_VBLANK_CRTC1 1 + #define DRM_RADEON_VBLANK_CRTC2 2 + ++/* ++ * Kernel modesetting world below. ++ */ ++#define RADEON_GEM_DOMAIN_CPU 0x1 ++#define RADEON_GEM_DOMAIN_GTT 0x2 ++#define RADEON_GEM_DOMAIN_VRAM 0x4 ++ ++struct drm_radeon_gem_info { ++ uint64_t gart_size; ++ uint64_t vram_size; ++ uint64_t vram_visible; ++}; ++ ++#define RADEON_GEM_NO_BACKING_STORE 1 ++ ++struct drm_radeon_gem_create { ++ uint64_t size; ++ uint64_t alignment; ++ uint32_t handle; ++ uint32_t initial_domain; ++ uint32_t flags; ++}; ++ ++struct drm_radeon_gem_mmap { ++ uint32_t handle; ++ uint32_t pad; ++ uint64_t offset; ++ uint64_t size; ++ uint64_t addr_ptr; ++}; ++ ++struct drm_radeon_gem_set_domain { ++ uint32_t handle; ++ uint32_t read_domains; ++ uint32_t write_domain; ++}; ++ ++struct drm_radeon_gem_wait_idle { ++ uint32_t handle; ++ uint32_t pad; ++}; ++ ++struct drm_radeon_gem_busy { ++ uint32_t handle; ++ uint32_t busy; ++}; ++ ++struct drm_radeon_gem_pread { ++ /** Handle for the object being read. */ ++ uint32_t handle; ++ uint32_t pad; ++ /** Offset into the object to read from */ ++ uint64_t offset; ++ /** Length of data to read */ ++ uint64_t size; ++ /** Pointer to write the data into. */ ++ /* void *, but pointers are not 32/64 compatible */ ++ uint64_t data_ptr; ++}; ++ ++struct drm_radeon_gem_pwrite { ++ /** Handle for the object being written to. */ ++ uint32_t handle; ++ uint32_t pad; ++ /** Offset into the object to write to */ ++ uint64_t offset; ++ /** Length of data to write */ ++ uint64_t size; ++ /** Pointer to read the data from. */ ++ /* void *, but pointers are not 32/64 compatible */ ++ uint64_t data_ptr; ++}; ++ ++#define RADEON_CHUNK_ID_RELOCS 0x01 ++#define RADEON_CHUNK_ID_IB 0x02 ++ ++struct drm_radeon_cs_chunk { ++ uint32_t chunk_id; ++ uint32_t length_dw; ++ uint64_t chunk_data; ++}; ++ ++struct drm_radeon_cs_reloc { ++ uint32_t handle; ++ uint32_t read_domains; ++ uint32_t write_domain; ++ uint32_t flags; ++}; ++ ++struct drm_radeon_cs { ++ uint32_t num_chunks; ++ uint32_t cs_id; ++ /* this points to uint64_t * which point to cs chunks */ ++ uint64_t chunks; ++ /* updates to the limits after this CS ioctl */ ++ uint64_t gart_limit; ++ uint64_t vram_limit; ++}; ++ ++#define RADEON_INFO_DEVICE_ID 0x00 ++#define RADEON_INFO_NUM_GB_PIPES 0x01 ++ ++struct drm_radeon_info { ++ uint32_t request; ++ uint32_t pad; ++ uint64_t value; ++}; ++ + #endif diff --git a/packages/graphics/libdrm/patches/nouveau-updates.diff b/packages/graphics/libdrm/patches/nouveau-updates.diff new file mode 100644 index 0000000000..606b3df898 --- /dev/null +++ b/packages/graphics/libdrm/patches/nouveau-updates.diff @@ -0,0 +1,26 @@ +diff --git a/libdrm/nouveau/nouveau_bo.c b/libdrm/nouveau/nouveau_bo.c +index 023c6be..66466e3 100644 +--- a/libdrm/nouveau/nouveau_bo.c ++++ b/libdrm/nouveau/nouveau_bo.c +@@ -404,7 +404,8 @@ nouveau_bo_handle_ref(struct nouveau_device *dev, uint32_t handle, + nvbo->size = req.size; + nvbo->handle = req.handle; + } +- ++ ++ nvbo->base.handle = nvbo->handle; + return 0; + } + +diff --git a/libdrm/nouveau/nouveau_dma.c b/libdrm/nouveau/nouveau_dma.c +index 23da64b..b084f70 100644 +--- a/libdrm/nouveau/nouveau_dma.c ++++ b/libdrm/nouveau/nouveau_dma.c +@@ -41,6 +41,7 @@ WRITE_PUT(struct nouveau_channel_priv *nvchan, uint32_t val) + volatile int dum; + + NOUVEAU_DMA_BARRIER; ++ dum = nvchan->pushbuf[0]; + dum = READ_GET(nvchan); + + *nvchan->put = put;