rpms/xorg-x11-drv-ati/devel radeon-modeset.patch,1.10,1.11

Dave Airlie airlied at fedoraproject.org
Tue Aug 26 09:04:07 UTC 2008


Author: airlied

Update of /cvs/pkgs/rpms/xorg-x11-drv-ati/devel
In directory cvs1.fedora.phx.redhat.com:/tmp/cvs-serv13489

Modified Files:
	radeon-modeset.patch 
Log Message:
* Tue Aug 26 2008 Dave Airlie <airlied at redhat.com> 6.9.0-6
- update modesetting/memory manager support


radeon-modeset.patch:

Index: radeon-modeset.patch
===================================================================
RCS file: /cvs/pkgs/rpms/xorg-x11-drv-ati/devel/radeon-modeset.patch,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -r1.10 -r1.11
--- radeon-modeset.patch	15 Aug 2008 03:16:09 -0000	1.10
+++ radeon-modeset.patch	26 Aug 2008 09:04:06 -0000	1.11
@@ -18,7 +18,7 @@
  
  save_CFLAGS="$CFLAGS"
 diff --git a/src/Makefile.am b/src/Makefile.am
-index 97c686b..0a7d1bb 100644
+index 97c686b..d32e74a 100644
 --- a/src/Makefile.am
 +++ b/src/Makefile.am
 @@ -90,12 +90,13 @@ radeon_drv_ladir = @moduledir@/drivers
@@ -33,7 +33,7 @@
  	$(RADEON_ATOMBIOS_SOURCES) radeon_atombios.c radeon_atomwrapper.c \
 -	$(RADEON_DRI_SRCS) $(RADEON_EXA_SOURCES) atombios_output.c atombios_crtc.c
 +	$(RADEON_DRI_SRCS) $(RADEON_EXA_SOURCES) atombios_output.c atombios_crtc.c  \
-+	drmmode_display.c radeon_bufmgr_exa.c
++	drmmode_display.c radeon_bufmgr_exa.c radeon_bufmgr_gem.c
  
  if XMODES
  radeon_drv_la_SOURCES += \
@@ -46,10 +46,10 @@
 +	drmmode_display.h
 diff --git a/src/drmmode_display.c b/src/drmmode_display.c
 new file mode 100644
-index 0000000..07a5349
+index 0000000..97762ce
 --- /dev/null
 +++ b/src/drmmode_display.c
-@@ -0,0 +1,680 @@
+@@ -0,0 +1,681 @@
 +/*
 + * Copyright © 2007 Red Hat, Inc.
 + *
@@ -634,7 +634,8 @@
 +	int ret;
 +
 +	ret = drmModeAddFB(drmmode->fd, width, height, scrn->depth,
-+			   scrn->bitsPerPixel, pitch, handle, &drmmode->fb_id);
++			   scrn->bitsPerPixel, pitch, handle,
++			   &drmmode->fb_id);
 +
 +	if (ret) {
 +		ErrorF("Failed to add fb\n");
@@ -732,7 +733,7 @@
 +#endif
 diff --git a/src/drmmode_display.h b/src/drmmode_display.h
 new file mode 100644
-index 0000000..03f8119
+index 0000000..691d62e
 --- /dev/null
 +++ b/src/drmmode_display.h
 @@ -0,0 +1,74 @@
@@ -770,7 +771,7 @@
 +#include "xf86drmMode.h"
 +
 +#include "radeon_probe.h"
-+#include "radeon_bufmgr_exa.h"
++#include "radeon_bufmgr.h"
 +
 +typedef struct {
 +  int fd;
@@ -811,7 +812,7 @@
 +#endif
 +#endif
 diff --git a/src/radeon.h b/src/radeon.h
-index 2348e7c..4082aac 100644
+index 2348e7c..32bfa4e 100644
 --- a/src/radeon.h
 +++ b/src/radeon.h
 @@ -46,6 +46,8 @@
@@ -827,7 +828,7 @@
  #include "xf86Crtc.h"
  #include "X11/Xatom.h"
  
-+#include "radeon_bufmgr_exa.h"
++#include "radeon_bufmgr.h"
  				/* Render support */
  #ifdef RENDER
  #include "picturestr.h"
@@ -939,11 +940,12 @@
  } RADEONInfoRec, *RADEONInfoPtr;
  
  #define RADEONWaitForFifo(pScrn, entries)				\
-@@ -1030,6 +1097,22 @@ extern void RADEONUpdateHVPosition(xf86OutputPtr output, DisplayModePtr mode);
+@@ -1030,6 +1097,23 @@ extern void RADEONUpdateHVPosition(xf86OutputPtr output, DisplayModePtr mode);
  extern void RADEONInitVideo(ScreenPtr pScreen);
  extern void RADEONResetVideo(ScrnInfoPtr pScrn);
  
 +/* radeon_memory.c */
