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