++extern uint32_t radeon_name_buffer(ScrnInfoPtr pScrn, struct radeon_memory *mem);
 +extern Bool radeon_bind_all_memory(ScrnInfoPtr pScrn);
 +extern Bool radeon_unbind_all_memory(ScrnInfoPtr pScrn);
 +extern struct radeon_memory *radeon_allocate_memory(ScrnInfoPtr pScrn, int pool, int size, int alignment, Bool no_backing_store, char *name, 
@@ -962,7 +964,7 @@
  #ifdef XF86DRI
  #  ifdef USE_XAA
  /* radeon_accelfuncs.c */
-@@ -1048,7 +1131,9 @@ do {									\
+@@ -1048,7 +1132,9 @@ do {									\
  
  #define RADEONCP_RELEASE(pScrn, info)					\
  do {									\
@@ -973,7 +975,7 @@
  	RADEON_PURGE_CACHE();						\
  	RADEON_WAIT_UNTIL_IDLE();					\
  	RADEONCPReleaseIndirect(pScrn);					\
-@@ -1082,7 +1167,7 @@ do {									\
+@@ -1082,7 +1168,7 @@ do {									\
  
  #define RADEONCP_REFRESH(pScrn, info)					\
  do {									\
@@ -982,7 +984,7 @@
  	if (info->needCacheFlush) {					\
  	    RADEON_PURGE_CACHE();					\
  	    RADEON_PURGE_ZCACHE();					\
-@@ -1109,6 +1194,13 @@ do {									\
+@@ -1109,6 +1195,13 @@ do {									\
  #define RING_LOCALS	uint32_t *__head = NULL; int __expected; int __count = 0
  
  #define BEGIN_RING(n) do {						\
@@ -996,7 +998,7 @@
      if (RADEON_VERBOSE) {						\
  	xf86DrvMsg(pScrn->scrnIndex, X_INFO,				\
  		   "BEGIN_RING(%d) in %s\n", (unsigned int)n, __FUNCTION__);\
-@@ -1121,13 +1213,6 @@ do {									\
+@@ -1121,13 +1214,6 @@ do {									\
      }									\
      info->dma_debug_func = __FILE__;					\
      info->dma_debug_lineno = __LINE__;					\
@@ -1010,15 +1012,15 @@
      __expected = n;							\
      __head = (pointer)((char *)info->indirectBuffer->address +		\
  		       info->indirectBuffer->used);			\
-@@ -1170,6 +1255,14 @@ do {									\
+@@ -1170,6 +1256,14 @@ do {									\
      OUT_RING(val);							\
  } while (0)
  
 +/* TODO - VRAM is wrong in general but true for now - all EXA stuff
 + is in VRAM */
-+#define OUT_RING_RELOC(x)						       \
-+  do {								       \
-+    radeon_bufmgr_exa_emit_reloc(x, __head, &__count);		       \
++#define OUT_RING_RELOC(x, read_domains, write_domains)			\
++  do {									\
++    radeon_bufmgr_emit_reloc(x, __head, &__count, read_domains, write_domains); \
 +  } while(0)
 +
 +
@@ -1026,7 +1028,7 @@
  do {									\
      if (RADEON_VERBOSE)							\
 diff --git a/src/radeon_accel.c b/src/radeon_accel.c
-index e617fd5..0014c16 100644
+index e617fd5..09aa7f6 100644
 --- a/src/radeon_accel.c
 +++ b/src/radeon_accel.c
 @@ -313,6 +313,9 @@ void RADEONEngineRestore(ScrnInfoPtr pScrn)
@@ -1214,7 +1216,7 @@
 +    info->indirectBuffer->total -= 16*4;
 +
 +    if (info->bufmgr)
-+      radeon_bufmgr_post_submit(info->bufmgr);
++      radeon_gem_bufmgr_post_submit(info->bufmgr);
 +
 +    /* copy some state into the buffer now - we need to add 2D state to each
 +       buffer as the kernel needs to use the blit engine to move stuff around */
@@ -1281,7 +1283,7 @@
 +    /* for now just wait for the buffer to come around again */
 +
 +    dom_args.handle = info->mm.gem_ib_memory->kernel_bo_handle;
-+    dom_args.read_domains = RADEON_GEM_DOMAIN_CPU;
++    dom_args.read_domains = RADEON_GEM_DOMAIN_GTT;
 +    dom_args.write_domain = 0;
 +
 +    drmCommandWriteRead(info->drmFD, DRM_RADEON_GEM_SET_DOMAIN,
@@ -1396,12 +1398,48 @@
  	RADEONInit3DEngineCP(pScrn);
      } else
  #endif
+diff --git a/src/radeon_bufmgr.h b/src/radeon_bufmgr.h
+new file mode 100644
+index 0000000..a16ad9a
+--- /dev/null
++++ b/src/radeon_bufmgr.h
+@@ -0,0 +1,30 @@
++/**
++ * @file intel_bufmgr.h
++ *
++ * Public definitions of Intel-specific bufmgr functions.
++ */
++
++#ifndef RADEON_BUFMGR_H
++#define RADEON_BUFMGR_H
++
++#include "dri_bufmgr.h"
++
++struct radeon_bufmgr {
++  void (*emit_reloc)(dri_bo *buf, uint32_t *head, uint32_t *count_p, uint32_t read_domains, uint32_t write_domain);
++};
++
++dri_bufmgr *radeon_bufmgr_gem_init(int fd);
++dri_bo *radeon_bo_gem_create_from_name(dri_bufmgr *bufmgr, const char *name,
++				       unsigned int handle);
++
++void radeon_bufmgr_emit_reloc(dri_bo *buf, uint32_t *head, uint32_t *count_p, uint32_t read_domains, uint32_t write_domain);
++
++dri_bufmgr *radeon_bufmgr_exa_init(ScrnInfoPtr pScrn);
++extern void radeon_bufmgr_exa_wait_rendering(dri_bo *bo);
++extern dri_bo *radeon_bufmgr_exa_create_bo(dri_bufmgr *bufmgr, struct radeon_memory *mem);
++void radeon_bufmgr_post_submit(dri_bufmgr *bufmgr);
++void radeon_bufmgr_pin(dri_bo *buf);
++void radeon_bufmgr_unpin(dri_bo *buf);
++uint32_t radeon_bufmgr_get_handle(dri_bo *buf);
++void radeon_bufmgr_gem_enable_reuse(dri_bufmgr *bufmgr);
++#endif
 diff --git a/src/radeon_bufmgr_exa.c b/src/radeon_bufmgr_exa.c
 new file mode 100644
-index 0000000..400b426
+index 0000000..64537a6
 --- /dev/null
 +++ b/src/radeon_bufmgr_exa.c
-@@ -0,0 +1,295 @@
+@@ -0,0 +1,324 @@
 +/**************************************************************************
 + *
 + * Copyright © 2007-2008 Red Hat Inc.
@@ -1457,7 +1495,7 @@
 +#include "radeon_reg.h"
 +#include "radeon_probe.h"
 +#include "radeon.h"
-+#include "radeon_bufmgr_exa.h"
++#include "radeon_bufmgr.h"
 +
 +
 +typedef struct _dri_bo_exa {
@@ -1472,6 +1510,7 @@
 +
 +typedef struct _dri_bufmgr_exa {
 +	dri_bufmgr bufmgr;
++	struct radeon_bufmgr radeon_bufmgr;
 +	ScrnInfoPtr pScrn;
 +	struct _dri_bo_exa *reloc_head;
 +} dri_bufmgr_exa;
@@ -1490,7 +1529,7 @@
 +		return NULL;
 +
 +	exa_buf->refcount = 1;
-+	exa_buf->mem = radeon_allocate_memory(bufmgr_exa->pScrn, RADEON_POOL_VRAM,
++	exa_buf->mem = radeon_allocate_memory(bufmgr_exa->pScrn, RADEON_POOL_GART,
 +					      size, alignment, 0, name, 0);
 +
 +	exa_buf->bo.size = exa_buf->mem->size;
@@ -1566,7 +1605,7 @@
 +	int ret;
 +
 +	dom_args.handle = exa_buf->mem->kernel_bo_handle;
-+	dom_args.read_domains = RADEON_GEM_DOMAIN_CPU;
++	dom_args.read_domains = RADEON_GEM_DOMAIN_GTT;
 +	dom_args.write_domain = 0;
 +	ret = drmCommandWriteRead(info->drmFD, DRM_RADEON_GEM_SET_DOMAIN,
 +				  &dom_args, sizeof(dom_args));
@@ -1574,6 +1613,34 @@
 +	return;
 +}
 +
++int radeon_bufmgr_subdata(dri_bo *buf, unsigned long offset,
++			  unsigned long size, const void *data)
++{
++	dri_bo_exa *exa_buf = (dri_bo_exa *)buf;
++	dri_bufmgr_exa *bufmgr_exa = (dri_bufmgr_exa *)buf->bufmgr;
++	RADEONInfoPtr info = RADEONPTR(bufmgr_exa->pScrn);
++	int ret;
++	/* go to pwrite */
++	struct drm_radeon_gem_pwrite pwrite;
++
++	pwrite.handle = exa_buf->mem->kernel_bo_handle;
++	pwrite.offset = offset;
++	pwrite.size = size;
++	pwrite.data_ptr = (uint64_t)(uintptr_t)data;
++
++	do {
++		ret = drmCommandWriteRead(info->drmFD, DRM_IOCTL_RADEON_GEM_PWRITE,
++					  &pwrite, sizeof(pwrite));
++	} while (ret == -1 && errno == EINTR);
++
++	if (ret != 0) {
++		fprintf(stderr,"Pwrite %lx at %lx failed\n", size, offset);
++		return -1;
++	}
++	return 0;
++}
++
++
 +dri_bo *
 +radeon_bufmgr_exa_create_bo(dri_bufmgr *bufmgr, struct radeon_memory *mem)
 +{
@@ -1597,6 +1664,35 @@
 +	return &exa_buf->bo;
 +}
 +
++static void radeon_bufmgr_exa_emit_reloc(dri_bo *buf, uint32_t *head, uint32_t *count_p, uint32_t read_domains, uint32_t write_domain)
++{
++	dri_bufmgr_exa *bufmgr_exa = (dri_bufmgr_exa *)buf->bufmgr;
++	ScrnInfoPtr pScrn = bufmgr_exa->pScrn;
++	dri_bo_exa *exa_buf = (dri_bo_exa *)buf;
++	uint32_t *__head = head;
++	uint32_t __count = *count_p;
++	dri_bo_exa *trav;
++
++	if (exa_buf->reloc_count == 0) {
++		dri_bo_reference(buf);
++
++		if (bufmgr_exa->reloc_head == NULL)
++			bufmgr_exa->reloc_head = exa_buf;
++		else {
++			trav = bufmgr_exa->reloc_head;
++			while (trav->next != NULL)
++				trav = trav->next;
++			trav->next = exa_buf;
++		}
++	}
++	exa_buf->reloc_count++;
++	OUT_RING(CP_PACKET3(RADEON_CP_PACKET3_NOP, 2));
++	OUT_RING(exa_buf->mem->kernel_bo_handle);
++	OUT_RING(read_domains);
++	OUT_RING(write_domain);
++	*count_p = __count;
++}
++
 +/**
 + * Initializes the EXA buffer manager, which is just a thin wrapper
 + * around the EXA allocator.
@@ -1621,39 +1717,10 @@
 +	bufmgr_exa->bufmgr.bo_unmap = dri_exa_bo_unmap;
 +	bufmgr_exa->bufmgr.destroy = dri_bufmgr_exa_destroy;
 +	bufmgr_exa->bufmgr.bo_wait_rendering = radeon_bufmgr_exa_wait_rendering;
-+
++	bufmgr_exa->radeon_bufmgr.emit_reloc = radeon_bufmgr_exa_emit_reloc;
 +	return &bufmgr_exa->bufmgr;
 +}
 +
-+void radeon_bufmgr_exa_emit_reloc(dri_bo *buf, uint32_t *head, uint32_t *count_p)
-+{
-+	dri_bufmgr_exa *bufmgr_exa = (dri_bufmgr_exa *)buf->bufmgr;
-+	ScrnInfoPtr pScrn = bufmgr_exa->pScrn;
-+	dri_bo_exa *exa_buf = (dri_bo_exa *)buf;
-+	uint32_t *__head = head;
-+	uint32_t __count = *count_p;
-+	dri_bo_exa *trav;
-+
-+	if (exa_buf->reloc_count == 0) {
-+		dri_bo_reference(buf);
-+
-+		if (bufmgr_exa->reloc_head == NULL)
-+			bufmgr_exa->reloc_head = exa_buf;
-+		else {
-+			trav = bufmgr_exa->reloc_head;
-+			while (trav->next != NULL)
-+				trav = trav->next;
-+			trav->next = exa_buf;
-+		}
-+	}
-+	exa_buf->reloc_count++;
-+	OUT_RING(CP_PACKET3(RADEON_CP_PACKET3_NOP, 2));
-+	OUT_RING(exa_buf->mem->kernel_bo_handle);
-+	OUT_RING(RADEON_GEM_DOMAIN_VRAM);
-+	OUT_RING(0);
-+	*count_p = __count;
-+}
-+
 +void radeon_bufmgr_post_submit(dri_bufmgr *bufmgr)
 +{
 +	dri_bufmgr_exa *bufmgr_exa = (dri_bufmgr_exa *)bufmgr;
@@ -1699,7 +1766,7 @@
 +}
 diff --git a/src/radeon_bufmgr_exa.h b/src/radeon_bufmgr_exa.h
 new file mode 100644
-index 0000000..03c9b0f
+index 0000000..260322c
 --- /dev/null
 +++ b/src/radeon_bufmgr_exa.h
 @@ -0,0 +1,14 @@
@@ -1711,7 +1778,563 @@
 +dri_bufmgr *radeon_bufmgr_exa_init(ScrnInfoPtr pScrn);
 +extern void radeon_bufmgr_exa_wait_rendering(dri_bo *bo);
 +extern dri_bo *radeon_bufmgr_exa_create_bo(dri_bufmgr *bufmgr, struct radeon_memory *mem);
-+void radeon_bufmgr_exa_emit_reloc(dri_bo *bo, uint32_t *head, uint32_t *count_p);
++void radeon_bufmgr_exa_emit_reloc(dri_bo *bo, uint32_t *head, uint32_t *count_p, uint32_t read_domains, uint32_t write_domain);
++void radeon_bufmgr_post_submit(dri_bufmgr *bufmgr);
++void radeon_bufmgr_pin(dri_bo *buf);
++void radeon_bufmgr_unpin(dri_bo *buf);
++uint32_t radeon_bufmgr_get_handle(dri_bo *buf);
++#endif
+diff --git a/src/radeon_bufmgr_gem.c b/src/radeon_bufmgr_gem.c
+new file mode 100644
+index 0000000..db28edc
+--- /dev/null
++++ b/src/radeon_bufmgr_gem.c
+@@ -0,0 +1,530 @@
++/**************************************************************************
++ *
++ * Copyright © 2007-2008 Red Hat Inc.
++ * Copyright © 2007 Intel Corporation
++ * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA
++ * All Rights Reserved.
++ *
++ * Permission is hereby granted, free of charge, to any person obtaining a
++ * copy of this software and associated documentation files (the
++ * "Software"), to deal in the Software without restriction, including
++ * without limitation the rights to use, copy, modify, merge, publish,
++ * distribute, sub license, and/or sell copies of the Software, and to
++ * permit persons to whom the Software is furnished to do so, subject to
++ * the following conditions:
++ *
++ * THE 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: Thomas Hellström <thomas-at-tungstengraphics-dot-com>
++ *          Keith Whitwell <keithw-at-tungstengraphics-dot-com>
++ *	    Eric Anholt <eric at anholt.net>
++ *	    Dave Airlie <airlied at linux.ie>
++ *	    Kristian Høgsberg <krh at redhat.com>
++ */
++#ifdef HAVE_CONFIG_H
++#include "config.h"
++#endif
++
++#include <xf86drm.h>
++#include <stdio.h>
++#include <stdlib.h>
++#include <string.h>
++#include <unistd.h>
++#include <assert.h>
++#include <sys/mman.h>
++#include <sys/ioctl.h>
++
++#include "xf86.h"
++#include "errno.h"
++#include "dri_bufmgr.h"
++#include "string.h"
++
++#include "radeon_reg.h"
++#include "radeon_probe.h"
++#include "radeon.h"
++#include "radeon_bufmgr.h"
++
++#define DBG(...) do {					\
++   if (bufmgr_gem->bufmgr.debug)			\
++      fprintf(stderr, __VA_ARGS__);			\
++} while (0)
++
++typedef struct _dri_bo_gem {
++	dri_bo bo;
++	int refcount;
++	int reloc_count;
++	int map_count;
++	/* reloc list - add to list for relocs */
++	uint32_t gem_handle;
++	const char *name;
++	struct _dri_bo_gem *next;
++	struct _dri_bo_gem *reloc_next;
++	int in_vram; /* have we migrated this bo to VRAM ever */
++} dri_bo_gem;
++
++struct dri_gem_bo_bucket {
++   dri_bo_gem *head, **tail;
++   /**
++    * Limit on the number of entries in this bucket.
++    *
++    * 0 means that this caching at this bucket size is disabled.
++    * -1 means that there is no limit to caching at this size.
++    */
++   int max_entries;
++   int num_entries;
++};
++
++/* Arbitrarily chosen, 16 means that the maximum size we'll cache for reuse
++ * is 1 << 16 pages, or 256MB.
++ */
++#define RADEON_GEM_BO_BUCKETS	16
++
++typedef struct _dri_bufmgr_gem {
++	dri_bufmgr bufmgr;
++	struct radeon_bufmgr radeon_bufmgr;
++	int fd;
++	struct _dri_bo_gem *reloc_head;
++	
++	/** Array of lists of cached gem objects of power-of-two sizes */
++	struct dri_gem_bo_bucket cache_bucket[RADEON_GEM_BO_BUCKETS];
++} dri_bufmgr_gem;
++
++static int
++logbase2(int n)
++{
++   int i = 1;
++   int log2 = 0;
++
++   while (n > i) {
++      i *= 2;
++      log2++;
++   }
++
++   return log2;
++}
++
++static struct dri_gem_bo_bucket *
++dri_gem_bo_bucket_for_size(dri_bufmgr_gem *bufmgr_gem, unsigned long size)
++{
++    int i;
++
++    /* We only do buckets in power of two increments */
++    if ((size & (size - 1)) != 0)
++	return NULL;
++
++    /* We should only see sizes rounded to pages. */
++    assert((size % 4096) == 0);
++
++    /* We always allocate in units of pages */
++    i = ffs(size / 4096) - 1;
++    if (i >= RADEON_GEM_BO_BUCKETS)
++	return NULL;
++
++    return &bufmgr_gem->cache_bucket[i];
++}
++
++
++static dri_bo *
++dri_gem_bo_alloc(dri_bufmgr *bufmgr, const char *name,
++		 unsigned long size, unsigned int alignment)
++
++{
++	dri_bufmgr_gem *bufmgr_gem = (dri_bufmgr_gem *)bufmgr;
++	struct drm_radeon_gem_create args;
++	int ret;
++	unsigned int page_size = getpagesize();
++	dri_bo_gem *gem_bo;
++	struct dri_gem_bo_bucket *bucket;
++	int alloc_from_cache = 0;
++	unsigned long bo_size;
++
++	/* Round the allocated size up to a power of two number of pages. */
++	bo_size = 1 << logbase2(size);
++	if (bo_size < page_size)
++		bo_size = page_size;
++	bucket = dri_gem_bo_bucket_for_size(bufmgr_gem, bo_size);
++    
++	/* If we don't have caching at this size, don't actually round the
++	 * allocation up.
++	 */
++	if (bucket == NULL || bucket->max_entries == 0) {
++		bo_size = size;
++		if (bo_size < page_size)
++			bo_size = page_size;
++	}
++
++	/* Get a buffer out of the cache if available */
++	if (bucket != NULL && bucket->num_entries > 0) {
++		struct drm_radeon_gem_set_domain args;
++
++		gem_bo = bucket->head;
++		args.handle = gem_bo->gem_handle;
++		args.read_domains = RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM;
++		args.write_domain = 0;
++		ret = ioctl(bufmgr_gem->fd, DRM_IOCTL_RADEON_GEM_SET_DOMAIN, &args);
++		alloc_from_cache = (ret == 0);
++
++		if (alloc_from_cache) {
++			bucket->head = gem_bo->next;
++			if (gem_bo->next == NULL)
++				bucket->tail = &bucket->head;
++			bucket->num_entries--;
++		}
++	}
++
++	if (!alloc_from_cache) {
++
++		gem_bo = calloc(1, sizeof(*gem_bo));
++		if (!gem_bo)
++			return NULL;
++
++		gem_bo->bo.size = bo_size;
++		args.size = bo_size;
++		args.alignment = alignment;
++		args.initial_domain = RADEON_GEM_DOMAIN_CPU;
++		args.no_backing_store = 0;
++
++		ret = drmCommandWriteRead(bufmgr_gem->fd, DRM_RADEON_GEM_CREATE, &args, sizeof(args));
++		gem_bo->gem_handle = args.handle;
++		if (ret != 0) {
++			free(gem_bo);
++			return NULL;
++		}
++		gem_bo->bo.bufmgr = bufmgr;
++	}
++
++	gem_bo->refcount = 1;
++	gem_bo->reloc_count = 0;
++	gem_bo->map_count = 0;
++	gem_bo->in_vram = 0;
++	gem_bo->name = name;
++
++	DBG("bo_create: buf %d (%s) %ldb: %d\n",
++	    gem_bo->gem_handle, gem_bo->name, size, alloc_from_cache);
++
++	return &gem_bo->bo;
++}
++
++static void
++dri_gem_bo_reference(dri_bo *bo)
++{
++	dri_bo_gem *gem_bo = (dri_bo_gem *)bo;
++	gem_bo->refcount++;
++}
++
++static void dri_gem_bo_free(dri_bo *bo)
++{
++	dri_bufmgr_gem *bufmgr_gem = (dri_bufmgr_gem *)bo->bufmgr;
++	dri_bo_gem *gem_bo = (dri_bo_gem *)bo;
++	struct drm_gem_close args;
++
++	if (gem_bo->map_count)
++		munmap(gem_bo->bo.virtual, gem_bo->bo.size);
++
++	/* close object */
++	args.handle = gem_bo->gem_handle;
++	ioctl(bufmgr_gem->fd, DRM_IOCTL_GEM_CLOSE, &args);
++	free(gem_bo);
++}
++
++static void
++dri_gem_bo_unreference(dri_bo *bo)
++{
++	dri_bufmgr_gem *bufmgr_gem = (dri_bufmgr_gem *)bo->bufmgr;
++	dri_bo_gem *gem_bo = (dri_bo_gem *)bo;
++
++	if (!bo)
++		return;
++	
++	if (--gem_bo->refcount == 0) {
++		struct dri_gem_bo_bucket *bucket;
++		
++
++		bucket = dri_gem_bo_bucket_for_size(bufmgr_gem, bo->size);
++		/* Put the buffer into our internal cache for reuse if we can. */
++		if ((gem_bo->in_vram == 0) && (bucket != NULL &&
++		    (bucket->max_entries == -1 ||
++		     (bucket->max_entries > 0 &&
++		      bucket->num_entries < bucket->max_entries))))
++		{
++			DBG("bo_unreference final: %d (%s) 1\n",
++			    gem_bo->gem_handle, gem_bo->name);
++		
++			gem_bo->name = 0;
++			
++			gem_bo->next = NULL;
++			*bucket->tail = gem_bo;
++			bucket->tail = &gem_bo->next;
++			bucket->num_entries++;
++		} else {
++			DBG("bo_unreference final: %d (%s) 0 - free %d\n",
++			    gem_bo->gem_handle, gem_bo->name, gem_bo->in_vram);
++			dri_gem_bo_free(bo);
++		}
++		
++		return;
++	}
++}
++
++static int
++dri_gem_bo_map(dri_bo *bo, int write_enable)
++{
++	dri_bufmgr_gem *bufmgr_gem = (dri_bufmgr_gem *)bo->bufmgr;
++	dri_bo_gem *gem_bo = (dri_bo_gem *)bo;
++	struct drm_radeon_gem_mmap args;
++	int ret;
++
++	if (gem_bo->map_count++ != 0)
++		return 0;
++	
++	args.handle = gem_bo->gem_handle;
++	args.offset = 0;
++	args.size = gem_bo->bo.size;
++
++	ret = drmCommandWriteRead(bufmgr_gem->fd, DRM_RADEON_GEM_MMAP, &args, sizeof(args));
++	if (!ret)
++		gem_bo->bo.virtual = (void *)(unsigned long)args.addr_ptr;
++
++	return ret;
++}
++
++static int
++dri_gem_bo_unmap(dri_bo *buf)
++{
++	dri_bufmgr_gem *bufmgr_gem = (dri_bufmgr_gem *)buf->bufmgr;
++	dri_bo_gem *gem_bo = (dri_bo_gem *)buf;
++
++	if (--gem_bo->map_count > 0)
++		return 0;
++
++        munmap(gem_bo->bo.virtual, gem_bo->bo.size);
++	gem_bo->bo.virtual = 0;
++	return 0;
++}
++
++static void
++dri_bufmgr_gem_destroy(dri_bufmgr *bufmgr)
++{
++	dri_bufmgr_gem *bufmgr_gem = (dri_bufmgr_gem *)bufmgr;
++	int i;
++
++	/* Free any cached buffer objects we were going to reuse */
++	for (i = 0; i < RADEON_GEM_BO_BUCKETS; i++) {
++		struct dri_gem_bo_bucket *bucket = &bufmgr_gem->cache_bucket[i];
++		dri_bo_gem *bo_gem;
++
++		while ((bo_gem = bucket->head) != NULL) {
++			bucket->head = bo_gem->next;
++			if (bo_gem->next == NULL)
++				bucket->tail = &bucket->head;
++			bucket->num_entries--;
++			
++			dri_gem_bo_free(&bo_gem->bo);
++		}
++	}
++	free(bufmgr);
++}
++
++void radeon_bufmgr_gem_wait_rendering(dri_bo *buf)
++{
++	dri_bufmgr_gem *bufmgr_gem = (dri_bufmgr_gem *)buf->bufmgr;
++	struct drm_radeon_gem_set_domain dom_args;
++	dri_bo_gem *gem_bo = (dri_bo_gem *)buf;
++	int ret;
++
++	dom_args.handle = gem_bo->gem_handle;
++	dom_args.read_domains = RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM;
++	dom_args.write_domain = 0;
++	ret = drmCommandWriteRead(bufmgr_gem->fd, DRM_RADEON_GEM_SET_DOMAIN,
++				  &dom_args, sizeof(dom_args));
++	return;
++}
++
++/**
++ * Returns a dri_bo wrapping the given buffer object handle.
++ *
++ * This can be used when one application needs to pass a buffer object
++ * to another.
++ */
++dri_bo *
++radeon_bo_gem_create_from_name(dri_bufmgr *bufmgr, const char *name,
++			       unsigned int handle)
++{
++    dri_bufmgr_gem *bufmgr_gem = (dri_bufmgr_gem *)bufmgr;
++    dri_bo_gem *bo_gem;
++    int ret;
++    struct drm_gem_open open_arg;
++
++    bo_gem = calloc(1, sizeof(*bo_gem));
++    if (!bo_gem)
++	return NULL;
++
++    memset(&open_arg, 0, sizeof(open_arg));
++    open_arg.name = handle;
++    ret = ioctl(bufmgr_gem->fd, DRM_IOCTL_GEM_OPEN, &open_arg);
++    if (ret != 0) {
++	fprintf(stderr, "Couldn't reference %s handle 0x%08x: %s\n",
++	       name, handle, strerror(-ret));
++	free(bo_gem);
++	return NULL;
++    }
++    bo_gem->bo.size = open_arg.size;
++    bo_gem->bo.offset = 0;
++    bo_gem->bo.virtual = NULL;
++    bo_gem->bo.bufmgr = bufmgr;
++    bo_gem->name = name;
++    bo_gem->refcount = 1;
++    bo_gem->gem_handle = open_arg.handle;
++
++    return &bo_gem->bo;
++}
++
++#define BUF_OUT_RING(x)	 do {			\
++		__head[__count++] = (x);				\
++	} while (0)
++
++void radeon_bufmgr_gem_emit_reloc(dri_bo *buf, uint32_t *head, uint32_t *count_p, uint32_t read_domains, uint32_t write_domain)
++{
++	dri_bufmgr_gem *bufmgr_gem = (dri_bufmgr_gem *)buf->bufmgr;
++	dri_bo_gem *gem_bo = (dri_bo_gem *)buf;
++	uint32_t *__head = head;
++	uint32_t __count = *count_p;
++	dri_bo_gem *trav;
++	
++	if (gem_bo->reloc_count == 0) {
++		dri_bo_reference(buf);
++
++		if (bufmgr_gem->reloc_head == NULL)
++			bufmgr_gem->reloc_head = gem_bo;
++		else {
++			trav = bufmgr_gem->reloc_head;
++			while (trav->reloc_next != NULL)
++				trav = trav->reloc_next;
++			trav->reloc_next = gem_bo;
++		}
++	}
++
++	if (write_domain == RADEON_GEM_DOMAIN_VRAM) {
++		if (gem_bo->in_vram == 0)
++			DBG("bo_into vram: buf %d (%s) %d %d\n",
++			    gem_bo->gem_handle, gem_bo->name, read_domains, write_domain);
++		
++		gem_bo->in_vram = 1;
++	}
++
++	gem_bo->reloc_count++;
++	BUF_OUT_RING(CP_PACKET3(RADEON_CP_PACKET3_NOP, 2));
++	BUF_OUT_RING(gem_bo->gem_handle);
++	BUF_OUT_RING(read_domains);
++	BUF_OUT_RING(write_domain);
++	*count_p = __count;
++}
++
++/**
++ * Enables unlimited caching of buffer objects for reuse.
++ *
++ * This is potentially very memory expensive, as the cache at each bucket
++ * size is only bounded by how many buffers of that size we've managed to have
++ * in flight at once.
++ */
++void
++radeon_bufmgr_gem_enable_reuse(dri_bufmgr *bufmgr)
++{
++    dri_bufmgr_gem *bufmgr_gem = (dri_bufmgr_gem *)bufmgr;
++    int i;
++
++    for (i = 0; i < RADEON_GEM_BO_BUCKETS; i++) {
++	bufmgr_gem->cache_bucket[i].max_entries = -1;
++    }
++}
++
++/**
++ * Initializes the GEM buffer manager, which is just a thin wrapper
++ * around the GEM allocator.
++ *
++ * \param fd File descriptor of the opened DRM device.
++ * \param fence_type Driver-specific fence type used for fences with no flush.
++ * \param fence_type_flush Driver-specific fence type used for fences with a
++ *	  flush.
++ */
++dri_bufmgr *
++radeon_bufmgr_gem_init(int fd)
++{
++	dri_bufmgr_gem *bufmgr_gem;
++	int i;
++
++	bufmgr_gem = calloc(1, sizeof(*bufmgr_gem));
++	bufmgr_gem->fd = fd;
++
++	bufmgr_gem->bufmgr.bo_alloc = dri_gem_bo_alloc;
++	bufmgr_gem->bufmgr.bo_reference = dri_gem_bo_reference;
++	bufmgr_gem->bufmgr.bo_unreference = dri_gem_bo_unreference;
++	bufmgr_gem->bufmgr.bo_map = dri_gem_bo_map;
++	bufmgr_gem->bufmgr.bo_unmap = dri_gem_bo_unmap;
++	bufmgr_gem->bufmgr.destroy = dri_bufmgr_gem_destroy;
++	bufmgr_gem->bufmgr.bo_wait_rendering = radeon_bufmgr_gem_wait_rendering;
++	bufmgr_gem->radeon_bufmgr.emit_reloc = radeon_bufmgr_gem_emit_reloc;
++	/* Initialize the linked lists for BO reuse cache. */
++	for (i = 0; i < RADEON_GEM_BO_BUCKETS; i++)
++		bufmgr_gem->cache_bucket[i].tail = &bufmgr_gem->cache_bucket[i].head;
++	bufmgr_gem->bufmgr.debug = 0;
++	return &bufmgr_gem->bufmgr;
++}
++
++
++void radeon_gem_bufmgr_post_submit(dri_bufmgr *bufmgr)
++{
++	dri_bufmgr_gem *bufmgr_gem = (dri_bufmgr_gem *)bufmgr;
++	struct _dri_bo_gem *trav, *prev;
++
++	if (!bufmgr_gem->reloc_head)
++		return;
++
++	trav = bufmgr_gem->reloc_head;
++	while (trav) {
++		prev = trav;
++		trav = trav->reloc_next;
++		
++		prev->reloc_count = 0;
++		prev->reloc_next = NULL;
++		dri_bo_unreference(&prev->bo);
++	}
++	bufmgr_gem->reloc_head = NULL;
++
++}
++
++void radeon_gem_bufmgr_pin(dri_bo *buf)
++{
++}
++
++void radeon_gem_bufmgr_unpin(dri_bo *buf)
++{
++}
++
++uint32_t radeon_gem_bufmgr_get_handle(dri_bo *buf)
++{
++	dri_bo_gem *gem_bo = (dri_bo_gem *)buf;
++	
++	return gem_bo->gem_handle;
++}
++
++void radeon_bufmgr_emit_reloc(dri_bo *buf, uint32_t *head, uint32_t *count_p, uint32_t read_domains, uint32_t write_domain)
++{
++	struct radeon_bufmgr *radeon_bufmgr;
++
++	radeon_bufmgr = (struct radeon_bufmgr *)(buf->bufmgr + 1);
++	radeon_bufmgr->emit_reloc(buf, head, count_p, read_domains, write_domain);
++}
+diff --git a/src/radeon_bufmgr_gem.h b/src/radeon_bufmgr_gem.h
+new file mode 100644
+index 0000000..e2f1ca6
+--- /dev/null
++++ b/src/radeon_bufmgr_gem.h
+@@ -0,0 +1,14 @@
++#ifndef RADEON_BUFMGR_GEM_H
++#define RADEON_BUFMGR_GEM_H
++
++#include "dri_bufmgr.h"
++
++dri_bufmgr *radeon_bufmgr_gem_init(ScrnInfoPtr pScrn);
++extern void radeon_bufmgr_gem_wait_rendering(dri_bo *bo);
++extern dri_bo *radeon_bufmgr_gem_create_bo(dri_bufmgr *bufmgr, struct radeon_memory *mem);
++void radeon_bufmgr_gem_emit_reloc(dri_bo *bo, uint32_t *head, uint32_t *count_p, uint32_t read_domains, uint32_t write_domain);
 +void radeon_bufmgr_post_submit(dri_bufmgr *bufmgr);
 +void radeon_bufmgr_pin(dri_bo *buf);
 +void radeon_bufmgr_unpin(dri_bo *buf);
@@ -1866,7 +2489,7 @@
  	FBAreaPtr          fbarea;
  
 diff --git a/src/radeon_dri.c b/src/radeon_dri.c
-index a192811..3783b8f 100644
+index a192811..9fa0add 100644
 --- a/src/radeon_dri.c
 +++ b/src/radeon_dri.c
 @@ -40,6 +40,8 @@
@@ -1926,7 +2549,7 @@
  }
  
 +
-+static uint32_t radeon_name_buffer(ScrnInfoPtr pScrn, struct radeon_memory *mem)
++uint32_t radeon_name_buffer(ScrnInfoPtr pScrn, struct radeon_memory *mem)
 +{
 +    RADEONInfoPtr  info  = RADEONPTR(pScrn);
 +    struct drm_gem_flink flink;
@@ -2595,7 +3218,7 @@
 +
 +}
 diff --git a/src/radeon_driver.c b/src/radeon_driver.c
-index 45d2c2f..bce3cc5 100644
+index 45d2c2f..8fa32ab 100644
 --- a/src/radeon_driver.c
 +++ b/src/radeon_driver.c
 @@ -1621,6 +1621,7 @@ static Bool RADEONPreInitVRAM(ScrnInfoPtr pScrn)
@@ -3368,7 +3991,7 @@
  	    xf86DrvMsg(scrnIndex, X_ERROR,
  		       "Static buffer allocation failed.  Disabling DRI.\n");
  	    xf86DrvMsg(scrnIndex, X_ERROR,
-@@ -3421,15 +3537,38 @@ Bool RADEONScreenInit(int scrnIndex, ScreenPtr pScreen,
+@@ -3421,15 +3537,39 @@ Bool RADEONScreenInit(int scrnIndex, ScreenPtr pScreen,
  	}
      }
  
@@ -3385,8 +4008,9 @@
  		info->directRenderingEnabled = FALSE;		
 +	    }
 +	}
-+	info->bufmgr = radeon_bufmgr_exa_init(pScrn);
++	info->bufmgr = radeon_bufmgr_gem_init(info->drmFD);
 +	drmmode_set_bufmgr(pScrn, &info->drmmode, info->bufmgr);
++	//radeon_bufmgr_gem_enable_reuse(info->bufmgr);
 +	radeon_setup_kernel_mem(pScreen);
 +	front_ptr = info->mm.front_buffer->map;
 +	pScrn->fbOffset = info->mm.front_buffer->offset;
@@ -3410,7 +4034,7 @@
  #endif
      xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
  		   "Initializing fb layer\n");
-@@ -3453,7 +3592,7 @@ Bool RADEONScreenInit(int scrnIndex, ScreenPtr pScreen,
+@@ -3453,7 +3593,7 @@ Bool RADEONScreenInit(int scrnIndex, ScreenPtr pScreen,
  
      if (info->r600_shadow_fb == FALSE) {
  	/* Init fb layer */
@@ -3419,7 +4043,7 @@
  			  pScrn->virtualX, pScrn->virtualY,
  			  pScrn->xDpi, pScrn->yDpi, pScrn->displayWidth,
  			  pScrn->bitsPerPixel))
-@@ -3508,7 +3647,7 @@ Bool RADEONScreenInit(int scrnIndex, ScreenPtr pScreen,
+@@ -3508,7 +3648,7 @@ Bool RADEONScreenInit(int scrnIndex, ScreenPtr pScreen,
  
      /* DRI finalisation */
  #ifdef XF86DRI
@@ -3428,7 +4052,7 @@
          info->pKernelDRMVersion->version_minor >= 19)
      {
        if (RADEONDRISetParam(pScrn, RADEON_SETPARAM_PCIGART_LOCATION, info->pciGartOffset) < 0)
-@@ -3527,15 +3666,21 @@ Bool RADEONScreenInit(int scrnIndex, ScreenPtr pScreen,
+@@ -3527,15 +3667,21 @@ Bool RADEONScreenInit(int scrnIndex, ScreenPtr pScreen,
  	info->directRenderingEnabled = RADEONDRIFinishScreenInit(pScreen);
      }
      if (info->directRenderingEnabled) {
@@ -3454,7 +4078,7 @@
  	}
  	xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Direct rendering enabled\n");
  
-@@ -5355,6 +5500,11 @@ void RADEONAdjustFrame(int scrnIndex, int x, int y, int flags)
+@@ -5355,6 +5501,11 @@ void RADEONAdjustFrame(int scrnIndex, int x, int y, int flags)
      xf86OutputPtr  output = config->output[config->compat_output];
      xf86CrtcPtr	crtc = output->crtc;
  
@@ -3466,7 +4090,7 @@
  #ifdef XF86DRI
      if (info->CPStarted && pScrn->pScreen) DRILock(pScrn->pScreen, 0);
  #endif
-@@ -5390,67 +5540,76 @@ Bool RADEONEnterVT(int scrnIndex, int flags)
+@@ -5390,67 +5541,76 @@ Bool RADEONEnterVT(int scrnIndex, int flags)
      xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
  		   "RADEONEnterVT\n");
  
@@ -3589,7 +4213,7 @@
      }
  #endif
      /* this will get XVideo going again, but only if XVideo was initialised
-@@ -5462,7 +5621,7 @@ Bool RADEONEnterVT(int scrnIndex, int flags)
+@@ -5462,7 +5622,7 @@ Bool RADEONEnterVT(int scrnIndex, int flags)
  	RADEONEngineRestore(pScrn);
  
  #ifdef XF86DRI
@@ -3598,7 +4222,7 @@
  	RADEONCP_START(pScrn, info);
  	DRIUnlock(pScrn->pScreen);
      }
-@@ -5485,24 +5644,26 @@ void RADEONLeaveVT(int scrnIndex, int flags)
+@@ -5485,24 +5645,26 @@ void RADEONLeaveVT(int scrnIndex, int flags)
  		   "RADEONLeaveVT\n");
  #ifdef XF86DRI
      if (RADEONPTR(pScrn)->directRenderingInited) {
@@ -3638,7 +4262,7 @@
  
  	    i = 0;
  
-@@ -5531,10 +5692,15 @@ void RADEONLeaveVT(int scrnIndex, int flags)
+@@ -5531,10 +5693,15 @@ void RADEONLeaveVT(int scrnIndex, int flags)
  
      xf86_hide_cursors (pScrn);
  
@@ -3657,7 +4281,7 @@
  
      xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
  		   "Ok, leaving now...\n");
-@@ -5579,7 +5745,8 @@ static Bool RADEONCloseScreen(int scrnIndex, ScreenPtr pScreen)
+@@ -5579,7 +5746,8 @@ static Bool RADEONCloseScreen(int scrnIndex, ScreenPtr pScreen)
  #endif /* USE_XAA */
  
      if (pScrn->vtSema) {
@@ -3667,7 +4291,7 @@
      }
  
      xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
-@@ -5614,6 +5781,12 @@ static Bool RADEONCloseScreen(int scrnIndex, ScreenPtr pScreen)
+@@ -5614,6 +5782,12 @@ static Bool RADEONCloseScreen(int scrnIndex, ScreenPtr pScreen)
      info->DGAModes = NULL;
      xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
  		   "Unmapping memory\n");
@@ -3681,7 +4305,7 @@
  
      pScrn->vtSema = FALSE;
 diff --git a/src/radeon_exa.c b/src/radeon_exa.c
-index 02fd4fc..bc489fc 100644
+index 02fd4fc..555ae16 100644
 --- a/src/radeon_exa.c
 +++ b/src/radeon_exa.c
 @@ -47,6 +47,13 @@
@@ -3744,13 +4368,13 @@
 +   
 +    driver_priv = exaGetPixmapDriverPrivate(pPix);
 +    if (driver_priv) {
- 
++
 +	if (driver_priv->bo) {
 +	    int ret;
 +
 +	    RADEONCPFlushIndirect(pScrn, 0);
 +
-+	    radeon_bufmgr_exa_wait_rendering(driver_priv->bo);
++	    //radeon_bufmgr_gem_wait_rendering(driver_priv->bo);
 +
 +	    /* flush IB */
 +	    ret = dri_bo_map(driver_priv->bo, 1);
@@ -3762,7 +4386,7 @@
 +	    pPix->devPrivate.ptr = driver_priv->bo->virtual;
 +	}
 +    }
-+
+ 
 +#if X_BYTE_ORDER == X_BIG_ENDIAN
      /* Front buffer is always set with proper swappers */
      if (offset == 0)
@@ -3782,17 +4406,17 @@
 +    struct radeon_exa_pixmap_priv *driver_priv;
 +
 +    driver_priv = exaGetPixmapDriverPrivate(pPix);
- 
++
 +    if (driver_priv) {
 +	dri_bo_unmap(driver_priv->bo);
 +    }
 +    pPix->devPrivate.ptr = NULL;
-+
+ 
 +#if X_BYTE_ORDER == X_BIG_ENDIAN
      /* Front buffer is always set with proper swappers */
      if (offset == 0)
          return;
-@@ -294,13 +348,97 @@ static void RADEONFinishAccess(PixmapPtr pPix, int index)
+@@ -294,13 +348,100 @@ static void RADEONFinishAccess(PixmapPtr pPix, int index)
      OUTREG(RADEON_SURFACE0_LOWER_BOUND + soff, 0);
      OUTREG(RADEON_SURFACE0_UPPER_BOUND + soff, 0);
      swapper_surfaces[index] = 0;
@@ -3862,8 +4486,11 @@
 +    if (pPixData == info->mm.front_buffer->map) {
 +	driver_priv->flags |= RADEON_PIXMAP_IS_FRONTBUFFER;
 +
-+	driver_priv->bo = 
-+	    radeon_bufmgr_exa_create_bo(info->bufmgr, info->mm.front_buffer);
++	if (info->new_cs)
++	  driver_priv->bo = radeon_bo_gem_create_from_name(info->bufmgr, "front",
++							   radeon_name_buffer(pScrn, info->mm.front_buffer));
++	else
++	  driver_priv->bo = radeon_bufmgr_exa_create_bo(info->bufmgr, info->mm.front_buffer);
 +
 +	miModifyPixmapHeader(pPixmap, width, height, depth,
 +                             bitsPerPixel, devKind, NULL);
@@ -3892,7 +4519,7 @@
  	BEGIN_ACCEL(1);							\
  	switch (info->engineMode) {					\
  	case EXA_ENGINEMODE_UNKNOWN:					\
-@@ -317,7 +455,7 @@ do {									\
+@@ -317,7 +458,7 @@ do {									\
  
  #define RADEON_SWITCH_TO_3D()						\
  do {									\
@@ -3901,15 +4528,15 @@
  	BEGIN_ACCEL(1);							\
  	switch (info->engineMode) {					\
  	case EXA_ENGINEMODE_UNKNOWN:					\
-@@ -341,6 +479,7 @@ do {									\
+@@ -341,6 +482,7 @@ do {									\
  #define BEGIN_ACCEL(n)		RADEONWaitForFifo(pScrn, (n))
  #define OUT_ACCEL_REG(reg, val)	OUTREG(reg, val)
  #define OUT_ACCEL_REG_F(reg, val) OUTREG(reg, F_TO_DW(val))
-+#define OUT_RELOC(x)            do {} while(0)
++#define OUT_RELOC(x, read, write)            do {} while(0)
  #define FINISH_ACCEL()
  
  #ifdef RENDER
-@@ -353,6 +492,7 @@ do {									\
+@@ -353,6 +495,7 @@ do {									\
  #undef BEGIN_ACCEL
  #undef OUT_ACCEL_REG
  #undef FINISH_ACCEL
@@ -3917,15 +4544,15 @@
  
  #ifdef XF86DRI
  
-@@ -363,6 +503,7 @@ do {									\
+@@ -363,6 +506,7 @@ do {									\
  #define BEGIN_ACCEL(n)		BEGIN_RING(2*(n))
  #define OUT_ACCEL_REG(reg, val)	OUT_RING_REG(reg, val)
  #define FINISH_ACCEL()		ADVANCE_RING()
-+#define OUT_RELOC(x) OUT_RING_RELOC(x)
++#define OUT_RELOC(x, read, write) OUT_RING_RELOC(x, read, write)
  
  #define OUT_RING_F(x) OUT_RING(F_TO_DW(x))
  
-@@ -373,6 +514,8 @@ do {									\
+@@ -373,6 +517,8 @@ do {									\
  
  #endif /* XF86DRI */
  
@@ -3934,7 +4561,7 @@
  /*
   * Once screen->off_screen_base is set, this function
   * allocates the remaining memory appropriately
-@@ -394,125 +537,124 @@ Bool RADEONSetupMemEXA (ScreenPtr pScreen)
+@@ -394,125 +540,124 @@ Bool RADEONSetupMemEXA (ScreenPtr pScreen)
      if (info->exa == NULL)
  	return FALSE;
  
@@ -4001,10 +4628,7 @@
 -	 * when GLX is set up, but the offscreen memory manager's allocations
 -	 * don't last through VT switches, while the kernel's understanding of
 -	 * offscreen locations does.
-+    if (info->drm_mm == FALSE) {
-+	/* Need to adjust screen size for 16 line tiles, and then make it align to.
-+	 * the buffer alignment requirement.
- 	 */
+-	 */
 -	info->backPitch = pScrn->displayWidth;
 -	next = RADEON_ALIGN(info->exa->offScreenBase, RADEON_BUFFER_ALIGN);
 -	if (!info->noBackBuffer &&
@@ -4019,7 +4643,10 @@
 -
 -	/* Reserve the static depth buffer, and adjust pitch and height to
 -	 * handle tiling.
--	 */
++    if (info->drm_mm == FALSE) {
++	/* Need to adjust screen size for 16 line tiles, and then make it align to.
++	 * the buffer alignment requirement.
+ 	 */
 -	info->depthPitch = RADEON_ALIGN(pScrn->displayWidth, 32);
 -	depth_size = RADEON_ALIGN(pScrn->virtualY, 16) * info->depthPitch * depthCpp;
 -	next = RADEON_ALIGN(info->exa->offScreenBase, RADEON_BUFFER_ALIGN);
@@ -4167,8 +4794,32 @@
      return TRUE;
  }
  
+@@ -525,10 +670,21 @@ extern void ExaOffscreenMarkUsed(PixmapPtr);
+ unsigned long long
+ RADEONTexOffsetStart(PixmapPtr pPix)
+ {
++    struct radeon_exa_pixmap_priv *driver_priv;
++    uint32_t offset;
++    driver_priv = exaGetPixmapDriverPrivate(pPix);
++
++    if (driver_priv) {
++        offset = driver_priv->bo->offset;
++	
++    } else {
++        offset = exaGetPixmapOffset(pPix);
++    	offset += RADEONPTR(xf86Screens[pPix->drawable.pScreen->myNum])->fbLocation;
++    }
+     exaMoveInPixmap(pPix);
+     ExaOffscreenMarkUsed(pPix);
++    
+ 
+-    return RADEONPTR(xf86Screens[pPix->drawable.pScreen->myNum])->fbLocation +
+-	exaGetPixmapOffset(pPix);
++    return offset;
+ }
+ #endif
 diff --git a/src/radeon_exa_funcs.c b/src/radeon_exa_funcs.c
-index 56de23e..51b792e 100644
+index 56de23e..628d2c7 100644
 --- a/src/radeon_exa_funcs.c
 +++ b/src/radeon_exa_funcs.c
 @@ -74,21 +74,69 @@ FUNC_NAME(RADEONSync)(ScreenPtr pScreen, int marker)
@@ -4217,12 +4868,12 @@
 +
 +    OUT_ACCEL_REG(RADEON_DST_PITCH_OFFSET, info->state_2d.dst_pitch_offset);
 +    if (info->new_cs)
-+	OUT_RELOC(info->state_2d.dst_bo);
++	OUT_RELOC(info->state_2d.dst_bo, 0, RADEON_GEM_DOMAIN_VRAM);
 +
 +    if (has_src) {
 +	    OUT_ACCEL_REG(RADEON_SRC_PITCH_OFFSET, info->state_2d.src_pitch_offset);
 +	    if (info->new_cs)
-+		    OUT_RELOC(info->state_2d.src_bo);
++		OUT_RELOC(info->state_2d.src_bo, RADEON_GEM_DOMAIN_GTT|RADEON_GEM_DOMAIN_VRAM, 0);
 +	    
 +    }
 +    FINISH_ACCEL();
@@ -4390,17 +5041,54 @@
  }
  
  static Bool
-@@ -276,10 +352,19 @@ FUNC_NAME(RADEONUploadToScreen)(PixmapPtr pDst, int x, int y, int w, int h,
+@@ -260,6 +336,8 @@ FUNC_NAME(RADEONUploadToScreen)(PixmapPtr pDst, int x, int y, int w, int h,
+     uint8_t	   *dst	     = info->FB + exaGetPixmapOffset(pDst);
+     unsigned int   dst_pitch = exaGetPixmapPitch(pDst);
+     unsigned int   bpp	     = pDst->drawable.bitsPerPixel;
++    int ret;
++    struct radeon_exa_pixmap_priv *driver_priv;
+ #ifdef ACCEL_CP
+     unsigned int   hpass;
+     uint32_t	   buf_pitch, dst_pitch_off;
+@@ -276,10 +354,47 @@ FUNC_NAME(RADEONUploadToScreen)(PixmapPtr pDst, int x, int y, int w, int h,
      if (bpp < 8)
  	return FALSE;
  
 +    if (info->new_cs)
-+	    dst = info->mm.front_buffer->map + exaGetPixmapOffset(pDst);
++	dst = info->mm.front_buffer->map + exaGetPixmapOffset(pDst);
 +
  #ifdef ACCEL_CP
 -    if (info->directRenderingEnabled &&
 -	RADEONGetPixmapOffsetPitch(pDst, &dst_pitch_off)) {
 -	uint8_t *buf;
++
++    if (info->new_cs){
++
++	if (info->drm_mm) {
++	    uint32_t offset, bo_width, bo_height = h;
++
++	    driver_priv = exaGetPixmapDriverPrivate(pDst);
++	    if (!driver_priv)
++		return FALSE;
++
++
++	    /* use pwrites - maybe require some sort of fallback */
++	    bo_width = w * (bpp / 8);
++	    offset = (x * bpp / 8) + (y * dst_pitch);
++
++	    while (bo_height--) {
++		ret = dri_bo_subdata(driver_priv->bo, offset, bo_width,
++				     src);
++		if (ret == -1)
++		    return FALSE;
++		    
++		src += src_pitch;
++		offset += dst_pitch;
++	    }
++
++	    return TRUE;
++	}
++    }
 +    if (!info->directRenderingEnabled && !info->drm_mode_setting)
 +        goto fallback;
 +
@@ -4413,7 +5101,7 @@
  	int cpp = bpp / 8;
  	ACCEL_PREAMBLE();
  
-@@ -294,9 +379,10 @@ FUNC_NAME(RADEONUploadToScreen)(PixmapPtr pDst, int x, int y, int w, int h,
+@@ -294,9 +409,10 @@ FUNC_NAME(RADEONUploadToScreen)(PixmapPtr pDst, int x, int y, int w, int h,
  
  	exaMarkSync(pDst->drawable.pScreen);
  	return TRUE;
@@ -4426,7 +5114,7 @@
      /* Do we need that sync here ? probably not .... */
      exaWaitSync(pDst->drawable.pScreen);
  
-@@ -388,13 +474,17 @@ FUNC_NAME(RADEONDownloadFromScreen)(PixmapPtr pSrc, int x, int y, int w, int h,
+@@ -388,13 +504,17 @@ FUNC_NAME(RADEONDownloadFromScreen)(PixmapPtr pSrc, int x, int y, int w, int h,
  
      TRACE;
  
@@ -4445,19 +5133,18 @@
  	RADEONGetPixmapOffsetPitch(pSrc, &src_pitch_offset) &&
  	(scratch = RADEONCPGetBuffer(pScrn)))
      {
-@@ -540,17 +630,23 @@ Bool FUNC_NAME(RADEONDrawInit)(ScreenPtr pScreen)
+@@ -540,17 +660,23 @@ Bool FUNC_NAME(RADEONDrawInit)(ScreenPtr pScreen)
  
      info->exa->MarkSync = FUNC_NAME(RADEONMarkSync);
      info->exa->WaitMarker = FUNC_NAME(RADEONSync);
--    info->exa->UploadToScreen = FUNC_NAME(RADEONUploadToScreen);
++
+     info->exa->UploadToScreen = FUNC_NAME(RADEONUploadToScreen);
 -    info->exa->DownloadFromScreen = FUNC_NAME(RADEONDownloadFromScreen);
- 
--#if X_BYTE_ORDER == X_BIG_ENDIAN
 +    if (!info->drm_mm) {
-+      info->exa->UploadToScreen = FUNC_NAME(RADEONUploadToScreen);
 +      info->exa->DownloadFromScreen = FUNC_NAME(RADEONDownloadFromScreen);
 +    }
-+
+ 
+-#if X_BYTE_ORDER == X_BIG_ENDIAN
      info->exa->PrepareAccess = RADEONPrepareAccess;
      info->exa->FinishAccess = RADEONFinishAccess;
 -#endif /* X_BYTE_ORDER == X_BIG_ENDIAN */
@@ -4474,7 +5161,7 @@
  
  #ifdef RENDER
      if (info->RenderAccel) {
-@@ -560,7 +656,7 @@ Bool FUNC_NAME(RADEONDrawInit)(ScreenPtr pScreen)
+@@ -560,7 +686,7 @@ Bool FUNC_NAME(RADEONDrawInit)(ScreenPtr pScreen)
  	else if (IS_R300_3D || IS_R500_3D) {
  	    if ((info->ChipFamily < CHIP_FAMILY_RS400)
  #ifdef XF86DRI
@@ -4483,7 +5170,7 @@
  #endif
  		) {
  		xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Render acceleration "
-@@ -595,6 +691,16 @@ Bool FUNC_NAME(RADEONDrawInit)(ScreenPtr pScreen)
+@@ -595,6 +721,16 @@ Bool FUNC_NAME(RADEONDrawInit)(ScreenPtr pScreen)
      }
  #endif
  
@@ -4501,7 +5188,7 @@
      xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Setting EXA maxPitchBytes\n");
  
 diff --git a/src/radeon_exa_render.c b/src/radeon_exa_render.c
-index 5d28d80..1738ca3 100644
+index 5d28d80..6426736 100644
 --- a/src/radeon_exa_render.c
 +++ b/src/radeon_exa_render.c
 @@ -410,19 +410,22 @@ static Bool FUNC_NAME(R100TextureSetup)(PicturePtr pPict, PixmapPtr pPix,
@@ -4581,7 +5268,7 @@
 +    if (info->new_cs) {
 +        uint32_t handle = 0;
 +        OUT_ACCEL_REG(R300_TX_OFFSET_0 + (unit * 4), driver_priv ? 0 : txoffset);
-+	OUT_RELOC(driver_priv->bo);
++	OUT_RELOC(driver_priv->bo, RADEON_GEM_DOMAIN_VRAM | RADEON_GEM_DOMAIN_GTT, 0);
 +    } else {
 +        txoffset += info->fbLocation + pScrn->fbOffset;
 +        OUT_ACCEL_REG(R300_TX_OFFSET_0 + (unit * 4), txoffset);
@@ -4620,7 +5307,7 @@
  
 -    OUT_ACCEL_REG(R300_RB3D_COLOROFFSET0, dst_offset);
 +        OUT_ACCEL_REG(R300_RB3D_COLOROFFSET0, 0);
-+	OUT_RELOC(driver_priv->bo);
++	OUT_RELOC(driver_priv->bo, 0, RADEON_GEM_DOMAIN_VRAM);
 +    } else {
 +        dst_offset += info->fbLocation + pScrn->fbOffset;
 +        OUT_ACCEL_REG(R300_RB3D_COLOROFFSET0, dst_offset);
@@ -5119,14 +5806,14 @@
 +typedef drm_radeon_sarea_t RADEONSAREAPriv, *RADEONSAREAPrivPtr;
 +#endif
 diff --git a/src/radeon_textured_video.c b/src/radeon_textured_video.c
-index cfa349d..2ec4cc1 100644
+index cfa349d..ef05c72 100644
 --- a/src/radeon_textured_video.c
 +++ b/src/radeon_textured_video.c
 @@ -85,6 +85,7 @@ static __inline__ uint32_t F_TO_DW(float val)
  #define BEGIN_VIDEO(n)		RADEONWaitForFifo(pScrn, (n))
  #define OUT_VIDEO_REG(reg, val)	OUTREG(reg, val)
  #define OUT_VIDEO_REG_F(reg, val) OUTREG(reg, F_TO_DW(val))
-+#define OUT_RELOC(x) do {} while(0)
++#define OUT_RELOC(x, read, write) do {} while(0)
  #define FINISH_VIDEO()
  
  #include "radeon_textured_videofuncs.c"
@@ -5142,7 +5829,7 @@
  #define OUT_VIDEO_REG(reg, val)	OUT_RING_REG(reg, val)
  #define FINISH_VIDEO()		ADVANCE_RING()
  #define OUT_VIDEO_RING_F(x) OUT_RING(F_TO_DW(x))
-+#define OUT_RELOC(x) OUT_RING_RELOC(x)
++#define OUT_RELOC(x, read, write) OUT_RING_RELOC(x, read, write)
  
  #include "radeon_textured_videofuncs.c"
  
@@ -5181,7 +5868,7 @@
      else
  #endif
 diff --git a/src/radeon_textured_videofuncs.c b/src/radeon_textured_videofuncs.c
-index d39f74d..aaf54a0 100644
+index d39f74d..56d71b1 100644
 --- a/src/radeon_textured_videofuncs.c
 +++ b/src/radeon_textured_videofuncs.c
 @@ -82,19 +82,19 @@ FUNC_NAME(RADEONDisplayTexturedVideo)(ScrnInfoPtr pScrn, RADEONPortPrivPtr pPriv
@@ -5223,7 +5910,7 @@
 +
 +	if (info->new_cs) {
 +	    OUT_VIDEO_REG(R300_TX_OFFSET_0, txoffset);
-+	    OUT_RELOC(info->mm.front_buffer->kernel_bo_handle);
++	    OUT_RELOC(info->mm.front_buffer->kernel_bo_handle, RADEON_GEM_DOMAIN_VRAM | RADEON_GEM_DOMAIN_GTT, 0);
 +	} else {
 +	    txoffset += info->fbLocation + pScrn->fbOffset;
 +	    OUT_VIDEO_REG(R300_TX_OFFSET_0, txoffset);
@@ -5244,7 +5931,7 @@
 -	OUT_VIDEO_REG(R300_RB3D_COLOROFFSET0, dst_offset);
 +	if (info->new_cs) {
 +	    OUT_VIDEO_REG(R300_RB3D_COLOROFFSET0, dst_offset);
-+	    OUT_RELOC(info->mm.front_buffer->kernel_bo_handle);
++	    OUT_RELOC(info->mm.front_buffer->kernel_bo_handle, 0, RADEON_GEM_DOMAIN_VRAM);
 +	} else {
 +	    dst_offset += info->fbLocation + pScrn->fbOffset;
 +	    OUT_VIDEO_REG(R300_RB3D_COLOROFFSET0, dst_offset);




More information about the scm-commits mailing list