summaryrefslogtreecommitdiff
path: root/src/gallium/winsys
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/winsys')
-rw-r--r--src/gallium/winsys/Makefile12
-rw-r--r--src/gallium/winsys/SConscript47
-rw-r--r--src/gallium/winsys/i915/drm/Makefile16
-rw-r--r--src/gallium/winsys/i915/drm/SConscript19
-rw-r--r--src/gallium/winsys/i915/drm/i915_drm_batchbuffer.c244
-rw-r--r--src/gallium/winsys/i915/drm/i915_drm_buffer.c217
-rw-r--r--src/gallium/winsys/i915/drm/i915_drm_fence.c83
-rw-r--r--src/gallium/winsys/i915/drm/i915_drm_winsys.c93
-rw-r--r--src/gallium/winsys/i915/drm/i915_drm_winsys.h75
-rw-r--r--src/gallium/winsys/i915/sw/Makefile12
-rw-r--r--src/gallium/winsys/i915/sw/SConscript17
-rw-r--r--src/gallium/winsys/i915/sw/i915_sw_batchbuffer.c157
-rw-r--r--src/gallium/winsys/i915/sw/i915_sw_buffer.c116
-rw-r--r--src/gallium/winsys/i915/sw/i915_sw_fence.c58
-rw-r--r--src/gallium/winsys/i915/sw/i915_sw_winsys.c56
-rw-r--r--src/gallium/winsys/i915/sw/i915_sw_winsys.h57
-rw-r--r--src/gallium/winsys/i965/drm/Makefile14
-rw-r--r--src/gallium/winsys/i965/drm/SConscript17
-rw-r--r--src/gallium/winsys/i965/drm/i965_drm_api.c104
-rw-r--r--src/gallium/winsys/i965/drm/i965_drm_buffer.c503
-rw-r--r--src/gallium/winsys/i965/drm/i965_drm_winsys.h64
-rw-r--r--src/gallium/winsys/i965/xlib/Makefile97
-rw-r--r--src/gallium/winsys/i965/xlib/xlib_i965.c503
-rw-r--r--src/gallium/winsys/nouveau/drm/Makefile11
-rw-r--r--src/gallium/winsys/nouveau/drm/nouveau_dri.h28
-rw-r--r--src/gallium/winsys/nouveau/drm/nouveau_drm_api.c85
-rw-r--r--src/gallium/winsys/nouveau/drm/nouveau_drm_api.h30
-rw-r--r--src/gallium/winsys/r600/drm/Makefile23
-rw-r--r--src/gallium/winsys/r600/drm/bof.c477
-rw-r--r--src/gallium/winsys/r600/drm/bof.h90
-rw-r--r--src/gallium/winsys/r600/drm/r600_drm.c89
-rw-r--r--src/gallium/winsys/r600/drm/r600_state.c399
-rw-r--r--src/gallium/winsys/r600/drm/r600_states.h461
-rw-r--r--src/gallium/winsys/r600/drm/r600d.h2122
-rw-r--r--src/gallium/winsys/r600/drm/radeon.c195
-rw-r--r--src/gallium/winsys/r600/drm/radeon_bo.c170
-rw-r--r--src/gallium/winsys/r600/drm/radeon_ctx.c406
-rw-r--r--src/gallium/winsys/r600/drm/radeon_draw.c141
-rw-r--r--src/gallium/winsys/r600/drm/radeon_pciid.c528
-rw-r--r--src/gallium/winsys/r600/drm/radeon_priv.h130
-rw-r--r--src/gallium/winsys/r600/drm/radeon_state.c168
-rw-r--r--src/gallium/winsys/radeon/drm/Makefile17
-rw-r--r--src/gallium/winsys/radeon/drm/SConscript19
-rw-r--r--src/gallium/winsys/radeon/drm/radeon_buffer.h98
-rw-r--r--src/gallium/winsys/radeon/drm/radeon_drm.c192
-rw-r--r--src/gallium/winsys/radeon/drm/radeon_drm.h48
-rw-r--r--src/gallium/winsys/radeon/drm/radeon_drm_buffer.c423
-rw-r--r--src/gallium/winsys/radeon/drm/radeon_r300.c369
-rw-r--r--src/gallium/winsys/radeon/drm/radeon_r300.h30
-rw-r--r--src/gallium/winsys/radeon/drm/radeon_winsys.h93
-rw-r--r--src/gallium/winsys/svga/drm/Makefile27
-rw-r--r--src/gallium/winsys/svga/drm/SConscript41
-rw-r--r--src/gallium/winsys/svga/drm/vmw_buffer.c274
-rw-r--r--src/gallium/winsys/svga/drm/vmw_buffer.h65
-rw-r--r--src/gallium/winsys/svga/drm/vmw_context.c416
-rw-r--r--src/gallium/winsys/svga/drm/vmw_context.h59
-rw-r--r--src/gallium/winsys/svga/drm/vmw_fence.c108
-rw-r--r--src/gallium/winsys/svga/drm/vmw_fence.h59
-rw-r--r--src/gallium/winsys/svga/drm/vmw_screen.c87
-rw-r--r--src/gallium/winsys/svga/drm/vmw_screen.h144
-rw-r--r--src/gallium/winsys/svga/drm/vmw_screen_dri.c267
-rw-r--r--src/gallium/winsys/svga/drm/vmw_screen_ioctl.c531
-rw-r--r--src/gallium/winsys/svga/drm/vmw_screen_pools.c97
-rw-r--r--src/gallium/winsys/svga/drm/vmw_screen_svga.c295
-rw-r--r--src/gallium/winsys/svga/drm/vmw_surface.c61
-rw-r--r--src/gallium/winsys/svga/drm/vmw_surface.h79
-rw-r--r--src/gallium/winsys/svga/drm/vmwgfx_drm.h571
-rw-r--r--src/gallium/winsys/sw/Makefile12
-rw-r--r--src/gallium/winsys/sw/dri/Makefile13
-rw-r--r--src/gallium/winsys/sw/dri/SConscript23
-rw-r--r--src/gallium/winsys/sw/dri/dri_sw_winsys.c225
-rw-r--r--src/gallium/winsys/sw/dri/dri_sw_winsys.h38
-rw-r--r--src/gallium/winsys/sw/drm/Makefile12
-rw-r--r--src/gallium/winsys/sw/drm/SConscript21
-rw-r--r--src/gallium/winsys/sw/drm/sw_drm_api.c103
-rw-r--r--src/gallium/winsys/sw/drm/sw_drm_api.h34
-rw-r--r--src/gallium/winsys/sw/fbdev/Makefile13
-rw-r--r--src/gallium/winsys/sw/fbdev/SConscript23
-rw-r--r--src/gallium/winsys/sw/fbdev/fbdev_sw_winsys.c224
-rw-r--r--src/gallium/winsys/sw/fbdev/fbdev_sw_winsys.h38
-rw-r--r--src/gallium/winsys/sw/gdi/SConscript23
-rw-r--r--src/gallium/winsys/sw/gdi/gdi_sw_winsys.c247
-rw-r--r--src/gallium/winsys/sw/gdi/gdi_sw_winsys.h16
-rw-r--r--src/gallium/winsys/sw/null/Makefile16
-rw-r--r--src/gallium/winsys/sw/null/SConscript21
-rw-r--r--src/gallium/winsys/sw/null/null_sw_winsys.c148
-rw-r--r--src/gallium/winsys/sw/null/null_sw_winsys.h40
-rw-r--r--src/gallium/winsys/sw/wrapper/Makefile12
-rw-r--r--src/gallium/winsys/sw/wrapper/SConscript21
-rw-r--r--src/gallium/winsys/sw/wrapper/wrapper_sw_winsys.c300
-rw-r--r--src/gallium/winsys/sw/wrapper/wrapper_sw_winsys.h35
-rw-r--r--src/gallium/winsys/sw/xlib/Makefile17
-rw-r--r--src/gallium/winsys/sw/xlib/SConscript23
-rw-r--r--src/gallium/winsys/sw/xlib/xlib_sw_winsys.c473
94 files changed, 14775 insertions, 0 deletions
diff --git a/src/gallium/winsys/Makefile b/src/gallium/winsys/Makefile
new file mode 100644
index 0000000000..bce5b3f9e0
--- /dev/null
+++ b/src/gallium/winsys/Makefile
@@ -0,0 +1,12 @@
+# src/gallium/winsys/Makefile
+TOP = ../../..
+include $(TOP)/configs/current
+
+SUBDIRS = $(GALLIUM_WINSYS_DIRS)
+
+default install clean:
+ @for dir in $(SUBDIRS) ; do \
+ if [ -d $$dir ] ; then \
+ (cd $$dir && $(MAKE) $@) || exit 1; \
+ fi \
+ done
diff --git a/src/gallium/winsys/SConscript b/src/gallium/winsys/SConscript
new file mode 100644
index 0000000000..907ac90bf0
--- /dev/null
+++ b/src/gallium/winsys/SConscript
@@ -0,0 +1,47 @@
+Import('*')
+
+
+SConscript([
+ 'sw/wrapper/SConscript',
+])
+
+if 'xlib' in env['winsys']:
+ SConscript([
+ 'sw/xlib/SConscript',
+ ])
+
+if 'gdi' in env['winsys']:
+ SConscript([
+ 'sw/gdi/SConscript',
+ ])
+
+if env['dri']:
+ SConscript([
+ 'sw/drm/SConscript',
+ 'sw/dri/SConscript',
+ ])
+
+ if 'vmware' in env['winsys']:
+ SConscript([
+ 'svga/drm/SConscript',
+ ])
+
+ if 'i915' in env['winsys']:
+ SConscript([
+ 'i915/drm/SConscript',
+ ])
+
+ if 'i965' in env['winsys']:
+ SConscript([
+ 'i965/drm/SConscript',
+ ])
+
+ if 'radeon' in env['winsys']:
+ SConscript([
+ 'radeon/drm/SConscript',
+ ])
+
+ if 'r600' in env['winsys']:
+ SConscript([
+ 'r600/drm/SConscript',
+ ])
diff --git a/src/gallium/winsys/i915/drm/Makefile b/src/gallium/winsys/i915/drm/Makefile
new file mode 100644
index 0000000000..1977de1fb0
--- /dev/null
+++ b/src/gallium/winsys/i915/drm/Makefile
@@ -0,0 +1,16 @@
+TOP = ../../../../..
+include $(TOP)/configs/current
+
+LIBNAME = i915drm
+
+C_SOURCES = \
+ i915_drm_batchbuffer.c \
+ i915_drm_buffer.c \
+ i915_drm_fence.c \
+ i915_drm_winsys.c
+
+LIBRARY_INCLUDES = $(shell pkg-config libdrm --cflags-only-I)
+
+LIBRARY_DEFINES = $(shell pkg-config libdrm --cflags-only-other)
+
+include ../../../Makefile.template
diff --git a/src/gallium/winsys/i915/drm/SConscript b/src/gallium/winsys/i915/drm/SConscript
new file mode 100644
index 0000000000..d8f5885b62
--- /dev/null
+++ b/src/gallium/winsys/i915/drm/SConscript
@@ -0,0 +1,19 @@
+Import('*')
+
+env = env.Clone()
+
+env.ParseConfig('pkg-config --cflags libdrm')
+
+i915drm_sources = [
+ 'i915_drm_batchbuffer.c',
+ 'i915_drm_buffer.c',
+ 'i915_drm_fence.c',
+ 'i915_drm_winsys.c',
+]
+
+i915drm = env.ConvenienceLibrary(
+ target ='i915drm',
+ source = i915drm_sources,
+)
+
+Export('i915drm')
diff --git a/src/gallium/winsys/i915/drm/i915_drm_batchbuffer.c b/src/gallium/winsys/i915/drm/i915_drm_batchbuffer.c
new file mode 100644
index 0000000000..102f59dc54
--- /dev/null
+++ b/src/gallium/winsys/i915/drm/i915_drm_batchbuffer.c
@@ -0,0 +1,244 @@
+
+#include "i915_drm_winsys.h"
+#include "util/u_memory.h"
+
+#include "i915_drm.h"
+
+#define BATCH_RESERVED 16
+
+#define INTEL_DEFAULT_RELOCS 100
+#define INTEL_MAX_RELOCS 400
+
+#define INTEL_BATCH_NO_CLIPRECTS 0x1
+#define INTEL_BATCH_CLIPRECTS 0x2
+
+#undef INTEL_RUN_SYNC
+#undef INTEL_MAP_BATCHBUFFER
+#undef INTEL_MAP_GTT
+#define INTEL_ALWAYS_FLUSH
+
+struct i915_drm_batchbuffer
+{
+ struct i915_winsys_batchbuffer base;
+
+ size_t actual_size;
+
+ drm_intel_bo *bo;
+};
+
+static INLINE struct i915_drm_batchbuffer *
+i915_drm_batchbuffer(struct i915_winsys_batchbuffer *batch)
+{
+ return (struct i915_drm_batchbuffer *)batch;
+}
+
+static void
+i915_drm_batchbuffer_reset(struct i915_drm_batchbuffer *batch)
+{
+ struct i915_drm_winsys *idws = i915_drm_winsys(batch->base.iws);
+ int ret;
+
+ if (batch->bo)
+ drm_intel_bo_unreference(batch->bo);
+ batch->bo = drm_intel_bo_alloc(idws->pools.gem,
+ "gallium3d_batchbuffer",
+ batch->actual_size,
+ 4096);
+
+#ifdef INTEL_MAP_BATCHBUFFER
+#ifdef INTEL_MAP_GTT
+ ret = drm_intel_gem_bo_map_gtt(batch->bo);
+#else
+ ret = drm_intel_bo_map(batch->bo, TRUE);
+#endif
+ assert(ret == 0);
+ batch->base.map = batch->bo->virtual;
+#else
+ (void)ret;
+#endif
+
+ memset(batch->base.map, 0, batch->actual_size);
+ batch->base.ptr = batch->base.map;
+ batch->base.size = batch->actual_size - BATCH_RESERVED;
+ batch->base.relocs = 0;
+}
+
+static struct i915_winsys_batchbuffer *
+i915_drm_batchbuffer_create(struct i915_winsys *iws)
+{
+ struct i915_drm_winsys *idws = i915_drm_winsys(iws);
+ struct i915_drm_batchbuffer *batch = CALLOC_STRUCT(i915_drm_batchbuffer);
+
+ batch->actual_size = idws->max_batch_size;
+
+#ifdef INTEL_MAP_BATCHBUFFER
+ batch->base.map = NULL;
+#else
+ batch->base.map = MALLOC(batch->actual_size);
+#endif
+ batch->base.ptr = NULL;
+ batch->base.size = 0;
+
+ batch->base.relocs = 0;
+ batch->base.max_relocs = 300;/*INTEL_DEFAULT_RELOCS;*/
+
+ batch->base.iws = iws;
+
+ i915_drm_batchbuffer_reset(batch);
+
+ return &batch->base;
+}
+
+static int
+i915_drm_batchbuffer_reloc(struct i915_winsys_batchbuffer *ibatch,
+ struct i915_winsys_buffer *buffer,
+ enum i915_winsys_buffer_usage usage,
+ unsigned pre_add)
+{
+ struct i915_drm_batchbuffer *batch = i915_drm_batchbuffer(ibatch);
+ unsigned write_domain = 0;
+ unsigned read_domain = 0;
+ unsigned offset;
+ int ret = 0;
+
+ assert(batch->base.relocs < batch->base.max_relocs);
+
+ if (usage == I915_USAGE_SAMPLER) {
+ write_domain = 0;
+ read_domain = I915_GEM_DOMAIN_SAMPLER;
+
+ } else if (usage == I915_USAGE_RENDER) {
+ write_domain = I915_GEM_DOMAIN_RENDER;
+ read_domain = I915_GEM_DOMAIN_RENDER;
+
+ } else if (usage == I915_USAGE_2D_TARGET) {
+ write_domain = I915_GEM_DOMAIN_RENDER;
+ read_domain = I915_GEM_DOMAIN_RENDER;
+
+ } else if (usage == I915_USAGE_2D_SOURCE) {
+ write_domain = 0;
+ read_domain = I915_GEM_DOMAIN_RENDER;
+
+ } else if (usage == I915_USAGE_VERTEX) {
+ write_domain = 0;
+ read_domain = I915_GEM_DOMAIN_VERTEX;
+
+ } else {
+ assert(0);
+ return -1;
+ }
+
+ offset = (unsigned)(batch->base.ptr - batch->base.map);
+
+ ret = drm_intel_bo_emit_reloc(batch->bo, offset,
+ intel_bo(buffer), pre_add,
+ read_domain,
+ write_domain);
+
+ ((uint32_t*)batch->base.ptr)[0] = intel_bo(buffer)->offset + pre_add;
+ batch->base.ptr += 4;
+
+ if (!ret)
+ batch->base.relocs++;
+
+ return ret;
+}
+
+static void
+i915_drm_batchbuffer_flush(struct i915_winsys_batchbuffer *ibatch,
+ struct pipe_fence_handle **fence)
+{
+ struct i915_drm_batchbuffer *batch = i915_drm_batchbuffer(ibatch);
+ unsigned used = 0;
+ int ret = 0;
+ int i;
+
+ assert(i915_winsys_batchbuffer_space(ibatch) >= 0);
+
+ used = batch->base.ptr - batch->base.map;
+ assert((used & 3) == 0);
+
+
+#ifdef INTEL_ALWAYS_FLUSH
+ /* MI_FLUSH | FLUSH_MAP_CACHE */
+ i915_winsys_batchbuffer_dword(ibatch, (0x4<<23)|(1<<0));
+ used += 4;
+#endif
+
+ if ((used & 4) == 0) {
+ /* MI_NOOP */
+ i915_winsys_batchbuffer_dword(ibatch, 0);
+ }
+ /* MI_BATCH_BUFFER_END */
+ i915_winsys_batchbuffer_dword(ibatch, (0xA<<23));
+
+ used = batch->base.ptr - batch->base.map;
+ assert((used & 4) == 0);
+
+#ifdef INTEL_MAP_BATCHBUFFER
+#ifdef INTEL_MAP_GTT
+ drm_intel_gem_bo_unmap_gtt(batch->bo);
+#else
+ drm_intel_bo_unmap(batch->bo);
+#endif
+#else
+ drm_intel_bo_subdata(batch->bo, 0, used, batch->base.map);
+#endif
+
+ /* Do the sending to HW */
+ ret = drm_intel_bo_exec(batch->bo, used, NULL, 0, 0);
+ assert(ret == 0);
+
+ if (i915_drm_winsys(ibatch->iws)->dump_cmd) {
+ unsigned *ptr;
+ drm_intel_bo_map(batch->bo, FALSE);
+ ptr = (unsigned*)batch->bo->virtual;
+
+ debug_printf("%s:\n", __func__);
+ for (i = 0; i < used / 4; i++, ptr++) {
+ debug_printf("\t%08x: %08x\n", i*4, *ptr);
+ }
+
+ drm_intel_bo_unmap(batch->bo);
+ } else {
+#ifdef INTEL_RUN_SYNC
+ drm_intel_bo_map(batch->bo, FALSE);
+ drm_intel_bo_unmap(batch->bo);
+#endif
+ }
+
+ if (fence) {
+ ibatch->iws->fence_reference(ibatch->iws, fence, NULL);
+
+#ifdef INTEL_RUN_SYNC
+ /* we run synced to GPU so just pass null */
+ (*fence) = i915_drm_fence_create(NULL);
+#else
+ (*fence) = i915_drm_fence_create(batch->bo);
+#endif
+ }
+
+ i915_drm_batchbuffer_reset(batch);
+}
+
+static void
+i915_drm_batchbuffer_destroy(struct i915_winsys_batchbuffer *ibatch)
+{
+ struct i915_drm_batchbuffer *batch = i915_drm_batchbuffer(ibatch);
+
+ if (batch->bo)
+ drm_intel_bo_unreference(batch->bo);
+
+#ifndef INTEL_MAP_BATCHBUFFER
+ FREE(batch->base.map);
+#endif
+ FREE(batch);
+}
+
+void i915_drm_winsys_init_batchbuffer_functions(struct i915_drm_winsys *idws)
+{
+ idws->base.batchbuffer_create = i915_drm_batchbuffer_create;
+ idws->base.batchbuffer_reloc = i915_drm_batchbuffer_reloc;
+ idws->base.batchbuffer_flush = i915_drm_batchbuffer_flush;
+ idws->base.batchbuffer_destroy = i915_drm_batchbuffer_destroy;
+}
diff --git a/src/gallium/winsys/i915/drm/i915_drm_buffer.c b/src/gallium/winsys/i915/drm/i915_drm_buffer.c
new file mode 100644
index 0000000000..3bd85026b2
--- /dev/null
+++ b/src/gallium/winsys/i915/drm/i915_drm_buffer.c
@@ -0,0 +1,217 @@
+
+#include "state_tracker/drm_api.h"
+#include "i915_drm_winsys.h"
+#include "util/u_memory.h"
+
+#include "i915_drm.h"
+
+static struct i915_winsys_buffer *
+i915_drm_buffer_create(struct i915_winsys *iws,
+ unsigned size, unsigned alignment,
+ enum i915_winsys_buffer_type type)
+{
+ struct i915_drm_buffer *buf = CALLOC_STRUCT(i915_drm_buffer);
+ struct i915_drm_winsys *idws = i915_drm_winsys(iws);
+ drm_intel_bufmgr *pool;
+ char *name;
+
+ if (!buf)
+ return NULL;
+
+ buf->magic = 0xDEAD1337;
+ buf->flinked = FALSE;
+ buf->flink = 0;
+ buf->map_gtt = FALSE;
+
+ if (type == I915_NEW_TEXTURE) {
+ name = "gallium3d_texture";
+ pool = idws->pools.gem;
+ } else if (type == I915_NEW_VERTEX) {
+ name = "gallium3d_vertex";
+ pool = idws->pools.gem;
+ buf->map_gtt = TRUE;
+ } else if (type == I915_NEW_SCANOUT) {
+ name = "gallium3d_scanout";
+ pool = idws->pools.gem;
+ buf->map_gtt = TRUE;
+ } else {
+ assert(0);
+ name = "gallium3d_unknown";
+ pool = idws->pools.gem;
+ }
+
+ buf->bo = drm_intel_bo_alloc(pool, name, size, alignment);
+
+ if (!buf->bo)
+ goto err;
+
+ return (struct i915_winsys_buffer *)buf;
+
+err:
+ assert(0);
+ FREE(buf);
+ return NULL;
+}
+
+static struct i915_winsys_buffer *
+i915_drm_buffer_from_handle(struct i915_winsys *iws,
+ struct winsys_handle *whandle,
+ unsigned *stride)
+{
+ struct i915_drm_winsys *idws = i915_drm_winsys(iws);
+ struct i915_drm_buffer *buf = CALLOC_STRUCT(i915_drm_buffer);
+ uint32_t tile = 0, swizzle = 0;
+
+ if (!buf)
+ return NULL;
+
+ buf->magic = 0xDEAD1337;
+ buf->bo = drm_intel_bo_gem_create_from_name(idws->pools.gem, "gallium3d_from_handle", whandle->handle);
+ buf->flinked = TRUE;
+ buf->flink = whandle->handle;
+
+ if (!buf->bo)
+ goto err;
+
+ drm_intel_bo_get_tiling(buf->bo, &tile, &swizzle);
+ if (tile != I915_TILE_NONE)
+ buf->map_gtt = TRUE;
+
+ *stride = whandle->stride;
+
+ return (struct i915_winsys_buffer *)buf;
+
+err:
+ FREE(buf);
+ return NULL;
+}
+
+static boolean
+i915_drm_buffer_get_handle(struct i915_winsys *iws,
+ struct i915_winsys_buffer *buffer,
+ struct winsys_handle *whandle,
+ unsigned stride)
+{
+ struct i915_drm_buffer *buf = i915_drm_buffer(buffer);
+
+ if (whandle->type == DRM_API_HANDLE_TYPE_SHARED) {
+ if (!buf->flinked) {
+ if (drm_intel_bo_flink(buf->bo, &buf->flink))
+ return FALSE;
+ buf->flinked = TRUE;
+ }
+
+ whandle->handle = buf->flink;
+ } else if (whandle->type == DRM_API_HANDLE_TYPE_KMS) {
+ whandle->handle = buf->bo->handle;
+ } else {
+ assert(!"unknown usage");
+ return FALSE;
+ }
+
+ whandle->stride = stride;
+ return TRUE;
+}
+
+static int
+i915_drm_buffer_set_fence_reg(struct i915_winsys *iws,
+ struct i915_winsys_buffer *buffer,
+ unsigned stride,
+ enum i915_winsys_buffer_tile tile)
+{
+ struct i915_drm_buffer *buf = i915_drm_buffer(buffer);
+ assert(I915_TILING_NONE == I915_TILE_NONE);
+ assert(I915_TILING_X == I915_TILE_X);
+ assert(I915_TILING_Y == I915_TILE_Y);
+
+ if (tile != I915_TILE_NONE) {
+ assert(buf->map_count == 0);
+ buf->map_gtt = TRUE;
+ }
+
+ return drm_intel_bo_set_tiling(buf->bo, &tile, stride);
+}
+
+static void *
+i915_drm_buffer_map(struct i915_winsys *iws,
+ struct i915_winsys_buffer *buffer,
+ boolean write)
+{
+ struct i915_drm_buffer *buf = i915_drm_buffer(buffer);
+ drm_intel_bo *bo = intel_bo(buffer);
+ int ret = 0;
+
+ assert(bo);
+
+ if (buf->map_count)
+ goto out;
+
+ if (buf->map_gtt)
+ ret = drm_intel_gem_bo_map_gtt(bo);
+ else
+ ret = drm_intel_bo_map(bo, write);
+
+ buf->ptr = bo->virtual;
+
+ assert(ret == 0);
+out:
+ if (ret)
+ return NULL;
+
+ buf->map_count++;
+ return buf->ptr;
+}
+
+static void
+i915_drm_buffer_unmap(struct i915_winsys *iws,
+ struct i915_winsys_buffer *buffer)
+{
+ struct i915_drm_buffer *buf = i915_drm_buffer(buffer);
+
+ if (--buf->map_count)
+ return;
+
+ if (buf->map_gtt)
+ drm_intel_gem_bo_unmap_gtt(intel_bo(buffer));
+ else
+ drm_intel_bo_unmap(intel_bo(buffer));
+}
+
+static int
+i915_drm_buffer_write(struct i915_winsys *iws,
+ struct i915_winsys_buffer *buffer,
+ size_t offset,
+ size_t size,
+ const void *data)
+{
+ struct i915_drm_buffer *buf = i915_drm_buffer(buffer);
+
+ return drm_intel_bo_subdata(buf->bo, offset, size, (void*)data);
+}
+
+static void
+i915_drm_buffer_destroy(struct i915_winsys *iws,
+ struct i915_winsys_buffer *buffer)
+{
+ drm_intel_bo_unreference(intel_bo(buffer));
+
+#ifdef DEBUG
+ i915_drm_buffer(buffer)->magic = 0;
+ i915_drm_buffer(buffer)->bo = NULL;
+#endif
+
+ FREE(buffer);
+}
+
+void
+i915_drm_winsys_init_buffer_functions(struct i915_drm_winsys *idws)
+{
+ idws->base.buffer_create = i915_drm_buffer_create;
+ idws->base.buffer_from_handle = i915_drm_buffer_from_handle;
+ idws->base.buffer_get_handle = i915_drm_buffer_get_handle;
+ idws->base.buffer_set_fence_reg = i915_drm_buffer_set_fence_reg;
+ idws->base.buffer_map = i915_drm_buffer_map;
+ idws->base.buffer_unmap = i915_drm_buffer_unmap;
+ idws->base.buffer_write = i915_drm_buffer_write;
+ idws->base.buffer_destroy = i915_drm_buffer_destroy;
+}
diff --git a/src/gallium/winsys/i915/drm/i915_drm_fence.c b/src/gallium/winsys/i915/drm/i915_drm_fence.c
new file mode 100644
index 0000000000..30ebf4835e
--- /dev/null
+++ b/src/gallium/winsys/i915/drm/i915_drm_fence.c
@@ -0,0 +1,83 @@
+
+#include "i915_drm_winsys.h"
+#include "util/u_memory.h"
+#include "util/u_atomic.h"
+#include "util/u_inlines.h"
+
+/**
+ * Because gem does not have fence's we have to create our own fences.
+ *
+ * They work by keeping the batchbuffer around and checking if that has
+ * been idled. If bo is NULL fence has expired.
+ */
+struct i915_drm_fence
+{
+ struct pipe_reference reference;
+ drm_intel_bo *bo;
+};
+
+
+struct pipe_fence_handle *
+i915_drm_fence_create(drm_intel_bo *bo)
+{
+ struct i915_drm_fence *fence = CALLOC_STRUCT(i915_drm_fence);
+
+ pipe_reference_init(&fence->reference, 1);
+ /* bo is null if fence already expired */
+ if (bo) {
+ drm_intel_bo_reference(bo);
+ fence->bo = bo;
+ }
+
+ return (struct pipe_fence_handle *)fence;
+}
+
+static void
+i915_drm_fence_reference(struct i915_winsys *iws,
+ struct pipe_fence_handle **ptr,
+ struct pipe_fence_handle *fence)
+{
+ struct i915_drm_fence *old = (struct i915_drm_fence *)*ptr;
+ struct i915_drm_fence *f = (struct i915_drm_fence *)fence;
+
+ if (pipe_reference(&((struct i915_drm_fence *)(*ptr))->reference, &f->reference)) {
+ if (old->bo)
+ drm_intel_bo_unreference(old->bo);
+ FREE(old);
+ }
+ *ptr = fence;
+}
+
+static int
+i915_drm_fence_signalled(struct i915_winsys *iws,
+ struct pipe_fence_handle *fence)
+{
+ assert(0);
+
+ return 0;
+}
+
+static int
+i915_drm_fence_finish(struct i915_winsys *iws,
+ struct pipe_fence_handle *fence)
+{
+ struct i915_drm_fence *f = (struct i915_drm_fence *)fence;
+
+ /* fence already expired */
+ if (!f->bo)
+ return 0;
+
+ drm_intel_bo_wait_rendering(f->bo);
+ drm_intel_bo_unreference(f->bo);
+ f->bo = NULL;
+
+ return 0;
+}
+
+void
+i915_drm_winsys_init_fence_functions(struct i915_drm_winsys *idws)
+{
+ idws->base.fence_reference = i915_drm_fence_reference;
+ idws->base.fence_signalled = i915_drm_fence_signalled;
+ idws->base.fence_finish = i915_drm_fence_finish;
+}
diff --git a/src/gallium/winsys/i915/drm/i915_drm_winsys.c b/src/gallium/winsys/i915/drm/i915_drm_winsys.c
new file mode 100644
index 0000000000..5a6b45e6c9
--- /dev/null
+++ b/src/gallium/winsys/i915/drm/i915_drm_winsys.c
@@ -0,0 +1,93 @@
+#include <stdio.h>
+
+#include "state_tracker/drm_api.h"
+
+#include "i915_drm_winsys.h"
+#include "util/u_memory.h"
+
+#include "i915/i915_context.h"
+#include "i915/i915_screen.h"
+
+#include "trace/tr_drm.h"
+
+/*
+ * Helper functions
+ */
+
+
+static void
+i915_drm_get_device_id(unsigned int *device_id)
+{
+ char path[512];
+ FILE *file;
+ void *shutup_gcc;
+
+ /*
+ * FIXME: Fix this up to use a drm ioctl or whatever.
+ */
+
+ snprintf(path, sizeof(path), "/sys/class/drm/card0/device/device");
+ file = fopen(path, "r");
+ if (!file) {
+ return;
+ }
+
+ shutup_gcc = fgets(path, sizeof(path), file);
+ (void) shutup_gcc;
+ sscanf(path, "%x", device_id);
+ fclose(file);
+}
+
+static void
+i915_drm_winsys_destroy(struct i915_winsys *iws)
+{
+ struct i915_drm_winsys *idws = i915_drm_winsys(iws);
+
+ drm_intel_bufmgr_destroy(idws->pools.gem);
+
+ FREE(idws);
+}
+
+static struct pipe_screen *
+i915_drm_create_screen(struct drm_api *api, int drmFD)
+{
+ struct i915_drm_winsys *idws;
+ unsigned int deviceID;
+
+ idws = CALLOC_STRUCT(i915_drm_winsys);
+ if (!idws)
+ return NULL;
+
+ i915_drm_get_device_id(&deviceID);
+
+ i915_drm_winsys_init_batchbuffer_functions(idws);
+ i915_drm_winsys_init_buffer_functions(idws);
+ i915_drm_winsys_init_fence_functions(idws);
+
+ idws->fd = drmFD;
+ idws->base.pci_id = deviceID;
+ idws->max_batch_size = 16 * 4096;
+
+ idws->base.destroy = i915_drm_winsys_destroy;
+
+ idws->pools.gem = drm_intel_bufmgr_gem_init(idws->fd, idws->max_batch_size);
+ drm_intel_bufmgr_gem_enable_reuse(idws->pools.gem);
+
+ idws->dump_cmd = debug_get_bool_option("INTEL_DUMP_CMD", FALSE);
+
+ return i915_screen_create(&idws->base);
+}
+
+static struct drm_api i915_drm_api =
+{
+ .name = "i915",
+ .driver_name = "i915",
+ .create_screen = i915_drm_create_screen,
+ .destroy = NULL,
+};
+
+struct drm_api *
+drm_api_create()
+{
+ return trace_drm_create(&i915_drm_api);
+}
diff --git a/src/gallium/winsys/i915/drm/i915_drm_winsys.h b/src/gallium/winsys/i915/drm/i915_drm_winsys.h
new file mode 100644
index 0000000000..99667bde4e
--- /dev/null
+++ b/src/gallium/winsys/i915/drm/i915_drm_winsys.h
@@ -0,0 +1,75 @@
+
+#ifndef INTEL_DRM_WINSYS_H
+#define INTEL_DRM_WINSYS_H
+
+#include "i915/i915_batchbuffer.h"
+
+#include "drm.h"
+#include "intel_bufmgr.h"
+
+
+/*
+ * Winsys
+ */
+
+
+struct i915_drm_winsys
+{
+ struct i915_winsys base;
+
+ boolean dump_cmd;
+
+ int fd; /**< Drm file discriptor */
+
+ size_t max_batch_size;
+
+ struct {
+ drm_intel_bufmgr *gem;
+ } pools;
+};
+
+static INLINE struct i915_drm_winsys *
+i915_drm_winsys(struct i915_winsys *iws)
+{
+ return (struct i915_drm_winsys *)iws;
+}
+
+struct i915_drm_winsys * i915_drm_winsys_create(int fd, unsigned pci_id);
+struct pipe_fence_handle * i915_drm_fence_create(drm_intel_bo *bo);
+
+void i915_drm_winsys_init_batchbuffer_functions(struct i915_drm_winsys *idws);
+void i915_drm_winsys_init_buffer_functions(struct i915_drm_winsys *idws);
+void i915_drm_winsys_init_fence_functions(struct i915_drm_winsys *idws);
+
+
+/*
+ * Buffer
+ */
+
+
+struct i915_drm_buffer {
+ unsigned magic;
+
+ drm_intel_bo *bo;
+
+ void *ptr;
+ unsigned map_count;
+ boolean map_gtt;
+
+ boolean flinked;
+ unsigned flink;
+};
+
+static INLINE struct i915_drm_buffer *
+i915_drm_buffer(struct i915_winsys_buffer *buffer)
+{
+ return (struct i915_drm_buffer *)buffer;
+}
+
+static INLINE drm_intel_bo *
+intel_bo(struct i915_winsys_buffer *buffer)
+{
+ return i915_drm_buffer(buffer)->bo;
+}
+
+#endif
diff --git a/src/gallium/winsys/i915/sw/Makefile b/src/gallium/winsys/i915/sw/Makefile
new file mode 100644
index 0000000000..6aab6d2961
--- /dev/null
+++ b/src/gallium/winsys/i915/sw/Makefile
@@ -0,0 +1,12 @@
+TOP = ../../../../..
+include $(TOP)/configs/current
+
+LIBNAME = i915sw
+
+C_SOURCES = \
+ i915_sw_batchbuffer.c \
+ i915_sw_buffer.c \
+ i915_sw_fence.c \
+ i915_sw_winsys.c
+
+include ../../../Makefile.template
diff --git a/src/gallium/winsys/i915/sw/SConscript b/src/gallium/winsys/i915/sw/SConscript
new file mode 100644
index 0000000000..84f427a128
--- /dev/null
+++ b/src/gallium/winsys/i915/sw/SConscript
@@ -0,0 +1,17 @@
+Import('*')
+
+env = env.Clone()
+
+i915_sw_sources = [
+ 'i915_sw_batchbuffer.c',
+ 'i915_sw_buffer.c',
+ 'i915_sw_winsys.c',
+ 'i915_sw_fence.c',
+]
+
+i915sw = env.ConvenienceLibrary(
+ target ='i915sw',
+ source = i915_sw_sources,
+)
+
+Export('i915sw')
diff --git a/src/gallium/winsys/i915/sw/i915_sw_batchbuffer.c b/src/gallium/winsys/i915/sw/i915_sw_batchbuffer.c
new file mode 100644
index 0000000000..a480cfed57
--- /dev/null
+++ b/src/gallium/winsys/i915/sw/i915_sw_batchbuffer.c
@@ -0,0 +1,157 @@
+
+#include "i915_sw_winsys.h"
+#include "i915/i915_batchbuffer.h"
+#include "util/u_memory.h"
+
+#define BATCH_RESERVED 16
+
+#define INTEL_DEFAULT_RELOCS 100
+#define INTEL_MAX_RELOCS 400
+
+#define INTEL_BATCH_NO_CLIPRECTS 0x1
+#define INTEL_BATCH_CLIPRECTS 0x2
+
+#define INTEL_ALWAYS_FLUSH
+
+struct i915_sw_batchbuffer
+{
+ struct i915_winsys_batchbuffer base;
+
+ size_t actual_size;
+};
+
+static INLINE struct i915_sw_batchbuffer *
+i915_sw_batchbuffer(struct i915_winsys_batchbuffer *batch)
+{
+ return (struct i915_sw_batchbuffer *)batch;
+}
+
+static void
+i915_sw_batchbuffer_reset(struct i915_sw_batchbuffer *batch)
+{
+ memset(batch->base.map, 0, batch->actual_size);
+ batch->base.ptr = batch->base.map;
+ batch->base.size = batch->actual_size - BATCH_RESERVED;
+ batch->base.relocs = 0;
+}
+
+static struct i915_winsys_batchbuffer *
+i915_sw_batchbuffer_create(struct i915_winsys *iws)
+{
+ struct i915_sw_winsys *isws = i915_sw_winsys(iws);
+ struct i915_sw_batchbuffer *batch = CALLOC_STRUCT(i915_sw_batchbuffer);
+
+ batch->actual_size = isws->max_batch_size;
+
+ batch->base.map = MALLOC(batch->actual_size);
+ batch->base.ptr = NULL;
+ batch->base.size = 0;
+
+ batch->base.relocs = 0;
+ batch->base.max_relocs = 300;/*INTEL_DEFAULT_RELOCS;*/
+
+ batch->base.iws = iws;
+
+ i915_sw_batchbuffer_reset(batch);
+
+ return &batch->base;
+}
+
+static int
+i915_sw_batchbuffer_reloc(struct i915_winsys_batchbuffer *ibatch,
+ struct i915_winsys_buffer *buffer,
+ enum i915_winsys_buffer_usage usage,
+ unsigned pre_add)
+{
+ struct i915_sw_batchbuffer *batch = i915_sw_batchbuffer(ibatch);
+ int ret = 0;
+
+ assert(batch->base.relocs < batch->base.max_relocs);
+
+ if (usage == I915_USAGE_SAMPLER) {
+
+ } else if (usage == I915_USAGE_RENDER) {
+
+ } else if (usage == I915_USAGE_2D_TARGET) {
+
+ } else if (usage == I915_USAGE_2D_SOURCE) {
+
+ } else if (usage == I915_USAGE_VERTEX) {
+
+ } else {
+ assert(0);
+ return -1;
+ }
+
+ ((uint32_t*)batch->base.ptr)[0] = 0;
+ batch->base.ptr += 4;
+
+ if (!ret)
+ batch->base.relocs++;
+
+ return ret;
+}
+
+static void
+i915_sw_batchbuffer_flush(struct i915_winsys_batchbuffer *ibatch,
+ struct pipe_fence_handle **fence)
+{
+ struct i915_sw_batchbuffer *batch = i915_sw_batchbuffer(ibatch);
+ unsigned used = 0;
+ int i;
+
+ assert(i915_winsys_batchbuffer_space(ibatch) >= 0);
+
+ used = batch->base.ptr - batch->base.map;
+ assert((used & 3) == 0);
+
+#ifdef INTEL_ALWAYS_FLUSH
+ /* MI_FLUSH | FLUSH_MAP_CACHE */
+ i915_winsys_batchbuffer_dword(ibatch, (0x4<<23)|(1<<0));
+ used += 4;
+#endif
+
+ if ((used & 4) == 0) {
+ /* MI_NOOP */
+ i915_winsys_batchbuffer_dword(ibatch, 0);
+ }
+ /* MI_BATCH_BUFFER_END */
+ i915_winsys_batchbuffer_dword(ibatch, (0xA<<23));
+
+ used = batch->base.ptr - batch->base.map;
+ assert((used & 4) == 0);
+
+ if (i915_sw_winsys(ibatch->iws)->dump_cmd) {
+ unsigned *ptr = (unsigned *)batch->base.map;
+
+ debug_printf("%s:\n", __func__);
+ for (i = 0; i < used / 4; i++, ptr++) {
+ debug_printf("\t%08x: %08x\n", i*4, *ptr);
+ }
+ }
+
+ if (fence) {
+ ibatch->iws->fence_reference(ibatch->iws, fence, NULL);
+
+ (*fence) = i915_sw_fence_create();
+ }
+
+ i915_sw_batchbuffer_reset(batch);
+}
+
+static void
+i915_sw_batchbuffer_destroy(struct i915_winsys_batchbuffer *ibatch)
+{
+ struct i915_sw_batchbuffer *batch = i915_sw_batchbuffer(ibatch);
+
+ FREE(batch->base.map);
+ FREE(batch);
+}
+
+void i915_sw_winsys_init_batchbuffer_functions(struct i915_sw_winsys *isws)
+{
+ isws->base.batchbuffer_create = i915_sw_batchbuffer_create;
+ isws->base.batchbuffer_reloc = i915_sw_batchbuffer_reloc;
+ isws->base.batchbuffer_flush = i915_sw_batchbuffer_flush;
+ isws->base.batchbuffer_destroy = i915_sw_batchbuffer_destroy;
+}
diff --git a/src/gallium/winsys/i915/sw/i915_sw_buffer.c b/src/gallium/winsys/i915/sw/i915_sw_buffer.c
new file mode 100644
index 0000000000..df17568886
--- /dev/null
+++ b/src/gallium/winsys/i915/sw/i915_sw_buffer.c
@@ -0,0 +1,116 @@
+
+#include "i915_sw_winsys.h"
+#include "util/u_memory.h"
+
+static struct i915_winsys_buffer *
+i915_sw_buffer_create(struct i915_winsys *iws,
+ unsigned size, unsigned alignment,
+ enum i915_winsys_buffer_type type)
+{
+ struct i915_sw_buffer *buf = CALLOC_STRUCT(i915_sw_buffer);
+ char *name;
+
+ if (!buf)
+ return NULL;
+
+ if (type == I915_NEW_TEXTURE) {
+ name = "gallium3d_texture";
+ } else if (type == I915_NEW_VERTEX) {
+ name = "gallium3d_vertex";
+ } else if (type == I915_NEW_SCANOUT) {
+ name = "gallium3d_scanout";
+ } else {
+ assert(0);
+ name = "gallium3d_unknown";
+ }
+
+ buf->magic = 0xDEAD1337;
+ buf->name = name;
+ buf->type = type;
+ buf->ptr = CALLOC(size, 1);
+
+ if (!buf->ptr)
+ goto err;
+
+ return (struct i915_winsys_buffer *)buf;
+
+err:
+ assert(0);
+ FREE(buf);
+ return NULL;
+}
+
+static int
+i915_sw_buffer_set_fence_reg(struct i915_winsys *iws,
+ struct i915_winsys_buffer *buffer,
+ unsigned stride,
+ enum i915_winsys_buffer_tile tile)
+{
+ struct i915_sw_buffer *buf = i915_sw_buffer(buffer);
+
+ if (tile != I915_TILE_NONE) {
+ assert(buf->map_count == 0);
+ }
+
+ buf->tile = tile;
+
+ return 0;
+}
+
+static void *
+i915_sw_buffer_map(struct i915_winsys *iws,
+ struct i915_winsys_buffer *buffer,
+ boolean write)
+{
+ struct i915_sw_buffer *buf = i915_sw_buffer(buffer);
+
+ buf->map_count += 1;
+ return buf->ptr;
+}
+
+static void
+i915_sw_buffer_unmap(struct i915_winsys *iws,
+ struct i915_winsys_buffer *buffer)
+{
+ struct i915_sw_buffer *buf = i915_sw_buffer(buffer);
+
+ buf->map_count -= 1;
+}
+
+static int
+i915_sw_buffer_write(struct i915_winsys *iws,
+ struct i915_winsys_buffer *buffer,
+ size_t offset,
+ size_t size,
+ const void *data)
+{
+ struct i915_sw_buffer *buf = i915_sw_buffer(buffer);
+
+ memcpy(buf->ptr + offset, data, size);
+ return 0;
+}
+
+static void
+i915_sw_buffer_destroy(struct i915_winsys *iws,
+ struct i915_winsys_buffer *buffer)
+{
+ struct i915_sw_buffer *buf = i915_sw_buffer(buffer);
+
+#ifdef DEBUG
+ buf->magic = 0;
+#endif
+
+ FREE(buf->ptr);
+ FREE(buf);
+}
+
+void
+i915_sw_winsys_init_buffer_functions(struct i915_sw_winsys *isws)
+{
+ isws->base.buffer_create = i915_sw_buffer_create;
+ isws->base.buffer_set_fence_reg = i915_sw_buffer_set_fence_reg;
+ isws->base.buffer_map = i915_sw_buffer_map;
+ isws->base.buffer_unmap = i915_sw_buffer_unmap;
+ isws->base.buffer_write = i915_sw_buffer_write;
+ isws->base.buffer_destroy = i915_sw_buffer_destroy;
+}
diff --git a/src/gallium/winsys/i915/sw/i915_sw_fence.c b/src/gallium/winsys/i915/sw/i915_sw_fence.c
new file mode 100644
index 0000000000..4b61b2a5e3
--- /dev/null
+++ b/src/gallium/winsys/i915/sw/i915_sw_fence.c
@@ -0,0 +1,58 @@
+
+#include "i915_sw_winsys.h"
+#include "util/u_memory.h"
+#include "util/u_atomic.h"
+#include "util/u_inlines.h"
+
+struct i915_sw_fence
+{
+ struct pipe_reference reference;
+};
+
+struct pipe_fence_handle *
+i915_sw_fence_create()
+{
+ struct i915_sw_fence *fence = CALLOC_STRUCT(i915_sw_fence);
+
+ pipe_reference_init(&fence->reference, 1);
+
+ return (struct pipe_fence_handle *)fence;
+}
+
+static void
+i915_sw_fence_reference(struct i915_winsys *iws,
+ struct pipe_fence_handle **ptr,
+ struct pipe_fence_handle *fence)
+{
+ struct i915_sw_fence *old = (struct i915_sw_fence *)*ptr;
+ struct i915_sw_fence *f = (struct i915_sw_fence *)fence;
+
+ if (pipe_reference(&((struct i915_sw_fence *)(*ptr))->reference, &f->reference)) {
+ FREE(old);
+ }
+ *ptr = fence;
+}
+
+static int
+i915_sw_fence_signalled(struct i915_winsys *iws,
+ struct pipe_fence_handle *fence)
+{
+ assert(0);
+
+ return 0;
+}
+
+static int
+i915_sw_fence_finish(struct i915_winsys *iws,
+ struct pipe_fence_handle *fence)
+{
+ return 0;
+}
+
+void
+i915_sw_winsys_init_fence_functions(struct i915_sw_winsys *isws)
+{
+ isws->base.fence_reference = i915_sw_fence_reference;
+ isws->base.fence_signalled = i915_sw_fence_signalled;
+ isws->base.fence_finish = i915_sw_fence_finish;
+}
diff --git a/src/gallium/winsys/i915/sw/i915_sw_winsys.c b/src/gallium/winsys/i915/sw/i915_sw_winsys.c
new file mode 100644
index 0000000000..bb1c107c05
--- /dev/null
+++ b/src/gallium/winsys/i915/sw/i915_sw_winsys.c
@@ -0,0 +1,56 @@
+
+#include "i915_sw_winsys.h"
+#include "util/u_memory.h"
+
+
+/*
+ * Helper functions
+ */
+
+
+static void
+i915_sw_get_device_id(unsigned int *device_id)
+{
+ /* just pick a i945 hw id */
+ *device_id = 0x27A2;
+}
+
+static void
+i915_sw_destroy(struct i915_winsys *iws)
+{
+ struct i915_sw_winsys *isws = i915_sw_winsys(iws);
+ FREE(isws);
+}
+
+
+/*
+ * Exported functions
+ */
+
+
+struct pipe_screen *
+i915_sw_create_screen()
+{
+ struct i915_sw_winsys *isws;
+ unsigned int deviceID;
+
+ isws = CALLOC_STRUCT(i915_sw_winsys);
+ if (!isws)
+ return NULL;
+
+ i915_sw_get_device_id(&deviceID);
+
+ i915_sw_winsys_init_batchbuffer_functions(isws);
+ i915_sw_winsys_init_buffer_functions(isws);
+ i915_sw_winsys_init_fence_functions(isws);
+
+ isws->base.destroy = i915_sw_destroy;
+
+ isws->base.pci_id = deviceID;
+ isws->max_batch_size = 16 * 4096;
+
+ isws->dump_cmd = debug_get_bool_option("INTEL_DUMP_CMD", FALSE);
+
+ /* XXX so this will leak winsys:es */
+ return i915_screen_create(&isws->base);
+}
diff --git a/src/gallium/winsys/i915/sw/i915_sw_winsys.h b/src/gallium/winsys/i915/sw/i915_sw_winsys.h
new file mode 100644
index 0000000000..b8aa9ef4ac
--- /dev/null
+++ b/src/gallium/winsys/i915/sw/i915_sw_winsys.h
@@ -0,0 +1,57 @@
+
+#ifndef I915_SW_WINSYS_H
+#define I915_SW_WINSYS_H
+
+#include "i915/i915_winsys.h"
+
+
+/*
+ * Winsys
+ */
+
+
+struct i915_sw_winsys
+{
+ struct i915_winsys base;
+
+ boolean dump_cmd;
+
+ size_t max_batch_size;
+};
+
+static INLINE struct i915_sw_winsys *
+i915_sw_winsys(struct i915_winsys *iws)
+{
+ return (struct i915_sw_winsys *)iws;
+}
+
+struct pipe_screen* i915_sw_create_screen(void);
+struct pipe_fence_handle * i915_sw_fence_create(void);
+
+void i915_sw_winsys_init_batchbuffer_functions(struct i915_sw_winsys *idws);
+void i915_sw_winsys_init_buffer_functions(struct i915_sw_winsys *idws);
+void i915_sw_winsys_init_fence_functions(struct i915_sw_winsys *idws);
+
+
+/*
+ * Buffer
+ */
+
+
+struct i915_sw_buffer {
+ unsigned magic;
+
+ void *ptr;
+ unsigned map_count;
+ enum i915_winsys_buffer_type type;
+ enum i915_winsys_buffer_tile tile;
+ const char *name;
+};
+
+static INLINE struct i915_sw_buffer *
+i915_sw_buffer(struct i915_winsys_buffer *buffer)
+{
+ return (struct i915_sw_buffer *)buffer;
+}
+
+#endif
diff --git a/src/gallium/winsys/i965/drm/Makefile b/src/gallium/winsys/i965/drm/Makefile
new file mode 100644
index 0000000000..bbb71e25d8
--- /dev/null
+++ b/src/gallium/winsys/i965/drm/Makefile
@@ -0,0 +1,14 @@
+TOP = ../../../../..
+include $(TOP)/configs/current
+
+LIBNAME = i965drm
+
+C_SOURCES = \
+ i965_drm_buffer.c \
+ i965_drm_api.c
+
+LIBRARY_INCLUDES = $(shell pkg-config libdrm --cflags-only-I)
+
+LIBRARY_DEFINES = $(shell pkg-config libdrm --cflags-only-other)
+
+include ../../../Makefile.template
diff --git a/src/gallium/winsys/i965/drm/SConscript b/src/gallium/winsys/i965/drm/SConscript
new file mode 100644
index 0000000000..abf9aac5c0
--- /dev/null
+++ b/src/gallium/winsys/i965/drm/SConscript
@@ -0,0 +1,17 @@
+Import('*')
+
+env = env.Clone()
+
+env.ParseConfig('pkg-config --cflags libdrm')
+
+i965drm_sources = [
+ 'i965_drm_api.c',
+ 'i965_drm_buffer.c',
+]
+
+i965drm = env.ConvenienceLibrary(
+ target ='i965drm',
+ source = i965drm_sources,
+)
+
+Export('i965drm')
diff --git a/src/gallium/winsys/i965/drm/i965_drm_api.c b/src/gallium/winsys/i965/drm/i965_drm_api.c
new file mode 100644
index 0000000000..87ee8070b1
--- /dev/null
+++ b/src/gallium/winsys/i965/drm/i965_drm_api.c
@@ -0,0 +1,104 @@
+
+#include <stdio.h>
+#include "state_tracker/drm_api.h"
+
+#include "i965_drm_winsys.h"
+#include "util/u_memory.h"
+
+#include "i965/brw_context.h" /* XXX: shouldn't be doing this */
+#include "i965/brw_screen.h" /* XXX: shouldn't be doing this */
+
+#include "trace/tr_drm.h"
+
+#include "../../sw/drm/sw_drm_api.h"
+
+/*
+ * Helper functions
+ */
+
+
+static void
+i965_libdrm_get_device_id(unsigned int *device_id)
+{
+ char path[512];
+ FILE *file;
+ void *shutup_gcc;
+
+ /*
+ * FIXME: Fix this up to use a drm ioctl or whatever.
+ */
+
+ snprintf(path, sizeof(path), "/sys/class/drm/card0/device/device");
+ file = fopen(path, "r");
+ if (!file) {
+ return;
+ }
+
+ shutup_gcc = fgets(path, sizeof(path), file);
+ sscanf(path, "%x", device_id);
+ fclose(file);
+}
+
+static void
+i965_libdrm_winsys_destroy(struct brw_winsys_screen *iws)
+{
+ struct i965_libdrm_winsys *idws = i965_libdrm_winsys(iws);
+
+ if (BRW_DUMP)
+ debug_printf("%s\n", __FUNCTION__);
+
+ drm_intel_bufmgr_destroy(idws->gem);
+
+ FREE(idws);
+}
+
+static struct pipe_screen *
+i965_libdrm_create_screen(struct drm_api *api, int drmFD)
+{
+ struct i965_libdrm_winsys *idws;
+ unsigned int deviceID;
+
+ debug_printf("%s\n", __FUNCTION__);
+
+ idws = CALLOC_STRUCT(i965_libdrm_winsys);
+ if (!idws)
+ return NULL;
+
+ i965_libdrm_get_device_id(&deviceID);
+
+ i965_libdrm_winsys_init_buffer_functions(idws);
+
+ idws->fd = drmFD;
+ idws->id = deviceID;
+
+ idws->base.destroy = i965_libdrm_winsys_destroy;
+
+ idws->gem = drm_intel_bufmgr_gem_init(idws->fd, BRW_BATCH_SIZE);
+ drm_intel_bufmgr_gem_enable_reuse(idws->gem);
+
+ idws->send_cmd = !debug_get_bool_option("BRW_NO_HW", FALSE);
+
+ return brw_create_screen(&idws->base, deviceID);
+}
+
+struct drm_api i965_libdrm_api =
+{
+ .name = "i965",
+ .driver_name = "i915",
+ .create_screen = i965_libdrm_create_screen,
+ .destroy = NULL,
+};
+
+struct drm_api *
+drm_api_create()
+{
+ struct drm_api *api = NULL;
+
+ if (api == NULL && debug_get_bool_option("BRW_SOFTPIPE", FALSE))
+ api = sw_drm_api_create(&i965_libdrm_api);
+
+ if (api == NULL)
+ api = &i965_libdrm_api;
+
+ return trace_drm_create(api);
+}
diff --git a/src/gallium/winsys/i965/drm/i965_drm_buffer.c b/src/gallium/winsys/i965/drm/i965_drm_buffer.c
new file mode 100644
index 0000000000..fb5e50ce81
--- /dev/null
+++ b/src/gallium/winsys/i965/drm/i965_drm_buffer.c
@@ -0,0 +1,503 @@
+
+#include "state_tracker/drm_api.h"
+#include "i965_drm_winsys.h"
+#include "util/u_memory.h"
+#include "util/u_inlines.h"
+
+#include "i915_drm.h"
+#include "intel_bufmgr.h"
+
+
+
+const char *names[BRW_BUFFER_TYPE_MAX] = {
+ "TEXTURE",
+ "SCANOUT",
+ "VERTEX",
+ "CURBE",
+ "QUERY",
+ "SHADER_CONSTANTS",
+ "WM_SCRATCH",
+ "BATCH",
+ "GENERAL_STATE",
+ "SURFACE_STATE",
+ "PIXEL",
+ "GENERIC",
+};
+
+const char *usages[BRW_USAGE_MAX] = {
+ "STATE",
+ "QUERY_RESULT",
+ "RENDER_TARGET",
+ "DEPTH_BUFFER",
+ "BLIT_SOURCE",
+ "BLIT_DEST",
+ "SAMPLER",
+ "VERTEX",
+ "SCRATCH"
+};
+
+
+const char *data_types[BRW_DATA_MAX] =
+{
+ "GS: CC_VP",
+ "GS: CC_UNIT",
+ "GS: WM_PROG",
+ "GS: SAMPLER_DEFAULT_COLOR",
+ "GS: SAMPLER",
+ "GS: WM_UNIT",
+ "GS: SF_PROG",
+ "GS: SF_VP",
+ "GS: SF_UNIT",
+ "GS: VS_UNIT",
+ "GS: VS_PROG",
+ "GS: GS_UNIT",
+ "GS: GS_PROG",
+ "GS: CLIP_VP",
+ "GS: CLIP_UNIT",
+ "GS: CLIP_PROG",
+ "SS: SURFACE",
+ "SS: SURF_BIND",
+ "CONSTANT DATA",
+ "BATCH DATA",
+ "(untyped)"
+};
+
+static enum pipe_error
+i965_libdrm_bo_alloc(struct brw_winsys_screen *sws,
+ enum brw_buffer_type type,
+ unsigned size,
+ unsigned alignment,
+ struct brw_winsys_buffer **bo_out)
+{
+ struct i965_libdrm_winsys *idws = i965_libdrm_winsys(sws);
+ struct i965_libdrm_buffer *buf;
+
+ if (BRW_DUMP)
+ debug_printf("%s type %s sz %d align %d\n",
+ __FUNCTION__, names[type], size, alignment );
+
+ buf = CALLOC_STRUCT(i965_libdrm_buffer);
+ if (!buf)
+ return PIPE_ERROR_OUT_OF_MEMORY;
+
+ switch (type) {
+ case BRW_BUFFER_TYPE_TEXTURE:
+/* case BRW_BUFFER_TYPE_SCANOUT:*/
+ case BRW_BUFFER_TYPE_VERTEX:
+ case BRW_BUFFER_TYPE_CURBE:
+ case BRW_BUFFER_TYPE_QUERY:
+ case BRW_BUFFER_TYPE_SHADER_CONSTANTS:
+ case BRW_BUFFER_TYPE_SHADER_SCRATCH:
+ case BRW_BUFFER_TYPE_BATCH:
+ case BRW_BUFFER_TYPE_GENERAL_STATE:
+ case BRW_BUFFER_TYPE_SURFACE_STATE:
+ case BRW_BUFFER_TYPE_PIXEL:
+ case BRW_BUFFER_TYPE_GENERIC:
+ break;
+ case BRW_BUFFER_TYPE_SCANOUT:
+ buf->map_gtt = TRUE;
+ break;
+ default:
+ assert(0);
+ break;
+ }
+
+ buf->bo = drm_intel_bo_alloc(idws->gem,
+ names[type],
+ size,
+ alignment);
+
+ if (!buf->bo)
+ goto err;
+
+ pipe_reference_init(&buf->base.reference, 1);
+ buf->base.size = size;
+ buf->base.sws = sws;
+
+ *bo_out = &buf->base;
+ return PIPE_OK;
+
+err:
+ assert(0);
+ FREE(buf);
+ return PIPE_ERROR_OUT_OF_MEMORY;
+}
+
+static enum pipe_error
+i965_libdrm_bo_from_handle(struct brw_winsys_screen *sws,
+ struct winsys_handle *whandle,
+ unsigned *stride,
+ unsigned *tile,
+ struct brw_winsys_buffer **bo_out)
+{
+ struct i965_libdrm_winsys *idws = i965_libdrm_winsys(sws);
+ struct i965_libdrm_buffer *buf = CALLOC_STRUCT(i965_libdrm_buffer);
+ uint32_t swizzle = 0;
+
+ if (BRW_DUMP)
+ debug_printf("%s\n", __FUNCTION__);
+
+ if (!buf)
+ return PIPE_ERROR_OUT_OF_MEMORY;
+
+ pipe_reference_init(&buf->base.reference, 1);
+ buf->bo = drm_intel_bo_gem_create_from_name(idws->gem, "FROM_HANDLE", whandle->handle);
+ buf->base.size = buf->bo->size;
+ buf->base.sws = &idws->base;
+ buf->flinked = TRUE;
+ buf->flink = whandle->handle;
+
+
+ if (!buf->bo)
+ goto err;
+
+ drm_intel_bo_get_tiling(buf->bo, &buf->tiling, &swizzle);
+ if (buf->tiling != 0)
+ buf->map_gtt = TRUE;
+
+ *tile = buf->tiling;
+ *stride = whandle->stride;
+
+ *bo_out = &buf->base;
+ return PIPE_OK;
+
+err:
+ FREE(buf);
+ return PIPE_ERROR_OUT_OF_MEMORY;
+}
+
+static enum pipe_error
+i965_libdrm_bo_get_handle(struct brw_winsys_buffer *buffer,
+ struct winsys_handle *whandle,
+ unsigned stride)
+{
+ struct i965_libdrm_buffer *buf = i965_libdrm_buffer(buffer);
+
+ if (BRW_DUMP)
+ debug_printf("%s\n", __FUNCTION__);
+
+ if (whandle->type == DRM_API_HANDLE_TYPE_SHARED) {
+ if (!buf->flinked) {
+ if (drm_intel_bo_flink(buf->bo, &buf->flink))
+ return PIPE_ERROR_BAD_INPUT;
+ buf->flinked = TRUE;
+ }
+
+ whandle->handle = buf->flink;
+ } else if (whandle->type == DRM_API_HANDLE_TYPE_KMS) {
+ whandle->handle = buf->bo->handle;
+ } else {
+ assert(!"unknown usage");
+ return PIPE_ERROR_BAD_INPUT;
+ }
+
+ whandle->stride = stride;
+ return PIPE_OK;
+}
+
+static void
+i965_libdrm_bo_destroy(struct brw_winsys_buffer *buffer)
+{
+ struct i965_libdrm_buffer *buf = i965_libdrm_buffer(buffer);
+
+ if (BRW_DUMP)
+ debug_printf("%s\n", __FUNCTION__);
+
+ drm_intel_bo_unreference(buf->bo);
+ FREE(buffer);
+}
+
+static enum pipe_error
+i965_libdrm_bo_emit_reloc(struct brw_winsys_buffer *buffer,
+ enum brw_buffer_usage usage,
+ unsigned delta,
+ unsigned offset,
+ struct brw_winsys_buffer *buffer2)
+{
+ struct i965_libdrm_buffer *buf = i965_libdrm_buffer(buffer);
+ struct i965_libdrm_buffer *buf2 = i965_libdrm_buffer(buffer2);
+ int read, write;
+ int ret;
+
+ if (BRW_DUMP)
+ debug_printf("%s buf %p offset %x delta %x buf2 %p/%s/%s\n",
+ __FUNCTION__, (void *)buffer,
+ offset, delta,
+ (void *)buffer2, names[buf2->data_type], usages[usage]);
+
+ switch (usage) {
+ case BRW_USAGE_STATE:
+ read = I915_GEM_DOMAIN_INSTRUCTION;
+ write = 0;
+ break;
+ case BRW_USAGE_QUERY_RESULT:
+ read = I915_GEM_DOMAIN_INSTRUCTION;
+ write = I915_GEM_DOMAIN_INSTRUCTION;
+ break;
+ case BRW_USAGE_RENDER_TARGET:
+ read = I915_GEM_DOMAIN_RENDER;
+ write = 0;
+ break;
+ case BRW_USAGE_DEPTH_BUFFER:
+ read = I915_GEM_DOMAIN_RENDER;
+ write = I915_GEM_DOMAIN_RENDER;
+ break;
+ case BRW_USAGE_BLIT_SOURCE:
+ read = 0;
+ write = I915_GEM_DOMAIN_RENDER;
+ break;
+ case BRW_USAGE_BLIT_DEST:
+ read = I915_GEM_DOMAIN_RENDER;
+ write = I915_GEM_DOMAIN_RENDER;
+ break;
+ case BRW_USAGE_SAMPLER:
+ read = I915_GEM_DOMAIN_SAMPLER;
+ write = 0;
+ break;
+ case BRW_USAGE_VERTEX:
+ read = I915_GEM_DOMAIN_VERTEX;
+ write = 0;
+ break;
+ case BRW_USAGE_SCRATCH:
+ read = 0;
+ write = 0;
+ break;
+ default:
+ assert(0);
+ return -1;
+ }
+
+ /* Needed??
+ ((uint32_t *)buf->bo->virtual)[offset/4] = (delta +
+ buf2->bo->offset);
+ */
+
+ ret = dri_bo_emit_reloc( buf->bo, read, write, delta, offset, buf2->bo );
+ if (ret)
+ return -1;
+
+ return 0;
+}
+
+static enum pipe_error
+i965_libdrm_bo_exec(struct brw_winsys_buffer *buffer,
+ unsigned bytes_used)
+{
+ struct i965_libdrm_buffer *buf = i965_libdrm_buffer(buffer);
+ struct i965_libdrm_winsys *idws = i965_libdrm_winsys(buffer->sws);
+ int ret;
+
+ if (BRW_DUMP)
+ debug_printf("execute buffer %p, bytes %d\n", (void *)buffer, bytes_used);
+
+ if (idws->send_cmd) {
+ ret = dri_bo_exec(buf->bo, bytes_used, NULL, 0, 0);
+ if (ret)
+ return PIPE_ERROR;
+ }
+
+ return PIPE_OK;
+}
+
+static enum pipe_error
+i965_libdrm_bo_subdata(struct brw_winsys_buffer *buffer,
+ enum brw_buffer_data_type data_type,
+ size_t offset,
+ size_t size,
+ const void *data,
+ const struct brw_winsys_reloc *reloc,
+ unsigned nr_reloc)
+{
+ struct i965_libdrm_buffer *buf = i965_libdrm_buffer(buffer);
+ struct i965_libdrm_winsys *idws = i965_libdrm_winsys(buffer->sws);
+ int ret, i;
+
+ (void)data_type;
+
+ if (BRW_DUMP)
+ debug_printf("%s buf %p off %d sz %d %s relocs: %d\n",
+ __FUNCTION__,
+ (void *)buffer, offset, size,
+ data_types[data_type],
+ nr_reloc);
+
+ if (BRW_DUMP)
+ brw_dump_data( idws->id,
+ data_type,
+ buf->bo->offset + offset,
+ data, size );
+
+ /* XXX: use bo_map_gtt/memcpy/unmap_gtt under some circumstances???
+ */
+ ret = drm_intel_bo_subdata(buf->bo, offset, size, (void*)data);
+ if (ret)
+ return PIPE_ERROR;
+
+ for (i = 0; i < nr_reloc; i++) {
+ i965_libdrm_bo_emit_reloc(buffer, reloc[i].usage, reloc[i].delta,
+ reloc[i].offset, reloc[i].bo);
+ }
+
+ return PIPE_OK;
+}
+
+static boolean
+i965_libdrm_bo_is_busy(struct brw_winsys_buffer *buffer)
+{
+ struct i965_libdrm_buffer *buf = i965_libdrm_buffer(buffer);
+ boolean ret;
+
+ if (BRW_DUMP)
+ debug_printf("%s %p\n", __FUNCTION__, (void *)buffer);
+
+ ret = drm_intel_bo_busy(buf->bo);
+
+ if (BRW_DUMP)
+ debug_printf(" --> %d\n", ret);
+
+ return ret;
+}
+
+static boolean
+i965_libdrm_bo_references(struct brw_winsys_buffer *a,
+ struct brw_winsys_buffer *b)
+{
+ struct i965_libdrm_buffer *bufa = i965_libdrm_buffer(a);
+ struct i965_libdrm_buffer *bufb = i965_libdrm_buffer(b);
+ boolean ret;
+
+ if (BRW_DUMP)
+ debug_printf("%s %p %p\n", __FUNCTION__, (void *)a, (void *)b);
+
+ ret = drm_intel_bo_references(bufa->bo, bufb->bo);
+
+ if (BRW_DUMP)
+ debug_printf(" --> %d\n", ret);
+
+ return ret;
+}
+
+/* XXX: couldn't this be handled by returning true/false on
+ * bo_emit_reloc?
+ */
+static enum pipe_error
+i965_libdrm_check_aperture_space(struct brw_winsys_screen *iws,
+ struct brw_winsys_buffer **buffers,
+ unsigned count)
+{
+ static drm_intel_bo *bos[128];
+ int i;
+ int ret;
+
+ if (BRW_DUMP)
+ debug_printf("%s\n", __FUNCTION__);
+
+ if (count > Elements(bos)) {
+ assert(0);
+ return FALSE;
+ }
+
+ for (i = 0; i < count; i++)
+ bos[i] = i965_libdrm_buffer(buffers[i])->bo;
+
+ /* XXX: converting from ??? to pipe_error:
+ */
+ ret = dri_bufmgr_check_aperture_space(bos, count);
+
+ if (BRW_DUMP)
+ debug_printf(" --> %d (ok == %d)\n", ret, PIPE_OK);
+
+ return ret;
+}
+
+static void *
+i965_libdrm_bo_map(struct brw_winsys_buffer *buffer,
+ enum brw_buffer_data_type data_type,
+ unsigned offset,
+ unsigned length,
+ boolean write,
+ boolean discard,
+ boolean flush_explicit)
+{
+ struct i965_libdrm_buffer *buf = i965_libdrm_buffer(buffer);
+ int ret;
+
+
+ if (BRW_DUMP)
+ debug_printf("%s %p %s %s\n", __FUNCTION__, (void *)buffer,
+ write ? "read/write" : "read",
+ write ? data_types[data_type] : "");
+
+ if (!buf->map_count) {
+ if (buf->map_gtt) {
+ ret = drm_intel_gem_bo_map_gtt(buf->bo);
+ if (ret)
+ return NULL;
+ }
+ else {
+ ret = drm_intel_bo_map(buf->bo, write);
+ if (ret)
+ return NULL;
+ }
+ }
+
+ buf->data_type = data_type;
+ buf->map_count++;
+ return buf->bo->virtual;
+}
+
+static void
+i965_libdrm_bo_flush_range(struct brw_winsys_buffer *buffer,
+ unsigned offset,
+ unsigned length)
+{
+ struct i965_libdrm_buffer *buf = i965_libdrm_buffer(buffer);
+ struct i965_libdrm_winsys *idws = i965_libdrm_winsys(buffer->sws);
+
+ if (BRW_DUMP)
+ debug_printf("%s %s offset %d len %d\n", __FUNCTION__,
+ data_types[buf->data_type],
+ offset, length);
+
+ if (BRW_DUMP)
+ brw_dump_data( idws->id,
+ buf->data_type,
+ buf->bo->offset + offset,
+ (char*)buf->bo->virtual + offset,
+ length );
+}
+
+static void
+i965_libdrm_bo_unmap(struct brw_winsys_buffer *buffer)
+{
+ struct i965_libdrm_buffer *buf = i965_libdrm_buffer(buffer);
+
+ if (BRW_DUMP)
+ debug_printf("%s\n", __FUNCTION__);
+
+ if (--buf->map_count > 0)
+ return;
+
+ if (buf->map_gtt)
+ drm_intel_gem_bo_unmap_gtt(buf->bo);
+ else
+ drm_intel_bo_unmap(buf->bo);
+}
+
+void
+i965_libdrm_winsys_init_buffer_functions(struct i965_libdrm_winsys *idws)
+{
+ idws->base.bo_alloc = i965_libdrm_bo_alloc;
+ idws->base.bo_from_handle = i965_libdrm_bo_from_handle;
+ idws->base.bo_get_handle = i965_libdrm_bo_get_handle;
+ idws->base.bo_destroy = i965_libdrm_bo_destroy;
+ idws->base.bo_emit_reloc = i965_libdrm_bo_emit_reloc;
+ idws->base.bo_exec = i965_libdrm_bo_exec;
+ idws->base.bo_subdata = i965_libdrm_bo_subdata;
+ idws->base.bo_is_busy = i965_libdrm_bo_is_busy;
+ idws->base.bo_references = i965_libdrm_bo_references;
+ idws->base.check_aperture_space = i965_libdrm_check_aperture_space;
+ idws->base.bo_map = i965_libdrm_bo_map;
+ idws->base.bo_flush_range = i965_libdrm_bo_flush_range;
+ idws->base.bo_unmap = i965_libdrm_bo_unmap;
+}
diff --git a/src/gallium/winsys/i965/drm/i965_drm_winsys.h b/src/gallium/winsys/i965/drm/i965_drm_winsys.h
new file mode 100644
index 0000000000..c6a7d4a8c5
--- /dev/null
+++ b/src/gallium/winsys/i965/drm/i965_drm_winsys.h
@@ -0,0 +1,64 @@
+
+#ifndef INTEL_DRM_WINSYS_H
+#define INTEL_DRM_WINSYS_H
+
+#include "i965/brw_winsys.h"
+
+#include "drm.h"
+#include "intel_bufmgr.h"
+
+
+
+/*
+ * Winsys
+ */
+
+
+struct i965_libdrm_winsys
+{
+ struct brw_winsys_screen base;
+ drm_intel_bufmgr *gem;
+
+ boolean send_cmd;
+
+ int fd; /**< Drm file discriptor */
+
+ unsigned id;
+};
+
+static INLINE struct i965_libdrm_winsys *
+i965_libdrm_winsys(struct brw_winsys_screen *iws)
+{
+ return (struct i965_libdrm_winsys *)iws;
+}
+
+struct i965_libdrm_winsys *i965_libdrm_winsys_create(int fd, unsigned pci_id);
+
+void i965_libdrm_winsys_init_buffer_functions(struct i965_libdrm_winsys *idws);
+
+
+/* Buffer.
+ */
+struct i965_libdrm_buffer {
+ struct brw_winsys_buffer base;
+
+ drm_intel_bo *bo;
+
+ void *ptr;
+ unsigned map_count;
+ unsigned data_type; /* valid while mapped */
+ unsigned tiling;
+
+ boolean map_gtt;
+ boolean flinked;
+ unsigned flink;
+};
+
+static INLINE struct i965_libdrm_buffer *
+i965_libdrm_buffer(struct brw_winsys_buffer *buffer)
+{
+ return (struct i965_libdrm_buffer *)buffer;
+}
+
+
+#endif
diff --git a/src/gallium/winsys/i965/xlib/Makefile b/src/gallium/winsys/i965/xlib/Makefile
new file mode 100644
index 0000000000..cc8249395c
--- /dev/null
+++ b/src/gallium/winsys/i965/xlib/Makefile
@@ -0,0 +1,97 @@
+# src/gallium/winsys/i965/xlib/Makefile
+
+# This makefile produces a "stand-alone" libGL.so which is based on
+# Xlib (no DRI HW acceleration)
+
+
+TOP = ../../../../..
+include $(TOP)/configs/current
+
+
+GL_MAJOR = 1
+GL_MINOR = 5
+GL_TINY = 0$(MESA_MAJOR)0$(MESA_MINOR)0$(MESA_TINY)
+
+
+INCLUDE_DIRS = \
+ -I$(TOP)/include \
+ -I$(TOP)/src/mesa \
+ -I$(TOP)/src/mesa/main \
+ -I$(TOP)/src/gallium/include \
+ -I$(TOP)/src/gallium/drivers \
+ -I$(TOP)/src/gallium/drivers/i965 \
+ -I$(TOP)/src/gallium/drivers/i965/include \
+ -I$(TOP)/src/gallium/state_trackers/glx/xlib \
+ -I$(TOP)/src/gallium/auxiliary \
+ -I/usr/include/drm
+
+XLIB_WINSYS_SOURCES = \
+ xlib_i965.c \
+
+
+
+XLIB_WINSYS_OBJECTS = $(XLIB_WINSYS_SOURCES:.c=.o)
+
+
+
+LIBS = \
+ $(TOP)/src/gallium/drivers/i965/libi965.a \
+ $(TOP)/src/gallium/drivers/trace/libtrace.a \
+ $(TOP)/src/gallium/state_trackers/glx/xlib/libxlib.a \
+ $(TOP)/src/mapi/glapi/libglapi.a \
+ $(TOP)/src/mesa/libmesagallium.a \
+ $(GALLIUM_AUXILIARIES)
+
+# $(TOP)/src/gallium/drivers/i965/lib/libi9xx.a \
+
+.SUFFIXES : .cpp
+
+.c.o:
+ $(CC) -c $(INCLUDE_DIRS) $(DEFINES) $(CFLAGS) $< -o $@
+
+.cpp.o:
+ $(CXX) -c $(INCLUDE_DIRS) $(DEFINES) $(CXXFLAGS) $< -o $@
+
+
+
+default: $(TOP)/$(LIB_DIR)/gallium $(TOP)/$(LIB_DIR)/gallium/$(GL_LIB_NAME)
+
+$(TOP)/$(LIB_DIR)/gallium:
+ @ mkdir -p $(TOP)/$(LIB_DIR)/gallium
+
+# Make the libGL.so library
+$(TOP)/$(LIB_DIR)/gallium/$(GL_LIB_NAME): $(XLIB_WINSYS_OBJECTS) $(LIBS) Makefile
+ $(TOP)/bin/mklib -o $(GL_LIB) \
+ -linker "$(CC)" \
+ -major $(GL_MAJOR) -minor $(GL_MINOR) -patch $(GL_TINY) \
+ -install $(TOP)/$(LIB_DIR)/gallium \
+ $(MKLIB_OPTIONS) $(XLIB_WINSYS_OBJECTS) \
+ -Wl,--start-group $(LIBS) -Wl,--end-group $(GL_LIB_DEPS)
+
+
+depend: $(XLIB_WINSYS_SOURCES)
+ @ echo "running $(MKDEP)"
+ @ rm -f depend # workaround oops on gutsy?!?
+ @ touch depend
+ $(MKDEP) $(MKDEP_OPTIONS) $(DEFINES) $(INCLUDE_DIRS) $(XLIB_WINSYS_SOURCES) \
+ > /dev/null 2>/dev/null
+
+
+install: default
+ $(INSTALL) -d $(INSTALL_DIR)/include/GL
+ $(INSTALL) -d $(INSTALL_DIR)/$(LIB_DIR)
+ $(INSTALL) -m 644 $(TOP)/include/GL/*.h $(INSTALL_DIR)/include/GL
+ @if [ -e $(TOP)/$(LIB_DIR)/$(GL_LIB_NAME) ]; then \
+ $(MINSTALL) $(TOP)/$(LIB_DIR)/libGL* $(INSTALL_DIR)/$(LIB_DIR); \
+ fi
+
+
+# Emacs tags
+tags:
+ etags `find . -name \*.[ch]` $(TOP)/include/GL/*.h
+
+clean:
+ -rm -f *.o
+
+
+include depend
diff --git a/src/gallium/winsys/i965/xlib/xlib_i965.c b/src/gallium/winsys/i965/xlib/xlib_i965.c
new file mode 100644
index 0000000000..063e9f600b
--- /dev/null
+++ b/src/gallium/winsys/i965/xlib/xlib_i965.c
@@ -0,0 +1,503 @@
+/**************************************************************************
+ *
+ * Copyright 2007 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:
+ * Keith Whitwell
+ * Brian Paul
+ */
+
+
+#include "util/u_memory.h"
+#include "util/u_math.h"
+#include "pipe/p_error.h"
+#include "pipe/p_context.h"
+
+#include "xm_public.h"
+
+#include "i965/brw_winsys.h"
+#include "i965/brw_screen.h"
+#include "i965/brw_reg.h"
+#include "i965/brw_structs_dump.h"
+
+#define MAX_VRAM (128*1024*1024)
+
+
+
+extern int brw_disasm (FILE *file,
+ const struct brw_instruction *inst,
+ unsigned count );
+
+extern int intel_decode(const uint32_t *data,
+ int count,
+ uint32_t hw_offset,
+ uint32_t devid);
+
+struct xlib_brw_buffer
+{
+ struct brw_winsys_buffer base;
+ char *virtual;
+ unsigned offset;
+ unsigned type;
+ int map_count;
+ boolean modified;
+};
+
+
+/**
+ * Subclass of brw_winsys_screen for Xlib winsys
+ */
+struct xlib_brw_winsys
+{
+ struct brw_winsys_screen base;
+ struct brw_chipset chipset;
+
+ unsigned size;
+ unsigned used;
+};
+
+static struct xlib_brw_winsys *
+xlib_brw_winsys( struct brw_winsys_screen *screen )
+{
+ return (struct xlib_brw_winsys *)screen;
+}
+
+
+static struct xlib_brw_buffer *
+xlib_brw_buffer( struct brw_winsys_buffer *buffer )
+{
+ return (struct xlib_brw_buffer *)buffer;
+}
+
+
+
+const char *names[BRW_BUFFER_TYPE_MAX] = {
+ "TEXTURE",
+ "SCANOUT",
+ "VERTEX",
+ "CURBE",
+ "QUERY",
+ "SHADER_CONSTANTS",
+ "WM_SCRATCH",
+ "BATCH",
+ "GENERAL_STATE",
+ "SURFACE_STATE",
+ "PIXEL",
+ "GENERIC",
+};
+
+const char *usages[BRW_USAGE_MAX] = {
+ "STATE",
+ "QUERY_RESULT",
+ "RENDER_TARGET",
+ "DEPTH_BUFFER",
+ "BLIT_SOURCE",
+ "BLIT_DEST",
+ "SAMPLER",
+ "VERTEX",
+ "SCRATCH"
+};
+
+
+const char *data_types[BRW_DATA_MAX] =
+{
+ "GS: CC_VP",
+ "GS: CC_UNIT",
+ "GS: WM_PROG",
+ "GS: SAMPLER_DEFAULT_COLOR",
+ "GS: SAMPLER",
+ "GS: WM_UNIT",
+ "GS: SF_PROG",
+ "GS: SF_VP",
+ "GS: SF_UNIT",
+ "GS: VS_UNIT",
+ "GS: VS_PROG",
+ "GS: GS_UNIT",
+ "GS: GS_PROG",
+ "GS: CLIP_VP",
+ "GS: CLIP_UNIT",
+ "GS: CLIP_PROG",
+ "SS: SURFACE",
+ "SS: SURF_BIND",
+ "CONSTANT DATA",
+ "BATCH DATA",
+ "(untyped)"
+};
+
+
+static enum pipe_error
+xlib_brw_bo_alloc( struct brw_winsys_screen *sws,
+ enum brw_buffer_type type,
+ unsigned size,
+ unsigned alignment,
+ struct brw_winsys_buffer **bo_out )
+{
+ struct xlib_brw_winsys *xbw = xlib_brw_winsys(sws);
+ struct xlib_brw_buffer *buf;
+
+ if (BRW_DEBUG & DEBUG_WINSYS)
+ debug_printf("%s type %s sz %d align %d\n",
+ __FUNCTION__, names[type], size, alignment );
+
+ buf = CALLOC_STRUCT(xlib_brw_buffer);
+ if (!buf)
+ return PIPE_ERROR_OUT_OF_MEMORY;
+
+ pipe_reference_init(&buf->base.reference, 1);
+
+ buf->offset = align(xbw->used, alignment);
+ buf->type = type;
+ buf->virtual = MALLOC(size);
+ buf->base.size = size;
+ buf->base.sws = sws;
+
+ xbw->used = align(xbw->used, alignment) + size;
+ if (xbw->used > MAX_VRAM)
+ goto err;
+
+ /* XXX: possibly rentrant call to bo_destroy:
+ */
+ bo_reference(bo_out, &buf->base);
+ return PIPE_OK;
+
+err:
+ assert(0);
+ FREE(buf->virtual);
+ FREE(buf);
+ return PIPE_ERROR_OUT_OF_MEMORY;
+}
+
+static void
+xlib_brw_bo_destroy( struct brw_winsys_buffer *buffer )
+{
+ struct xlib_brw_buffer *buf = xlib_brw_buffer(buffer);
+
+ FREE(buf);
+}
+
+static int
+xlib_brw_bo_emit_reloc( struct brw_winsys_buffer *buffer,
+ enum brw_buffer_usage usage,
+ unsigned delta,
+ unsigned offset,
+ struct brw_winsys_buffer *buffer2)
+{
+ struct xlib_brw_buffer *buf = xlib_brw_buffer(buffer);
+ struct xlib_brw_buffer *buf2 = xlib_brw_buffer(buffer2);
+
+ if (BRW_DEBUG & DEBUG_WINSYS)
+ debug_printf("%s buf %p offset %x val %x + %x buf2 %p/%s/%s\n",
+ __FUNCTION__, (void *)buffer, offset,
+ buf2->offset, delta,
+ (void *)buffer2, names[buf2->type], usages[usage]);
+
+ *(uint32_t *)(buf->virtual + offset) = buf2->offset + delta;
+
+ return 0;
+}
+
+static int
+xlib_brw_bo_exec( struct brw_winsys_buffer *buffer,
+ unsigned bytes_used )
+{
+ if (BRW_DEBUG & DEBUG_WINSYS)
+ debug_printf("execute buffer %p, bytes %d\n", (void *)buffer, bytes_used);
+
+ return 0;
+}
+
+
+
+
+static int
+xlib_brw_bo_subdata(struct brw_winsys_buffer *buffer,
+ enum brw_buffer_data_type data_type,
+ size_t offset,
+ size_t size,
+ const void *data,
+ const struct brw_winsys_reloc *reloc,
+ unsigned nr_relocs)
+{
+ struct xlib_brw_buffer *buf = xlib_brw_buffer(buffer);
+ struct xlib_brw_winsys *xbw = xlib_brw_winsys(buffer->sws);
+ unsigned i;
+
+ if (BRW_DEBUG & DEBUG_WINSYS)
+ debug_printf("%s buf %p off %d sz %d %s relocs: %d\n",
+ __FUNCTION__,
+ (void *)buffer, offset, size,
+ data_types[data_type],
+ nr_relocs);
+
+ assert(buf->base.size >= offset + size);
+ memcpy(buf->virtual + offset, data, size);
+
+ /* Apply the relocations:
+ */
+ for (i = 0; i < nr_relocs; i++) {
+ if (BRW_DEBUG & DEBUG_WINSYS)
+ debug_printf("\treloc[%d] usage %s off %d value %x+%x\n",
+ i, usages[reloc[i].usage], reloc[i].offset,
+ xlib_brw_buffer(reloc[i].bo)->offset, reloc[i].delta);
+
+ *(unsigned *)(buf->virtual + offset + reloc[i].offset) =
+ xlib_brw_buffer(reloc[i].bo)->offset + reloc[i].delta;
+ }
+
+ if (BRW_DUMP)
+ brw_dump_data( xbw->chipset.pci_id,
+ data_type,
+ buf->offset + offset,
+ buf->virtual + offset, size );
+
+
+ return 0;
+}
+
+
+static boolean
+xlib_brw_bo_is_busy(struct brw_winsys_buffer *buffer)
+{
+ if (BRW_DEBUG & DEBUG_WINSYS)
+ debug_printf("%s %p\n", __FUNCTION__, (void *)buffer);
+ return TRUE;
+}
+
+static boolean
+xlib_brw_bo_references(struct brw_winsys_buffer *a,
+ struct brw_winsys_buffer *b)
+{
+ if (BRW_DEBUG & DEBUG_WINSYS)
+ debug_printf("%s %p %p\n", __FUNCTION__, (void *)a, (void *)b);
+ return TRUE;
+}
+
+static enum pipe_error
+xlib_brw_check_aperture_space( struct brw_winsys_screen *iws,
+ struct brw_winsys_buffer **buffers,
+ unsigned count )
+{
+ unsigned tot_size = 0;
+ unsigned i;
+
+ for (i = 0; i < count; i++)
+ tot_size += buffers[i]->size;
+
+ if (BRW_DEBUG & DEBUG_WINSYS)
+ debug_printf("%s %d bufs, tot_size: %d kb\n",
+ __FUNCTION__, count,
+ (tot_size + 1023) / 1024);
+
+ return PIPE_OK;
+}
+
+static void *
+xlib_brw_bo_map(struct brw_winsys_buffer *buffer,
+ enum brw_buffer_data_type data_type,
+ unsigned offset,
+ unsigned length,
+ boolean write,
+ boolean discard,
+ boolean explicit)
+{
+ struct xlib_brw_buffer *buf = xlib_brw_buffer(buffer);
+
+ if (BRW_DEBUG & DEBUG_WINSYS)
+ debug_printf("%s %p %s %s\n", __FUNCTION__, (void *)buffer,
+ write ? "read/write" : "read",
+ write ? data_types[data_type] : "");
+
+ if (write)
+ buf->modified = 1;
+
+ buf->map_count++;
+ return buf->virtual;
+}
+
+
+static void
+xlib_brw_bo_flush_range( struct brw_winsys_buffer *buffer,
+ unsigned offset,
+ unsigned length )
+{
+}
+
+
+static void
+xlib_brw_bo_unmap(struct brw_winsys_buffer *buffer)
+{
+ struct xlib_brw_buffer *buf = xlib_brw_buffer(buffer);
+
+ if (BRW_DEBUG & DEBUG_WINSYS)
+ debug_printf("%s %p\n", __FUNCTION__, (void *)buffer);
+
+ --buf->map_count;
+ assert(buf->map_count >= 0);
+
+ if (buf->map_count == 0 &&
+ buf->modified) {
+
+ buf->modified = 0;
+
+ /* Consider dumping new buffer contents here, using the
+ * flush-range info to minimize verbosity.
+ */
+ }
+}
+
+
+static void
+xlib_brw_bo_wait_idle( struct brw_winsys_buffer *buffer )
+{
+}
+
+
+static void
+xlib_brw_winsys_destroy( struct brw_winsys_screen *sws )
+{
+ struct xlib_brw_winsys *xbw = xlib_brw_winsys(sws);
+
+ FREE(xbw);
+}
+
+static struct brw_winsys_screen *
+xlib_create_brw_winsys_screen( void )
+{
+ struct xlib_brw_winsys *ws;
+
+ ws = CALLOC_STRUCT(xlib_brw_winsys);
+ if (!ws)
+ return NULL;
+
+ ws->used = 0;
+
+ ws->base.destroy = xlib_brw_winsys_destroy;
+ ws->base.bo_alloc = xlib_brw_bo_alloc;
+ ws->base.bo_destroy = xlib_brw_bo_destroy;
+ ws->base.bo_emit_reloc = xlib_brw_bo_emit_reloc;
+ ws->base.bo_exec = xlib_brw_bo_exec;
+ ws->base.bo_subdata = xlib_brw_bo_subdata;
+ ws->base.bo_is_busy = xlib_brw_bo_is_busy;
+ ws->base.bo_references = xlib_brw_bo_references;
+ ws->base.check_aperture_space = xlib_brw_check_aperture_space;
+ ws->base.bo_map = xlib_brw_bo_map;
+ ws->base.bo_flush_range = xlib_brw_bo_flush_range;
+ ws->base.bo_unmap = xlib_brw_bo_unmap;
+ ws->base.bo_wait_idle = xlib_brw_bo_wait_idle;
+
+ return &ws->base;
+}
+
+
+/***********************************************************************
+ * Implementation of Xlib co-state-tracker's winsys interface
+ */
+
+static void
+xlib_i965_display_surface(struct xmesa_buffer *xm_buffer,
+ struct pipe_surface *surf)
+{
+ struct brw_surface *surface = brw_surface(surf);
+ struct xlib_brw_buffer *bo = xlib_brw_buffer(surface->bo);
+
+ if (BRW_DEBUG & DEBUG_WINSYS)
+ debug_printf("%s offset %x+%x sz %dx%d\n", __FUNCTION__,
+ bo->offset,
+ surface->draw_offset,
+ surf->width,
+ surf->height);
+}
+
+static void
+xlib_i965_flush_frontbuffer(struct pipe_screen *screen,
+ struct pipe_surface *surf,
+ void *context_private)
+{
+ xlib_i965_display_surface(NULL, surf);
+}
+
+
+static struct pipe_screen *
+xlib_create_i965_screen( void )
+{
+ struct brw_winsys_screen *winsys;
+ struct pipe_screen *screen;
+
+ winsys = xlib_create_brw_winsys_screen();
+ if (winsys == NULL)
+ return NULL;
+
+ screen = brw_create_screen(winsys, PCI_CHIP_GM45_GM);
+ if (screen == NULL)
+ goto fail;
+
+ xlib_brw_winsys(winsys)->chipset = brw_screen(screen)->chipset;
+
+ screen->flush_frontbuffer = xlib_i965_flush_frontbuffer;
+ return screen;
+
+fail:
+ if (winsys)
+ winsys->destroy( winsys );
+
+ return NULL;
+}
+
+
+
+
+
+struct xm_driver xlib_i965_driver =
+{
+ .create_pipe_screen = xlib_create_i965_screen,
+ .display_surface = xlib_i965_display_surface
+};
+
+
+/* Register this driver at library load:
+ */
+static void _init( void ) __attribute__((constructor));
+static void _init( void )
+{
+ xmesa_set_driver( &xlib_i965_driver );
+}
+
+
+
+/***********************************************************************
+ *
+ * Butt-ugly hack to convince the linker not to throw away public GL
+ * symbols (they are all referenced from getprocaddress, I guess).
+ */
+extern void (*linker_foo(const unsigned char *procName))();
+extern void (*glXGetProcAddress(const unsigned char *procName))();
+
+extern void (*linker_foo(const unsigned char *procName))()
+{
+ return glXGetProcAddress(procName);
+}
diff --git a/src/gallium/winsys/nouveau/drm/Makefile b/src/gallium/winsys/nouveau/drm/Makefile
new file mode 100644
index 0000000000..71029858f7
--- /dev/null
+++ b/src/gallium/winsys/nouveau/drm/Makefile
@@ -0,0 +1,11 @@
+TOP = ../../../../..
+include $(TOP)/configs/current
+
+LIBNAME = nouveaudrm
+
+C_SOURCES = nouveau_drm_api.c
+
+LIBRARY_INCLUDES = $(shell pkg-config libdrm libdrm_nouveau --cflags-only-I)
+LIBRARY_DEFINES = $(shell pkg-config libdrm libdrm_nouveau --cflags-only-other)
+
+include ../../../Makefile.template
diff --git a/src/gallium/winsys/nouveau/drm/nouveau_dri.h b/src/gallium/winsys/nouveau/drm/nouveau_dri.h
new file mode 100644
index 0000000000..1207c2d609
--- /dev/null
+++ b/src/gallium/winsys/nouveau/drm/nouveau_dri.h
@@ -0,0 +1,28 @@
+#ifndef _NOUVEAU_DRI_
+#define _NOUVEAU_DRI_
+
+#include "xf86drm.h"
+#include "drm.h"
+#include "nouveau_drm.h"
+
+struct nouveau_dri {
+ uint32_t device_id; /**< \brief PCI device ID */
+ uint32_t width; /**< \brief width in pixels of display */
+ uint32_t height; /**< \brief height in scanlines of display */
+ uint32_t depth; /**< \brief depth of display (8, 15, 16, 24) */
+ uint32_t bpp; /**< \brief bit depth of display (8, 16, 24, 32) */
+
+ uint32_t bus_type; /**< \brief ths bus type */
+ uint32_t bus_mode; /**< \brief bus mode (used for AGP, maybe also for PCI-E ?) */
+
+ uint32_t front_offset; /**< \brief front buffer offset */
+ uint32_t front_pitch; /**< \brief front buffer pitch */
+ uint32_t back_offset; /**< \brief private back buffer offset */
+ uint32_t back_pitch; /**< \brief private back buffer pitch */
+ uint32_t depth_offset; /**< \brief private depth buffer offset */
+ uint32_t depth_pitch; /**< \brief private depth buffer pitch */
+
+};
+
+#endif
+
diff --git a/src/gallium/winsys/nouveau/drm/nouveau_drm_api.c b/src/gallium/winsys/nouveau/drm/nouveau_drm_api.c
new file mode 100644
index 0000000000..2f24431462
--- /dev/null
+++ b/src/gallium/winsys/nouveau/drm/nouveau_drm_api.c
@@ -0,0 +1,85 @@
+#include "pipe/p_context.h"
+#include "pipe/p_state.h"
+#include "util/u_format.h"
+#include "util/u_memory.h"
+#include "util/u_inlines.h"
+
+#include "nouveau_drm_api.h"
+
+#include "nouveau_drmif.h"
+#include "nouveau_channel.h"
+#include "nouveau_bo.h"
+
+#include "nouveau/nouveau_winsys.h"
+#include "nouveau/nouveau_screen.h"
+
+static void
+nouveau_drm_destroy_winsys(struct pipe_winsys *s)
+{
+ struct nouveau_winsys *nv_winsys = nouveau_winsys(s);
+ struct nouveau_screen *nv_screen= nouveau_screen(nv_winsys->pscreen);
+ nouveau_device_close(&nv_screen->device);
+ FREE(nv_winsys);
+}
+
+static struct pipe_screen *
+nouveau_drm_create_screen(struct drm_api *api, int fd)
+{
+ struct nouveau_winsys *nvws;
+ struct pipe_winsys *ws;
+ struct nouveau_device *dev = NULL;
+ struct pipe_screen *(*init)(struct pipe_winsys *,
+ struct nouveau_device *);
+ int ret;
+
+ ret = nouveau_device_open_existing(&dev, 0, fd, 0);
+ if (ret)
+ return NULL;
+
+ switch (dev->chipset & 0xf0) {
+ case 0x30:
+ case 0x40:
+ case 0x60:
+ init = nvfx_screen_create;
+ break;
+ case 0x50:
+ case 0x80:
+ case 0x90:
+ case 0xa0:
+ init = nv50_screen_create;
+ break;
+ default:
+ debug_printf("%s: unknown chipset nv%02x\n", __func__,
+ dev->chipset);
+ return NULL;
+ }
+
+ nvws = CALLOC_STRUCT(nouveau_winsys);
+ if (!nvws) {
+ nouveau_device_close(&dev);
+ return NULL;
+ }
+ ws = &nvws->base;
+ ws->destroy = nouveau_drm_destroy_winsys;
+
+ nvws->pscreen = init(ws, dev);
+ if (!nvws->pscreen) {
+ ws->destroy(ws);
+ return NULL;
+ }
+
+ return nvws->pscreen;
+}
+
+static struct drm_api nouveau_drm_api_hooks = {
+ .name = "nouveau",
+ .driver_name = "nouveau",
+ .create_screen = nouveau_drm_create_screen,
+ .destroy = NULL,
+};
+
+struct drm_api *
+drm_api_create() {
+ return &nouveau_drm_api_hooks;
+}
+
diff --git a/src/gallium/winsys/nouveau/drm/nouveau_drm_api.h b/src/gallium/winsys/nouveau/drm/nouveau_drm_api.h
new file mode 100644
index 0000000000..ba6305c17e
--- /dev/null
+++ b/src/gallium/winsys/nouveau/drm/nouveau_drm_api.h
@@ -0,0 +1,30 @@
+#ifndef __NOUVEAU_DRM_API_H__
+#define __NOUVEAU_DRM_API_H__
+
+#include "state_tracker/drm_api.h"
+
+#include "util/u_simple_screen.h"
+
+#include "nouveau_dri.h"
+
+struct nouveau_winsys {
+ struct pipe_winsys base;
+
+ struct pipe_screen *pscreen;
+
+ struct pipe_surface *front;
+};
+
+static INLINE struct nouveau_winsys *
+nouveau_winsys(struct pipe_winsys *ws)
+{
+ return (struct nouveau_winsys *)ws;
+}
+
+static INLINE struct nouveau_winsys *
+nouveau_winsys_screen(struct pipe_screen *pscreen)
+{
+ return nouveau_winsys(pscreen->winsys);
+}
+
+#endif
diff --git a/src/gallium/winsys/r600/drm/Makefile b/src/gallium/winsys/r600/drm/Makefile
new file mode 100644
index 0000000000..e3b943c4d4
--- /dev/null
+++ b/src/gallium/winsys/r600/drm/Makefile
@@ -0,0 +1,23 @@
+
+TOP = ../../../../..
+include $(TOP)/configs/current
+
+LIBNAME = r600winsys
+
+C_SOURCES = \
+ bof.c \
+ r600_state.c \
+ radeon_ctx.c \
+ radeon_draw.c \
+ radeon_state.c \
+ radeon_bo.c \
+ radeon_pciid.c \
+ radeon.c \
+ r600_drm.c
+
+LIBRARY_INCLUDES = -I$(TOP)/src/gallium/drivers/r600 \
+ $(shell pkg-config libdrm --cflags-only-I)
+
+include ../../../Makefile.template
+
+symlinks:
diff --git a/src/gallium/winsys/r600/drm/bof.c b/src/gallium/winsys/r600/drm/bof.c
new file mode 100644
index 0000000000..0598cc6bc0
--- /dev/null
+++ b/src/gallium/winsys/r600/drm/bof.c
@@ -0,0 +1,477 @@
+/*
+ * Copyright 2010 Jerome Glisse <glisse@freedesktop.org>
+ *
+ * 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
+ * on the rights to use, copy, modify, merge, publish, distribute, sub
+ * license, and/or sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * Jerome Glisse
+ */
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include "bof.h"
+
+/*
+ * helpers
+ */
+static int bof_entry_grow(bof_t *bof)
+{
+ bof_t **array;
+
+ if (bof->array_size < bof->nentry)
+ return 0;
+ array = realloc(bof->array, (bof->nentry + 16) * sizeof(void*));
+ if (array == NULL)
+ return -ENOMEM;
+ bof->array = array;
+ bof->nentry += 16;
+ return 0;
+}
+
+/*
+ * object
+ */
+bof_t *bof_object(void)
+{
+ bof_t *object;
+
+ object = calloc(1, sizeof(bof_t));
+ if (object == NULL)
+ return NULL;
+ object->refcount = 1;
+ object->type = BOF_TYPE_OBJECT;
+ object->size = 12;
+ return object;
+}
+
+bof_t *bof_object_get(bof_t *object, const char *keyname)
+{
+ unsigned i;
+
+ for (i = 0; i < object->array_size; i += 2) {
+ if (!strcmp(object->array[i]->value, keyname)) {
+ return object->array[i + 1];
+ }
+ }
+ return NULL;
+}
+
+int bof_object_set(bof_t *object, const char *keyname, bof_t *value)
+{
+ bof_t *key;
+ int r;
+
+ if (object->type != BOF_TYPE_OBJECT)
+ return -EINVAL;
+ r = bof_entry_grow(object);
+ if (r)
+ return r;
+ key = bof_string(keyname);
+ if (key == NULL)
+ return -ENOMEM;
+ object->array[object->array_size++] = key;
+ object->array[object->array_size++] = value;
+ object->size += value->size;
+ object->size += key->size;
+ bof_incref(value);
+ return 0;
+}
+
+/*
+ * array
+ */
+bof_t *bof_array(void)
+{
+ bof_t *array = bof_object();
+
+ if (array == NULL)
+ return NULL;
+ array->type = BOF_TYPE_ARRAY;
+ array->size = 12;
+ return array;
+}
+
+int bof_array_append(bof_t *array, bof_t *value)
+{
+ int r;
+ if (array->type != BOF_TYPE_ARRAY)
+ return -EINVAL;
+ r = bof_entry_grow(array);
+ if (r)
+ return r;
+ array->array[array->array_size++] = value;
+ array->size += value->size;
+ bof_incref(value);
+ return 0;
+}
+
+bof_t *bof_array_get(bof_t *bof, unsigned i)
+{
+ if (!bof_is_array(bof) || i >= bof->array_size)
+ return NULL;
+ return bof->array[i];
+}
+
+unsigned bof_array_size(bof_t *bof)
+{
+ if (!bof_is_array(bof))
+ return 0;
+ return bof->array_size;
+}
+
+/*
+ * blob
+ */
+bof_t *bof_blob(unsigned size, void *value)
+{
+ bof_t *blob = bof_object();
+
+ if (blob == NULL)
+ return NULL;
+ blob->type = BOF_TYPE_BLOB;
+ blob->value = calloc(1, size);
+ if (blob->value == NULL) {
+ bof_decref(blob);
+ return NULL;
+ }
+ blob->size = size;
+ memcpy(blob->value, value, size);
+ blob->size += 12;
+ return blob;
+}
+
+unsigned bof_blob_size(bof_t *bof)
+{
+ if (!bof_is_blob(bof))
+ return 0;
+ return bof->size - 12;
+}
+
+void *bof_blob_value(bof_t *bof)
+{
+ if (!bof_is_blob(bof))
+ return NULL;
+ return bof->value;
+}
+
+/*
+ * string
+ */
+bof_t *bof_string(const char *value)
+{
+ bof_t *string = bof_object();
+
+ if (string == NULL)
+ return NULL;
+ string->type = BOF_TYPE_STRING;
+ string->size = strlen(value) + 1;
+ string->value = calloc(1, string->size);
+ if (string->value == NULL) {
+ bof_decref(string);
+ return NULL;
+ }
+ strcpy(string->value, value);
+ string->size += 12;
+ return string;
+}
+
+/*
+ * int32
+ */
+bof_t *bof_int32(int32_t value)
+{
+ bof_t *int32 = bof_object();
+
+ if (int32 == NULL)
+ return NULL;
+ int32->type = BOF_TYPE_INT32;
+ int32->size = 4;
+ int32->value = calloc(1, int32->size);
+ if (int32->value == NULL) {
+ bof_decref(int32);
+ return NULL;
+ }
+ memcpy(int32->value, &value, 4);
+ int32->size += 12;
+ return int32;
+}
+
+int32_t bof_int32_value(bof_t *bof)
+{
+ return *((uint32_t*)bof->value);
+}
+
+/*
+ * common
+ */
+static void bof_indent(int level)
+{
+ int i;
+
+ for (i = 0; i < level; i++)
+ fprintf(stderr, " ");
+}
+
+static void bof_print_bof(bof_t *bof, int level, int entry)
+{
+ bof_indent(level);
+ if (bof == NULL) {
+ fprintf(stderr, "--NULL-- for entry %d\n", entry);
+ return;
+ }
+ switch (bof->type) {
+ case BOF_TYPE_STRING:
+ fprintf(stderr, "%p string [%s %d]\n", bof, (char*)bof->value, bof->size);
+ break;
+ case BOF_TYPE_INT32:
+ fprintf(stderr, "%p int32 [%d %d]\n", bof, *(int*)bof->value, bof->size);
+ break;
+ case BOF_TYPE_BLOB:
+ fprintf(stderr, "%p blob [%d]\n", bof, bof->size);
+ break;
+ case BOF_TYPE_NULL:
+ fprintf(stderr, "%p null [%d]\n", bof, bof->size);
+ break;
+ case BOF_TYPE_OBJECT:
+ fprintf(stderr, "%p object [%d %d]\n", bof, bof->array_size / 2, bof->size);
+ break;
+ case BOF_TYPE_ARRAY:
+ fprintf(stderr, "%p array [%d %d]\n", bof, bof->array_size, bof->size);
+ break;
+ default:
+ fprintf(stderr, "%p unknown [%d]\n", bof, bof->type);
+ return;
+ }
+}
+
+static void bof_print_rec(bof_t *bof, int level, int entry)
+{
+ unsigned i;
+
+ bof_print_bof(bof, level, entry);
+ for (i = 0; i < bof->array_size; i++) {
+ bof_print_rec(bof->array[i], level + 2, i);
+ }
+}
+
+void bof_print(bof_t *bof)
+{
+ bof_print_rec(bof, 0, 0);
+}
+
+static int bof_read(bof_t *root, FILE *file, long end, int level)
+{
+ bof_t *bof = NULL;
+ int r;
+
+ if (ftell(file) >= end) {
+ return 0;
+ }
+ r = bof_entry_grow(root);
+ if (r)
+ return r;
+ bof = bof_object();
+ if (bof == NULL)
+ return -ENOMEM;
+ bof->offset = ftell(file);
+ r = fread(&bof->type, 4, 1, file);
+ if (r != 1)
+ goto out_err;
+ r = fread(&bof->size, 4, 1, file);
+ if (r != 1)
+ goto out_err;
+ r = fread(&bof->array_size, 4, 1, file);
+ if (r != 1)
+ goto out_err;
+ switch (bof->type) {
+ case BOF_TYPE_STRING:
+ case BOF_TYPE_INT32:
+ case BOF_TYPE_BLOB:
+ bof->value = calloc(1, bof->size - 12);
+ if (bof->value == NULL) {
+ goto out_err;
+ }
+ r = fread(bof->value, bof->size - 12, 1, file);
+ if (r != 1) {
+ fprintf(stderr, "error reading %d\n", bof->size - 12);
+ goto out_err;
+ }
+ break;
+ case BOF_TYPE_NULL:
+ return 0;
+ case BOF_TYPE_OBJECT:
+ case BOF_TYPE_ARRAY:
+ r = bof_read(bof, file, bof->offset + bof->size, level + 2);
+ if (r)
+ goto out_err;
+ break;
+ default:
+ fprintf(stderr, "invalid type %d\n", bof->type);
+ goto out_err;
+ }
+ root->array[root->centry++] = bof;
+ return bof_read(root, file, end, level);
+out_err:
+ bof_decref(bof);
+ return -EINVAL;
+}
+
+bof_t *bof_load_file(const char *filename)
+{
+ bof_t *root = bof_object();
+ int r;
+
+ if (root == NULL) {
+ fprintf(stderr, "%s failed to create root object\n", __func__);
+ return NULL;
+ }
+ root->file = fopen(filename, "r");
+ if (root->file == NULL)
+ goto out_err;
+ r = fseek(root->file, 0L, SEEK_SET);
+ if (r) {
+ fprintf(stderr, "%s failed to seek into file %s\n", __func__, filename);
+ goto out_err;
+ }
+ root->offset = ftell(root->file);
+ r = fread(&root->type, 4, 1, root->file);
+ if (r != 1)
+ goto out_err;
+ r = fread(&root->size, 4, 1, root->file);
+ if (r != 1)
+ goto out_err;
+ r = fread(&root->array_size, 4, 1, root->file);
+ if (r != 1)
+ goto out_err;
+ r = bof_read(root, root->file, root->offset + root->size, 2);
+ if (r)
+ goto out_err;
+ return root;
+out_err:
+ bof_decref(root);
+ return NULL;
+}
+
+void bof_incref(bof_t *bof)
+{
+ bof->refcount++;
+}
+
+void bof_decref(bof_t *bof)
+{
+ unsigned i;
+
+ if (bof == NULL)
+ return;
+ if (--bof->refcount > 0)
+ return;
+ for (i = 0; i < bof->array_size; i++) {
+ bof_decref(bof->array[i]);
+ bof->array[i] = NULL;
+ }
+ bof->array_size = 0;
+ if (bof->file) {
+ fclose(bof->file);
+ bof->file = NULL;
+ }
+ free(bof->array);
+ free(bof->value);
+ free(bof);
+}
+
+static int bof_file_write(bof_t *bof, FILE *file)
+{
+ unsigned i;
+ int r;
+
+ r = fwrite(&bof->type, 4, 1, file);
+ if (r != 1)
+ return -EINVAL;
+ r = fwrite(&bof->size, 4, 1, file);
+ if (r != 1)
+ return -EINVAL;
+ r = fwrite(&bof->array_size, 4, 1, file);
+ if (r != 1)
+ return -EINVAL;
+ switch (bof->type) {
+ case BOF_TYPE_NULL:
+ if (bof->size)
+ return -EINVAL;
+ break;
+ case BOF_TYPE_STRING:
+ case BOF_TYPE_INT32:
+ case BOF_TYPE_BLOB:
+ r = fwrite(bof->value, bof->size - 12, 1, file);
+ if (r != 1)
+ return -EINVAL;
+ break;
+ case BOF_TYPE_OBJECT:
+ case BOF_TYPE_ARRAY:
+ for (i = 0; i < bof->array_size; i++) {
+ r = bof_file_write(bof->array[i], file);
+ if (r)
+ return r;
+ }
+ break;
+ default:
+ return -EINVAL;
+ }
+ return 0;
+}
+
+int bof_dump_file(bof_t *bof, const char *filename)
+{
+ unsigned i;
+ int r = 0;
+
+ if (bof->file) {
+ fclose(bof->file);
+ bof->file = NULL;
+ }
+ bof->file = fopen(filename, "w");
+ if (bof->file == NULL) {
+ fprintf(stderr, "%s failed to open file %s\n", __func__, filename);
+ r = -EINVAL;
+ goto out_err;
+ }
+ r = fseek(bof->file, 0L, SEEK_SET);
+ if (r) {
+ fprintf(stderr, "%s failed to seek into file %s\n", __func__, filename);
+ goto out_err;
+ }
+ r = fwrite(&bof->type, 4, 1, bof->file);
+ if (r != 1)
+ goto out_err;
+ r = fwrite(&bof->size, 4, 1, bof->file);
+ if (r != 1)
+ goto out_err;
+ r = fwrite(&bof->array_size, 4, 1, bof->file);
+ if (r != 1)
+ goto out_err;
+ for (i = 0; i < bof->array_size; i++) {
+ r = bof_file_write(bof->array[i], bof->file);
+ if (r)
+ return r;
+ }
+out_err:
+ fclose(bof->file);
+ bof->file = NULL;
+ return r;
+}
diff --git a/src/gallium/winsys/r600/drm/bof.h b/src/gallium/winsys/r600/drm/bof.h
new file mode 100644
index 0000000000..014affb74f
--- /dev/null
+++ b/src/gallium/winsys/r600/drm/bof.h
@@ -0,0 +1,90 @@
+/*
+ * Copyright 2010 Jerome Glisse <glisse@freedesktop.org>
+ *
+ * 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
+ * on the rights to use, copy, modify, merge, publish, distribute, sub
+ * license, and/or sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * Jerome Glisse
+ */
+#ifndef BOF_H
+#define BOF_H
+
+#include <stdio.h>
+#include <stdint.h>
+
+#define BOF_TYPE_STRING 0
+#define BOF_TYPE_NULL 1
+#define BOF_TYPE_BLOB 2
+#define BOF_TYPE_OBJECT 3
+#define BOF_TYPE_ARRAY 4
+#define BOF_TYPE_INT32 5
+
+struct bof;
+
+typedef struct bof {
+ struct bof **array;
+ unsigned centry;
+ unsigned nentry;
+ unsigned refcount;
+ FILE *file;
+ uint32_t type;
+ uint32_t size;
+ uint32_t array_size;
+ void *value;
+ long offset;
+} bof_t;
+
+extern int bof_file_flush(bof_t *root);
+extern bof_t *bof_file_new(const char *filename);
+extern int bof_object_dump(bof_t *object, const char *filename);
+
+/* object */
+extern bof_t *bof_object(void);
+extern bof_t *bof_object_get(bof_t *object, const char *keyname);
+extern int bof_object_set(bof_t *object, const char *keyname, bof_t *value);
+/* array */
+extern bof_t *bof_array(void);
+extern int bof_array_append(bof_t *array, bof_t *value);
+extern bof_t *bof_array_get(bof_t *bof, unsigned i);
+extern unsigned bof_array_size(bof_t *bof);
+/* blob */
+extern bof_t *bof_blob(unsigned size, void *value);
+extern unsigned bof_blob_size(bof_t *bof);
+extern void *bof_blob_value(bof_t *bof);
+/* string */
+extern bof_t *bof_string(const char *value);
+/* int32 */
+extern bof_t *bof_int32(int32_t value);
+extern int32_t bof_int32_value(bof_t *bof);
+/* common functions */
+extern void bof_decref(bof_t *bof);
+extern void bof_incref(bof_t *bof);
+extern bof_t *bof_load_file(const char *filename);
+extern int bof_dump_file(bof_t *bof, const char *filename);
+extern void bof_print(bof_t *bof);
+
+static inline int bof_is_object(bof_t *bof){return (bof->type == BOF_TYPE_OBJECT);}
+static inline int bof_is_blob(bof_t *bof){return (bof->type == BOF_TYPE_BLOB);}
+static inline int bof_is_null(bof_t *bof){return (bof->type == BOF_TYPE_NULL);}
+static inline int bof_is_int32(bof_t *bof){return (bof->type == BOF_TYPE_INT32);}
+static inline int bof_is_array(bof_t *bof){return (bof->type == BOF_TYPE_ARRAY);}
+static inline int bof_is_string(bof_t *bof){return (bof->type == BOF_TYPE_STRING);}
+
+#endif
diff --git a/src/gallium/winsys/r600/drm/r600_drm.c b/src/gallium/winsys/r600/drm/r600_drm.c
new file mode 100644
index 0000000000..803049d58c
--- /dev/null
+++ b/src/gallium/winsys/r600/drm/r600_drm.c
@@ -0,0 +1,89 @@
+/*
+ * Copyright 2010 Jerome Glisse <glisse@freedesktop.org>
+ *
+ * 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
+ * on the rights to use, copy, modify, merge, publish, distribute, sub
+ * license, and/or sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * Jerome Glisse
+ * Corbin Simpson <MostAwesomeDude@gmail.com>
+ * Joakim Sindholt <opensource@zhasha.com>
+ */
+#include <sys/ioctl.h>
+#include "trace/tr_drm.h"
+#include "util/u_inlines.h"
+#include "util/u_debug.h"
+#include "state_tracker/drm_api.h"
+#include "radeon_priv.h"
+#include "r600_screen.h"
+#include "r600_texture.h"
+
+static struct pipe_screen *r600_drm_create_screen(struct drm_api* api, int drmfd)
+{
+ struct radeon *rw = radeon_new(drmfd, 0);
+
+ if (rw == NULL)
+ return NULL;
+ return radeon_create_screen(rw);
+}
+
+boolean r600_buffer_get_handle(struct radeon *rw,
+ struct pipe_resource *buf,
+ struct winsys_handle *whandle)
+{
+ struct drm_gem_flink flink;
+ struct r600_buffer* rbuffer = (struct r600_buffer*)buf;
+
+ if (whandle->type == DRM_API_HANDLE_TYPE_SHARED) {
+ if (!rbuffer->flink) {
+ flink.handle = rbuffer->bo->handle;
+
+ if (ioctl(rw->fd, DRM_IOCTL_GEM_FLINK, &flink)) {
+ return FALSE;
+ }
+
+ rbuffer->flink = flink.name;
+ }
+ whandle->handle = rbuffer->flink;
+ } else if (whandle->type == DRM_API_HANDLE_TYPE_KMS) {
+ whandle->handle = rbuffer->bo->handle;
+ }
+ return TRUE;
+}
+
+static void r600_drm_api_destroy(struct drm_api *api)
+{
+ return;
+}
+
+struct drm_api drm_api_hooks = {
+ .name = "r600",
+ .driver_name = "r600",
+ .create_screen = r600_drm_create_screen,
+ .destroy = r600_drm_api_destroy,
+};
+
+struct drm_api* drm_api_create()
+{
+#ifdef DEBUG
+ return trace_drm_create(&drm_api_hooks);
+#else
+ return &drm_api_hooks;
+#endif
+}
diff --git a/src/gallium/winsys/r600/drm/r600_state.c b/src/gallium/winsys/r600/drm/r600_state.c
new file mode 100644
index 0000000000..d17d6e7954
--- /dev/null
+++ b/src/gallium/winsys/r600/drm/r600_state.c
@@ -0,0 +1,399 @@
+/*
+ * Copyright 2010 Jerome Glisse <glisse@freedesktop.org>
+ *
+ * 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
+ * on the rights to use, copy, modify, merge, publish, distribute, sub
+ * license, and/or sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * Jerome Glisse
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include "radeon_priv.h"
+#include "r600d.h"
+
+static int r600_state_pm4_resource(struct radeon_state *state);
+static int r600_state_pm4_cb0(struct radeon_state *state);
+static int r600_state_pm4_vgt(struct radeon_state *state);
+static int r600_state_pm4_db(struct radeon_state *state);
+static int r600_state_pm4_shader(struct radeon_state *state);
+static int r600_state_pm4_draw(struct radeon_state *state);
+static int r600_state_pm4_config(struct radeon_state *state);
+static int r600_state_pm4_generic(struct radeon_state *state);
+static int r700_state_pm4_config(struct radeon_state *state);
+static int r700_state_pm4_cb0(struct radeon_state *state);
+static int r700_state_pm4_db(struct radeon_state *state);
+
+#include "r600_states.h"
+
+/*
+ * r600/r700 state functions
+ */
+static int r600_state_pm4_bytecode(struct radeon_state *state, unsigned offset, unsigned id, unsigned nreg)
+{
+ const struct radeon_register *regs = state->radeon->type[state->type].regs;
+ unsigned i;
+ int r;
+
+ if (!offset) {
+ fprintf(stderr, "%s invalid register for state %d %d\n",
+ __func__, state->type, id);
+ return -EINVAL;
+ }
+ if (offset >= R600_CONFIG_REG_OFFSET && offset < R600_CONFIG_REG_END) {
+ state->pm4[state->cpm4++] = PKT3(PKT3_SET_CONFIG_REG, nreg);
+ state->pm4[state->cpm4++] = (offset - R600_CONFIG_REG_OFFSET) >> 2;
+ for (i = 0; i < nreg; i++) {
+ state->pm4[state->cpm4++] = state->states[id + i];
+ }
+ for (i = 0; i < nreg; i++) {
+ if (regs[id + i].need_reloc) {
+ state->pm4[state->cpm4++] = PKT3(PKT3_NOP, 0);
+ r = radeon_state_reloc(state, state->cpm4, regs[id + i].bo_id);
+ if (r)
+ return r;
+ state->pm4[state->cpm4++] = state->bo[regs[id + i].bo_id]->handle;
+ }
+ }
+ return 0;
+ }
+ if (offset >= R600_CONTEXT_REG_OFFSET && offset < R600_CONTEXT_REG_END) {
+ state->pm4[state->cpm4++] = PKT3(PKT3_SET_CONTEXT_REG, nreg);
+ state->pm4[state->cpm4++] = (offset - R600_CONTEXT_REG_OFFSET) >> 2;
+ for (i = 0; i < nreg; i++) {
+ state->pm4[state->cpm4++] = state->states[id + i];
+ }
+ for (i = 0; i < nreg; i++) {
+ if (regs[id + i].need_reloc) {
+ state->pm4[state->cpm4++] = PKT3(PKT3_NOP, 0);
+ r = radeon_state_reloc(state, state->cpm4, regs[id + i].bo_id);
+ if (r)
+ return r;
+ state->pm4[state->cpm4++] = state->bo[regs[id + i].bo_id]->handle;
+ }
+ }
+ return 0;
+ }
+ if (offset >= R600_ALU_CONST_OFFSET && offset < R600_ALU_CONST_END) {
+ state->pm4[state->cpm4++] = PKT3(PKT3_SET_ALU_CONST, nreg);
+ state->pm4[state->cpm4++] = (offset - R600_ALU_CONST_OFFSET) >> 2;
+ for (i = 0; i < nreg; i++) {
+ state->pm4[state->cpm4++] = state->states[id + i];
+ }
+ return 0;
+ }
+ if (offset >= R600_SAMPLER_OFFSET && offset < R600_SAMPLER_END) {
+ state->pm4[state->cpm4++] = PKT3(PKT3_SET_SAMPLER, nreg);
+ state->pm4[state->cpm4++] = (offset - R600_SAMPLER_OFFSET) >> 2;
+ for (i = 0; i < nreg; i++) {
+ state->pm4[state->cpm4++] = state->states[id + i];
+ }
+ return 0;
+ }
+ fprintf(stderr, "%s unsupported offset 0x%08X\n", __func__, offset);
+ return -EINVAL;
+}
+
+static int r600_state_pm4_generic(struct radeon_state *state)
+{
+ struct radeon *radeon = state->radeon;
+ unsigned i, offset, nreg, type, coffset, loffset, soffset;
+ unsigned start;
+ int r;
+
+ if (!state->nstates)
+ return 0;
+ type = state->type;
+ soffset = (state->id - radeon->type[type].id) * radeon->type[type].stride;
+ offset = loffset = radeon->type[type].regs[0].offset + soffset;
+ start = 0;
+ for (i = 1, nreg = 1; i < state->nstates; i++) {
+ coffset = radeon->type[type].regs[i].offset + soffset;
+ if (coffset == (loffset + 4)) {
+ nreg++;
+ loffset = coffset;
+ } else {
+ r = r600_state_pm4_bytecode(state, offset, start, nreg);
+ if (r) {
+ fprintf(stderr, "%s invalid 0x%08X %d\n", __func__, start, nreg);
+ return r;
+ }
+ offset = loffset = coffset;
+ nreg = 1;
+ start = i;
+ }
+ }
+ return r600_state_pm4_bytecode(state, offset, start, nreg);
+}
+
+static void r600_state_pm4_with_flush(struct radeon_state *state, u32 flags)
+{
+ unsigned i, j, add, size;
+
+ state->nreloc = 0;
+ for (i = 0; i < state->nbo; i++) {
+ for (j = 0, add = 1; j < state->nreloc; j++) {
+ if (state->bo[state->reloc_bo_id[j]] == state->bo[i]) {
+ add = 0;
+ break;
+ }
+ }
+ if (add) {
+ state->reloc_bo_id[state->nreloc++] = i;
+ }
+ }
+ for (i = 0; i < state->nreloc; i++) {
+ size = (state->bo[state->reloc_bo_id[i]]->size + 255) >> 8;
+ state->pm4[state->cpm4++] = PKT3(PKT3_SURFACE_SYNC, 3);
+ state->pm4[state->cpm4++] = flags;
+ state->pm4[state->cpm4++] = size;
+ state->pm4[state->cpm4++] = 0x00000000;
+ state->pm4[state->cpm4++] = 0x0000000A;
+ state->pm4[state->cpm4++] = PKT3(PKT3_NOP, 0);
+ state->reloc_pm4_id[i] = state->cpm4;
+ state->pm4[state->cpm4++] = state->bo[state->reloc_bo_id[i]]->handle;
+ }
+}
+
+static int r600_state_pm4_cb0(struct radeon_state *state)
+{
+ int r;
+
+ r600_state_pm4_with_flush(state, S_0085F0_CB_ACTION_ENA(1) |
+ S_0085F0_CB0_DEST_BASE_ENA(1));
+ r = r600_state_pm4_generic(state);
+ if (r)
+ return r;
+ state->pm4[state->cpm4++] = PKT3(PKT3_SURFACE_BASE_UPDATE, 0);
+ state->pm4[state->cpm4++] = 0x00000002;
+ return 0;
+}
+
+static int r700_state_pm4_cb0(struct radeon_state *state)
+{
+ int r;
+
+ r600_state_pm4_with_flush(state, S_0085F0_CB_ACTION_ENA(1) |
+ S_0085F0_CB0_DEST_BASE_ENA(1));
+ r = r600_state_pm4_generic(state);
+ if (r)
+ return r;
+ return 0;
+}
+
+static int r600_state_pm4_db(struct radeon_state *state)
+{
+ int r;
+
+ r600_state_pm4_with_flush(state, S_0085F0_DB_ACTION_ENA(1) |
+ S_0085F0_DB_DEST_BASE_ENA(1));
+ r = r600_state_pm4_generic(state);
+ if (r)
+ return r;
+ state->pm4[state->cpm4++] = PKT3(PKT3_SURFACE_BASE_UPDATE, 0);
+ state->pm4[state->cpm4++] = 0x00000001;
+ return 0;
+}
+
+static int r700_state_pm4_db(struct radeon_state *state)
+{
+ int r;
+
+ r600_state_pm4_with_flush(state, S_0085F0_DB_ACTION_ENA(1) |
+ S_0085F0_DB_DEST_BASE_ENA(1));
+ r = r600_state_pm4_generic(state);
+ if (r)
+ return r;
+ return 0;
+}
+
+static int r600_state_pm4_config(struct radeon_state *state)
+{
+ state->pm4[state->cpm4++] = PKT3(PKT3_START_3D_CMDBUF, 0);
+ state->pm4[state->cpm4++] = 0x00000000;
+ state->pm4[state->cpm4++] = PKT3(PKT3_CONTEXT_CONTROL, 1);
+ state->pm4[state->cpm4++] = 0x80000000;
+ state->pm4[state->cpm4++] = 0x80000000;
+ state->pm4[state->cpm4++] = PKT3(PKT3_EVENT_WRITE, 0);
+ state->pm4[state->cpm4++] = 0x00000016;
+ state->pm4[state->cpm4++] = PKT3(PKT3_SET_CONFIG_REG, 1);
+ state->pm4[state->cpm4++] = 0x00000010;
+ state->pm4[state->cpm4++] = 0x00028000;
+ return r600_state_pm4_generic(state);
+}
+
+static int r700_state_pm4_config(struct radeon_state *state)
+{
+ state->pm4[state->cpm4++] = PKT3(PKT3_CONTEXT_CONTROL, 1);
+ state->pm4[state->cpm4++] = 0x80000000;
+ state->pm4[state->cpm4++] = 0x80000000;
+ state->pm4[state->cpm4++] = PKT3(PKT3_EVENT_WRITE, 0);
+ state->pm4[state->cpm4++] = 0x00000016;
+ state->pm4[state->cpm4++] = PKT3(PKT3_SET_CONFIG_REG, 1);
+ state->pm4[state->cpm4++] = 0x00000010;
+ state->pm4[state->cpm4++] = 0x00028000;
+ return r600_state_pm4_generic(state);
+}
+
+static int r600_state_pm4_shader(struct radeon_state *state)
+{
+ r600_state_pm4_with_flush(state, S_0085F0_SH_ACTION_ENA(1));
+ return r600_state_pm4_generic(state);
+}
+
+static int r600_state_pm4_vgt(struct radeon_state *state)
+{
+ int r;
+
+ r = r600_state_pm4_bytecode(state, R_028400_VGT_MAX_VTX_INDX, R600_VGT__VGT_MAX_VTX_INDX, 1);
+ if (r)
+ return r;
+ r = r600_state_pm4_bytecode(state, R_028404_VGT_MIN_VTX_INDX, R600_VGT__VGT_MIN_VTX_INDX, 1);
+ if (r)
+ return r;
+ r = r600_state_pm4_bytecode(state, R_028408_VGT_INDX_OFFSET, R600_VGT__VGT_INDX_OFFSET, 1);
+ if (r)
+ return r;
+ r = r600_state_pm4_bytecode(state, R_02840C_VGT_MULTI_PRIM_IB_RESET_INDX, R600_VGT__VGT_MULTI_PRIM_IB_RESET_INDX, 1);
+ if (r)
+ return r;
+ r = r600_state_pm4_bytecode(state, R_008958_VGT_PRIMITIVE_TYPE, R600_VGT__VGT_PRIMITIVE_TYPE, 1);
+ if (r)
+ return r;
+ state->pm4[state->cpm4++] = PKT3(PKT3_INDEX_TYPE, 0);
+ state->pm4[state->cpm4++] = state->states[R600_VGT__VGT_DMA_INDEX_TYPE];
+ state->pm4[state->cpm4++] = PKT3(PKT3_NUM_INSTANCES, 0);
+ state->pm4[state->cpm4++] = state->states[R600_VGT__VGT_DMA_NUM_INSTANCES];
+ return 0;
+}
+
+static int r600_state_pm4_draw(struct radeon_state *state)
+{
+ unsigned i;
+ int r;
+
+ if (state->nbo) {
+ state->pm4[state->cpm4++] = PKT3(PKT3_DRAW_INDEX, 3);
+ state->pm4[state->cpm4++] = state->states[R600_DRAW__VGT_DMA_BASE];
+ state->pm4[state->cpm4++] = state->states[R600_DRAW__VGT_DMA_BASE_HI];
+ state->pm4[state->cpm4++] = state->states[R600_DRAW__VGT_NUM_INDICES];
+ state->pm4[state->cpm4++] = state->states[R600_DRAW__VGT_DRAW_INITIATOR];
+ state->pm4[state->cpm4++] = PKT3(PKT3_NOP, 0);
+ r = radeon_state_reloc(state, state->cpm4, 0);
+ if (r)
+ return r;
+ state->pm4[state->cpm4++] = state->bo[0]->handle;
+ } else if (state->nimmd) {
+ state->pm4[state->cpm4++] = PKT3(PKT3_DRAW_INDEX_IMMD, state->nimmd + 1);
+ state->pm4[state->cpm4++] = state->states[R600_DRAW__VGT_NUM_INDICES];
+ state->pm4[state->cpm4++] = state->states[R600_DRAW__VGT_DRAW_INITIATOR];
+ for (i = 0; i < state->nimmd; i++) {
+ state->pm4[state->cpm4++] = state->immd[i];
+ }
+ } else {
+ state->pm4[state->cpm4++] = PKT3(PKT3_DRAW_INDEX_AUTO, 1);
+ state->pm4[state->cpm4++] = state->states[R600_DRAW__VGT_NUM_INDICES];
+ state->pm4[state->cpm4++] = state->states[R600_DRAW__VGT_DRAW_INITIATOR];
+ }
+ state->pm4[state->cpm4++] = PKT3(PKT3_EVENT_WRITE, 0);
+ state->pm4[state->cpm4++] = 0x00000016;
+ return 0;
+}
+
+static int r600_state_pm4_resource(struct radeon_state *state)
+{
+ u32 flags, type, nbo, offset, soffset;
+ int r;
+
+ soffset = (state->id - state->radeon->type[state->type].id) * state->radeon->type[state->type].stride;
+ type = G_038018_TYPE(state->states[6]);
+ switch (type) {
+ case 2:
+ flags = S_0085F0_TC_ACTION_ENA(1);
+ nbo = 2;
+ break;
+ case 3:
+ flags = S_0085F0_VC_ACTION_ENA(1);
+ nbo = 1;
+ break;
+ default:
+ return 0;
+ }
+ if (state->nbo != nbo) {
+ fprintf(stderr, "%s need %d bo got %d\n", __func__, nbo, state->nbo);
+ return -EINVAL;
+ }
+ r600_state_pm4_with_flush(state, flags);
+ offset = state->radeon->type[state->type].regs[0].offset + soffset;
+ state->pm4[state->cpm4++] = PKT3(PKT3_SET_RESOURCE, 7);
+ state->pm4[state->cpm4++] = (offset - R_038000_SQ_TEX_RESOURCE_WORD0_0) >> 2;
+ state->pm4[state->cpm4++] = state->states[0];
+ state->pm4[state->cpm4++] = state->states[1];
+ state->pm4[state->cpm4++] = state->states[2];
+ state->pm4[state->cpm4++] = state->states[3];
+ state->pm4[state->cpm4++] = state->states[4];
+ state->pm4[state->cpm4++] = state->states[5];
+ state->pm4[state->cpm4++] = state->states[6];
+ state->pm4[state->cpm4++] = PKT3(PKT3_NOP, 0);
+ r = radeon_state_reloc(state, state->cpm4, 0);
+ if (r)
+ return r;
+ state->pm4[state->cpm4++] = state->bo[0]->handle;
+ if (type == 2) {
+ state->pm4[state->cpm4++] = PKT3(PKT3_NOP, 0);
+ r = radeon_state_reloc(state, state->cpm4, 1);
+ if (r)
+ return r;
+ state->pm4[state->cpm4++] = state->bo[1]->handle;
+ }
+ return 0;
+}
+
+int r600_init(struct radeon *radeon)
+{
+ switch (radeon->family) {
+ case CHIP_R600:
+ case CHIP_RV610:
+ case CHIP_RV630:
+ case CHIP_RV670:
+ case CHIP_RV620:
+ case CHIP_RV635:
+ case CHIP_RS780:
+ case CHIP_RS880:
+ radeon->ntype = R600_NTYPE;
+ radeon->nstate = R600_NSTATE;
+ radeon->type = R600_types;
+ break;
+ case CHIP_RV770:
+ case CHIP_RV730:
+ case CHIP_RV710:
+ case CHIP_RV740:
+ radeon->ntype = R600_NTYPE;
+ radeon->nstate = R600_NSTATE;
+ radeon->type = R700_types;
+ break;
+ default:
+ fprintf(stderr, "%s unknown or unsupported chipset 0x%04X\n",
+ __func__, radeon->device);
+ return -EINVAL;
+ }
+ return 0;
+}
diff --git a/src/gallium/winsys/r600/drm/r600_states.h b/src/gallium/winsys/r600/drm/r600_states.h
new file mode 100644
index 0000000000..5896df21b2
--- /dev/null
+++ b/src/gallium/winsys/r600/drm/r600_states.h
@@ -0,0 +1,461 @@
+/*
+ * Copyright © 2009 Jerome Glisse <glisse@freedesktop.org>
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+#ifndef R600_STATES_H
+#define R600_STATES_H
+
+static const struct radeon_register R600_CONFIG_names[] = {
+ {0x00008C00, 0, 0, "SQ_CONFIG"},
+ {0x00008C04, 0, 0, "SQ_GPR_RESOURCE_MGMT_1"},
+ {0x00008C08, 0, 0, "SQ_GPR_RESOURCE_MGMT_2"},
+ {0x00008C0C, 0, 0, "SQ_THREAD_RESOURCE_MGMT"},
+ {0x00008C10, 0, 0, "SQ_STACK_RESOURCE_MGMT_1"},
+ {0x00008C14, 0, 0, "SQ_STACK_RESOURCE_MGMT_2"},
+ {0x00008D8C, 0, 0, "SQ_DYN_GPR_CNTL_PS_FLUSH_REQ"},
+ {0x00009508, 0, 0, "TA_CNTL_AUX"},
+ {0x00009714, 0, 0, "VC_ENHANCE"},
+ {0x00009830, 0, 0, "DB_DEBUG"},
+ {0x00009838, 0, 0, "DB_WATERMARKS"},
+ {0x00028350, 0, 0, "SX_MISC"},
+ {0x000286C8, 0, 0, "SPI_THREAD_GROUPING"},
+ {0x000287A0, 0, 0, "CB_SHADER_CONTROL"},
+ {0x000288A8, 0, 0, "SQ_ESGS_RING_ITEMSIZE"},
+ {0x000288AC, 0, 0, "SQ_GSVS_RING_ITEMSIZE"},
+ {0x000288B0, 0, 0, "SQ_ESTMP_RING_ITEMSIZE"},
+ {0x000288B4, 0, 0, "SQ_GSTMP_RING_ITEMSIZE"},
+ {0x000288B8, 0, 0, "SQ_VSTMP_RING_ITEMSIZE"},
+ {0x000288BC, 0, 0, "SQ_PSTMP_RING_ITEMSIZE"},
+ {0x000288C0, 0, 0, "SQ_FBUF_RING_ITEMSIZE"},
+ {0x000288C4, 0, 0, "SQ_REDUC_RING_ITEMSIZE"},
+ {0x000288C8, 0, 0, "SQ_GS_VERT_ITEMSIZE"},
+ {0x00028A10, 0, 0, "VGT_OUTPUT_PATH_CNTL"},
+ {0x00028A14, 0, 0, "VGT_HOS_CNTL"},
+ {0x00028A18, 0, 0, "VGT_HOS_MAX_TESS_LEVEL"},
+ {0x00028A1C, 0, 0, "VGT_HOS_MIN_TESS_LEVEL"},
+ {0x00028A20, 0, 0, "VGT_HOS_REUSE_DEPTH"},
+ {0x00028A24, 0, 0, "VGT_GROUP_PRIM_TYPE"},
+ {0x00028A28, 0, 0, "VGT_GROUP_FIRST_DECR"},
+ {0x00028A2C, 0, 0, "VGT_GROUP_DECR"},
+ {0x00028A30, 0, 0, "VGT_GROUP_VECT_0_CNTL"},
+ {0x00028A34, 0, 0, "VGT_GROUP_VECT_1_CNTL"},
+ {0x00028A38, 0, 0, "VGT_GROUP_VECT_0_FMT_CNTL"},
+ {0x00028A3C, 0, 0, "VGT_GROUP_VECT_1_FMT_CNTL"},
+ {0x00028A40, 0, 0, "VGT_GS_MODE"},
+ {0x00028A4C, 0, 0, "PA_SC_MODE_CNTL"},
+ {0x00028AB0, 0, 0, "VGT_STRMOUT_EN"},
+ {0x00028AB4, 0, 0, "VGT_REUSE_OFF"},
+ {0x00028AB8, 0, 0, "VGT_VTX_CNT_EN"},
+ {0x00028B20, 0, 0, "VGT_STRMOUT_BUFFER_EN"},
+};
+
+static const struct radeon_register R600_CB_CNTL_names[] = {
+ {0x00028120, 0, 0, "CB_CLEAR_RED"},
+ {0x00028124, 0, 0, "CB_CLEAR_GREEN"},
+ {0x00028128, 0, 0, "CB_CLEAR_BLUE"},
+ {0x0002812C, 0, 0, "CB_CLEAR_ALPHA"},
+ {0x0002823C, 0, 0, "CB_SHADER_MASK"},
+ {0x00028238, 0, 0, "CB_TARGET_MASK"},
+ {0x00028424, 0, 0, "CB_FOG_RED"},
+ {0x00028428, 0, 0, "CB_FOG_GREEN"},
+ {0x0002842C, 0, 0, "CB_FOG_BLUE"},
+ {0x00028808, 0, 0, "CB_COLOR_CONTROL"},
+ {0x00028C04, 0, 0, "PA_SC_AA_CONFIG"},
+ {0x00028C1C, 0, 0, "PA_SC_AA_SAMPLE_LOCS_MCTX"},
+ {0x00028C20, 0, 0, "PA_SC_AA_SAMPLE_LOCS_8S_WD1_MCTX"},
+ {0x00028C30, 0, 0, "CB_CLRCMP_CONTROL"},
+ {0x00028C34, 0, 0, "CB_CLRCMP_SRC"},
+ {0x00028C38, 0, 0, "CB_CLRCMP_DST"},
+ {0x00028C3C, 0, 0, "CB_CLRCMP_MSK"},
+ {0x00028C48, 0, 0, "PA_SC_AA_MASK"},
+};
+
+static const struct radeon_register R600_RASTERIZER_names[] = {
+ {0x000286D4, 0, 0, "SPI_INTERP_CONTROL_0"},
+ {0x00028810, 0, 0, "PA_CL_CLIP_CNTL"},
+ {0x00028814, 0, 0, "PA_SU_SC_MODE_CNTL"},
+ {0x0002881C, 0, 0, "PA_CL_VS_OUT_CNTL"},
+ {0x00028820, 0, 0, "PA_CL_NANINF_CNTL"},
+ {0x00028A00, 0, 0, "PA_SU_POINT_SIZE"},
+ {0x00028A04, 0, 0, "PA_SU_POINT_MINMAX"},
+ {0x00028A08, 0, 0, "PA_SU_LINE_CNTL"},
+ {0x00028A0C, 0, 0, "PA_SC_LINE_STIPPLE"},
+ {0x00028A48, 0, 0, "PA_SC_MPASS_PS_CNTL"},
+ {0x00028C00, 0, 0, "PA_SC_LINE_CNTL"},
+ {0x00028C0C, 0, 0, "PA_CL_GB_VERT_CLIP_ADJ"},
+ {0x00028C10, 0, 0, "PA_CL_GB_VERT_DISC_ADJ"},
+ {0x00028C14, 0, 0, "PA_CL_GB_HORZ_CLIP_ADJ"},
+ {0x00028C18, 0, 0, "PA_CL_GB_HORZ_DISC_ADJ"},
+ {0x00028DF8, 0, 0, "PA_SU_POLY_OFFSET_DB_FMT_CNTL"},
+ {0x00028DFC, 0, 0, "PA_SU_POLY_OFFSET_CLAMP"},
+ {0x00028E00, 0, 0, "PA_SU_POLY_OFFSET_FRONT_SCALE"},
+ {0x00028E04, 0, 0, "PA_SU_POLY_OFFSET_FRONT_OFFSET"},
+ {0x00028E08, 0, 0, "PA_SU_POLY_OFFSET_BACK_SCALE"},
+ {0x00028E0C, 0, 0, "PA_SU_POLY_OFFSET_BACK_OFFSET"},
+};
+
+static const struct radeon_register R600_VIEWPORT_names[] = {
+ {0x000282D0, 0, 0, "PA_SC_VPORT_ZMIN_0"},
+ {0x000282D4, 0, 0, "PA_SC_VPORT_ZMAX_0"},
+ {0x0002843C, 0, 0, "PA_CL_VPORT_XSCALE_0"},
+ {0x00028444, 0, 0, "PA_CL_VPORT_YSCALE_0"},
+ {0x0002844C, 0, 0, "PA_CL_VPORT_ZSCALE_0"},
+ {0x00028440, 0, 0, "PA_CL_VPORT_XOFFSET_0"},
+ {0x00028448, 0, 0, "PA_CL_VPORT_YOFFSET_0"},
+ {0x00028450, 0, 0, "PA_CL_VPORT_ZOFFSET_0"},
+ {0x00028818, 0, 0, "PA_CL_VTE_CNTL"},
+};
+
+static const struct radeon_register R600_SCISSOR_names[] = {
+ {0x00028030, 0, 0, "PA_SC_SCREEN_SCISSOR_TL"},
+ {0x00028034, 0, 0, "PA_SC_SCREEN_SCISSOR_BR"},
+ {0x00028200, 0, 0, "PA_SC_WINDOW_OFFSET"},
+ {0x00028204, 0, 0, "PA_SC_WINDOW_SCISSOR_TL"},
+ {0x00028208, 0, 0, "PA_SC_WINDOW_SCISSOR_BR"},
+ {0x0002820C, 0, 0, "PA_SC_CLIPRECT_RULE"},
+ {0x00028210, 0, 0, "PA_SC_CLIPRECT_0_TL"},
+ {0x00028214, 0, 0, "PA_SC_CLIPRECT_0_BR"},
+ {0x00028218, 0, 0, "PA_SC_CLIPRECT_1_TL"},
+ {0x0002821C, 0, 0, "PA_SC_CLIPRECT_1_BR"},
+ {0x00028220, 0, 0, "PA_SC_CLIPRECT_2_TL"},
+ {0x00028224, 0, 0, "PA_SC_CLIPRECT_2_BR"},
+ {0x00028228, 0, 0, "PA_SC_CLIPRECT_3_TL"},
+ {0x0002822C, 0, 0, "PA_SC_CLIPRECT_3_BR"},
+ {0x00028230, 0, 0, "PA_SC_EDGERULE"},
+ {0x00028240, 0, 0, "PA_SC_GENERIC_SCISSOR_TL"},
+ {0x00028244, 0, 0, "PA_SC_GENERIC_SCISSOR_BR"},
+ {0x00028250, 0, 0, "PA_SC_VPORT_SCISSOR_0_TL"},
+ {0x00028254, 0, 0, "PA_SC_VPORT_SCISSOR_0_BR"},
+};
+
+static const struct radeon_register R600_BLEND_names[] = {
+ {0x00028414, 0, 0, "CB_BLEND_RED"},
+ {0x00028418, 0, 0, "CB_BLEND_GREEN"},
+ {0x0002841C, 0, 0, "CB_BLEND_BLUE"},
+ {0x00028420, 0, 0, "CB_BLEND_ALPHA"},
+ {0x00028780, 0, 0, "CB_BLEND0_CONTROL"},
+ {0x00028784, 0, 0, "CB_BLEND1_CONTROL"},
+ {0x00028788, 0, 0, "CB_BLEND2_CONTROL"},
+ {0x0002878C, 0, 0, "CB_BLEND3_CONTROL"},
+ {0x00028790, 0, 0, "CB_BLEND4_CONTROL"},
+ {0x00028794, 0, 0, "CB_BLEND5_CONTROL"},
+ {0x00028798, 0, 0, "CB_BLEND6_CONTROL"},
+ {0x0002879C, 0, 0, "CB_BLEND7_CONTROL"},
+ {0x00028804, 0, 0, "CB_BLEND_CONTROL"},
+};
+
+static const struct radeon_register R600_DSA_names[] = {
+ {0x00028028, 0, 0, "DB_STENCIL_CLEAR"},
+ {0x0002802C, 0, 0, "DB_DEPTH_CLEAR"},
+ {0x00028410, 0, 0, "SX_ALPHA_TEST_CONTROL"},
+ {0x00028430, 0, 0, "DB_STENCILREFMASK"},
+ {0x00028434, 0, 0, "DB_STENCILREFMASK_BF"},
+ {0x00028438, 0, 0, "SX_ALPHA_REF"},
+ {0x000286E0, 0, 0, "SPI_FOG_FUNC_SCALE"},
+ {0x000286E4, 0, 0, "SPI_FOG_FUNC_BIAS"},
+ {0x000286DC, 0, 0, "SPI_FOG_CNTL"},
+ {0x00028800, 0, 0, "DB_DEPTH_CONTROL"},
+ {0x0002880C, 0, 0, "DB_SHADER_CONTROL"},
+ {0x00028D0C, 0, 0, "DB_RENDER_CONTROL"},
+ {0x00028D10, 0, 0, "DB_RENDER_OVERRIDE"},
+ {0x00028D2C, 0, 0, "DB_SRESULTS_COMPARE_STATE1"},
+ {0x00028D30, 0, 0, "DB_PRELOAD_CONTROL"},
+ {0x00028D44, 0, 0, "DB_ALPHA_TO_MASK"},
+};
+
+static const struct radeon_register R600_VS_SHADER_names[] = {
+ {0x00028380, 0, 0, "SQ_VTX_SEMANTIC_0"},
+ {0x00028384, 0, 0, "SQ_VTX_SEMANTIC_1"},
+ {0x00028388, 0, 0, "SQ_VTX_SEMANTIC_2"},
+ {0x0002838C, 0, 0, "SQ_VTX_SEMANTIC_3"},
+ {0x00028390, 0, 0, "SQ_VTX_SEMANTIC_4"},
+ {0x00028394, 0, 0, "SQ_VTX_SEMANTIC_5"},
+ {0x00028398, 0, 0, "SQ_VTX_SEMANTIC_6"},
+ {0x0002839C, 0, 0, "SQ_VTX_SEMANTIC_7"},
+ {0x000283A0, 0, 0, "SQ_VTX_SEMANTIC_8"},
+ {0x000283A4, 0, 0, "SQ_VTX_SEMANTIC_9"},
+ {0x000283A8, 0, 0, "SQ_VTX_SEMANTIC_10"},
+ {0x000283AC, 0, 0, "SQ_VTX_SEMANTIC_11"},
+ {0x000283B0, 0, 0, "SQ_VTX_SEMANTIC_12"},
+ {0x000283B4, 0, 0, "SQ_VTX_SEMANTIC_13"},
+ {0x000283B8, 0, 0, "SQ_VTX_SEMANTIC_14"},
+ {0x000283BC, 0, 0, "SQ_VTX_SEMANTIC_15"},
+ {0x000283C0, 0, 0, "SQ_VTX_SEMANTIC_16"},
+ {0x000283C4, 0, 0, "SQ_VTX_SEMANTIC_17"},
+ {0x000283C8, 0, 0, "SQ_VTX_SEMANTIC_18"},
+ {0x000283CC, 0, 0, "SQ_VTX_SEMANTIC_19"},
+ {0x000283D0, 0, 0, "SQ_VTX_SEMANTIC_20"},
+ {0x000283D4, 0, 0, "SQ_VTX_SEMANTIC_21"},
+ {0x000283D8, 0, 0, "SQ_VTX_SEMANTIC_22"},
+ {0x000283DC, 0, 0, "SQ_VTX_SEMANTIC_23"},
+ {0x000283E0, 0, 0, "SQ_VTX_SEMANTIC_24"},
+ {0x000283E4, 0, 0, "SQ_VTX_SEMANTIC_25"},
+ {0x000283E8, 0, 0, "SQ_VTX_SEMANTIC_26"},
+ {0x000283EC, 0, 0, "SQ_VTX_SEMANTIC_27"},
+ {0x000283F0, 0, 0, "SQ_VTX_SEMANTIC_28"},
+ {0x000283F4, 0, 0, "SQ_VTX_SEMANTIC_29"},
+ {0x000283F8, 0, 0, "SQ_VTX_SEMANTIC_30"},
+ {0x000283FC, 0, 0, "SQ_VTX_SEMANTIC_31"},
+ {0x00028614, 0, 0, "SPI_VS_OUT_ID_0"},
+ {0x00028618, 0, 0, "SPI_VS_OUT_ID_1"},
+ {0x0002861C, 0, 0, "SPI_VS_OUT_ID_2"},
+ {0x00028620, 0, 0, "SPI_VS_OUT_ID_3"},
+ {0x00028624, 0, 0, "SPI_VS_OUT_ID_4"},
+ {0x00028628, 0, 0, "SPI_VS_OUT_ID_5"},
+ {0x0002862C, 0, 0, "SPI_VS_OUT_ID_6"},
+ {0x00028630, 0, 0, "SPI_VS_OUT_ID_7"},
+ {0x00028634, 0, 0, "SPI_VS_OUT_ID_8"},
+ {0x00028638, 0, 0, "SPI_VS_OUT_ID_9"},
+ {0x000286C4, 0, 0, "SPI_VS_OUT_CONFIG"},
+ {0x00028858, 1, 0, "SQ_PGM_START_VS"},
+ {0x00028868, 0, 0, "SQ_PGM_RESOURCES_VS"},
+ {0x00028894, 1, 1, "SQ_PGM_START_FS"},
+ {0x000288A4, 0, 0, "SQ_PGM_RESOURCES_FS"},
+ {0x000288D0, 0, 0, "SQ_PGM_CF_OFFSET_VS"},
+ {0x000288DC, 0, 0, "SQ_PGM_CF_OFFSET_FS"},
+};
+
+static const struct radeon_register R600_PS_SHADER_names[] = {
+ {0x00028644, 0, 0, "SPI_PS_INPUT_CNTL_0"},
+ {0x00028648, 0, 0, "SPI_PS_INPUT_CNTL_1"},
+ {0x0002864C, 0, 0, "SPI_PS_INPUT_CNTL_2"},
+ {0x00028650, 0, 0, "SPI_PS_INPUT_CNTL_3"},
+ {0x00028654, 0, 0, "SPI_PS_INPUT_CNTL_4"},
+ {0x00028658, 0, 0, "SPI_PS_INPUT_CNTL_5"},
+ {0x0002865C, 0, 0, "SPI_PS_INPUT_CNTL_6"},
+ {0x00028660, 0, 0, "SPI_PS_INPUT_CNTL_7"},
+ {0x00028664, 0, 0, "SPI_PS_INPUT_CNTL_8"},
+ {0x00028668, 0, 0, "SPI_PS_INPUT_CNTL_9"},
+ {0x0002866C, 0, 0, "SPI_PS_INPUT_CNTL_10"},
+ {0x00028670, 0, 0, "SPI_PS_INPUT_CNTL_11"},
+ {0x00028674, 0, 0, "SPI_PS_INPUT_CNTL_12"},
+ {0x00028678, 0, 0, "SPI_PS_INPUT_CNTL_13"},
+ {0x0002867C, 0, 0, "SPI_PS_INPUT_CNTL_14"},
+ {0x00028680, 0, 0, "SPI_PS_INPUT_CNTL_15"},
+ {0x00028684, 0, 0, "SPI_PS_INPUT_CNTL_16"},
+ {0x00028688, 0, 0, "SPI_PS_INPUT_CNTL_17"},
+ {0x0002868C, 0, 0, "SPI_PS_INPUT_CNTL_18"},
+ {0x00028690, 0, 0, "SPI_PS_INPUT_CNTL_19"},
+ {0x00028694, 0, 0, "SPI_PS_INPUT_CNTL_20"},
+ {0x00028698, 0, 0, "SPI_PS_INPUT_CNTL_21"},
+ {0x0002869C, 0, 0, "SPI_PS_INPUT_CNTL_22"},
+ {0x000286A0, 0, 0, "SPI_PS_INPUT_CNTL_23"},
+ {0x000286A4, 0, 0, "SPI_PS_INPUT_CNTL_24"},
+ {0x000286A8, 0, 0, "SPI_PS_INPUT_CNTL_25"},
+ {0x000286AC, 0, 0, "SPI_PS_INPUT_CNTL_26"},
+ {0x000286B0, 0, 0, "SPI_PS_INPUT_CNTL_27"},
+ {0x000286B4, 0, 0, "SPI_PS_INPUT_CNTL_28"},
+ {0x000286B8, 0, 0, "SPI_PS_INPUT_CNTL_29"},
+ {0x000286BC, 0, 0, "SPI_PS_INPUT_CNTL_30"},
+ {0x000286C0, 0, 0, "SPI_PS_INPUT_CNTL_31"},
+ {0x000286CC, 0, 0, "SPI_PS_IN_CONTROL_0"},
+ {0x000286D0, 0, 0, "SPI_PS_IN_CONTROL_1"},
+ {0x000286D8, 0, 0, "SPI_INPUT_Z"},
+ {0x00028840, 1, 0, "SQ_PGM_START_PS"},
+ {0x00028850, 0, 0, "SQ_PGM_RESOURCES_PS"},
+ {0x00028854, 0, 0, "SQ_PGM_EXPORTS_PS"},
+ {0x000288CC, 0, 0, "SQ_PGM_CF_OFFSET_PS"},
+};
+
+static const struct radeon_register R600_PS_CONSTANT_names[] = {
+ {0x00030000, 0, 0, "SQ_ALU_CONSTANT0_0"},
+ {0x00030004, 0, 0, "SQ_ALU_CONSTANT1_0"},
+ {0x00030008, 0, 0, "SQ_ALU_CONSTANT2_0"},
+ {0x0003000C, 0, 0, "SQ_ALU_CONSTANT3_0"},
+};
+
+static const struct radeon_register R600_VS_CONSTANT_names[] = {
+ {0x00031000, 0, 0, "SQ_ALU_CONSTANT0_256"},
+ {0x00031004, 0, 0, "SQ_ALU_CONSTANT1_256"},
+ {0x00031008, 0, 0, "SQ_ALU_CONSTANT2_256"},
+ {0x0003100C, 0, 0, "SQ_ALU_CONSTANT3_256"},
+};
+
+static const struct radeon_register R600_PS_RESOURCE_names[] = {
+ {0x00038000, 0, 0, "RESOURCE0_WORD0"},
+ {0x00038004, 0, 0, "RESOURCE0_WORD1"},
+ {0x00038008, 0, 0, "RESOURCE0_WORD2"},
+ {0x0003800C, 0, 0, "RESOURCE0_WORD3"},
+ {0x00038010, 0, 0, "RESOURCE0_WORD4"},
+ {0x00038014, 0, 0, "RESOURCE0_WORD5"},
+ {0x00038018, 0, 0, "RESOURCE0_WORD6"},
+};
+
+static const struct radeon_register R600_VS_RESOURCE_names[] = {
+ {0x00039180, 0, 0, "RESOURCE160_WORD0"},
+ {0x00039184, 0, 0, "RESOURCE160_WORD1"},
+ {0x00039188, 0, 0, "RESOURCE160_WORD2"},
+ {0x0003918C, 0, 0, "RESOURCE160_WORD3"},
+ {0x00039190, 0, 0, "RESOURCE160_WORD4"},
+ {0x00039194, 0, 0, "RESOURCE160_WORD5"},
+ {0x00039198, 0, 0, "RESOURCE160_WORD6"},
+};
+
+static const struct radeon_register R600_FS_RESOURCE_names[] = {
+ {0x0003A300, 0, 0, "RESOURCE320_WORD0"},
+ {0x0003A304, 0, 0, "RESOURCE320_WORD1"},
+ {0x0003A308, 0, 0, "RESOURCE320_WORD2"},
+ {0x0003A30C, 0, 0, "RESOURCE320_WORD3"},
+ {0x0003A310, 0, 0, "RESOURCE320_WORD4"},
+ {0x0003A314, 0, 0, "RESOURCE320_WORD5"},
+ {0x0003A318, 0, 0, "RESOURCE320_WORD6"},
+};
+
+static const struct radeon_register R600_GS_RESOURCE_names[] = {
+ {0x0003A4C0, 0, 0, "RESOURCE336_WORD0"},
+ {0x0003A4C4, 0, 0, "RESOURCE336_WORD1"},
+ {0x0003A4C8, 0, 0, "RESOURCE336_WORD2"},
+ {0x0003A4CC, 0, 0, "RESOURCE336_WORD3"},
+ {0x0003A4D0, 0, 0, "RESOURCE336_WORD4"},
+ {0x0003A4D4, 0, 0, "RESOURCE336_WORD5"},
+ {0x0003A4D8, 0, 0, "RESOURCE336_WORD6"},
+};
+
+static const struct radeon_register R600_PS_SAMPLER_names[] = {
+ {0x0003C000, 0, 0, "SQ_TEX_SAMPLER_WORD0_0"},
+ {0x0003C004, 0, 0, "SQ_TEX_SAMPLER_WORD1_0"},
+ {0x0003C008, 0, 0, "SQ_TEX_SAMPLER_WORD2_0"},
+};
+
+static const struct radeon_register R600_VS_SAMPLER_names[] = {
+ {0x0003C0D8, 0, 0, "SQ_TEX_SAMPLER_WORD0_18"},
+ {0x0003C0DC, 0, 0, "SQ_TEX_SAMPLER_WORD1_18"},
+ {0x0003C0E0, 0, 0, "SQ_TEX_SAMPLER_WORD2_18"},
+};
+
+static const struct radeon_register R600_GS_SAMPLER_names[] = {
+ {0x0003C1B0, 0, 0, "SQ_TEX_SAMPLER_WORD0_36"},
+ {0x0003C1B4, 0, 0, "SQ_TEX_SAMPLER_WORD1_36"},
+ {0x0003C1B8, 0, 0, "SQ_TEX_SAMPLER_WORD2_36"},
+};
+
+static const struct radeon_register R600_PS_SAMPLER_BORDER_names[] = {
+ {0x0000A400, 0, 0, "TD_PS_SAMPLER0_BORDER_RED"},
+ {0x0000A404, 0, 0, "TD_PS_SAMPLER0_BORDER_GREEN"},
+ {0x0000A408, 0, 0, "TD_PS_SAMPLER0_BORDER_BLUE"},
+ {0x0000A40C, 0, 0, "TD_PS_SAMPLER0_BORDER_ALPHA"},
+};
+
+static const struct radeon_register R600_VS_SAMPLER_BORDER_names[] = {
+ {0x0000A600, 0, 0, "TD_VS_SAMPLER0_BORDER_RED"},
+ {0x0000A604, 0, 0, "TD_VS_SAMPLER0_BORDER_GREEN"},
+ {0x0000A608, 0, 0, "TD_VS_SAMPLER0_BORDER_BLUE"},
+ {0x0000A60C, 0, 0, "TD_VS_SAMPLER0_BORDER_ALPHA"},
+};
+
+static const struct radeon_register R600_GS_SAMPLER_BORDER_names[] = {
+ {0x0000A800, 0, 0, "TD_GS_SAMPLER0_BORDER_RED"},
+ {0x0000A804, 0, 0, "TD_GS_SAMPLER0_BORDER_GREEN"},
+ {0x0000A808, 0, 0, "TD_GS_SAMPLER0_BORDER_BLUE"},
+ {0x0000A80C, 0, 0, "TD_GS_SAMPLER0_BORDER_ALPHA"},
+};
+
+static const struct radeon_register R600_CB0_names[] = {
+ {0x00028040, 1, 0, "CB_COLOR0_BASE"},
+ {0x000280A0, 0, 0, "CB_COLOR0_INFO"},
+ {0x00028060, 0, 0, "CB_COLOR0_SIZE"},
+ {0x00028080, 0, 0, "CB_COLOR0_VIEW"},
+ {0x000280E0, 1, 1, "CB_COLOR0_FRAG"},
+ {0x000280C0, 1, 2, "CB_COLOR0_TILE"},
+ {0x00028100, 0, 0, "CB_COLOR0_MASK"},
+};
+
+static const struct radeon_register R600_DB_names[] = {
+ {0x0002800C, 1, 0, "DB_DEPTH_BASE"},
+ {0x00028000, 0, 0, "DB_DEPTH_SIZE"},
+ {0x00028004, 0, 0, "DB_DEPTH_VIEW"},
+ {0x00028010, 0, 0, "DB_DEPTH_INFO"},
+ {0x00028D24, 0, 0, "DB_HTILE_SURFACE"},
+ {0x00028D34, 0, 0, "DB_PREFETCH_LIMIT"},
+};
+
+static const struct radeon_register R600_VGT_names[] = {
+ {0x00008958, 0, 0, "VGT_PRIMITIVE_TYPE"},
+ {0x00028400, 0, 0, "VGT_MAX_VTX_INDX"},
+ {0x00028404, 0, 0, "VGT_MIN_VTX_INDX"},
+ {0x00028408, 0, 0, "VGT_INDX_OFFSET"},
+ {0x0002840C, 0, 0, "VGT_MULTI_PRIM_IB_RESET_INDX"},
+ {0x00028A7C, 0, 0, "VGT_DMA_INDEX_TYPE"},
+ {0x00028A84, 0, 0, "VGT_PRIMITIVEID_EN"},
+ {0x00028A88, 0, 0, "VGT_DMA_NUM_INSTANCES"},
+ {0x00028A94, 0, 0, "VGT_MULTI_PRIM_IB_RESET_EN"},
+ {0x00028AA0, 0, 0, "VGT_INSTANCE_STEP_RATE_0"},
+ {0x00028AA4, 0, 0, "VGT_INSTANCE_STEP_RATE_1"},
+};
+
+static const struct radeon_register R600_DRAW_names[] = {
+ {0x00008970, 0, 0, "VGT_NUM_INDICES"},
+ {0x000287E4, 0, 0, "VGT_DMA_BASE_HI"},
+ {0x000287E8, 1, 0, "VGT_DMA_BASE"},
+ {0x000287F0, 0, 0, "VGT_DRAW_INITIATOR"},
+};
+
+static struct radeon_type R600_types[] = {
+ { 128, 0, 0x00000000, 0x00000000, 0x0000, 0, "R600_CONFIG", 41, r600_state_pm4_config, R600_CONFIG_names},
+ { 128, 1, 0x00000000, 0x00000000, 0x0000, 0, "R600_CB_CNTL", 18, r600_state_pm4_generic, R600_CB_CNTL_names},
+ { 128, 2, 0x00000000, 0x00000000, 0x0000, 0, "R600_RASTERIZER", 21, r600_state_pm4_generic, R600_RASTERIZER_names},
+ { 128, 3, 0x00000000, 0x00000000, 0x0000, 0, "R600_VIEWPORT", 9, r600_state_pm4_generic, R600_VIEWPORT_names},
+ { 128, 4, 0x00000000, 0x00000000, 0x0000, 0, "R600_SCISSOR", 19, r600_state_pm4_generic, R600_SCISSOR_names},
+ { 128, 5, 0x00000000, 0x00000000, 0x0000, 0, "R600_BLEND", 13, r600_state_pm4_generic, R600_BLEND_names},
+ { 128, 6, 0x00000000, 0x00000000, 0x0000, 0, "R600_DSA", 16, r600_state_pm4_generic, R600_DSA_names},
+ { 128, 7, 0x00000000, 0x00000000, 0x0000, 0, "R600_VS_SHADER", 49, r600_state_pm4_shader, R600_VS_SHADER_names},
+ { 128, 8, 0x00000000, 0x00000000, 0x0000, 0, "R600_PS_SHADER", 39, r600_state_pm4_shader, R600_PS_SHADER_names},
+ { 128, 9, 0x00030000, 0x00031000, 0x0010, 0, "R600_PS_CONSTANT", 4, r600_state_pm4_generic, R600_PS_CONSTANT_names},
+ { 128, 265, 0x00031000, 0x00032000, 0x0010, 0, "R600_VS_CONSTANT", 4, r600_state_pm4_generic, R600_VS_CONSTANT_names},
+ { 128, 521, 0x00038000, 0x00039180, 0x001C, 0, "R600_PS_RESOURCE", 7, r600_state_pm4_resource, R600_PS_RESOURCE_names},
+ { 128, 681, 0x00039180, 0x0003A300, 0x001C, 0, "R600_VS_RESOURCE", 7, r600_state_pm4_resource, R600_VS_RESOURCE_names},
+ { 128, 841, 0x00039180, 0x0003A300, 0x001C, 0, "R600_FS_RESOURCE", 7, r600_state_pm4_resource, R600_FS_RESOURCE_names},
+ { 128, 1001, 0x00039180, 0x0003A300, 0x001C, 0, "R600_GS_RESOURCE", 7, r600_state_pm4_resource, R600_GS_RESOURCE_names},
+ { 128, 1161, 0x0003C000, 0x0003C0D8, 0x000C, 0, "R600_PS_SAMPLER", 3, r600_state_pm4_generic, R600_PS_SAMPLER_names},
+ { 128, 1179, 0x0003C0D8, 0x0003C1B0, 0x000C, 0, "R600_VS_SAMPLER", 3, r600_state_pm4_generic, R600_VS_SAMPLER_names},
+ { 128, 1197, 0x0003C1B0, 0x0003C288, 0x000C, 0, "R600_GS_SAMPLER", 3, r600_state_pm4_generic, R600_GS_SAMPLER_names},
+ { 128, 1215, 0x0000A400, 0x0000A520, 0x0010, 0, "R600_PS_SAMPLER_BORDER", 4, r600_state_pm4_generic, R600_PS_SAMPLER_BORDER_names},
+ { 128, 1233, 0x0000A600, 0x0000A720, 0x0010, 0, "R600_VS_SAMPLER_BORDER", 4, r600_state_pm4_generic, R600_VS_SAMPLER_BORDER_names},
+ { 128, 1251, 0x0000A800, 0x0000A920, 0x0010, 0, "R600_GS_SAMPLER_BORDER", 4, r600_state_pm4_generic, R600_GS_SAMPLER_BORDER_names},
+ { 128, 1269, 0x00000000, 0x00000000, 0x0000, 0, "R600_CB0", 7, r600_state_pm4_cb0, R600_CB0_names},
+ { 128, 1270, 0x00000000, 0x00000000, 0x0000, 0, "R600_DB", 6, r600_state_pm4_db, R600_DB_names},
+ { 128, 1271, 0x00000000, 0x00000000, 0x0000, 0, "R600_VGT", 11, r600_state_pm4_vgt, R600_VGT_names},
+ { 128, 1272, 0x00000000, 0x00000000, 0x0000, 0, "R600_DRAW", 4, r600_state_pm4_draw, R600_DRAW_names},
+};
+
+static struct radeon_type R700_types[] = {
+ { 128, 0, 0x00000000, 0x00000000, 0x0000, 0, "R600_CONFIG", 41, r700_state_pm4_config, R600_CONFIG_names},
+ { 128, 1, 0x00000000, 0x00000000, 0x0000, 0, "R600_CB_CNTL", 18, r600_state_pm4_generic, R600_CB_CNTL_names},
+ { 128, 2, 0x00000000, 0x00000000, 0x0000, 0, "R600_RASTERIZER", 21, r600_state_pm4_generic, R600_RASTERIZER_names},
+ { 128, 3, 0x00000000, 0x00000000, 0x0000, 0, "R600_VIEWPORT", 9, r600_state_pm4_generic, R600_VIEWPORT_names},
+ { 128, 4, 0x00000000, 0x00000000, 0x0000, 0, "R600_SCISSOR", 19, r600_state_pm4_generic, R600_SCISSOR_names},
+ { 128, 5, 0x00000000, 0x00000000, 0x0000, 0, "R600_BLEND", 13, r600_state_pm4_generic, R600_BLEND_names},
+ { 128, 6, 0x00000000, 0x00000000, 0x0000, 0, "R600_DSA", 16, r600_state_pm4_generic, R600_DSA_names},
+ { 128, 7, 0x00000000, 0x00000000, 0x0000, 0, "R600_VS_SHADER", 49, r600_state_pm4_shader, R600_VS_SHADER_names},
+ { 128, 8, 0x00000000, 0x00000000, 0x0000, 0, "R600_PS_SHADER", 39, r600_state_pm4_shader, R600_PS_SHADER_names},
+ { 128, 9, 0x00030000, 0x00031000, 0x0010, 0, "R600_PS_CONSTANT", 4, r600_state_pm4_generic, R600_PS_CONSTANT_names},
+ { 128, 265, 0x00031000, 0x00032000, 0x0010, 0, "R600_VS_CONSTANT", 4, r600_state_pm4_generic, R600_VS_CONSTANT_names},
+ { 128, 521, 0x00038000, 0x00039180, 0x001C, 0, "R600_PS_RESOURCE", 7, r600_state_pm4_resource, R600_PS_RESOURCE_names},
+ { 128, 681, 0x00039180, 0x0003A300, 0x001C, 0, "R600_VS_RESOURCE", 7, r600_state_pm4_resource, R600_VS_RESOURCE_names},
+ { 128, 841, 0x00039180, 0x0003A300, 0x001C, 0, "R600_FS_RESOURCE", 7, r600_state_pm4_resource, R600_FS_RESOURCE_names},
+ { 128, 1001, 0x00039180, 0x0003A300, 0x001C, 0, "R600_GS_RESOURCE", 7, r600_state_pm4_resource, R600_GS_RESOURCE_names},
+ { 128, 1161, 0x0003C000, 0x0003C0D8, 0x000C, 0, "R600_PS_SAMPLER", 3, r600_state_pm4_generic, R600_PS_SAMPLER_names},
+ { 128, 1179, 0x0003C0D8, 0x0003C1B0, 0x000C, 0, "R600_VS_SAMPLER", 3, r600_state_pm4_generic, R600_VS_SAMPLER_names},
+ { 128, 1197, 0x0003C1B0, 0x0003C288, 0x000C, 0, "R600_GS_SAMPLER", 3, r600_state_pm4_generic, R600_GS_SAMPLER_names},
+ { 128, 1215, 0x0000A400, 0x0000A520, 0x0010, 0, "R600_PS_SAMPLER_BORDER", 4, r600_state_pm4_generic, R600_PS_SAMPLER_BORDER_names},
+ { 128, 1233, 0x0000A600, 0x0000A720, 0x0010, 0, "R600_VS_SAMPLER_BORDER", 4, r600_state_pm4_generic, R600_VS_SAMPLER_BORDER_names},
+ { 128, 1251, 0x0000A800, 0x0000A920, 0x0010, 0, "R600_GS_SAMPLER_BORDER", 4, r600_state_pm4_generic, R600_GS_SAMPLER_BORDER_names},
+ { 128, 1269, 0x00000000, 0x00000000, 0x0000, 0, "R600_CB0", 7, r700_state_pm4_cb0, R600_CB0_names},
+ { 128, 1270, 0x00000000, 0x00000000, 0x0000, 0, "R600_DB", 6, r700_state_pm4_db, R600_DB_names},
+ { 128, 1271, 0x00000000, 0x00000000, 0x0000, 0, "R600_VGT", 11, r600_state_pm4_vgt, R600_VGT_names},
+ { 128, 1272, 0x00000000, 0x00000000, 0x0000, 0, "R600_DRAW", 4, r600_state_pm4_draw, R600_DRAW_names},
+};
+
+#endif
diff --git a/src/gallium/winsys/r600/drm/r600d.h b/src/gallium/winsys/r600/drm/r600d.h
new file mode 100644
index 0000000000..5d13378627
--- /dev/null
+++ b/src/gallium/winsys/r600/drm/r600d.h
@@ -0,0 +1,2122 @@
+/*
+ * Copyright 2010 Jerome Glisse <glisse@freedesktop.org>
+ *
+ * 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
+ * on the rights to use, copy, modify, merge, publish, distribute, sub
+ * license, and/or sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * Jerome Glisse
+ */
+#ifndef R600D_H
+#define R600D_H
+
+#define R600_CONFIG_REG_OFFSET 0X00008000
+#define R600_CONFIG_REG_END 0X0000AC00
+#define R600_CONTEXT_REG_OFFSET 0X00028000
+#define R600_CONTEXT_REG_END 0X00029000
+#define R600_ALU_CONST_OFFSET 0X00030000
+#define R600_ALU_CONST_END 0X00032000
+#define R600_RESOURCE_OFFSET 0X00038000
+#define R600_RESOURCE_END 0X0003C000
+#define R600_SAMPLER_OFFSET 0X0003C000
+#define R600_SAMPLER_END 0X0003CFF0
+#define R600_CTL_CONST_OFFSET 0X0003CFF0
+#define R600_CTL_CONST_END 0X0003E200
+#define R600_LOOP_CONST_OFFSET 0X0003E200
+#define R600_LOOP_CONST_END 0X0003E380
+#define R600_BOOL_CONST_OFFSET 0X0003E380
+#define R600_BOOL_CONST_END 0X00040000
+
+#define PKT3_NOP 0x10
+#define PKT3_INDIRECT_BUFFER_END 0x17
+#define PKT3_SET_PREDICATION 0x20
+#define PKT3_REG_RMW 0x21
+#define PKT3_COND_EXEC 0x22
+#define PKT3_PRED_EXEC 0x23
+#define PKT3_START_3D_CMDBUF 0x24
+#define PKT3_DRAW_INDEX_2 0x27
+#define PKT3_CONTEXT_CONTROL 0x28
+#define PKT3_DRAW_INDEX_IMMD_BE 0x29
+#define PKT3_INDEX_TYPE 0x2A
+#define PKT3_DRAW_INDEX 0x2B
+#define PKT3_DRAW_INDEX_AUTO 0x2D
+#define PKT3_DRAW_INDEX_IMMD 0x2E
+#define PKT3_NUM_INSTANCES 0x2F
+#define PKT3_STRMOUT_BUFFER_UPDATE 0x34
+#define PKT3_INDIRECT_BUFFER_MP 0x38
+#define PKT3_MEM_SEMAPHORE 0x39
+#define PKT3_MPEG_INDEX 0x3A
+#define PKT3_WAIT_REG_MEM 0x3C
+#define PKT3_MEM_WRITE 0x3D
+#define PKT3_INDIRECT_BUFFER 0x32
+#define PKT3_CP_INTERRUPT 0x40
+#define PKT3_SURFACE_SYNC 0x43
+#define PKT3_ME_INITIALIZE 0x44
+#define PKT3_COND_WRITE 0x45
+#define PKT3_EVENT_WRITE 0x46
+#define PKT3_EVENT_WRITE_EOP 0x47
+#define PKT3_ONE_REG_WRITE 0x57
+#define PKT3_SET_CONFIG_REG 0x68
+#define PKT3_SET_CONTEXT_REG 0x69
+#define PKT3_SET_ALU_CONST 0x6A
+#define PKT3_SET_BOOL_CONST 0x6B
+#define PKT3_SET_LOOP_CONST 0x6C
+#define PKT3_SET_RESOURCE 0x6D
+#define PKT3_SET_SAMPLER 0x6E
+#define PKT3_SET_CTL_CONST 0x6F
+#define PKT3_SURFACE_BASE_UPDATE 0x73
+
+#define PKT_TYPE_S(x) (((x) & 0x3) << 30)
+#define PKT_TYPE_G(x) (((x) >> 30) & 0x3)
+#define PKT_TYPE_C 0x3FFFFFFF
+#define PKT_COUNT_S(x) (((x) & 0x3FFF) << 16)
+#define PKT_COUNT_G(x) (((x) >> 16) & 0x3FFF)
+#define PKT_COUNT_C 0xC000FFFF
+#define PKT0_BASE_INDEX_S(x) (((x) & 0xFFFF) << 0)
+#define PKT0_BASE_INDEX_G(x) (((x) >> 0) & 0xFFFF)
+#define PKT0_BASE_INDEX_C 0xFFFF0000
+#define PKT3_IT_OPCODE_S(x) (((x) & 0xFF) << 8)
+#define PKT3_IT_OPCODE_G(x) (((x) >> 8) & 0xFF)
+#define PKT3_IT_OPCODE_C 0xFFFF00FF
+#define PKT0(index, count) (PKT_TYPE_S(0) | PKT0_BASE_INDEX_S(index) | PKT_COUNT_S(count))
+#define PKT3(op, count) (PKT_TYPE_S(3) | PKT3_IT_OPCODE_S(op) | PKT_COUNT_S(count))
+
+/* Registers */
+#define R_0280A0_CB_COLOR0_INFO 0x0280A0
+#define S_0280A0_ENDIAN(x) (((x) & 0x3) << 0)
+#define G_0280A0_ENDIAN(x) (((x) >> 0) & 0x3)
+#define C_0280A0_ENDIAN 0xFFFFFFFC
+#define S_0280A0_FORMAT(x) (((x) & 0x3F) << 2)
+#define G_0280A0_FORMAT(x) (((x) >> 2) & 0x3F)
+#define C_0280A0_FORMAT 0xFFFFFF03
+#define V_0280A0_COLOR_INVALID 0x00000000
+#define V_0280A0_COLOR_8 0x00000001
+#define V_0280A0_COLOR_4_4 0x00000002
+#define V_0280A0_COLOR_3_3_2 0x00000003
+#define V_0280A0_COLOR_16 0x00000005
+#define V_0280A0_COLOR_16_FLOAT 0x00000006
+#define V_0280A0_COLOR_8_8 0x00000007
+#define V_0280A0_COLOR_5_6_5 0x00000008
+#define V_0280A0_COLOR_6_5_5 0x00000009
+#define V_0280A0_COLOR_1_5_5_5 0x0000000A
+#define V_0280A0_COLOR_4_4_4_4 0x0000000B
+#define V_0280A0_COLOR_5_5_5_1 0x0000000C
+#define V_0280A0_COLOR_32 0x0000000D
+#define V_0280A0_COLOR_32_FLOAT 0x0000000E
+#define V_0280A0_COLOR_16_16 0x0000000F
+#define V_0280A0_COLOR_16_16_FLOAT 0x00000010
+#define V_0280A0_COLOR_8_24 0x00000011
+#define V_0280A0_COLOR_8_24_FLOAT 0x00000012
+#define V_0280A0_COLOR_24_8 0x00000013
+#define V_0280A0_COLOR_24_8_FLOAT 0x00000014
+#define V_0280A0_COLOR_10_11_11 0x00000015
+#define V_0280A0_COLOR_10_11_11_FLOAT 0x00000016
+#define V_0280A0_COLOR_11_11_10 0x00000017
+#define V_0280A0_COLOR_11_11_10_FLOAT 0x00000018
+#define V_0280A0_COLOR_2_10_10_10 0x00000019
+#define V_0280A0_COLOR_8_8_8_8 0x0000001A
+#define V_0280A0_COLOR_10_10_10_2 0x0000001B
+#define V_0280A0_COLOR_X24_8_32_FLOAT 0x0000001C
+#define V_0280A0_COLOR_32_32 0x0000001D
+#define V_0280A0_COLOR_32_32_FLOAT 0x0000001E
+#define V_0280A0_COLOR_16_16_16_16 0x0000001F
+#define V_0280A0_COLOR_16_16_16_16_FLOAT 0x00000020
+#define V_0280A0_COLOR_32_32_32_32 0x00000022
+#define V_0280A0_COLOR_32_32_32_32_FLOAT 0x00000023
+#define S_0280A0_ARRAY_MODE(x) (((x) & 0xF) << 8)
+#define G_0280A0_ARRAY_MODE(x) (((x) >> 8) & 0xF)
+#define C_0280A0_ARRAY_MODE 0xFFFFF0FF
+#define V_0280A0_ARRAY_LINEAR_GENERAL 0x00000000
+#define V_0280A0_ARRAY_LINEAR_ALIGNED 0x00000001
+#define V_0280A0_ARRAY_1D_TILED_THIN1 0x00000002
+#define V_0280A0_ARRAY_2D_TILED_THIN1 0x00000004
+#define S_0280A0_NUMBER_TYPE(x) (((x) & 0x7) << 12)
+#define G_0280A0_NUMBER_TYPE(x) (((x) >> 12) & 0x7)
+#define C_0280A0_NUMBER_TYPE 0xFFFF8FFF
+#define S_0280A0_READ_SIZE(x) (((x) & 0x1) << 15)
+#define G_0280A0_READ_SIZE(x) (((x) >> 15) & 0x1)
+#define C_0280A0_READ_SIZE 0xFFFF7FFF
+#define S_0280A0_COMP_SWAP(x) (((x) & 0x3) << 16)
+#define G_0280A0_COMP_SWAP(x) (((x) >> 16) & 0x3)
+#define C_0280A0_COMP_SWAP 0xFFFCFFFF
+#define S_0280A0_TILE_MODE(x) (((x) & 0x3) << 18)
+#define G_0280A0_TILE_MODE(x) (((x) >> 18) & 0x3)
+#define C_0280A0_TILE_MODE 0xFFF3FFFF
+#define S_0280A0_BLEND_CLAMP(x) (((x) & 0x1) << 20)
+#define G_0280A0_BLEND_CLAMP(x) (((x) >> 20) & 0x1)
+#define C_0280A0_BLEND_CLAMP 0xFFEFFFFF
+#define S_0280A0_CLEAR_COLOR(x) (((x) & 0x1) << 21)
+#define G_0280A0_CLEAR_COLOR(x) (((x) >> 21) & 0x1)
+#define C_0280A0_CLEAR_COLOR 0xFFDFFFFF
+#define S_0280A0_BLEND_BYPASS(x) (((x) & 0x1) << 22)
+#define G_0280A0_BLEND_BYPASS(x) (((x) >> 22) & 0x1)
+#define C_0280A0_BLEND_BYPASS 0xFFBFFFFF
+#define S_0280A0_BLEND_FLOAT32(x) (((x) & 0x1) << 23)
+#define G_0280A0_BLEND_FLOAT32(x) (((x) >> 23) & 0x1)
+#define C_0280A0_BLEND_FLOAT32 0xFF7FFFFF
+#define S_0280A0_SIMPLE_FLOAT(x) (((x) & 0x1) << 24)
+#define G_0280A0_SIMPLE_FLOAT(x) (((x) >> 24) & 0x1)
+#define C_0280A0_SIMPLE_FLOAT 0xFEFFFFFF
+#define S_0280A0_ROUND_MODE(x) (((x) & 0x1) << 25)
+#define G_0280A0_ROUND_MODE(x) (((x) >> 25) & 0x1)
+#define C_0280A0_ROUND_MODE 0xFDFFFFFF
+#define S_0280A0_TILE_COMPACT(x) (((x) & 0x1) << 26)
+#define G_0280A0_TILE_COMPACT(x) (((x) >> 26) & 0x1)
+#define C_0280A0_TILE_COMPACT 0xFBFFFFFF
+#define S_0280A0_SOURCE_FORMAT(x) (((x) & 0x1) << 27)
+#define G_0280A0_SOURCE_FORMAT(x) (((x) >> 27) & 0x1)
+#define C_0280A0_SOURCE_FORMAT 0xF7FFFFFF
+#define R_028060_CB_COLOR0_SIZE 0x028060
+#define S_028060_PITCH_TILE_MAX(x) (((x) & 0x3FF) << 0)
+#define G_028060_PITCH_TILE_MAX(x) (((x) >> 0) & 0x3FF)
+#define C_028060_PITCH_TILE_MAX 0xFFFFFC00
+#define S_028060_SLICE_TILE_MAX(x) (((x) & 0xFFFFF) << 10)
+#define G_028060_SLICE_TILE_MAX(x) (((x) >> 10) & 0xFFFFF)
+#define C_028060_SLICE_TILE_MAX 0xC00003FF
+#define R_028800_DB_DEPTH_CONTROL 0x028800
+#define S_028800_STENCIL_ENABLE(x) (((x) & 0x1) << 0)
+#define G_028800_STENCIL_ENABLE(x) (((x) >> 0) & 0x1)
+#define C_028800_STENCIL_ENABLE 0xFFFFFFFE
+#define S_028800_Z_ENABLE(x) (((x) & 0x1) << 1)
+#define G_028800_Z_ENABLE(x) (((x) >> 1) & 0x1)
+#define C_028800_Z_ENABLE 0xFFFFFFFD
+#define S_028800_Z_WRITE_ENABLE(x) (((x) & 0x1) << 2)
+#define G_028800_Z_WRITE_ENABLE(x) (((x) >> 2) & 0x1)
+#define C_028800_Z_WRITE_ENABLE 0xFFFFFFFB
+#define S_028800_ZFUNC(x) (((x) & 0x7) << 4)
+#define G_028800_ZFUNC(x) (((x) >> 4) & 0x7)
+#define C_028800_ZFUNC 0xFFFFFF8F
+#define S_028800_BACKFACE_ENABLE(x) (((x) & 0x1) << 7)
+#define G_028800_BACKFACE_ENABLE(x) (((x) >> 7) & 0x1)
+#define C_028800_BACKFACE_ENABLE 0xFFFFFF7F
+#define S_028800_STENCILFUNC(x) (((x) & 0x7) << 8)
+#define G_028800_STENCILFUNC(x) (((x) >> 8) & 0x7)
+#define C_028800_STENCILFUNC 0xFFFFF8FF
+#define S_028800_STENCILFAIL(x) (((x) & 0x7) << 11)
+#define G_028800_STENCILFAIL(x) (((x) >> 11) & 0x7)
+#define C_028800_STENCILFAIL 0xFFFFC7FF
+#define S_028800_STENCILZPASS(x) (((x) & 0x7) << 14)
+#define G_028800_STENCILZPASS(x) (((x) >> 14) & 0x7)
+#define C_028800_STENCILZPASS 0xFFFE3FFF
+#define S_028800_STENCILZFAIL(x) (((x) & 0x7) << 17)
+#define G_028800_STENCILZFAIL(x) (((x) >> 17) & 0x7)
+#define C_028800_STENCILZFAIL 0xFFF1FFFF
+#define S_028800_STENCILFUNC_BF(x) (((x) & 0x7) << 20)
+#define G_028800_STENCILFUNC_BF(x) (((x) >> 20) & 0x7)
+#define C_028800_STENCILFUNC_BF 0xFF8FFFFF
+#define S_028800_STENCILFAIL_BF(x) (((x) & 0x7) << 23)
+#define G_028800_STENCILFAIL_BF(x) (((x) >> 23) & 0x7)
+#define C_028800_STENCILFAIL_BF 0xFC7FFFFF
+#define S_028800_STENCILZPASS_BF(x) (((x) & 0x7) << 26)
+#define G_028800_STENCILZPASS_BF(x) (((x) >> 26) & 0x7)
+#define C_028800_STENCILZPASS_BF 0xE3FFFFFF
+#define S_028800_STENCILZFAIL_BF(x) (((x) & 0x7) << 29)
+#define G_028800_STENCILZFAIL_BF(x) (((x) >> 29) & 0x7)
+#define C_028800_STENCILZFAIL_BF 0x1FFFFFFF
+#define R_028010_DB_DEPTH_INFO 0x028010
+#define S_028010_FORMAT(x) (((x) & 0x7) << 0)
+#define G_028010_FORMAT(x) (((x) >> 0) & 0x7)
+#define C_028010_FORMAT 0xFFFFFFF8
+#define V_028010_DEPTH_INVALID 0x00000000
+#define V_028010_DEPTH_16 0x00000001
+#define V_028010_DEPTH_X8_24 0x00000002
+#define V_028010_DEPTH_8_24 0x00000003
+#define V_028010_DEPTH_X8_24_FLOAT 0x00000004
+#define V_028010_DEPTH_8_24_FLOAT 0x00000005
+#define V_028010_DEPTH_32_FLOAT 0x00000006
+#define V_028010_DEPTH_X24_8_32_FLOAT 0x00000007
+#define S_028010_READ_SIZE(x) (((x) & 0x1) << 3)
+#define G_028010_READ_SIZE(x) (((x) >> 3) & 0x1)
+#define C_028010_READ_SIZE 0xFFFFFFF7
+#define S_028010_ARRAY_MODE(x) (((x) & 0xF) << 15)
+#define G_028010_ARRAY_MODE(x) (((x) >> 15) & 0xF)
+#define C_028010_ARRAY_MODE 0xFFF87FFF
+#define S_028010_TILE_SURFACE_ENABLE(x) (((x) & 0x1) << 25)
+#define G_028010_TILE_SURFACE_ENABLE(x) (((x) >> 25) & 0x1)
+#define C_028010_TILE_SURFACE_ENABLE 0xFDFFFFFF
+#define S_028010_TILE_COMPACT(x) (((x) & 0x1) << 26)
+#define G_028010_TILE_COMPACT(x) (((x) >> 26) & 0x1)
+#define C_028010_TILE_COMPACT 0xFBFFFFFF
+#define S_028010_ZRANGE_PRECISION(x) (((x) & 0x1) << 31)
+#define G_028010_ZRANGE_PRECISION(x) (((x) >> 31) & 0x1)
+#define C_028010_ZRANGE_PRECISION 0x7FFFFFFF
+#define R_028000_DB_DEPTH_SIZE 0x028000
+#define S_028000_PITCH_TILE_MAX(x) (((x) & 0x3FF) << 0)
+#define G_028000_PITCH_TILE_MAX(x) (((x) >> 0) & 0x3FF)
+#define C_028000_PITCH_TILE_MAX 0xFFFFFC00
+#define S_028000_SLICE_TILE_MAX(x) (((x) & 0xFFFFF) << 10)
+#define G_028000_SLICE_TILE_MAX(x) (((x) >> 10) & 0xFFFFF)
+#define C_028000_SLICE_TILE_MAX 0xC00003FF
+#define R_028004_DB_DEPTH_VIEW 0x028004
+#define S_028004_SLICE_START(x) (((x) & 0x7FF) << 0)
+#define G_028004_SLICE_START(x) (((x) >> 0) & 0x7FF)
+#define C_028004_SLICE_START 0xFFFFF800
+#define S_028004_SLICE_MAX(x) (((x) & 0x7FF) << 13)
+#define G_028004_SLICE_MAX(x) (((x) >> 13) & 0x7FF)
+#define C_028004_SLICE_MAX 0xFF001FFF
+#define R_028D24_DB_HTILE_SURFACE 0x028D24
+#define S_028D24_HTILE_WIDTH(x) (((x) & 0x1) << 0)
+#define G_028D24_HTILE_WIDTH(x) (((x) >> 0) & 0x1)
+#define C_028D24_HTILE_WIDTH 0xFFFFFFFE
+#define S_028D24_HTILE_HEIGHT(x) (((x) & 0x1) << 1)
+#define G_028D24_HTILE_HEIGHT(x) (((x) >> 1) & 0x1)
+#define C_028D24_HTILE_HEIGHT 0xFFFFFFFD
+#define S_028D24_LINEAR(x) (((x) & 0x1) << 2)
+#define G_028D24_LINEAR(x) (((x) >> 2) & 0x1)
+#define C_028D24_LINEAR 0xFFFFFFFB
+#define S_028D24_FULL_CACHE(x) (((x) & 0x1) << 3)
+#define G_028D24_FULL_CACHE(x) (((x) >> 3) & 0x1)
+#define C_028D24_FULL_CACHE 0xFFFFFFF7
+#define S_028D24_HTILE_USES_PRELOAD_WIN(x) (((x) & 0x1) << 4)
+#define G_028D24_HTILE_USES_PRELOAD_WIN(x) (((x) >> 4) & 0x1)
+#define C_028D24_HTILE_USES_PRELOAD_WIN 0xFFFFFFEF
+#define S_028D24_PRELOAD(x) (((x) & 0x1) << 5)
+#define G_028D24_PRELOAD(x) (((x) >> 5) & 0x1)
+#define C_028D24_PRELOAD 0xFFFFFFDF
+#define S_028D24_PREFETCH_WIDTH(x) (((x) & 0x3F) << 6)
+#define G_028D24_PREFETCH_WIDTH(x) (((x) >> 6) & 0x3F)
+#define C_028D24_PREFETCH_WIDTH 0xFFFFF03F
+#define S_028D24_PREFETCH_HEIGHT(x) (((x) & 0x3F) << 12)
+#define G_028D24_PREFETCH_HEIGHT(x) (((x) >> 12) & 0x3F)
+#define C_028D24_PREFETCH_HEIGHT 0xFFFC0FFF
+#define R_028D34_DB_PREFETCH_LIMIT 0x028D34
+#define S_028D34_DEPTH_HEIGHT_TILE_MAX(x) (((x) & 0x3FF) << 0)
+#define G_028D34_DEPTH_HEIGHT_TILE_MAX(x) (((x) >> 0) & 0x3FF)
+#define C_028D34_DEPTH_HEIGHT_TILE_MAX 0xFFFFFC00
+#define R_028D10_DB_RENDER_OVERRIDE 0x028D10
+#define S_028D10_FORCE_HIZ_ENABLE(x) (((x) & 0x3) << 0)
+#define G_028D10_FORCE_HIZ_ENABLE(x) (((x) >> 0) & 0x3)
+#define C_028D10_FORCE_HIZ_ENABLE 0xFFFFFFFC
+#define S_028D10_FORCE_HIS_ENABLE0(x) (((x) & 0x3) << 2)
+#define G_028D10_FORCE_HIS_ENABLE0(x) (((x) >> 2) & 0x3)
+#define C_028D10_FORCE_HIS_ENABLE0 0xFFFFFFF3
+#define S_028D10_FORCE_HIS_ENABLE1(x) (((x) & 0x3) << 4)
+#define G_028D10_FORCE_HIS_ENABLE1(x) (((x) >> 4) & 0x3)
+#define C_028D10_FORCE_HIS_ENABLE1 0xFFFFFFCF
+#define S_028D10_FORCE_SHADER_Z_ORDER(x) (((x) & 0x1) << 6)
+#define G_028D10_FORCE_SHADER_Z_ORDER(x) (((x) >> 6) & 0x1)
+#define C_028D10_FORCE_SHADER_Z_ORDER 0xFFFFFFBF
+#define S_028D10_FAST_Z_DISABLE(x) (((x) & 0x1) << 7)
+#define G_028D10_FAST_Z_DISABLE(x) (((x) >> 7) & 0x1)
+#define C_028D10_FAST_Z_DISABLE 0xFFFFFF7F
+#define S_028D10_FAST_STENCIL_DISABLE(x) (((x) & 0x1) << 8)
+#define G_028D10_FAST_STENCIL_DISABLE(x) (((x) >> 8) & 0x1)
+#define C_028D10_FAST_STENCIL_DISABLE 0xFFFFFEFF
+#define S_028D10_NOOP_CULL_DISABLE(x) (((x) & 0x1) << 9)
+#define G_028D10_NOOP_CULL_DISABLE(x) (((x) >> 9) & 0x1)
+#define C_028D10_NOOP_CULL_DISABLE 0xFFFFFDFF
+#define S_028D10_FORCE_COLOR_KILL(x) (((x) & 0x1) << 10)
+#define G_028D10_FORCE_COLOR_KILL(x) (((x) >> 10) & 0x1)
+#define C_028D10_FORCE_COLOR_KILL 0xFFFFFBFF
+#define S_028D10_FORCE_Z_READ(x) (((x) & 0x1) << 11)
+#define G_028D10_FORCE_Z_READ(x) (((x) >> 11) & 0x1)
+#define C_028D10_FORCE_Z_READ 0xFFFFF7FF
+#define S_028D10_FORCE_STENCIL_READ(x) (((x) & 0x1) << 12)
+#define G_028D10_FORCE_STENCIL_READ(x) (((x) >> 12) & 0x1)
+#define C_028D10_FORCE_STENCIL_READ 0xFFFFEFFF
+#define S_028D10_FORCE_FULL_Z_RANGE(x) (((x) & 0x3) << 13)
+#define G_028D10_FORCE_FULL_Z_RANGE(x) (((x) >> 13) & 0x3)
+#define C_028D10_FORCE_FULL_Z_RANGE 0xFFFF9FFF
+#define S_028D10_FORCE_QC_SMASK_CONFLICT(x) (((x) & 0x1) << 15)
+#define G_028D10_FORCE_QC_SMASK_CONFLICT(x) (((x) >> 15) & 0x1)
+#define C_028D10_FORCE_QC_SMASK_CONFLICT 0xFFFF7FFF
+#define S_028D10_DISABLE_VIEWPORT_CLAMP(x) (((x) & 0x1) << 16)
+#define G_028D10_DISABLE_VIEWPORT_CLAMP(x) (((x) >> 16) & 0x1)
+#define C_028D10_DISABLE_VIEWPORT_CLAMP 0xFFFEFFFF
+#define S_028D10_IGNORE_SC_ZRANGE(x) (((x) & 0x1) << 17)
+#define G_028D10_IGNORE_SC_ZRANGE(x) (((x) >> 17) & 0x1)
+#define C_028D10_IGNORE_SC_ZRANGE 0xFFFDFFFF
+#define R_028A40_VGT_GS_MODE 0x028A40
+#define S_028A40_MODE(x) (((x) & 0x3) << 0)
+#define G_028A40_MODE(x) (((x) >> 0) & 0x3)
+#define C_028A40_MODE 0xFFFFFFFC
+#define S_028A40_ES_PASSTHRU(x) (((x) & 0x1) << 2)
+#define G_028A40_ES_PASSTHRU(x) (((x) >> 2) & 0x1)
+#define C_028A40_ES_PASSTHRU 0xFFFFFFFB
+#define S_028A40_CUT_MODE(x) (((x) & 0x3) << 3)
+#define G_028A40_CUT_MODE(x) (((x) >> 3) & 0x3)
+#define C_028A40_CUT_MODE 0xFFFFFFE7
+#define R_008DFC_SQ_CF_WORD0 0x008DFC
+#define S_008DFC_ADDR(x) (((x) & 0xFFFFFFFF) << 0)
+#define G_008DFC_ADDR(x) (((x) >> 0) & 0xFFFFFFFF)
+#define C_008DFC_ADDR 0x00000000
+#define R_008DFC_SQ_CF_WORD1 0x008DFC
+#define S_008DFC_POP_COUNT(x) (((x) & 0x7) << 0)
+#define G_008DFC_POP_COUNT(x) (((x) >> 0) & 0x7)
+#define C_008DFC_POP_COUNT 0xFFFFFFF8
+#define S_008DFC_CF_CONST(x) (((x) & 0x1F) << 3)
+#define G_008DFC_CF_CONST(x) (((x) >> 3) & 0x1F)
+#define C_008DFC_CF_CONST 0xFFFFFF07
+#define S_008DFC_COND(x) (((x) & 0x3) << 8)
+#define G_008DFC_COND(x) (((x) >> 8) & 0x3)
+#define C_008DFC_COND 0xFFFFFCFF
+#define S_008DFC_COUNT(x) (((x) & 0x7) << 10)
+#define G_008DFC_COUNT(x) (((x) >> 10) & 0x7)
+#define C_008DFC_COUNT 0xFFFFE3FF
+#define S_008DFC_CALL_COUNT(x) (((x) & 0x3F) << 13)
+#define G_008DFC_CALL_COUNT(x) (((x) >> 13) & 0x3F)
+#define C_008DFC_CALL_COUNT 0xFFF81FFF
+#define S_008DFC_END_OF_PROGRAM(x) (((x) & 0x1) << 21)
+#define G_008DFC_END_OF_PROGRAM(x) (((x) >> 21) & 0x1)
+#define C_008DFC_END_OF_PROGRAM 0xFFDFFFFF
+#define S_008DFC_VALID_PIXEL_MODE(x) (((x) & 0x1) << 22)
+#define G_008DFC_VALID_PIXEL_MODE(x) (((x) >> 22) & 0x1)
+#define C_008DFC_VALID_PIXEL_MODE 0xFFBFFFFF
+#define S_008DFC_CF_INST(x) (((x) & 0x7F) << 23)
+#define G_008DFC_CF_INST(x) (((x) >> 23) & 0x7F)
+#define C_008DFC_CF_INST 0xC07FFFFF
+#define V_008DFC_SQ_CF_INST_NOP 0x00000000
+#define V_008DFC_SQ_CF_INST_TEX 0x00000001
+#define V_008DFC_SQ_CF_INST_VTX 0x00000002
+#define V_008DFC_SQ_CF_INST_VTX_TC 0x00000003
+#define V_008DFC_SQ_CF_INST_LOOP_START 0x00000004
+#define V_008DFC_SQ_CF_INST_LOOP_END 0x00000005
+#define V_008DFC_SQ_CF_INST_LOOP_START_DX10 0x00000006
+#define V_008DFC_SQ_CF_INST_LOOP_START_NO_AL 0x00000007
+#define V_008DFC_SQ_CF_INST_LOOP_CONTINUE 0x00000008
+#define V_008DFC_SQ_CF_INST_LOOP_BREAK 0x00000009
+#define V_008DFC_SQ_CF_INST_JUMP 0x0000000A
+#define V_008DFC_SQ_CF_INST_PUSH 0x0000000B
+#define V_008DFC_SQ_CF_INST_PUSH_ELSE 0x0000000C
+#define V_008DFC_SQ_CF_INST_ELSE 0x0000000D
+#define V_008DFC_SQ_CF_INST_POP 0x0000000E
+#define V_008DFC_SQ_CF_INST_POP_JUMP 0x0000000F
+#define V_008DFC_SQ_CF_INST_POP_PUSH 0x00000010
+#define V_008DFC_SQ_CF_INST_POP_PUSH_ELSE 0x00000011
+#define V_008DFC_SQ_CF_INST_CALL 0x00000012
+#define V_008DFC_SQ_CF_INST_CALL_FS 0x00000013
+#define V_008DFC_SQ_CF_INST_RETURN 0x00000014
+#define V_008DFC_SQ_CF_INST_EMIT_VERTEX 0x00000015
+#define V_008DFC_SQ_CF_INST_EMIT_CUT_VERTEX 0x00000016
+#define V_008DFC_SQ_CF_INST_CUT_VERTEX 0x00000017
+#define V_008DFC_SQ_CF_INST_KILL 0x00000018
+#define S_008DFC_WHOLE_QUAD_MODE(x) (((x) & 0x1) << 30)
+#define G_008DFC_WHOLE_QUAD_MODE(x) (((x) >> 30) & 0x1)
+#define C_008DFC_WHOLE_QUAD_MODE 0xBFFFFFFF
+#define S_008DFC_BARRIER(x) (((x) & 0x1) << 31)
+#define G_008DFC_BARRIER(x) (((x) >> 31) & 0x1)
+#define C_008DFC_BARRIER 0x7FFFFFFF
+#define R_008DFC_SQ_CF_ALU_WORD0 0x008DFC
+#define S_008DFC_ALU_ADDR(x) (((x) & 0x3FFFFF) << 0)
+#define G_008DFC_ALU_ADDR(x) (((x) >> 0) & 0x3FFFFF)
+#define C_008DFC_ALU_ADDR 0xFFC00000
+#define S_008DFC_KCACHE_BANK0(x) (((x) & 0xF) << 22)
+#define G_008DFC_KCACHE_BANK0(x) (((x) >> 22) & 0xF)
+#define C_008DFC_KCACHE_BANK0 0xFC3FFFFF
+#define S_008DFC_KCACHE_BANK1(x) (((x) & 0xF) << 26)
+#define G_008DFC_KCACHE_BANK1(x) (((x) >> 26) & 0xF)
+#define C_008DFC_KCACHE_BANK1 0xC3FFFFFF
+#define S_008DFC_KCACHE_MODE0(x) (((x) & 0x3) << 30)
+#define G_008DFC_KCACHE_MODE0(x) (((x) >> 30) & 0x3)
+#define C_008DFC_KCACHE_MODE0 0x3FFFFFFF
+#define R_008DFC_SQ_CF_ALU_WORD1 0x008DFC
+#define S_008DFC_KCACHE_MODE1(x) (((x) & 0x3) << 0)
+#define G_008DFC_KCACHE_MODE1(x) (((x) >> 0) & 0x3)
+#define C_008DFC_KCACHE_MODE1 0xFFFFFFFC
+#define S_008DFC_KCACHE_ADDR0(x) (((x) & 0xFF) << 2)
+#define G_008DFC_KCACHE_ADDR0(x) (((x) >> 2) & 0xFF)
+#define C_008DFC_KCACHE_ADDR0 0xFFFFFC03
+#define S_008DFC_KCACHE_ADDR1(x) (((x) & 0xFF) << 10)
+#define G_008DFC_KCACHE_ADDR1(x) (((x) >> 10) & 0xFF)
+#define C_008DFC_KCACHE_ADDR1 0xFFFC03FF
+#define S_008DFC_ALU_COUNT(x) (((x) & 0x7F) << 18)
+#define G_008DFC_ALU_COUNT(x) (((x) >> 18) & 0x7F)
+#define C_008DFC_ALU_COUNT 0xFE03FFFF
+#define S_008DFC_USES_WATERFALL(x) (((x) & 0x1) << 25)
+#define G_008DFC_USES_WATERFALL(x) (((x) >> 25) & 0x1)
+#define C_008DFC_USES_WATERFALL 0xFDFFFFFF
+#define S_008DFC_CF_ALU_INST(x) (((x) & 0xF) << 26)
+#define G_008DFC_CF_ALU_INST(x) (((x) >> 26) & 0xF)
+#define C_008DFC_CF_ALU_INST 0xC3FFFFFF
+#define V_008DFC_SQ_CF_INST_ALU 0x00000008
+#define V_008DFC_SQ_CF_INST_ALU_PUSH_BEFORE 0x00000009
+#define V_008DFC_SQ_CF_INST_ALU_POP_AFTER 0x0000000A
+#define V_008DFC_SQ_CF_INST_ALU_POP2_AFTER 0x0000000B
+#define V_008DFC_SQ_CF_INST_ALU_CONTINUE 0x0000000D
+#define V_008DFC_SQ_CF_INST_ALU_BREAK 0x0000000E
+#define V_008DFC_SQ_CF_INST_ALU_ELSE_AFTER 0x0000000F
+#define S_008DFC_WHOLE_QUAD_MODE(x) (((x) & 0x1) << 30)
+#define G_008DFC_WHOLE_QUAD_MODE(x) (((x) >> 30) & 0x1)
+#define C_008DFC_WHOLE_QUAD_MODE 0xBFFFFFFF
+#define S_008DFC_BARRIER(x) (((x) & 0x1) << 31)
+#define G_008DFC_BARRIER(x) (((x) >> 31) & 0x1)
+#define C_008DFC_BARRIER 0x7FFFFFFF
+#define R_008DFC_SQ_CF_ALLOC_EXPORT_WORD0 0x008DFC
+#define S_008DFC_ARRAY_BASE(x) (((x) & 0x1FFF) << 0)
+#define G_008DFC_ARRAY_BASE(x) (((x) >> 0) & 0x1FFF)
+#define C_008DFC_ARRAY_BASE 0xFFFFE000
+#define S_008DFC_TYPE(x) (((x) & 0x3) << 13)
+#define G_008DFC_TYPE(x) (((x) >> 13) & 0x3)
+#define C_008DFC_TYPE 0xFFFF9FFF
+#define S_008DFC_RW_GPR(x) (((x) & 0x7F) << 15)
+#define G_008DFC_RW_GPR(x) (((x) >> 15) & 0x7F)
+#define C_008DFC_RW_GPR 0xFFC07FFF
+#define S_008DFC_RW_REL(x) (((x) & 0x1) << 22)
+#define G_008DFC_RW_REL(x) (((x) >> 22) & 0x1)
+#define C_008DFC_RW_REL 0xFFBFFFFF
+#define S_008DFC_INDEX_GPR(x) (((x) & 0x7F) << 23)
+#define G_008DFC_INDEX_GPR(x) (((x) >> 23) & 0x7F)
+#define C_008DFC_INDEX_GPR 0xC07FFFFF
+#define S_008DFC_ELEM_SIZE(x) (((x) & 0x3) << 30)
+#define G_008DFC_ELEM_SIZE(x) (((x) >> 30) & 0x3)
+#define C_008DFC_ELEM_SIZE 0x3FFFFFFF
+#define R_008DFC_SQ_CF_ALLOC_EXPORT_WORD1 0x008DFC
+#define S_008DFC_BURST_COUNT(x) (((x) & 0xF) << 17)
+#define G_008DFC_BURST_COUNT(x) (((x) >> 17) & 0xF)
+#define C_008DFC_BURST_COUNT 0xFFE1FFFF
+#define S_008DFC_END_OF_PROGRAM(x) (((x) & 0x1) << 21)
+#define G_008DFC_END_OF_PROGRAM(x) (((x) >> 21) & 0x1)
+#define C_008DFC_END_OF_PROGRAM 0xFFDFFFFF
+#define S_008DFC_VALID_PIXEL_MODE(x) (((x) & 0x1) << 22)
+#define G_008DFC_VALID_PIXEL_MODE(x) (((x) >> 22) & 0x1)
+#define C_008DFC_VALID_PIXEL_MODE 0xFFBFFFFF
+#define S_008DFC_CF_INST(x) (((x) & 0x7F) << 23)
+#define G_008DFC_CF_INST(x) (((x) >> 23) & 0x7F)
+#define C_008DFC_CF_INST 0xC07FFFFF
+#define V_008DFC_SQ_CF_INST_MEM_STREAM0 0x00000020
+#define V_008DFC_SQ_CF_INST_MEM_STREAM1 0x00000021
+#define V_008DFC_SQ_CF_INST_MEM_STREAM2 0x00000022
+#define V_008DFC_SQ_CF_INST_MEM_STREAM3 0x00000023
+#define V_008DFC_SQ_CF_INST_MEM_SCRATCH 0x00000024
+#define V_008DFC_SQ_CF_INST_MEM_REDUCTION 0x00000025
+#define V_008DFC_SQ_CF_INST_MEM_RING 0x00000026
+#define V_008DFC_SQ_CF_INST_EXPORT 0x00000027
+#define V_008DFC_SQ_CF_INST_EXPORT_DONE 0x00000028
+#define S_008DFC_WHOLE_QUAD_MODE(x) (((x) & 0x1) << 30)
+#define G_008DFC_WHOLE_QUAD_MODE(x) (((x) >> 30) & 0x1)
+#define C_008DFC_WHOLE_QUAD_MODE 0xBFFFFFFF
+#define S_008DFC_BARRIER(x) (((x) & 0x1) << 31)
+#define G_008DFC_BARRIER(x) (((x) >> 31) & 0x1)
+#define C_008DFC_BARRIER 0x7FFFFFFF
+#define R_008DFC_SQ_CF_ALLOC_EXPORT_WORD1_BUF 0x008DFC
+#define S_008DFC_ARRAY_SIZE(x) (((x) & 0xFFF) << 0)
+#define G_008DFC_ARRAY_SIZE(x) (((x) >> 0) & 0xFFF)
+#define C_008DFC_ARRAY_SIZE 0xFFFFF000
+#define S_008DFC_COMP_MASK(x) (((x) & 0xF) << 12)
+#define G_008DFC_COMP_MASK(x) (((x) >> 12) & 0xF)
+#define C_008DFC_COMP_MASK 0xFFFF0FFF
+#define R_008DFC_SQ_CF_ALLOC_EXPORT_WORD1_SWIZ 0x008DFC
+#define S_008DFC_SEL_X(x) (((x) & 0x7) << 0)
+#define G_008DFC_SEL_X(x) (((x) >> 0) & 0x7)
+#define C_008DFC_SEL_X 0xFFFFFFF8
+#define S_008DFC_SEL_Y(x) (((x) & 0x7) << 3)
+#define G_008DFC_SEL_Y(x) (((x) >> 3) & 0x7)
+#define C_008DFC_SEL_Y 0xFFFFFFC7
+#define S_008DFC_SEL_Z(x) (((x) & 0x7) << 6)
+#define G_008DFC_SEL_Z(x) (((x) >> 6) & 0x7)
+#define C_008DFC_SEL_Z 0xFFFFFE3F
+#define S_008DFC_SEL_W(x) (((x) & 0x7) << 9)
+#define G_008DFC_SEL_W(x) (((x) >> 9) & 0x7)
+#define C_008DFC_SEL_W 0xFFFFF1FF
+#define R_008DFC_SQ_VTX_WORD0 0x008DFC
+#define S_008DFC_VTX_INST(x) (((x) & 0x1F) << 0)
+#define G_008DFC_VTX_INST(x) (((x) >> 0) & 0x1F)
+#define C_008DFC_VTX_INST 0xFFFFFFE0
+#define S_008DFC_FETCH_TYPE(x) (((x) & 0x3) << 5)
+#define G_008DFC_FETCH_TYPE(x) (((x) >> 5) & 0x3)
+#define C_008DFC_FETCH_TYPE 0xFFFFFF9F
+#define S_008DFC_FETCH_WHOLE_QUAD(x) (((x) & 0x1) << 7)
+#define G_008DFC_FETCH_WHOLE_QUAD(x) (((x) >> 7) & 0x1)
+#define C_008DFC_FETCH_WHOLE_QUAD 0xFFFFFF7F
+#define S_008DFC_BUFFER_ID(x) (((x) & 0xFF) << 8)
+#define G_008DFC_BUFFER_ID(x) (((x) >> 8) & 0xFF)
+#define C_008DFC_BUFFER_ID 0xFFFF00FF
+#define S_008DFC_SRC_GPR(x) (((x) & 0x7F) << 16)
+#define G_008DFC_SRC_GPR(x) (((x) >> 16) & 0x7F)
+#define C_008DFC_SRC_GPR 0xFF80FFFF
+#define S_008DFC_SRC_REL(x) (((x) & 0x1) << 23)
+#define G_008DFC_SRC_REL(x) (((x) >> 23) & 0x1)
+#define C_008DFC_SRC_REL 0xFF7FFFFF
+#define S_008DFC_SRC_SEL_X(x) (((x) & 0x3) << 24)
+#define G_008DFC_SRC_SEL_X(x) (((x) >> 24) & 0x3)
+#define C_008DFC_SRC_SEL_X 0xFCFFFFFF
+#define S_008DFC_MEGA_FETCH_COUNT(x) (((x) & 0x3F) << 26)
+#define G_008DFC_MEGA_FETCH_COUNT(x) (((x) >> 26) & 0x3F)
+#define C_008DFC_MEGA_FETCH_COUNT 0x03FFFFFF
+#define R_008DFC_SQ_VTX_WORD1 0x008DFC
+#define S_008DFC_DST_SEL_X(x) (((x) & 0x7) << 9)
+#define G_008DFC_DST_SEL_X(x) (((x) >> 9) & 0x7)
+#define C_008DFC_DST_SEL_X 0xFFFFF1FF
+#define S_008DFC_DST_SEL_Y(x) (((x) & 0x7) << 12)
+#define G_008DFC_DST_SEL_Y(x) (((x) >> 12) & 0x7)
+#define C_008DFC_DST_SEL_Y 0xFFFF8FFF
+#define S_008DFC_DST_SEL_Z(x) (((x) & 0x7) << 15)
+#define G_008DFC_DST_SEL_Z(x) (((x) >> 15) & 0x7)
+#define C_008DFC_DST_SEL_Z 0xFFFC7FFF
+#define S_008DFC_DST_SEL_W(x) (((x) & 0x7) << 18)
+#define G_008DFC_DST_SEL_W(x) (((x) >> 18) & 0x7)
+#define C_008DFC_DST_SEL_W 0xFFE3FFFF
+#define S_008DFC_USE_CONST_FIELDS(x) (((x) & 0x1) << 21)
+#define G_008DFC_USE_CONST_FIELDS(x) (((x) >> 21) & 0x1)
+#define C_008DFC_USE_CONST_FIELDS 0xFFDFFFFF
+#define S_008DFC_DATA_FORMAT(x) (((x) & 0x3F) << 22)
+#define G_008DFC_DATA_FORMAT(x) (((x) >> 22) & 0x3F)
+#define C_008DFC_DATA_FORMAT 0xF03FFFFF
+#define S_008DFC_NUM_FORMAT_ALL(x) (((x) & 0x3) << 28)
+#define G_008DFC_NUM_FORMAT_ALL(x) (((x) >> 28) & 0x3)
+#define C_008DFC_NUM_FORMAT_ALL 0xCFFFFFFF
+#define S_008DFC_FORMAT_COMP_ALL(x) (((x) & 0x1) << 30)
+#define G_008DFC_FORMAT_COMP_ALL(x) (((x) >> 30) & 0x1)
+#define C_008DFC_FORMAT_COMP_ALL 0xBFFFFFFF
+#define S_008DFC_SRF_MODE_ALL(x) (((x) & 0x1) << 31)
+#define G_008DFC_SRF_MODE_ALL(x) (((x) >> 31) & 0x1)
+#define C_008DFC_SRF_MODE_ALL 0x7FFFFFFF
+#define R_008DFC_SQ_VTX_WORD1_GPR 0x008DFC
+#define S_008DFC_DST_GPR(x) (((x) & 0x7F) << 0)
+#define G_008DFC_DST_GPR(x) (((x) >> 0) & 0x7F)
+#define C_008DFC_DST_GPR 0xFFFFFF80
+#define S_008DFC_DST_REL(x) (((x) & 0x1) << 7)
+#define G_008DFC_DST_REL(x) (((x) >> 7) & 0x1)
+#define C_008DFC_DST_REL 0xFFFFFF7F
+#define R_008DFC_SQ_VTX_WORD2 0x008DFC
+#define S_008DFC_OFFSET(x) (((x) & 0xFFFF) << 0)
+#define G_008DFC_OFFSET(x) (((x) >> 0) & 0xFFFF)
+#define C_008DFC_OFFSET 0xFFFF0000
+#define S_008DFC_ENDIAN_SWAP(x) (((x) & 0x3) << 16)
+#define G_008DFC_ENDIAN_SWAP(x) (((x) >> 16) & 0x3)
+#define C_008DFC_ENDIAN_SWAP 0xFFFCFFFF
+#define S_008DFC_CONST_BUF_NO_STRIDE(x) (((x) & 0x1) << 18)
+#define G_008DFC_CONST_BUF_NO_STRIDE(x) (((x) >> 18) & 0x1)
+#define C_008DFC_CONST_BUF_NO_STRIDE 0xFFFBFFFF
+#define S_008DFC_MEGA_FETCH(x) (((x) & 0x1) << 19)
+#define G_008DFC_MEGA_FETCH(x) (((x) >> 19) & 0x1)
+#define C_008DFC_MEGA_FETCH 0xFFF7FFFF
+#define S_008DFC_ALT_CONST(x) (((x) & 0x1) << 20)
+#define G_008DFC_ALT_CONST(x) (((x) >> 20) & 0x1)
+#define C_008DFC_ALT_CONST 0xFFEFFFFF
+#define R_008040_WAIT_UNTIL 0x008040
+#define S_008040_WAIT_CP_DMA_IDLE(x) (((x) & 0x1) << 8)
+#define G_008040_WAIT_CP_DMA_IDLE(x) (((x) >> 8) & 0x1)
+#define C_008040_WAIT_CP_DMA_IDLE 0xFFFFFEFF
+#define S_008040_WAIT_CMDFIFO(x) (((x) & 0x1) << 10)
+#define G_008040_WAIT_CMDFIFO(x) (((x) >> 10) & 0x1)
+#define C_008040_WAIT_CMDFIFO 0xFFFFFBFF
+#define S_008040_WAIT_2D_IDLE(x) (((x) & 0x1) << 14)
+#define G_008040_WAIT_2D_IDLE(x) (((x) >> 14) & 0x1)
+#define C_008040_WAIT_2D_IDLE 0xFFFFBFFF
+#define S_008040_WAIT_3D_IDLE(x) (((x) & 0x1) << 15)
+#define G_008040_WAIT_3D_IDLE(x) (((x) >> 15) & 0x1)
+#define C_008040_WAIT_3D_IDLE 0xFFFF7FFF
+#define S_008040_WAIT_2D_IDLECLEAN(x) (((x) & 0x1) << 16)
+#define G_008040_WAIT_2D_IDLECLEAN(x) (((x) >> 16) & 0x1)
+#define C_008040_WAIT_2D_IDLECLEAN 0xFFFEFFFF
+#define S_008040_WAIT_3D_IDLECLEAN(x) (((x) & 0x1) << 17)
+#define G_008040_WAIT_3D_IDLECLEAN(x) (((x) >> 17) & 0x1)
+#define C_008040_WAIT_3D_IDLECLEAN 0xFFFDFFFF
+#define S_008040_WAIT_EXTERN_SIG(x) (((x) & 0x1) << 19)
+#define G_008040_WAIT_EXTERN_SIG(x) (((x) >> 19) & 0x1)
+#define C_008040_WAIT_EXTERN_SIG 0xFFF7FFFF
+#define S_008040_CMDFIFO_ENTRIES(x) (((x) & 0x1F) << 20)
+#define G_008040_CMDFIFO_ENTRIES(x) (((x) >> 20) & 0x1F)
+#define C_008040_CMDFIFO_ENTRIES 0xFE0FFFFF
+#define R_0286CC_SPI_PS_IN_CONTROL_0 0x0286CC
+#define S_0286CC_NUM_INTERP(x) (((x) & 0x3F) << 0)
+#define G_0286CC_NUM_INTERP(x) (((x) >> 0) & 0x3F)
+#define C_0286CC_NUM_INTERP 0xFFFFFFC0
+#define S_0286CC_POSITION_ENA(x) (((x) & 0x1) << 8)
+#define G_0286CC_POSITION_ENA(x) (((x) >> 8) & 0x1)
+#define C_0286CC_POSITION_ENA 0xFFFFFEFF
+#define S_0286CC_POSITION_CENTROID(x) (((x) & 0x1) << 9)
+#define G_0286CC_POSITION_CENTROID(x) (((x) >> 9) & 0x1)
+#define C_0286CC_POSITION_CENTROID 0xFFFFFDFF
+#define S_0286CC_POSITION_ADDR(x) (((x) & 0x1F) << 10)
+#define G_0286CC_POSITION_ADDR(x) (((x) >> 10) & 0x1F)
+#define C_0286CC_POSITION_ADDR 0xFFFF83FF
+#define S_0286CC_PARAM_GEN(x) (((x) & 0xF) << 15)
+#define G_0286CC_PARAM_GEN(x) (((x) >> 15) & 0xF)
+#define C_0286CC_PARAM_GEN 0xFFF87FFF
+#define S_0286CC_PARAM_GEN_ADDR(x) (((x) & 0x7F) << 19)
+#define G_0286CC_PARAM_GEN_ADDR(x) (((x) >> 19) & 0x7F)
+#define C_0286CC_PARAM_GEN_ADDR 0xFC07FFFF
+#define S_0286CC_BARYC_SAMPLE_CNTL(x) (((x) & 0x3) << 26)
+#define G_0286CC_BARYC_SAMPLE_CNTL(x) (((x) >> 26) & 0x3)
+#define C_0286CC_BARYC_SAMPLE_CNTL 0xF3FFFFFF
+#define S_0286CC_PERSP_GRADIENT_ENA(x) (((x) & 0x1) << 28)
+#define G_0286CC_PERSP_GRADIENT_ENA(x) (((x) >> 28) & 0x1)
+#define C_0286CC_PERSP_GRADIENT_ENA 0xEFFFFFFF
+#define S_0286CC_LINEAR_GRADIENT_ENA(x) (((x) & 0x1) << 29)
+#define G_0286CC_LINEAR_GRADIENT_ENA(x) (((x) >> 29) & 0x1)
+#define C_0286CC_LINEAR_GRADIENT_ENA 0xDFFFFFFF
+#define S_0286CC_POSITION_SAMPLE(x) (((x) & 0x1) << 30)
+#define G_0286CC_POSITION_SAMPLE(x) (((x) >> 30) & 0x1)
+#define C_0286CC_POSITION_SAMPLE 0xBFFFFFFF
+#define S_0286CC_BARYC_AT_SAMPLE_ENA(x) (((x) & 0x1) << 31)
+#define G_0286CC_BARYC_AT_SAMPLE_ENA(x) (((x) >> 31) & 0x1)
+#define C_0286CC_BARYC_AT_SAMPLE_ENA 0x7FFFFFFF
+#define R_0286D0_SPI_PS_IN_CONTROL_1 0x0286D0
+#define S_0286D0_GEN_INDEX_PIX(x) (((x) & 0x1) << 0)
+#define G_0286D0_GEN_INDEX_PIX(x) (((x) >> 0) & 0x1)
+#define C_0286D0_GEN_INDEX_PIX 0xFFFFFFFE
+#define S_0286D0_GEN_INDEX_PIX_ADDR(x) (((x) & 0x7F) << 1)
+#define G_0286D0_GEN_INDEX_PIX_ADDR(x) (((x) >> 1) & 0x7F)
+#define C_0286D0_GEN_INDEX_PIX_ADDR 0xFFFFFF01
+#define S_0286D0_FRONT_FACE_ENA(x) (((x) & 0x1) << 8)
+#define G_0286D0_FRONT_FACE_ENA(x) (((x) >> 8) & 0x1)
+#define C_0286D0_FRONT_FACE_ENA 0xFFFFFEFF
+#define S_0286D0_FRONT_FACE_CHAN(x) (((x) & 0x3) << 9)
+#define G_0286D0_FRONT_FACE_CHAN(x) (((x) >> 9) & 0x3)
+#define C_0286D0_FRONT_FACE_CHAN 0xFFFFF9FF
+#define S_0286D0_FRONT_FACE_ALL_BITS(x) (((x) & 0x1) << 11)
+#define G_0286D0_FRONT_FACE_ALL_BITS(x) (((x) >> 11) & 0x1)
+#define C_0286D0_FRONT_FACE_ALL_BITS 0xFFFFF7FF
+#define S_0286D0_FRONT_FACE_ADDR(x) (((x) & 0x1F) << 12)
+#define G_0286D0_FRONT_FACE_ADDR(x) (((x) >> 12) & 0x1F)
+#define C_0286D0_FRONT_FACE_ADDR 0xFFFE0FFF
+#define S_0286D0_FOG_ADDR(x) (((x) & 0x7F) << 17)
+#define G_0286D0_FOG_ADDR(x) (((x) >> 17) & 0x7F)
+#define C_0286D0_FOG_ADDR 0xFF01FFFF
+#define S_0286D0_FIXED_PT_POSITION_ENA(x) (((x) & 0x1) << 24)
+#define G_0286D0_FIXED_PT_POSITION_ENA(x) (((x) >> 24) & 0x1)
+#define C_0286D0_FIXED_PT_POSITION_ENA 0xFEFFFFFF
+#define S_0286D0_FIXED_PT_POSITION_ADDR(x) (((x) & 0x1F) << 25)
+#define G_0286D0_FIXED_PT_POSITION_ADDR(x) (((x) >> 25) & 0x1F)
+#define C_0286D0_FIXED_PT_POSITION_ADDR 0xC1FFFFFF
+#define R_0286C4_SPI_VS_OUT_CONFIG 0x0286C4
+#define S_0286C4_VS_PER_COMPONENT(x) (((x) & 0x1) << 0)
+#define G_0286C4_VS_PER_COMPONENT(x) (((x) >> 0) & 0x1)
+#define C_0286C4_VS_PER_COMPONENT 0xFFFFFFFE
+#define S_0286C4_VS_EXPORT_COUNT(x) (((x) & 0x1F) << 1)
+#define G_0286C4_VS_EXPORT_COUNT(x) (((x) >> 1) & 0x1F)
+#define C_0286C4_VS_EXPORT_COUNT 0xFFFFFFC1
+#define S_0286C4_VS_EXPORTS_FOG(x) (((x) & 0x1) << 8)
+#define G_0286C4_VS_EXPORTS_FOG(x) (((x) >> 8) & 0x1)
+#define C_0286C4_VS_EXPORTS_FOG 0xFFFFFEFF
+#define S_0286C4_VS_OUT_FOG_VEC_ADDR(x) (((x) & 0x1F) << 9)
+#define G_0286C4_VS_OUT_FOG_VEC_ADDR(x) (((x) >> 9) & 0x1F)
+#define C_0286C4_VS_OUT_FOG_VEC_ADDR 0xFFFFC1FF
+#define R_028240_PA_SC_GENERIC_SCISSOR_TL 0x028240
+#define S_028240_TL_X(x) (((x) & 0x3FFF) << 0)
+#define G_028240_TL_X(x) (((x) >> 0) & 0x3FFF)
+#define C_028240_TL_X 0xFFFFC000
+#define S_028240_TL_Y(x) (((x) & 0x3FFF) << 16)
+#define G_028240_TL_Y(x) (((x) >> 16) & 0x3FFF)
+#define C_028240_TL_Y 0xC000FFFF
+#define S_028240_WINDOW_OFFSET_DISABLE(x) (((x) & 0x1) << 31)
+#define G_028240_WINDOW_OFFSET_DISABLE(x) (((x) >> 31) & 0x1)
+#define C_028240_WINDOW_OFFSET_DISABLE 0x7FFFFFFF
+#define R_028244_PA_SC_GENERIC_SCISSOR_BR 0x028244
+#define S_028244_BR_X(x) (((x) & 0x3FFF) << 0)
+#define G_028244_BR_X(x) (((x) >> 0) & 0x3FFF)
+#define C_028244_BR_X 0xFFFFC000
+#define S_028244_BR_Y(x) (((x) & 0x3FFF) << 16)
+#define G_028244_BR_Y(x) (((x) >> 16) & 0x3FFF)
+#define C_028244_BR_Y 0xC000FFFF
+#define R_028030_PA_SC_SCREEN_SCISSOR_TL 0x028030
+#define S_028030_TL_X(x) (((x) & 0x7FFF) << 0)
+#define G_028030_TL_X(x) (((x) >> 0) & 0x7FFF)
+#define C_028030_TL_X 0xFFFF8000
+#define S_028030_TL_Y(x) (((x) & 0x7FFF) << 16)
+#define G_028030_TL_Y(x) (((x) >> 16) & 0x7FFF)
+#define C_028030_TL_Y 0x8000FFFF
+#define R_028034_PA_SC_SCREEN_SCISSOR_BR 0x028034
+#define S_028034_BR_X(x) (((x) & 0x7FFF) << 0)
+#define G_028034_BR_X(x) (((x) >> 0) & 0x7FFF)
+#define C_028034_BR_X 0xFFFF8000
+#define S_028034_BR_Y(x) (((x) & 0x7FFF) << 16)
+#define G_028034_BR_Y(x) (((x) >> 16) & 0x7FFF)
+#define C_028034_BR_Y 0x8000FFFF
+#define R_028204_PA_SC_WINDOW_SCISSOR_TL 0x028204
+#define S_028204_TL_X(x) (((x) & 0x3FFF) << 0)
+#define G_028204_TL_X(x) (((x) >> 0) & 0x3FFF)
+#define C_028204_TL_X 0xFFFFC000
+#define S_028204_TL_Y(x) (((x) & 0x3FFF) << 16)
+#define G_028204_TL_Y(x) (((x) >> 16) & 0x3FFF)
+#define C_028204_TL_Y 0xC000FFFF
+#define S_028204_WINDOW_OFFSET_DISABLE(x) (((x) & 0x1) << 31)
+#define G_028204_WINDOW_OFFSET_DISABLE(x) (((x) >> 31) & 0x1)
+#define C_028204_WINDOW_OFFSET_DISABLE 0x7FFFFFFF
+#define R_028208_PA_SC_WINDOW_SCISSOR_BR 0x028208
+#define S_028208_BR_X(x) (((x) & 0x3FFF) << 0)
+#define G_028208_BR_X(x) (((x) >> 0) & 0x3FFF)
+#define C_028208_BR_X 0xFFFFC000
+#define S_028208_BR_Y(x) (((x) & 0x3FFF) << 16)
+#define G_028208_BR_Y(x) (((x) >> 16) & 0x3FFF)
+#define C_028208_BR_Y 0xC000FFFF
+#define R_0287F0_VGT_DRAW_INITIATOR 0x0287F0
+#define S_0287F0_SOURCE_SELECT(x) (((x) & 0x3) << 0)
+#define G_0287F0_SOURCE_SELECT(x) (((x) >> 0) & 0x3)
+#define C_0287F0_SOURCE_SELECT 0xFFFFFFFC
+#define S_0287F0_MAJOR_MODE(x) (((x) & 0x3) << 2)
+#define G_0287F0_MAJOR_MODE(x) (((x) >> 2) & 0x3)
+#define C_0287F0_MAJOR_MODE 0xFFFFFFF3
+#define S_0287F0_SPRITE_EN(x) (((x) & 0x1) << 4)
+#define G_0287F0_SPRITE_EN(x) (((x) >> 4) & 0x1)
+#define C_0287F0_SPRITE_EN 0xFFFFFFEF
+#define S_0287F0_NOT_EOP(x) (((x) & 0x1) << 5)
+#define G_0287F0_NOT_EOP(x) (((x) >> 5) & 0x1)
+#define C_0287F0_NOT_EOP 0xFFFFFFDF
+#define S_0287F0_USE_OPAQUE(x) (((x) & 0x1) << 6)
+#define G_0287F0_USE_OPAQUE(x) (((x) >> 6) & 0x1)
+#define C_0287F0_USE_OPAQUE 0xFFFFFFBF
+#define R_0280A0_CB_COLOR0_INFO 0x0280A0
+#define R_0280A4_CB_COLOR1_INFO 0x0280A4
+#define R_0280A8_CB_COLOR2_INFO 0x0280A8
+#define R_0280AC_CB_COLOR3_INFO 0x0280AC
+#define R_0280B0_CB_COLOR4_INFO 0x0280B0
+#define R_0280B4_CB_COLOR5_INFO 0x0280B4
+#define R_0280B8_CB_COLOR6_INFO 0x0280B8
+#define R_0280BC_CB_COLOR7_INFO 0x0280BC
+#define R_02800C_DB_DEPTH_BASE 0x02800C
+#define R_028000_DB_DEPTH_SIZE 0x028000
+#define R_028004_DB_DEPTH_VIEW 0x028004
+#define R_028010_DB_DEPTH_INFO 0x028010
+#define R_028D24_DB_HTILE_SURFACE 0x028D24
+#define R_028D34_DB_PREFETCH_LIMIT 0x028D34
+#define R_0286D4_SPI_INTERP_CONTROL_0 0x0286D4
+#define R_028A48_PA_SC_MPASS_PS_CNTL 0x028A48
+#define R_028C00_PA_SC_LINE_CNTL 0x028C00
+#define R_028C04_PA_SC_AA_CONFIG 0x028C04
+#define R_028C1C_PA_SC_AA_SAMPLE_LOCS_MCTX 0x028C1C
+#define R_028C48_PA_SC_AA_MASK 0x028C48
+#define R_028810_PA_CL_CLIP_CNTL 0x028810
+#define R_02881C_PA_CL_VS_OUT_CNTL 0x02881C
+#define R_028820_PA_CL_NANINF_CNTL 0x028820
+#define R_028C0C_PA_CL_GB_VERT_CLIP_ADJ 0x028C0C
+#define R_028C10_PA_CL_GB_VERT_DISC_ADJ 0x028C10
+#define R_028C14_PA_CL_GB_HORZ_CLIP_ADJ 0x028C14
+#define R_028C18_PA_CL_GB_HORZ_DISC_ADJ 0x028C18
+#define R_028814_PA_SU_SC_MODE_CNTL 0x028814
+#define R_028A00_PA_SU_POINT_SIZE 0x028A00
+#define R_028A04_PA_SU_POINT_MINMAX 0x028A04
+#define R_028A08_PA_SU_LINE_CNTL 0x028A08
+#define R_028A0C_PA_SC_LINE_STIPPLE 0x028A0C
+#define R_028DF8_PA_SU_POLY_OFFSET_DB_FMT_CNTL 0x028DF8
+#define R_028DFC_PA_SU_POLY_OFFSET_CLAMP 0x028DFC
+#define R_028E00_PA_SU_POLY_OFFSET_FRONT_SCALE 0x028E00
+#define R_028E04_PA_SU_POLY_OFFSET_FRONT_OFFSET 0x028E04
+#define R_028E08_PA_SU_POLY_OFFSET_BACK_SCALE 0x028E08
+#define R_028E0C_PA_SU_POLY_OFFSET_BACK_OFFSET 0x028E0C
+#define R_028818_PA_CL_VTE_CNTL 0x028818
+#define R_02843C_PA_CL_VPORT_XSCALE_0 0x02843C
+#define R_028444_PA_CL_VPORT_YSCALE_0 0x028444
+#define R_02844C_PA_CL_VPORT_ZSCALE_0 0x02844C
+#define R_028440_PA_CL_VPORT_XOFFSET_0 0x028440
+#define R_028448_PA_CL_VPORT_YOFFSET_0 0x028448
+#define R_028450_PA_CL_VPORT_ZOFFSET_0 0x028450
+#define R_028250_PA_SC_VPORT_SCISSOR_0_TL 0x028250
+#define R_028254_PA_SC_VPORT_SCISSOR_0_BR 0x028254
+#define R_028780_CB_BLEND0_CONTROL 0x028780
+#define R_028784_CB_BLEND1_CONTROL 0x028784
+#define R_028788_CB_BLEND2_CONTROL 0x028788
+#define R_02878C_CB_BLEND3_CONTROL 0x02878C
+#define R_028790_CB_BLEND4_CONTROL 0x028790
+#define R_028794_CB_BLEND5_CONTROL 0x028794
+#define R_028798_CB_BLEND6_CONTROL 0x028798
+#define R_02879C_CB_BLEND7_CONTROL 0x02879C
+#define R_028804_CB_BLEND_CONTROL 0x028804
+#define R_028028_DB_STENCIL_CLEAR 0x028028
+#define R_02802C_DB_DEPTH_CLEAR 0x02802C
+#define R_028430_DB_STENCILREFMASK 0x028430
+#define R_028434_DB_STENCILREFMASK_BF 0x028434
+#define R_028800_DB_DEPTH_CONTROL 0x028800
+#define R_02880C_DB_SHADER_CONTROL 0x02880C
+#define R_028D0C_DB_RENDER_CONTROL 0x028D0C
+#define R_028D10_DB_RENDER_OVERRIDE 0x028D10
+#define R_028D2C_DB_SRESULTS_COMPARE_STATE1 0x028D2C
+#define R_028D30_DB_PRELOAD_CONTROL 0x028D30
+#define R_028D44_DB_ALPHA_TO_MASK 0x028D44
+#define R_028868_SQ_PGM_RESOURCES_VS 0x028868
+#define R_0286CC_SPI_PS_IN_CONTROL_0 0x0286CC
+#define R_0286D0_SPI_PS_IN_CONTROL_1 0x0286D0
+#define R_028644_SPI_PS_INPUT_CNTL_0 0x028644
+#define R_028648_SPI_PS_INPUT_CNTL_1 0x028648
+#define R_02864C_SPI_PS_INPUT_CNTL_2 0x02864C
+#define R_028650_SPI_PS_INPUT_CNTL_3 0x028650
+#define R_028654_SPI_PS_INPUT_CNTL_4 0x028654
+#define R_028658_SPI_PS_INPUT_CNTL_5 0x028658
+#define R_02865C_SPI_PS_INPUT_CNTL_6 0x02865C
+#define R_028660_SPI_PS_INPUT_CNTL_7 0x028660
+#define R_028664_SPI_PS_INPUT_CNTL_8 0x028664
+#define R_028668_SPI_PS_INPUT_CNTL_9 0x028668
+#define R_02866C_SPI_PS_INPUT_CNTL_10 0x02866C
+#define R_028670_SPI_PS_INPUT_CNTL_11 0x028670
+#define R_028674_SPI_PS_INPUT_CNTL_12 0x028674
+#define R_028678_SPI_PS_INPUT_CNTL_13 0x028678
+#define R_02867C_SPI_PS_INPUT_CNTL_14 0x02867C
+#define R_028680_SPI_PS_INPUT_CNTL_15 0x028680
+#define R_028684_SPI_PS_INPUT_CNTL_16 0x028684
+#define R_028688_SPI_PS_INPUT_CNTL_17 0x028688
+#define R_02868C_SPI_PS_INPUT_CNTL_18 0x02868C
+#define R_028690_SPI_PS_INPUT_CNTL_19 0x028690
+#define R_028694_SPI_PS_INPUT_CNTL_20 0x028694
+#define R_028698_SPI_PS_INPUT_CNTL_21 0x028698
+#define R_02869C_SPI_PS_INPUT_CNTL_22 0x02869C
+#define R_0286A0_SPI_PS_INPUT_CNTL_23 0x0286A0
+#define R_0286A4_SPI_PS_INPUT_CNTL_24 0x0286A4
+#define R_0286A8_SPI_PS_INPUT_CNTL_25 0x0286A8
+#define R_0286AC_SPI_PS_INPUT_CNTL_26 0x0286AC
+#define R_0286B0_SPI_PS_INPUT_CNTL_27 0x0286B0
+#define R_0286B4_SPI_PS_INPUT_CNTL_28 0x0286B4
+#define R_0286B8_SPI_PS_INPUT_CNTL_29 0x0286B8
+#define R_0286BC_SPI_PS_INPUT_CNTL_30 0x0286BC
+#define R_0286C0_SPI_PS_INPUT_CNTL_31 0x0286C0
+#define R_028850_SQ_PGM_RESOURCES_PS 0x028850
+#define R_028854_SQ_PGM_EXPORTS_PS 0x028854
+#define R_008958_VGT_PRIMITIVE_TYPE 0x008958
+#define R_028A7C_VGT_DMA_INDEX_TYPE 0x028A7C
+#define R_028A88_VGT_DMA_NUM_INSTANCES 0x028A88
+#define R_008970_VGT_NUM_INDICES 0x008970
+#define R_0287F0_VGT_DRAW_INITIATOR 0x0287F0
+#define R_028238_CB_TARGET_MASK 0x028238
+#define R_02823C_CB_SHADER_MASK 0x02823C
+#define R_028060_CB_COLOR0_SIZE 0x028060
+#define S_028060_PITCH_TILE_MAX(x) (((x) & 0x3FF) << 0)
+#define G_028060_PITCH_TILE_MAX(x) (((x) >> 0) & 0x3FF)
+#define C_028060_PITCH_TILE_MAX 0xFFFFFC00
+#define S_028060_SLICE_TILE_MAX(x) (((x) & 0xFFFFF) << 10)
+#define G_028060_SLICE_TILE_MAX(x) (((x) >> 10) & 0xFFFFF)
+#define C_028060_SLICE_TILE_MAX 0xC00003FF
+#define R_028064_CB_COLOR1_SIZE 0x028064
+#define R_028068_CB_COLOR2_SIZE 0x028068
+#define R_02806C_CB_COLOR3_SIZE 0x02806C
+#define R_028070_CB_COLOR4_SIZE 0x028070
+#define R_028074_CB_COLOR5_SIZE 0x028074
+#define R_028078_CB_COLOR6_SIZE 0x028078
+#define R_02807C_CB_COLOR7_SIZE 0x02807C
+#define R_028040_CB_COLOR0_BASE 0x028040
+#define R_028044_CB_COLOR1_BASE 0x028044
+#define R_028048_CB_COLOR2_BASE 0x028048
+#define R_02804C_CB_COLOR3_BASE 0x02804C
+#define R_028050_CB_COLOR4_BASE 0x028050
+#define R_028054_CB_COLOR5_BASE 0x028054
+#define R_028058_CB_COLOR6_BASE 0x028058
+#define R_02805C_CB_COLOR7_BASE 0x02805C
+#define R_028240_PA_SC_GENERIC_SCISSOR_TL 0x028240
+#define S_028240_TL_X(x) (((x) & 0x3FFF) << 0)
+#define G_028240_TL_X(x) (((x) >> 0) & 0x3FFF)
+#define C_028240_TL_X 0xFFFFC000
+#define S_028240_TL_Y(x) (((x) & 0x3FFF) << 16)
+#define G_028240_TL_Y(x) (((x) >> 16) & 0x3FFF)
+#define C_028240_TL_Y 0xC000FFFF
+#define R_028C04_PA_SC_AA_CONFIG 0x028C04
+#define S_028C04_MSAA_NUM_SAMPLES(x) (((x) & 0x3) << 0)
+#define G_028C04_MSAA_NUM_SAMPLES(x) (((x) >> 0) & 0x3)
+#define C_028C04_MSAA_NUM_SAMPLES 0xFFFFFFFC
+#define S_028C04_AA_MASK_CENTROID_DTMN(x) (((x) & 0x1) << 4)
+#define G_028C04_AA_MASK_CENTROID_DTMN(x) (((x) >> 4) & 0x1)
+#define C_028C04_AA_MASK_CENTROID_DTMN 0xFFFFFFEF
+#define S_028C04_MAX_SAMPLE_DIST(x) (((x) & 0xF) << 13)
+#define G_028C04_MAX_SAMPLE_DIST(x) (((x) >> 13) & 0xF)
+#define C_028C04_MAX_SAMPLE_DIST 0xFFFE1FFF
+#define R_0288CC_SQ_PGM_CF_OFFSET_PS 0x0288CC
+#define R_0288DC_SQ_PGM_CF_OFFSET_FS 0x0288DC
+#define R_0288D0_SQ_PGM_CF_OFFSET_VS 0x0288D0
+#define R_028840_SQ_PGM_START_PS 0x028840
+#define R_028894_SQ_PGM_START_FS 0x028894
+#define R_028858_SQ_PGM_START_VS 0x028858
+#define R_028080_CB_COLOR0_VIEW 0x028080
+#define S_028080_SLICE_START(x) (((x) & 0x7FF) << 0)
+#define G_028080_SLICE_START(x) (((x) >> 0) & 0x7FF)
+#define C_028080_SLICE_START 0xFFFFF800
+#define S_028080_SLICE_MAX(x) (((x) & 0x7FF) << 13)
+#define G_028080_SLICE_MAX(x) (((x) >> 13) & 0x7FF)
+#define C_028080_SLICE_MAX 0xFF001FFF
+#define R_028100_CB_COLOR0_MASK 0x028100
+#define S_028100_CMASK_BLOCK_MAX(x) (((x) & 0xFFF) << 0)
+#define G_028100_CMASK_BLOCK_MAX(x) (((x) >> 0) & 0xFFF)
+#define C_028100_CMASK_BLOCK_MAX 0xFFFFF000
+#define S_028100_FMASK_TILE_MAX(x) (((x) & 0xFFFFF) << 12)
+#define G_028100_FMASK_TILE_MAX(x) (((x) >> 12) & 0xFFFFF)
+#define C_028100_FMASK_TILE_MAX 0x00000FFF
+#define R_028040_CB_COLOR0_BASE 0x028040
+#define S_028040_BASE_256B(x) (((x) & 0xFFFFFFFF) << 0)
+#define G_028040_BASE_256B(x) (((x) >> 0) & 0xFFFFFFFF)
+#define C_028040_BASE_256B 0x00000000
+#define R_0280E0_CB_COLOR0_FRAG 0x0280E0
+#define S_0280E0_BASE_256B(x) (((x) & 0xFFFFFFFF) << 0)
+#define G_0280E0_BASE_256B(x) (((x) >> 0) & 0xFFFFFFFF)
+#define C_0280E0_BASE_256B 0x00000000
+#define R_0280C0_CB_COLOR0_TILE 0x0280C0
+#define S_0280C0_BASE_256B(x) (((x) & 0xFFFFFFFF) << 0)
+#define G_0280C0_BASE_256B(x) (((x) >> 0) & 0xFFFFFFFF)
+#define C_0280C0_BASE_256B 0x00000000
+#define R_028808_CB_COLOR_CONTROL 0x028808
+#define S_028808_FOG_ENABLE(x) (((x) & 0x1) << 0)
+#define G_028808_FOG_ENABLE(x) (((x) >> 0) & 0x1)
+#define C_028808_FOG_ENABLE 0xFFFFFFFE
+#define S_028808_MULTIWRITE_ENABLE(x) (((x) & 0x1) << 1)
+#define G_028808_MULTIWRITE_ENABLE(x) (((x) >> 1) & 0x1)
+#define C_028808_MULTIWRITE_ENABLE 0xFFFFFFFD
+#define S_028808_DITHER_ENABLE(x) (((x) & 0x1) << 2)
+#define G_028808_DITHER_ENABLE(x) (((x) >> 2) & 0x1)
+#define C_028808_DITHER_ENABLE 0xFFFFFFFB
+#define S_028808_DEGAMMA_ENABLE(x) (((x) & 0x1) << 3)
+#define G_028808_DEGAMMA_ENABLE(x) (((x) >> 3) & 0x1)
+#define C_028808_DEGAMMA_ENABLE 0xFFFFFFF7
+#define S_028808_SPECIAL_OP(x) (((x) & 0x7) << 4)
+#define G_028808_SPECIAL_OP(x) (((x) >> 4) & 0x7)
+#define C_028808_SPECIAL_OP 0xFFFFFF8F
+#define S_028808_PER_MRT_BLEND(x) (((x) & 0x1) << 7)
+#define G_028808_PER_MRT_BLEND(x) (((x) >> 7) & 0x1)
+#define C_028808_PER_MRT_BLEND 0xFFFFFF7F
+#define S_028808_TARGET_BLEND_ENABLE(x) (((x) & 0xFF) << 8)
+#define G_028808_TARGET_BLEND_ENABLE(x) (((x) >> 8) & 0xFF)
+#define C_028808_TARGET_BLEND_ENABLE 0xFFFF00FF
+#define S_028808_ROP3(x) (((x) & 0xFF) << 16)
+#define G_028808_ROP3(x) (((x) >> 16) & 0xFF)
+#define C_028808_ROP3 0xFF00FFFF
+#define R_028614_SPI_VS_OUT_ID_0 0x028614
+#define S_028614_SEMANTIC_0(x) (((x) & 0xFF) << 0)
+#define G_028614_SEMANTIC_0(x) (((x) >> 0) & 0xFF)
+#define C_028614_SEMANTIC_0 0xFFFFFF00
+#define S_028614_SEMANTIC_1(x) (((x) & 0xFF) << 8)
+#define G_028614_SEMANTIC_1(x) (((x) >> 8) & 0xFF)
+#define C_028614_SEMANTIC_1 0xFFFF00FF
+#define S_028614_SEMANTIC_2(x) (((x) & 0xFF) << 16)
+#define G_028614_SEMANTIC_2(x) (((x) >> 16) & 0xFF)
+#define C_028614_SEMANTIC_2 0xFF00FFFF
+#define S_028614_SEMANTIC_3(x) (((x) & 0xFF) << 24)
+#define G_028614_SEMANTIC_3(x) (((x) >> 24) & 0xFF)
+#define C_028614_SEMANTIC_3 0x00FFFFFF
+#define R_028618_SPI_VS_OUT_ID_1 0x028618
+#define R_02861C_SPI_VS_OUT_ID_2 0x02861C
+#define R_028620_SPI_VS_OUT_ID_3 0x028620
+#define R_028624_SPI_VS_OUT_ID_4 0x028624
+#define R_028628_SPI_VS_OUT_ID_5 0x028628
+#define R_02862C_SPI_VS_OUT_ID_6 0x02862C
+#define R_028630_SPI_VS_OUT_ID_7 0x028630
+#define R_028634_SPI_VS_OUT_ID_8 0x028634
+#define R_028638_SPI_VS_OUT_ID_9 0x028638
+#define R_038000_SQ_TEX_RESOURCE_WORD0_0 0x038000
+#define S_038000_DIM(x) (((x) & 0x7) << 0)
+#define G_038000_DIM(x) (((x) >> 0) & 0x7)
+#define C_038000_DIM 0xFFFFFFF8
+#define S_038000_TILE_MODE(x) (((x) & 0xF) << 3)
+#define G_038000_TILE_MODE(x) (((x) >> 3) & 0xF)
+#define C_038000_TILE_MODE 0xFFFFFF87
+#define S_038000_TILE_TYPE(x) (((x) & 0x1) << 7)
+#define G_038000_TILE_TYPE(x) (((x) >> 7) & 0x1)
+#define C_038000_TILE_TYPE 0xFFFFFF7F
+#define S_038000_PITCH(x) (((x) & 0x7FF) << 8)
+#define G_038000_PITCH(x) (((x) >> 8) & 0x7FF)
+#define C_038000_PITCH 0xFFF800FF
+#define S_038000_TEX_WIDTH(x) (((x) & 0x1FFF) << 19)
+#define G_038000_TEX_WIDTH(x) (((x) >> 19) & 0x1FFF)
+#define C_038000_TEX_WIDTH 0x0007FFFF
+#define R_038004_SQ_TEX_RESOURCE_WORD1_0 0x038004
+#define S_038004_TEX_HEIGHT(x) (((x) & 0x1FFF) << 0)
+#define G_038004_TEX_HEIGHT(x) (((x) >> 0) & 0x1FFF)
+#define C_038004_TEX_HEIGHT 0xFFFFE000
+#define S_038004_TEX_DEPTH(x) (((x) & 0x1FFF) << 13)
+#define G_038004_TEX_DEPTH(x) (((x) >> 13) & 0x1FFF)
+#define C_038004_TEX_DEPTH 0xFC001FFF
+#define S_038004_DATA_FORMAT(x) (((x) & 0x3F) << 26)
+#define G_038004_DATA_FORMAT(x) (((x) >> 26) & 0x3F)
+#define C_038004_DATA_FORMAT 0x03FFFFFF
+#define V_038004_COLOR_INVALID 0x00000000
+#define V_038004_COLOR_8 0x00000001
+#define V_038004_COLOR_4_4 0x00000002
+#define V_038004_COLOR_3_3_2 0x00000003
+#define V_038004_COLOR_16 0x00000005
+#define V_038004_COLOR_16_FLOAT 0x00000006
+#define V_038004_COLOR_8_8 0x00000007
+#define V_038004_COLOR_5_6_5 0x00000008
+#define V_038004_COLOR_6_5_5 0x00000009
+#define V_038004_COLOR_1_5_5_5 0x0000000A
+#define V_038004_COLOR_4_4_4_4 0x0000000B
+#define V_038004_COLOR_5_5_5_1 0x0000000C
+#define V_038004_COLOR_32 0x0000000D
+#define V_038004_COLOR_32_FLOAT 0x0000000E
+#define V_038004_COLOR_16_16 0x0000000F
+#define V_038004_COLOR_16_16_FLOAT 0x00000010
+#define V_038004_COLOR_8_24 0x00000011
+#define V_038004_COLOR_8_24_FLOAT 0x00000012
+#define V_038004_COLOR_24_8 0x00000013
+#define V_038004_COLOR_24_8_FLOAT 0x00000014
+#define V_038004_COLOR_10_11_11 0x00000015
+#define V_038004_COLOR_10_11_11_FLOAT 0x00000016
+#define V_038004_COLOR_11_11_10 0x00000017
+#define V_038004_COLOR_11_11_10_FLOAT 0x00000018
+#define V_038004_COLOR_2_10_10_10 0x00000019
+#define V_038004_COLOR_8_8_8_8 0x0000001A
+#define V_038004_COLOR_10_10_10_2 0x0000001B
+#define V_038004_COLOR_X24_8_32_FLOAT 0x0000001C
+#define V_038004_COLOR_32_32 0x0000001D
+#define V_038004_COLOR_32_32_FLOAT 0x0000001E
+#define V_038004_COLOR_16_16_16_16 0x0000001F
+#define V_038004_COLOR_16_16_16_16_FLOAT 0x00000020
+#define V_038004_COLOR_32_32_32_32 0x00000022
+#define V_038004_COLOR_32_32_32_32_FLOAT 0x00000023
+#define R_038008_SQ_TEX_RESOURCE_WORD2_0 0x038008
+#define S_038008_BASE_ADDRESS(x) (((x) & 0xFFFFFFFF) << 0)
+#define G_038008_BASE_ADDRESS(x) (((x) >> 0) & 0xFFFFFFFF)
+#define C_038008_BASE_ADDRESS 0x00000000
+#define R_03800C_SQ_TEX_RESOURCE_WORD3_0 0x03800C
+#define S_03800C_MIP_ADDRESS(x) (((x) & 0xFFFFFFFF) << 0)
+#define G_03800C_MIP_ADDRESS(x) (((x) >> 0) & 0xFFFFFFFF)
+#define C_03800C_MIP_ADDRESS 0x00000000
+#define R_038010_SQ_TEX_RESOURCE_WORD4_0 0x038010
+#define S_038010_FORMAT_COMP_X(x) (((x) & 0x3) << 0)
+#define G_038010_FORMAT_COMP_X(x) (((x) >> 0) & 0x3)
+#define C_038010_FORMAT_COMP_X 0xFFFFFFFC
+#define S_038010_FORMAT_COMP_Y(x) (((x) & 0x3) << 2)
+#define G_038010_FORMAT_COMP_Y(x) (((x) >> 2) & 0x3)
+#define C_038010_FORMAT_COMP_Y 0xFFFFFFF3
+#define S_038010_FORMAT_COMP_Z(x) (((x) & 0x3) << 4)
+#define G_038010_FORMAT_COMP_Z(x) (((x) >> 4) & 0x3)
+#define C_038010_FORMAT_COMP_Z 0xFFFFFFCF
+#define S_038010_FORMAT_COMP_W(x) (((x) & 0x3) << 6)
+#define G_038010_FORMAT_COMP_W(x) (((x) >> 6) & 0x3)
+#define C_038010_FORMAT_COMP_W 0xFFFFFF3F
+#define S_038010_NUM_FORMAT_ALL(x) (((x) & 0x3) << 8)
+#define G_038010_NUM_FORMAT_ALL(x) (((x) >> 8) & 0x3)
+#define C_038010_NUM_FORMAT_ALL 0xFFFFFCFF
+#define S_038010_SRF_MODE_ALL(x) (((x) & 0x1) << 10)
+#define G_038010_SRF_MODE_ALL(x) (((x) >> 10) & 0x1)
+#define C_038010_SRF_MODE_ALL 0xFFFFFBFF
+#define S_038010_FORCE_DEGAMMA(x) (((x) & 0x1) << 11)
+#define G_038010_FORCE_DEGAMMA(x) (((x) >> 11) & 0x1)
+#define C_038010_FORCE_DEGAMMA 0xFFFFF7FF
+#define S_038010_ENDIAN_SWAP(x) (((x) & 0x3) << 12)
+#define G_038010_ENDIAN_SWAP(x) (((x) >> 12) & 0x3)
+#define C_038010_ENDIAN_SWAP 0xFFFFCFFF
+#define S_038010_REQUEST_SIZE(x) (((x) & 0x3) << 14)
+#define G_038010_REQUEST_SIZE(x) (((x) >> 14) & 0x3)
+#define C_038010_REQUEST_SIZE 0xFFFF3FFF
+#define S_038010_DST_SEL_X(x) (((x) & 0x7) << 16)
+#define G_038010_DST_SEL_X(x) (((x) >> 16) & 0x7)
+#define C_038010_DST_SEL_X 0xFFF8FFFF
+#define S_038010_DST_SEL_Y(x) (((x) & 0x7) << 19)
+#define G_038010_DST_SEL_Y(x) (((x) >> 19) & 0x7)
+#define C_038010_DST_SEL_Y 0xFFC7FFFF
+#define S_038010_DST_SEL_Z(x) (((x) & 0x7) << 22)
+#define G_038010_DST_SEL_Z(x) (((x) >> 22) & 0x7)
+#define C_038010_DST_SEL_Z 0xFE3FFFFF
+#define S_038010_DST_SEL_W(x) (((x) & 0x7) << 25)
+#define G_038010_DST_SEL_W(x) (((x) >> 25) & 0x7)
+#define C_038010_DST_SEL_W 0xF1FFFFFF
+#define S_038010_BASE_LEVEL(x) (((x) & 0xF) << 28)
+#define G_038010_BASE_LEVEL(x) (((x) >> 28) & 0xF)
+#define C_038010_BASE_LEVEL 0x0FFFFFFF
+#define R_038014_SQ_TEX_RESOURCE_WORD5_0 0x038014
+#define S_038014_LAST_LEVEL(x) (((x) & 0xF) << 0)
+#define G_038014_LAST_LEVEL(x) (((x) >> 0) & 0xF)
+#define C_038014_LAST_LEVEL 0xFFFFFFF0
+#define S_038014_BASE_ARRAY(x) (((x) & 0x1FFF) << 4)
+#define G_038014_BASE_ARRAY(x) (((x) >> 4) & 0x1FFF)
+#define C_038014_BASE_ARRAY 0xFFFE000F
+#define S_038014_LAST_ARRAY(x) (((x) & 0x1FFF) << 17)
+#define G_038014_LAST_ARRAY(x) (((x) >> 17) & 0x1FFF)
+#define C_038014_LAST_ARRAY 0xC001FFFF
+#define R_038018_SQ_TEX_RESOURCE_WORD6_0 0x038018
+#define S_038018_MPEG_CLAMP(x) (((x) & 0x3) << 0)
+#define G_038018_MPEG_CLAMP(x) (((x) >> 0) & 0x3)
+#define C_038018_MPEG_CLAMP 0xFFFFFFFC
+#define S_038018_PERF_MODULATION(x) (((x) & 0x7) << 5)
+#define G_038018_PERF_MODULATION(x) (((x) >> 5) & 0x7)
+#define C_038018_PERF_MODULATION 0xFFFFFF1F
+#define S_038018_INTERLACED(x) (((x) & 0x1) << 8)
+#define G_038018_INTERLACED(x) (((x) >> 8) & 0x1)
+#define C_038018_INTERLACED 0xFFFFFEFF
+#define S_038018_TYPE(x) (((x) & 0x3) << 30)
+#define G_038018_TYPE(x) (((x) >> 30) & 0x3)
+#define C_038018_TYPE 0x3FFFFFFF
+#define R_008040_WAIT_UNTIL 0x008040
+#define S_008040_WAIT_CP_DMA_IDLE(x) (((x) & 0x1) << 8)
+#define G_008040_WAIT_CP_DMA_IDLE(x) (((x) >> 8) & 0x1)
+#define C_008040_WAIT_CP_DMA_IDLE 0xFFFFFEFF
+#define S_008040_WAIT_CMDFIFO(x) (((x) & 0x1) << 10)
+#define G_008040_WAIT_CMDFIFO(x) (((x) >> 10) & 0x1)
+#define C_008040_WAIT_CMDFIFO 0xFFFFFBFF
+#define S_008040_WAIT_2D_IDLE(x) (((x) & 0x1) << 14)
+#define G_008040_WAIT_2D_IDLE(x) (((x) >> 14) & 0x1)
+#define C_008040_WAIT_2D_IDLE 0xFFFFBFFF
+#define S_008040_WAIT_3D_IDLE(x) (((x) & 0x1) << 15)
+#define G_008040_WAIT_3D_IDLE(x) (((x) >> 15) & 0x1)
+#define C_008040_WAIT_3D_IDLE 0xFFFF7FFF
+#define S_008040_WAIT_2D_IDLECLEAN(x) (((x) & 0x1) << 16)
+#define G_008040_WAIT_2D_IDLECLEAN(x) (((x) >> 16) & 0x1)
+#define C_008040_WAIT_2D_IDLECLEAN 0xFFFEFFFF
+#define S_008040_WAIT_3D_IDLECLEAN(x) (((x) & 0x1) << 17)
+#define G_008040_WAIT_3D_IDLECLEAN(x) (((x) >> 17) & 0x1)
+#define C_008040_WAIT_3D_IDLECLEAN 0xFFFDFFFF
+#define S_008040_WAIT_EXTERN_SIG(x) (((x) & 0x1) << 19)
+#define G_008040_WAIT_EXTERN_SIG(x) (((x) >> 19) & 0x1)
+#define C_008040_WAIT_EXTERN_SIG 0xFFF7FFFF
+#define S_008040_CMDFIFO_ENTRIES(x) (((x) & 0x1F) << 20)
+#define G_008040_CMDFIFO_ENTRIES(x) (((x) >> 20) & 0x1F)
+#define C_008040_CMDFIFO_ENTRIES 0xFE0FFFFF
+#define R_008958_VGT_PRIMITIVE_TYPE 0x008958
+#define S_008958_PRIM_TYPE(x) (((x) & 0x3F) << 0)
+#define G_008958_PRIM_TYPE(x) (((x) >> 0) & 0x3F)
+#define C_008958_PRIM_TYPE 0xFFFFFFC0
+#define R_008C00_SQ_CONFIG 0x008C00
+#define S_008C00_VC_ENABLE(x) (((x) & 0x1) << 0)
+#define G_008C00_VC_ENABLE(x) (((x) >> 0) & 0x1)
+#define C_008C00_VC_ENABLE 0xFFFFFFFE
+#define S_008C00_EXPORT_SRC_C(x) (((x) & 0x1) << 1)
+#define G_008C00_EXPORT_SRC_C(x) (((x) >> 1) & 0x1)
+#define C_008C00_EXPORT_SRC_C 0xFFFFFFFD
+#define S_008C00_DX9_CONSTS(x) (((x) & 0x1) << 2)
+#define G_008C00_DX9_CONSTS(x) (((x) >> 2) & 0x1)
+#define C_008C00_DX9_CONSTS 0xFFFFFFFB
+#define S_008C00_ALU_INST_PREFER_VECTOR(x) (((x) & 0x1) << 3)
+#define G_008C00_ALU_INST_PREFER_VECTOR(x) (((x) >> 3) & 0x1)
+#define C_008C00_ALU_INST_PREFER_VECTOR 0xFFFFFFF7
+#define S_008C00_DX10_CLAMP(x) (((x) & 0x1) << 4)
+#define G_008C00_DX10_CLAMP(x) (((x) >> 4) & 0x1)
+#define C_008C00_DX10_CLAMP 0xFFFFFFEF
+#define S_008C00_ALU_PREFER_ONE_WATERFALL(x) (((x) & 0x1) << 5)
+#define G_008C00_ALU_PREFER_ONE_WATERFALL(x) (((x) >> 5) & 0x1)
+#define C_008C00_ALU_PREFER_ONE_WATERFALL 0xFFFFFFDF
+#define S_008C00_ALU_MAX_ONE_WATERFALL(x) (((x) & 0x1) << 6)
+#define G_008C00_ALU_MAX_ONE_WATERFALL(x) (((x) >> 6) & 0x1)
+#define C_008C00_ALU_MAX_ONE_WATERFALL 0xFFFFFFBF
+#define S_008C00_CLAUSE_SEQ_PRIO(x) (((x) & 0x3) << 8)
+#define G_008C00_CLAUSE_SEQ_PRIO(x) (((x) >> 8) & 0x3)
+#define C_008C00_CLAUSE_SEQ_PRIO 0xFFFFFCFF
+#define S_008C00_PS_PRIO(x) (((x) & 0x3) << 24)
+#define G_008C00_PS_PRIO(x) (((x) >> 24) & 0x3)
+#define C_008C00_PS_PRIO 0xFCFFFFFF
+#define S_008C00_VS_PRIO(x) (((x) & 0x3) << 26)
+#define G_008C00_VS_PRIO(x) (((x) >> 26) & 0x3)
+#define C_008C00_VS_PRIO 0xF3FFFFFF
+#define S_008C00_GS_PRIO(x) (((x) & 0x3) << 28)
+#define G_008C00_GS_PRIO(x) (((x) >> 28) & 0x3)
+#define C_008C00_GS_PRIO 0xCFFFFFFF
+#define S_008C00_ES_PRIO(x) (((x) & 0x3) << 30)
+#define G_008C00_ES_PRIO(x) (((x) >> 30) & 0x3)
+#define C_008C00_ES_PRIO 0x3FFFFFFF
+#define R_008C04_SQ_GPR_RESOURCE_MGMT_1 0x008C04
+#define S_008C04_NUM_PS_GPRS(x) (((x) & 0xFF) << 0)
+#define G_008C04_NUM_PS_GPRS(x) (((x) >> 0) & 0xFF)
+#define C_008C04_NUM_PS_GPRS 0xFFFFFF00
+#define S_008C04_NUM_VS_GPRS(x) (((x) & 0xFF) << 16)
+#define G_008C04_NUM_VS_GPRS(x) (((x) >> 16) & 0xFF)
+#define C_008C04_NUM_VS_GPRS 0xFF00FFFF
+#define S_008C04_NUM_CLAUSE_TEMP_GPRS(x) (((x) & 0xF) << 28)
+#define G_008C04_NUM_CLAUSE_TEMP_GPRS(x) (((x) >> 28) & 0xF)
+#define C_008C04_NUM_CLAUSE_TEMP_GPRS 0x0FFFFFFF
+#define R_008C08_SQ_GPR_RESOURCE_MGMT_2 0x008C08
+#define S_008C08_NUM_GS_GPRS(x) (((x) & 0xFF) << 0)
+#define G_008C08_NUM_GS_GPRS(x) (((x) >> 0) & 0xFF)
+#define C_008C08_NUM_GS_GPRS 0xFFFFFF00
+#define S_008C08_NUM_ES_GPRS(x) (((x) & 0xFF) << 16)
+#define G_008C08_NUM_ES_GPRS(x) (((x) >> 16) & 0xFF)
+#define C_008C08_NUM_ES_GPRS 0xFF00FFFF
+#define R_008C0C_SQ_THREAD_RESOURCE_MGMT 0x008C0C
+#define S_008C0C_NUM_PS_THREADS(x) (((x) & 0xFF) << 0)
+#define G_008C0C_NUM_PS_THREADS(x) (((x) >> 0) & 0xFF)
+#define C_008C0C_NUM_PS_THREADS 0xFFFFFF00
+#define S_008C0C_NUM_VS_THREADS(x) (((x) & 0xFF) << 8)
+#define G_008C0C_NUM_VS_THREADS(x) (((x) >> 8) & 0xFF)
+#define C_008C0C_NUM_VS_THREADS 0xFFFF00FF
+#define S_008C0C_NUM_GS_THREADS(x) (((x) & 0xFF) << 16)
+#define G_008C0C_NUM_GS_THREADS(x) (((x) >> 16) & 0xFF)
+#define C_008C0C_NUM_GS_THREADS 0xFF00FFFF
+#define S_008C0C_NUM_ES_THREADS(x) (((x) & 0xFF) << 24)
+#define G_008C0C_NUM_ES_THREADS(x) (((x) >> 24) & 0xFF)
+#define C_008C0C_NUM_ES_THREADS 0x00FFFFFF
+#define R_008C10_SQ_STACK_RESOURCE_MGMT_1 0x008C10
+#define S_008C10_NUM_PS_STACK_ENTRIES(x) (((x) & 0xFFF) << 0)
+#define G_008C10_NUM_PS_STACK_ENTRIES(x) (((x) >> 0) & 0xFFF)
+#define C_008C10_NUM_PS_STACK_ENTRIES 0xFFFFF000
+#define S_008C10_NUM_VS_STACK_ENTRIES(x) (((x) & 0xFFF) << 16)
+#define G_008C10_NUM_VS_STACK_ENTRIES(x) (((x) >> 16) & 0xFFF)
+#define C_008C10_NUM_VS_STACK_ENTRIES 0xF000FFFF
+#define R_008C14_SQ_STACK_RESOURCE_MGMT_2 0x008C14
+#define S_008C14_NUM_GS_STACK_ENTRIES(x) (((x) & 0xFFF) << 0)
+#define G_008C14_NUM_GS_STACK_ENTRIES(x) (((x) >> 0) & 0xFFF)
+#define C_008C14_NUM_GS_STACK_ENTRIES 0xFFFFF000
+#define S_008C14_NUM_ES_STACK_ENTRIES(x) (((x) & 0xFFF) << 16)
+#define G_008C14_NUM_ES_STACK_ENTRIES(x) (((x) >> 16) & 0xFFF)
+#define C_008C14_NUM_ES_STACK_ENTRIES 0xF000FFFF
+#define R_008D8C_SQ_DYN_GPR_CNTL_PS_FLUSH_REQ 0x008D8C
+#define S_008D8C_RING0_OFFSET(x) (((x) & 0xFF) << 0)
+#define G_008D8C_RING0_OFFSET(x) (((x) >> 0) & 0xFF)
+#define C_008D8C_RING0_OFFSET 0xFFFFFF00
+#define S_008D8C_ISOLATE_ES_ENABLE(x) (((x) & 0x1) << 12)
+#define G_008D8C_ISOLATE_ES_ENABLE(x) (((x) >> 12) & 0x1)
+#define C_008D8C_ISOLATE_ES_ENABLE 0xFFFFEFFF
+#define S_008D8C_ISOLATE_GS_ENABLE(x) (((x) & 0x1) << 13)
+#define G_008D8C_ISOLATE_GS_ENABLE(x) (((x) >> 13) & 0x1)
+#define C_008D8C_ISOLATE_GS_ENABLE 0xFFFFDFFF
+#define S_008D8C_VS_PC_LIMIT_ENABLE(x) (((x) & 0x1) << 14)
+#define G_008D8C_VS_PC_LIMIT_ENABLE(x) (((x) >> 14) & 0x1)
+#define C_008D8C_VS_PC_LIMIT_ENABLE 0xFFFFBFFF
+#define R_009508_TA_CNTL_AUX 0x009508
+#define S_009508_DISABLE_CUBE_WRAP(x) (((x) & 0x1) << 0)
+#define G_009508_DISABLE_CUBE_WRAP(x) (((x) >> 0) & 0x1)
+#define C_009508_DISABLE_CUBE_WRAP 0xFFFFFFFE
+#define S_009508_SYNC_GRADIENT(x) (((x) & 0x1) << 24)
+#define G_009508_SYNC_GRADIENT(x) (((x) >> 24) & 0x1)
+#define C_009508_SYNC_GRADIENT 0xFEFFFFFF
+#define S_009508_SYNC_WALKER(x) (((x) & 0x1) << 25)
+#define G_009508_SYNC_WALKER(x) (((x) >> 25) & 0x1)
+#define C_009508_SYNC_WALKER 0xFDFFFFFF
+#define S_009508_SYNC_ALIGNER(x) (((x) & 0x1) << 26)
+#define G_009508_SYNC_ALIGNER(x) (((x) >> 26) & 0x1)
+#define C_009508_SYNC_ALIGNER 0xFBFFFFFF
+#define S_009508_BILINEAR_PRECISION(x) (((x) & 0x1) << 31)
+#define G_009508_BILINEAR_PRECISION(x) (((x) >> 31) & 0x1)
+#define C_009508_BILINEAR_PRECISION 0x7FFFFFFF
+#define R_009714_VC_ENHANCE 0x009714
+#define R_009830_DB_DEBUG 0x009830
+#define R_009838_DB_WATERMARKS 0x009838
+#define S_009838_DEPTH_FREE(x) (((x) & 0x1F) << 0)
+#define G_009838_DEPTH_FREE(x) (((x) >> 0) & 0x1F)
+#define C_009838_DEPTH_FREE 0xFFFFFFE0
+#define S_009838_DEPTH_FLUSH(x) (((x) & 0x3F) << 5)
+#define G_009838_DEPTH_FLUSH(x) (((x) >> 5) & 0x3F)
+#define C_009838_DEPTH_FLUSH 0xFFFFF81F
+#define S_009838_FORCE_SUMMARIZE(x) (((x) & 0xF) << 11)
+#define G_009838_FORCE_SUMMARIZE(x) (((x) >> 11) & 0xF)
+#define C_009838_FORCE_SUMMARIZE 0xFFFF87FF
+#define S_009838_DEPTH_PENDING_FREE(x) (((x) & 0x1F) << 15)
+#define G_009838_DEPTH_PENDING_FREE(x) (((x) >> 15) & 0x1F)
+#define C_009838_DEPTH_PENDING_FREE 0xFFF07FFF
+#define S_009838_DEPTH_CACHELINE_FREE(x) (((x) & 0x1F) << 20)
+#define G_009838_DEPTH_CACHELINE_FREE(x) (((x) >> 20) & 0x1F)
+#define C_009838_DEPTH_CACHELINE_FREE 0xFE0FFFFF
+#define S_009838_EARLY_Z_PANIC_DISABLE(x) (((x) & 0x1) << 25)
+#define G_009838_EARLY_Z_PANIC_DISABLE(x) (((x) >> 25) & 0x1)
+#define C_009838_EARLY_Z_PANIC_DISABLE 0xFDFFFFFF
+#define S_009838_LATE_Z_PANIC_DISABLE(x) (((x) & 0x1) << 26)
+#define G_009838_LATE_Z_PANIC_DISABLE(x) (((x) >> 26) & 0x1)
+#define C_009838_LATE_Z_PANIC_DISABLE 0xFBFFFFFF
+#define S_009838_RE_Z_PANIC_DISABLE(x) (((x) & 0x1) << 27)
+#define G_009838_RE_Z_PANIC_DISABLE(x) (((x) >> 27) & 0x1)
+#define C_009838_RE_Z_PANIC_DISABLE 0xF7FFFFFF
+#define S_009838_DB_EXTRA_DEBUG(x) (((x) & 0xF) << 28)
+#define G_009838_DB_EXTRA_DEBUG(x) (((x) >> 28) & 0xF)
+#define C_009838_DB_EXTRA_DEBUG 0x0FFFFFFF
+#define R_028030_PA_SC_SCREEN_SCISSOR_TL 0x028030
+#define S_028030_TL_X(x) (((x) & 0x7FFF) << 0)
+#define G_028030_TL_X(x) (((x) >> 0) & 0x7FFF)
+#define C_028030_TL_X 0xFFFF8000
+#define S_028030_TL_Y(x) (((x) & 0x7FFF) << 16)
+#define G_028030_TL_Y(x) (((x) >> 16) & 0x7FFF)
+#define C_028030_TL_Y 0x8000FFFF
+#define R_028034_PA_SC_SCREEN_SCISSOR_BR 0x028034
+#define S_028034_BR_X(x) (((x) & 0x7FFF) << 0)
+#define G_028034_BR_X(x) (((x) >> 0) & 0x7FFF)
+#define C_028034_BR_X 0xFFFF8000
+#define S_028034_BR_Y(x) (((x) & 0x7FFF) << 16)
+#define G_028034_BR_Y(x) (((x) >> 16) & 0x7FFF)
+#define C_028034_BR_Y 0x8000FFFF
+#define R_028200_PA_SC_WINDOW_OFFSET 0x028200
+#define S_028200_WINDOW_X_OFFSET(x) (((x) & 0x7FFF) << 0)
+#define G_028200_WINDOW_X_OFFSET(x) (((x) >> 0) & 0x7FFF)
+#define C_028200_WINDOW_X_OFFSET 0xFFFF8000
+#define S_028200_WINDOW_Y_OFFSET(x) (((x) & 0x7FFF) << 16)
+#define G_028200_WINDOW_Y_OFFSET(x) (((x) >> 16) & 0x7FFF)
+#define C_028200_WINDOW_Y_OFFSET 0x8000FFFF
+#define R_028204_PA_SC_WINDOW_SCISSOR_TL 0x028204
+#define S_028204_TL_X(x) (((x) & 0x3FFF) << 0)
+#define G_028204_TL_X(x) (((x) >> 0) & 0x3FFF)
+#define C_028204_TL_X 0xFFFFC000
+#define S_028204_TL_Y(x) (((x) & 0x3FFF) << 16)
+#define G_028204_TL_Y(x) (((x) >> 16) & 0x3FFF)
+#define C_028204_TL_Y 0xC000FFFF
+#define S_028204_WINDOW_OFFSET_DISABLE(x) (((x) & 0x1) << 31)
+#define G_028204_WINDOW_OFFSET_DISABLE(x) (((x) >> 31) & 0x1)
+#define C_028204_WINDOW_OFFSET_DISABLE 0x7FFFFFFF
+#define R_028208_PA_SC_WINDOW_SCISSOR_BR 0x028208
+#define S_028208_BR_X(x) (((x) & 0x3FFF) << 0)
+#define G_028208_BR_X(x) (((x) >> 0) & 0x3FFF)
+#define C_028208_BR_X 0xFFFFC000
+#define S_028208_BR_Y(x) (((x) & 0x3FFF) << 16)
+#define G_028208_BR_Y(x) (((x) >> 16) & 0x3FFF)
+#define C_028208_BR_Y 0xC000FFFF
+#define R_02820C_PA_SC_CLIPRECT_RULE 0x02820C
+#define S_02820C_CLIP_RULE(x) (((x) & 0xFFFF) << 0)
+#define G_02820C_CLIP_RULE(x) (((x) >> 0) & 0xFFFF)
+#define C_02820C_CLIP_RULE 0xFFFF0000
+#define R_028210_PA_SC_CLIPRECT_0_TL 0x028210
+#define S_028210_TL_X(x) (((x) & 0x3FFF) << 0)
+#define G_028210_TL_X(x) (((x) >> 0) & 0x3FFF)
+#define C_028210_TL_X 0xFFFFC000
+#define S_028210_TL_Y(x) (((x) & 0x3FFF) << 16)
+#define G_028210_TL_Y(x) (((x) >> 16) & 0x3FFF)
+#define C_028210_TL_Y 0xC000FFFF
+#define R_028214_PA_SC_CLIPRECT_0_BR 0x028214
+#define S_028214_BR_X(x) (((x) & 0x3FFF) << 0)
+#define G_028214_BR_X(x) (((x) >> 0) & 0x3FFF)
+#define C_028214_BR_X 0xFFFFC000
+#define S_028214_BR_Y(x) (((x) & 0x3FFF) << 16)
+#define G_028214_BR_Y(x) (((x) >> 16) & 0x3FFF)
+#define C_028214_BR_Y 0xC000FFFF
+#define R_028218_PA_SC_CLIPRECT_1_TL 0x028218
+#define R_02821C_PA_SC_CLIPRECT_1_BR 0x02821C
+#define R_028220_PA_SC_CLIPRECT_2_TL 0x028220
+#define R_028224_PA_SC_CLIPRECT_2_BR 0x028224
+#define R_028228_PA_SC_CLIPRECT_3_TL 0x028228
+#define R_02822C_PA_SC_CLIPRECT_3_BR 0x02822C
+#define R_028230_PA_SC_EDGERULE 0x028230
+#define R_028240_PA_SC_GENERIC_SCISSOR_TL 0x028240
+#define S_028240_TL_X(x) (((x) & 0x3FFF) << 0)
+#define G_028240_TL_X(x) (((x) >> 0) & 0x3FFF)
+#define C_028240_TL_X 0xFFFFC000
+#define S_028240_TL_Y(x) (((x) & 0x3FFF) << 16)
+#define G_028240_TL_Y(x) (((x) >> 16) & 0x3FFF)
+#define C_028240_TL_Y 0xC000FFFF
+#define S_028240_WINDOW_OFFSET_DISABLE(x) (((x) & 0x1) << 31)
+#define G_028240_WINDOW_OFFSET_DISABLE(x) (((x) >> 31) & 0x1)
+#define C_028240_WINDOW_OFFSET_DISABLE 0x7FFFFFFF
+#define R_028244_PA_SC_GENERIC_SCISSOR_BR 0x028244
+#define S_028244_BR_X(x) (((x) & 0x3FFF) << 0)
+#define G_028244_BR_X(x) (((x) >> 0) & 0x3FFF)
+#define C_028244_BR_X 0xFFFFC000
+#define S_028244_BR_Y(x) (((x) & 0x3FFF) << 16)
+#define G_028244_BR_Y(x) (((x) >> 16) & 0x3FFF)
+#define C_028244_BR_Y 0xC000FFFF
+#define R_0282D0_PA_SC_VPORT_ZMIN_0 0x0282D0
+#define S_0282D0_VPORT_ZMIN(x) (((x) & 0xFFFFFFFF) << 0)
+#define G_0282D0_VPORT_ZMIN(x) (((x) >> 0) & 0xFFFFFFFF)
+#define C_0282D0_VPORT_ZMIN 0x00000000
+#define R_0282D4_PA_SC_VPORT_ZMAX_0 0x0282D4
+#define S_0282D4_VPORT_ZMAX(x) (((x) & 0xFFFFFFFF) << 0)
+#define G_0282D4_VPORT_ZMAX(x) (((x) >> 0) & 0xFFFFFFFF)
+#define C_0282D4_VPORT_ZMAX 0x00000000
+#define R_028350_SX_MISC 0x028350
+#define S_028350_MULTIPASS(x) (((x) & 0x1) << 0)
+#define G_028350_MULTIPASS(x) (((x) >> 0) & 0x1)
+#define C_028350_MULTIPASS 0xFFFFFFFE
+#define R_028380_SQ_VTX_SEMANTIC_0 0x028380
+#define S_028380_SEMANTIC_ID(x) (((x) & 0xFF) << 0)
+#define G_028380_SEMANTIC_ID(x) (((x) >> 0) & 0xFF)
+#define C_028380_SEMANTIC_ID 0xFFFFFF00
+#define R_028384_SQ_VTX_SEMANTIC_1 0x028384
+#define R_028388_SQ_VTX_SEMANTIC_2 0x028388
+#define R_02838C_SQ_VTX_SEMANTIC_3 0x02838C
+#define R_028390_SQ_VTX_SEMANTIC_4 0x028390
+#define R_028394_SQ_VTX_SEMANTIC_5 0x028394
+#define R_028398_SQ_VTX_SEMANTIC_6 0x028398
+#define R_02839C_SQ_VTX_SEMANTIC_7 0x02839C
+#define R_0283A0_SQ_VTX_SEMANTIC_8 0x0283A0
+#define R_0283A4_SQ_VTX_SEMANTIC_9 0x0283A4
+#define R_0283A8_SQ_VTX_SEMANTIC_10 0x0283A8
+#define R_0283AC_SQ_VTX_SEMANTIC_11 0x0283AC
+#define R_0283B0_SQ_VTX_SEMANTIC_12 0x0283B0
+#define R_0283B4_SQ_VTX_SEMANTIC_13 0x0283B4
+#define R_0283B8_SQ_VTX_SEMANTIC_14 0x0283B8
+#define R_0283BC_SQ_VTX_SEMANTIC_15 0x0283BC
+#define R_0283C0_SQ_VTX_SEMANTIC_16 0x0283C0
+#define R_0283C4_SQ_VTX_SEMANTIC_17 0x0283C4
+#define R_0283C8_SQ_VTX_SEMANTIC_18 0x0283C8
+#define R_0283CC_SQ_VTX_SEMANTIC_19 0x0283CC
+#define R_0283D0_SQ_VTX_SEMANTIC_20 0x0283D0
+#define R_0283D4_SQ_VTX_SEMANTIC_21 0x0283D4
+#define R_0283D8_SQ_VTX_SEMANTIC_22 0x0283D8
+#define R_0283DC_SQ_VTX_SEMANTIC_23 0x0283DC
+#define R_0283E0_SQ_VTX_SEMANTIC_24 0x0283E0
+#define R_0283E4_SQ_VTX_SEMANTIC_25 0x0283E4
+#define R_0283E8_SQ_VTX_SEMANTIC_26 0x0283E8
+#define R_0283EC_SQ_VTX_SEMANTIC_27 0x0283EC
+#define R_0283F0_SQ_VTX_SEMANTIC_28 0x0283F0
+#define R_0283F4_SQ_VTX_SEMANTIC_29 0x0283F4
+#define R_0283F8_SQ_VTX_SEMANTIC_30 0x0283F8
+#define R_0283FC_SQ_VTX_SEMANTIC_31 0x0283FC
+#define R_028400_VGT_MAX_VTX_INDX 0x028400
+#define S_028400_MAX_INDX(x) (((x) & 0xFFFFFFFF) << 0)
+#define G_028400_MAX_INDX(x) (((x) >> 0) & 0xFFFFFFFF)
+#define C_028400_MAX_INDX 0x00000000
+#define R_028404_VGT_MIN_VTX_INDX 0x028404
+#define S_028404_MIN_INDX(x) (((x) & 0xFFFFFFFF) << 0)
+#define G_028404_MIN_INDX(x) (((x) >> 0) & 0xFFFFFFFF)
+#define C_028404_MIN_INDX 0x00000000
+#define R_028408_VGT_INDX_OFFSET 0x028408
+#define S_028408_INDX_OFFSET(x) (((x) & 0xFFFFFFFF) << 0)
+#define G_028408_INDX_OFFSET(x) (((x) >> 0) & 0xFFFFFFFF)
+#define C_028408_INDX_OFFSET 0x00000000
+#define R_02840C_VGT_MULTI_PRIM_IB_RESET_INDX 0x02840C
+#define S_02840C_RESET_INDX(x) (((x) & 0xFFFFFFFF) << 0)
+#define G_02840C_RESET_INDX(x) (((x) >> 0) & 0xFFFFFFFF)
+#define C_02840C_RESET_INDX 0x00000000
+#define R_028410_SX_ALPHA_TEST_CONTROL 0x028410
+#define S_028410_ALPHA_FUNC(x) (((x) & 0x7) << 0)
+#define G_028410_ALPHA_FUNC(x) (((x) >> 0) & 0x7)
+#define C_028410_ALPHA_FUNC 0xFFFFFFF8
+#define S_028410_ALPHA_TEST_ENABLE(x) (((x) & 0x1) << 3)
+#define G_028410_ALPHA_TEST_ENABLE(x) (((x) >> 3) & 0x1)
+#define C_028410_ALPHA_TEST_ENABLE 0xFFFFFFF7
+#define S_028410_ALPHA_TEST_BYPASS(x) (((x) & 0x1) << 8)
+#define G_028410_ALPHA_TEST_BYPASS(x) (((x) >> 8) & 0x1)
+#define C_028410_ALPHA_TEST_BYPASS 0xFFFFFEFF
+#define R_028414_CB_BLEND_RED 0x028414
+#define S_028414_BLEND_RED(x) (((x) & 0xFFFFFFFF) << 0)
+#define G_028414_BLEND_RED(x) (((x) >> 0) & 0xFFFFFFFF)
+#define C_028414_BLEND_RED 0x00000000
+#define R_028418_CB_BLEND_GREEN 0x028418
+#define S_028418_BLEND_GREEN(x) (((x) & 0xFFFFFFFF) << 0)
+#define G_028418_BLEND_GREEN(x) (((x) >> 0) & 0xFFFFFFFF)
+#define C_028418_BLEND_GREEN 0x00000000
+#define R_02841C_CB_BLEND_BLUE 0x02841C
+#define S_02841C_BLEND_BLUE(x) (((x) & 0xFFFFFFFF) << 0)
+#define G_02841C_BLEND_BLUE(x) (((x) >> 0) & 0xFFFFFFFF)
+#define C_02841C_BLEND_BLUE 0x00000000
+#define R_028420_CB_BLEND_ALPHA 0x028420
+#define S_028420_BLEND_ALPHA(x) (((x) & 0xFFFFFFFF) << 0)
+#define G_028420_BLEND_ALPHA(x) (((x) >> 0) & 0xFFFFFFFF)
+#define C_028420_BLEND_ALPHA 0x00000000
+#define R_028438_SX_ALPHA_REF 0x028438
+#define S_028438_ALPHA_REF(x) (((x) & 0xFFFFFFFF) << 0)
+#define G_028438_ALPHA_REF(x) (((x) >> 0) & 0xFFFFFFFF)
+#define C_028438_ALPHA_REF 0x00000000
+#define R_0286C8_SPI_THREAD_GROUPING 0x0286C8
+#define S_0286C8_PS_GROUPING(x) (((x) & 0x1F) << 0)
+#define G_0286C8_PS_GROUPING(x) (((x) >> 0) & 0x1F)
+#define C_0286C8_PS_GROUPING 0xFFFFFFE0
+#define S_0286C8_VS_GROUPING(x) (((x) & 0x1F) << 8)
+#define G_0286C8_VS_GROUPING(x) (((x) >> 8) & 0x1F)
+#define C_0286C8_VS_GROUPING 0xFFFFE0FF
+#define S_0286C8_GS_GROUPING(x) (((x) & 0x1F) << 16)
+#define G_0286C8_GS_GROUPING(x) (((x) >> 16) & 0x1F)
+#define C_0286C8_GS_GROUPING 0xFFE0FFFF
+#define S_0286C8_ES_GROUPING(x) (((x) & 0x1F) << 24)
+#define G_0286C8_ES_GROUPING(x) (((x) >> 24) & 0x1F)
+#define C_0286C8_ES_GROUPING 0xE0FFFFFF
+#define R_0286D8_SPI_INPUT_Z 0x0286D8
+#define S_0286D8_PROVIDE_Z_TO_SPI(x) (((x) & 0x1) << 0)
+#define G_0286D8_PROVIDE_Z_TO_SPI(x) (((x) >> 0) & 0x1)
+#define C_0286D8_PROVIDE_Z_TO_SPI 0xFFFFFFFE
+#define R_0286DC_SPI_FOG_CNTL 0x0286DC
+#define S_0286DC_PASS_FOG_THROUGH_PS(x) (((x) & 0x1) << 0)
+#define G_0286DC_PASS_FOG_THROUGH_PS(x) (((x) >> 0) & 0x1)
+#define C_0286DC_PASS_FOG_THROUGH_PS 0xFFFFFFFE
+#define S_0286DC_PIXEL_FOG_FUNC(x) (((x) & 0x3) << 1)
+#define G_0286DC_PIXEL_FOG_FUNC(x) (((x) >> 1) & 0x3)
+#define C_0286DC_PIXEL_FOG_FUNC 0xFFFFFFF9
+#define S_0286DC_PIXEL_FOG_SRC_SEL(x) (((x) & 0x1) << 3)
+#define G_0286DC_PIXEL_FOG_SRC_SEL(x) (((x) >> 3) & 0x1)
+#define C_0286DC_PIXEL_FOG_SRC_SEL 0xFFFFFFF7
+#define S_0286DC_VS_FOG_CLAMP_DISABLE(x) (((x) & 0x1) << 4)
+#define G_0286DC_VS_FOG_CLAMP_DISABLE(x) (((x) >> 4) & 0x1)
+#define C_0286DC_VS_FOG_CLAMP_DISABLE 0xFFFFFFEF
+#define R_0286E0_SPI_FOG_FUNC_SCALE 0x0286E0
+#define S_0286E0_VALUE(x) (((x) & 0xFFFFFFFF) << 0)
+#define G_0286E0_VALUE(x) (((x) >> 0) & 0xFFFFFFFF)
+#define C_0286E0_VALUE 0x00000000
+#define R_0286E4_SPI_FOG_FUNC_BIAS 0x0286E4
+#define S_0286E4_VALUE(x) (((x) & 0xFFFFFFFF) << 0)
+#define G_0286E4_VALUE(x) (((x) >> 0) & 0xFFFFFFFF)
+#define C_0286E4_VALUE 0x00000000
+#define R_0287A0_CB_SHADER_CONTROL 0x0287A0
+#define S_0287A0_RT0_ENABLE(x) (((x) & 0x1) << 0)
+#define G_0287A0_RT0_ENABLE(x) (((x) >> 0) & 0x1)
+#define C_0287A0_RT0_ENABLE 0xFFFFFFFE
+#define S_0287A0_RT1_ENABLE(x) (((x) & 0x1) << 1)
+#define G_0287A0_RT1_ENABLE(x) (((x) >> 1) & 0x1)
+#define C_0287A0_RT1_ENABLE 0xFFFFFFFD
+#define S_0287A0_RT2_ENABLE(x) (((x) & 0x1) << 2)
+#define G_0287A0_RT2_ENABLE(x) (((x) >> 2) & 0x1)
+#define C_0287A0_RT2_ENABLE 0xFFFFFFFB
+#define S_0287A0_RT3_ENABLE(x) (((x) & 0x1) << 3)
+#define G_0287A0_RT3_ENABLE(x) (((x) >> 3) & 0x1)
+#define C_0287A0_RT3_ENABLE 0xFFFFFFF7
+#define S_0287A0_RT4_ENABLE(x) (((x) & 0x1) << 4)
+#define G_0287A0_RT4_ENABLE(x) (((x) >> 4) & 0x1)
+#define C_0287A0_RT4_ENABLE 0xFFFFFFEF
+#define S_0287A0_RT5_ENABLE(x) (((x) & 0x1) << 5)
+#define G_0287A0_RT5_ENABLE(x) (((x) >> 5) & 0x1)
+#define C_0287A0_RT5_ENABLE 0xFFFFFFDF
+#define S_0287A0_RT6_ENABLE(x) (((x) & 0x1) << 6)
+#define G_0287A0_RT6_ENABLE(x) (((x) >> 6) & 0x1)
+#define C_0287A0_RT6_ENABLE 0xFFFFFFBF
+#define S_0287A0_RT7_ENABLE(x) (((x) & 0x1) << 7)
+#define G_0287A0_RT7_ENABLE(x) (((x) >> 7) & 0x1)
+#define C_0287A0_RT7_ENABLE 0xFFFFFF7F
+#define R_028894_SQ_PGM_START_FS 0x028894
+#define S_028894_PGM_START(x) (((x) & 0xFFFFFFFF) << 0)
+#define G_028894_PGM_START(x) (((x) >> 0) & 0xFFFFFFFF)
+#define C_028894_PGM_START 0x00000000
+#define R_0288A4_SQ_PGM_RESOURCES_FS 0x0288A4
+#define S_0288A4_NUM_GPRS(x) (((x) & 0xFF) << 0)
+#define G_0288A4_NUM_GPRS(x) (((x) >> 0) & 0xFF)
+#define C_0288A4_NUM_GPRS 0xFFFFFF00
+#define S_0288A4_STACK_SIZE(x) (((x) & 0xFF) << 8)
+#define G_0288A4_STACK_SIZE(x) (((x) >> 8) & 0xFF)
+#define C_0288A4_STACK_SIZE 0xFFFF00FF
+#define S_0288A4_DX10_CLAMP(x) (((x) & 0x1) << 21)
+#define G_0288A4_DX10_CLAMP(x) (((x) >> 21) & 0x1)
+#define C_0288A4_DX10_CLAMP 0xFFDFFFFF
+#define R_0288A8_SQ_ESGS_RING_ITEMSIZE 0x0288A8
+#define S_0288A8_ITEMSIZE(x) (((x) & 0x7FFF) << 0)
+#define G_0288A8_ITEMSIZE(x) (((x) >> 0) & 0x7FFF)
+#define C_0288A8_ITEMSIZE 0xFFFF8000
+#define R_0288AC_SQ_GSVS_RING_ITEMSIZE 0x0288AC
+#define S_0288AC_ITEMSIZE(x) (((x) & 0x7FFF) << 0)
+#define G_0288AC_ITEMSIZE(x) (((x) >> 0) & 0x7FFF)
+#define C_0288AC_ITEMSIZE 0xFFFF8000
+#define R_0288B0_SQ_ESTMP_RING_ITEMSIZE 0x0288B0
+#define S_0288B0_ITEMSIZE(x) (((x) & 0x7FFF) << 0)
+#define G_0288B0_ITEMSIZE(x) (((x) >> 0) & 0x7FFF)
+#define C_0288B0_ITEMSIZE 0xFFFF8000
+#define R_0288B4_SQ_GSTMP_RING_ITEMSIZE 0x0288B4
+#define S_0288B4_ITEMSIZE(x) (((x) & 0x7FFF) << 0)
+#define G_0288B4_ITEMSIZE(x) (((x) >> 0) & 0x7FFF)
+#define C_0288B4_ITEMSIZE 0xFFFF8000
+#define R_0288B8_SQ_VSTMP_RING_ITEMSIZE 0x0288B8
+#define S_0288B8_ITEMSIZE(x) (((x) & 0x7FFF) << 0)
+#define G_0288B8_ITEMSIZE(x) (((x) >> 0) & 0x7FFF)
+#define C_0288B8_ITEMSIZE 0xFFFF8000
+#define R_0288BC_SQ_PSTMP_RING_ITEMSIZE 0x0288BC
+#define S_0288BC_ITEMSIZE(x) (((x) & 0x7FFF) << 0)
+#define G_0288BC_ITEMSIZE(x) (((x) >> 0) & 0x7FFF)
+#define C_0288BC_ITEMSIZE 0xFFFF8000
+#define R_0288C0_SQ_FBUF_RING_ITEMSIZE 0x0288C0
+#define S_0288C0_ITEMSIZE(x) (((x) & 0x7FFF) << 0)
+#define G_0288C0_ITEMSIZE(x) (((x) >> 0) & 0x7FFF)
+#define C_0288C0_ITEMSIZE 0xFFFF8000
+#define R_0288C4_SQ_REDUC_RING_ITEMSIZE 0x0288C4
+#define S_0288C4_ITEMSIZE(x) (((x) & 0x7FFF) << 0)
+#define G_0288C4_ITEMSIZE(x) (((x) >> 0) & 0x7FFF)
+#define C_0288C4_ITEMSIZE 0xFFFF8000
+#define R_0288C8_SQ_GS_VERT_ITEMSIZE 0x0288C8
+#define S_0288C8_ITEMSIZE(x) (((x) & 0x7FFF) << 0)
+#define G_0288C8_ITEMSIZE(x) (((x) >> 0) & 0x7FFF)
+#define C_0288C8_ITEMSIZE 0xFFFF8000
+#define R_0288DC_SQ_PGM_CF_OFFSET_FS 0x0288DC
+#define S_0288DC_PGM_CF_OFFSET(x) (((x) & 0xFFFFF) << 0)
+#define G_0288DC_PGM_CF_OFFSET(x) (((x) >> 0) & 0xFFFFF)
+#define C_0288DC_PGM_CF_OFFSET 0xFFF00000
+#define R_028A10_VGT_OUTPUT_PATH_CNTL 0x028A10
+#define S_028A10_PATH_SELECT(x) (((x) & 0x3) << 0)
+#define G_028A10_PATH_SELECT(x) (((x) >> 0) & 0x3)
+#define C_028A10_PATH_SELECT 0xFFFFFFFC
+#define R_028A14_VGT_HOS_CNTL 0x028A14
+#define S_028A14_TESS_MODE(x) (((x) & 0x3) << 0)
+#define G_028A14_TESS_MODE(x) (((x) >> 0) & 0x3)
+#define C_028A14_TESS_MODE 0xFFFFFFFC
+#define R_028A18_VGT_HOS_MAX_TESS_LEVEL 0x028A18
+#define S_028A18_MAX_TESS(x) (((x) & 0xFFFFFFFF) << 0)
+#define G_028A18_MAX_TESS(x) (((x) >> 0) & 0xFFFFFFFF)
+#define C_028A18_MAX_TESS 0x00000000
+#define R_028A1C_VGT_HOS_MIN_TESS_LEVEL 0x028A1C
+#define S_028A1C_MIN_TESS(x) (((x) & 0xFFFFFFFF) << 0)
+#define G_028A1C_MIN_TESS(x) (((x) >> 0) & 0xFFFFFFFF)
+#define C_028A1C_MIN_TESS 0x00000000
+#define R_028A20_VGT_HOS_REUSE_DEPTH 0x028A20
+#define S_028A20_REUSE_DEPTH(x) (((x) & 0xFF) << 0)
+#define G_028A20_REUSE_DEPTH(x) (((x) >> 0) & 0xFF)
+#define C_028A20_REUSE_DEPTH 0xFFFFFF00
+#define R_028A24_VGT_GROUP_PRIM_TYPE 0x028A24
+#define S_028A24_PRIM_TYPE(x) (((x) & 0x1F) << 0)
+#define G_028A24_PRIM_TYPE(x) (((x) >> 0) & 0x1F)
+#define C_028A24_PRIM_TYPE 0xFFFFFFE0
+#define S_028A24_RETAIN_ORDER(x) (((x) & 0x1) << 14)
+#define G_028A24_RETAIN_ORDER(x) (((x) >> 14) & 0x1)
+#define C_028A24_RETAIN_ORDER 0xFFFFBFFF
+#define S_028A24_RETAIN_QUADS(x) (((x) & 0x1) << 15)
+#define G_028A24_RETAIN_QUADS(x) (((x) >> 15) & 0x1)
+#define C_028A24_RETAIN_QUADS 0xFFFF7FFF
+#define S_028A24_PRIM_ORDER(x) (((x) & 0x7) << 16)
+#define G_028A24_PRIM_ORDER(x) (((x) >> 16) & 0x7)
+#define C_028A24_PRIM_ORDER 0xFFF8FFFF
+#define R_028A28_VGT_GROUP_FIRST_DECR 0x028A28
+#define S_028A28_FIRST_DECR(x) (((x) & 0xF) << 0)
+#define G_028A28_FIRST_DECR(x) (((x) >> 0) & 0xF)
+#define C_028A28_FIRST_DECR 0xFFFFFFF0
+#define R_028A2C_VGT_GROUP_DECR 0x028A2C
+#define S_028A2C_DECR(x) (((x) & 0xF) << 0)
+#define G_028A2C_DECR(x) (((x) >> 0) & 0xF)
+#define C_028A2C_DECR 0xFFFFFFF0
+#define R_028A30_VGT_GROUP_VECT_0_CNTL 0x028A30
+#define S_028A30_COMP_X_EN(x) (((x) & 0x1) << 0)
+#define G_028A30_COMP_X_EN(x) (((x) >> 0) & 0x1)
+#define C_028A30_COMP_X_EN 0xFFFFFFFE
+#define S_028A30_COMP_Y_EN(x) (((x) & 0x1) << 1)
+#define G_028A30_COMP_Y_EN(x) (((x) >> 1) & 0x1)
+#define C_028A30_COMP_Y_EN 0xFFFFFFFD
+#define S_028A30_COMP_Z_EN(x) (((x) & 0x1) << 2)
+#define G_028A30_COMP_Z_EN(x) (((x) >> 2) & 0x1)
+#define C_028A30_COMP_Z_EN 0xFFFFFFFB
+#define S_028A30_COMP_W_EN(x) (((x) & 0x1) << 3)
+#define G_028A30_COMP_W_EN(x) (((x) >> 3) & 0x1)
+#define C_028A30_COMP_W_EN 0xFFFFFFF7
+#define S_028A30_STRIDE(x) (((x) & 0xFF) << 8)
+#define G_028A30_STRIDE(x) (((x) >> 8) & 0xFF)
+#define C_028A30_STRIDE 0xFFFF00FF
+#define S_028A30_SHIFT(x) (((x) & 0xFF) << 16)
+#define G_028A30_SHIFT(x) (((x) >> 16) & 0xFF)
+#define C_028A30_SHIFT 0xFF00FFFF
+#define R_028A34_VGT_GROUP_VECT_1_CNTL 0x028A34
+#define S_028A34_COMP_X_EN(x) (((x) & 0x1) << 0)
+#define G_028A34_COMP_X_EN(x) (((x) >> 0) & 0x1)
+#define C_028A34_COMP_X_EN 0xFFFFFFFE
+#define S_028A34_COMP_Y_EN(x) (((x) & 0x1) << 1)
+#define G_028A34_COMP_Y_EN(x) (((x) >> 1) & 0x1)
+#define C_028A34_COMP_Y_EN 0xFFFFFFFD
+#define S_028A34_COMP_Z_EN(x) (((x) & 0x1) << 2)
+#define G_028A34_COMP_Z_EN(x) (((x) >> 2) & 0x1)
+#define C_028A34_COMP_Z_EN 0xFFFFFFFB
+#define S_028A34_COMP_W_EN(x) (((x) & 0x1) << 3)
+#define G_028A34_COMP_W_EN(x) (((x) >> 3) & 0x1)
+#define C_028A34_COMP_W_EN 0xFFFFFFF7
+#define S_028A34_STRIDE(x) (((x) & 0xFF) << 8)
+#define G_028A34_STRIDE(x) (((x) >> 8) & 0xFF)
+#define C_028A34_STRIDE 0xFFFF00FF
+#define S_028A34_SHIFT(x) (((x) & 0xFF) << 16)
+#define G_028A34_SHIFT(x) (((x) >> 16) & 0xFF)
+#define C_028A34_SHIFT 0xFF00FFFF
+#define R_028A38_VGT_GROUP_VECT_0_FMT_CNTL 0x028A38
+#define S_028A38_X_CONV(x) (((x) & 0xF) << 0)
+#define G_028A38_X_CONV(x) (((x) >> 0) & 0xF)
+#define C_028A38_X_CONV 0xFFFFFFF0
+#define S_028A38_X_OFFSET(x) (((x) & 0xF) << 4)
+#define G_028A38_X_OFFSET(x) (((x) >> 4) & 0xF)
+#define C_028A38_X_OFFSET 0xFFFFFF0F
+#define S_028A38_Y_CONV(x) (((x) & 0xF) << 8)
+#define G_028A38_Y_CONV(x) (((x) >> 8) & 0xF)
+#define C_028A38_Y_CONV 0xFFFFF0FF
+#define S_028A38_Y_OFFSET(x) (((x) & 0xF) << 12)
+#define G_028A38_Y_OFFSET(x) (((x) >> 12) & 0xF)
+#define C_028A38_Y_OFFSET 0xFFFF0FFF
+#define S_028A38_Z_CONV(x) (((x) & 0xF) << 16)
+#define G_028A38_Z_CONV(x) (((x) >> 16) & 0xF)
+#define C_028A38_Z_CONV 0xFFF0FFFF
+#define S_028A38_Z_OFFSET(x) (((x) & 0xF) << 20)
+#define G_028A38_Z_OFFSET(x) (((x) >> 20) & 0xF)
+#define C_028A38_Z_OFFSET 0xFF0FFFFF
+#define S_028A38_W_CONV(x) (((x) & 0xF) << 24)
+#define G_028A38_W_CONV(x) (((x) >> 24) & 0xF)
+#define C_028A38_W_CONV 0xF0FFFFFF
+#define S_028A38_W_OFFSET(x) (((x) & 0xF) << 28)
+#define G_028A38_W_OFFSET(x) (((x) >> 28) & 0xF)
+#define C_028A38_W_OFFSET 0x0FFFFFFF
+#define R_028A3C_VGT_GROUP_VECT_1_FMT_CNTL 0x028A3C
+#define S_028A3C_X_CONV(x) (((x) & 0xF) << 0)
+#define G_028A3C_X_CONV(x) (((x) >> 0) & 0xF)
+#define C_028A3C_X_CONV 0xFFFFFFF0
+#define S_028A3C_X_OFFSET(x) (((x) & 0xF) << 4)
+#define G_028A3C_X_OFFSET(x) (((x) >> 4) & 0xF)
+#define C_028A3C_X_OFFSET 0xFFFFFF0F
+#define S_028A3C_Y_CONV(x) (((x) & 0xF) << 8)
+#define G_028A3C_Y_CONV(x) (((x) >> 8) & 0xF)
+#define C_028A3C_Y_CONV 0xFFFFF0FF
+#define S_028A3C_Y_OFFSET(x) (((x) & 0xF) << 12)
+#define G_028A3C_Y_OFFSET(x) (((x) >> 12) & 0xF)
+#define C_028A3C_Y_OFFSET 0xFFFF0FFF
+#define S_028A3C_Z_CONV(x) (((x) & 0xF) << 16)
+#define G_028A3C_Z_CONV(x) (((x) >> 16) & 0xF)
+#define C_028A3C_Z_CONV 0xFFF0FFFF
+#define S_028A3C_Z_OFFSET(x) (((x) & 0xF) << 20)
+#define G_028A3C_Z_OFFSET(x) (((x) >> 20) & 0xF)
+#define C_028A3C_Z_OFFSET 0xFF0FFFFF
+#define S_028A3C_W_CONV(x) (((x) & 0xF) << 24)
+#define G_028A3C_W_CONV(x) (((x) >> 24) & 0xF)
+#define C_028A3C_W_CONV 0xF0FFFFFF
+#define S_028A3C_W_OFFSET(x) (((x) & 0xF) << 28)
+#define G_028A3C_W_OFFSET(x) (((x) >> 28) & 0xF)
+#define C_028A3C_W_OFFSET 0x0FFFFFFF
+#define R_028A40_VGT_GS_MODE 0x028A40
+#define S_028A40_MODE(x) (((x) & 0x3) << 0)
+#define G_028A40_MODE(x) (((x) >> 0) & 0x3)
+#define C_028A40_MODE 0xFFFFFFFC
+#define S_028A40_ES_PASSTHRU(x) (((x) & 0x1) << 2)
+#define G_028A40_ES_PASSTHRU(x) (((x) >> 2) & 0x1)
+#define C_028A40_ES_PASSTHRU 0xFFFFFFFB
+#define S_028A40_CUT_MODE(x) (((x) & 0x3) << 3)
+#define G_028A40_CUT_MODE(x) (((x) >> 3) & 0x3)
+#define C_028A40_CUT_MODE 0xFFFFFFE7
+#define R_028A4C_PA_SC_MODE_CNTL 0x028A4C
+#define S_028A4C_MSAA_ENABLE(x) (((x) & 0x1) << 0)
+#define G_028A4C_MSAA_ENABLE(x) (((x) >> 0) & 0x1)
+#define C_028A4C_MSAA_ENABLE 0xFFFFFFFE
+#define S_028A4C_CLIPRECT_ENABLE(x) (((x) & 0x1) << 1)
+#define G_028A4C_CLIPRECT_ENABLE(x) (((x) >> 1) & 0x1)
+#define C_028A4C_CLIPRECT_ENABLE 0xFFFFFFFD
+#define S_028A4C_LINE_STIPPLE_ENABLE(x) (((x) & 0x1) << 2)
+#define G_028A4C_LINE_STIPPLE_ENABLE(x) (((x) >> 2) & 0x1)
+#define C_028A4C_LINE_STIPPLE_ENABLE 0xFFFFFFFB
+#define S_028A4C_MULTI_CHIP_PRIM_DISCARD_ENAB(x) (((x) & 0x1) << 3)
+#define G_028A4C_MULTI_CHIP_PRIM_DISCARD_ENAB(x) (((x) >> 3) & 0x1)
+#define C_028A4C_MULTI_CHIP_PRIM_DISCARD_ENAB 0xFFFFFFF7
+#define S_028A4C_WALK_ORDER_ENABLE(x) (((x) & 0x1) << 4)
+#define G_028A4C_WALK_ORDER_ENABLE(x) (((x) >> 4) & 0x1)
+#define C_028A4C_WALK_ORDER_ENABLE 0xFFFFFFEF
+#define S_028A4C_HALVE_DETAIL_SAMPLE_PERF(x) (((x) & 0x1) << 5)
+#define G_028A4C_HALVE_DETAIL_SAMPLE_PERF(x) (((x) >> 5) & 0x1)
+#define C_028A4C_HALVE_DETAIL_SAMPLE_PERF 0xFFFFFFDF
+#define S_028A4C_WALK_SIZE(x) (((x) & 0x1) << 6)
+#define G_028A4C_WALK_SIZE(x) (((x) >> 6) & 0x1)
+#define C_028A4C_WALK_SIZE 0xFFFFFFBF
+#define S_028A4C_WALK_ALIGNMENT(x) (((x) & 0x1) << 7)
+#define G_028A4C_WALK_ALIGNMENT(x) (((x) >> 7) & 0x1)
+#define C_028A4C_WALK_ALIGNMENT 0xFFFFFF7F
+#define S_028A4C_WALK_ALIGN8_PRIM_FITS_ST(x) (((x) & 0x1) << 8)
+#define G_028A4C_WALK_ALIGN8_PRIM_FITS_ST(x) (((x) >> 8) & 0x1)
+#define C_028A4C_WALK_ALIGN8_PRIM_FITS_ST 0xFFFFFEFF
+#define S_028A4C_TILE_COVER_NO_SCISSOR(x) (((x) & 0x1) << 9)
+#define G_028A4C_TILE_COVER_NO_SCISSOR(x) (((x) >> 9) & 0x1)
+#define C_028A4C_TILE_COVER_NO_SCISSOR 0xFFFFFDFF
+#define S_028A4C_KILL_PIX_POST_HI_Z(x) (((x) & 0x1) << 10)
+#define G_028A4C_KILL_PIX_POST_HI_Z(x) (((x) >> 10) & 0x1)
+#define C_028A4C_KILL_PIX_POST_HI_Z 0xFFFFFBFF
+#define S_028A4C_KILL_PIX_POST_DETAIL_MASK(x) (((x) & 0x1) << 11)
+#define G_028A4C_KILL_PIX_POST_DETAIL_MASK(x) (((x) >> 11) & 0x1)
+#define C_028A4C_KILL_PIX_POST_DETAIL_MASK 0xFFFFF7FF
+#define S_028A4C_MULTI_CHIP_SUPERTILE_ENABLE(x) (((x) & 0x1) << 12)
+#define G_028A4C_MULTI_CHIP_SUPERTILE_ENABLE(x) (((x) >> 12) & 0x1)
+#define C_028A4C_MULTI_CHIP_SUPERTILE_ENABLE 0xFFFFEFFF
+#define S_028A4C_TILE_COVER_DISABLE(x) (((x) & 0x1) << 13)
+#define G_028A4C_TILE_COVER_DISABLE(x) (((x) >> 13) & 0x1)
+#define C_028A4C_TILE_COVER_DISABLE 0xFFFFDFFF
+#define S_028A4C_FORCE_EOV_CNTDWN_ENABLE(x) (((x) & 0x1) << 14)
+#define G_028A4C_FORCE_EOV_CNTDWN_ENABLE(x) (((x) >> 14) & 0x1)
+#define C_028A4C_FORCE_EOV_CNTDWN_ENABLE 0xFFFFBFFF
+#define S_028A4C_FORCE_EOV_TILE_ENABLE(x) (((x) & 0x1) << 15)
+#define G_028A4C_FORCE_EOV_TILE_ENABLE(x) (((x) >> 15) & 0x1)
+#define C_028A4C_FORCE_EOV_TILE_ENABLE 0xFFFF7FFF
+#define S_028A4C_FORCE_EOV_REZ_ENABLE(x) (((x) & 0x1) << 16)
+#define G_028A4C_FORCE_EOV_REZ_ENABLE(x) (((x) >> 16) & 0x1)
+#define C_028A4C_FORCE_EOV_REZ_ENABLE 0xFFFEFFFF
+#define S_028A4C_PS_ITER_SAMPLE(x) (((x) & 0x1) << 17)
+#define G_028A4C_PS_ITER_SAMPLE(x) (((x) >> 17) & 0x1)
+#define C_028A4C_PS_ITER_SAMPLE 0xFFFDFFFF
+#define R_028A84_VGT_PRIMITIVEID_EN 0x028A84
+#define S_028A84_PRIMITIVEID_EN(x) (((x) & 0x1) << 0)
+#define G_028A84_PRIMITIVEID_EN(x) (((x) >> 0) & 0x1)
+#define C_028A84_PRIMITIVEID_EN 0xFFFFFFFE
+#define R_028A94_VGT_MULTI_PRIM_IB_RESET_EN 0x028A94
+#define S_028A94_RESET_EN(x) (((x) & 0x1) << 0)
+#define G_028A94_RESET_EN(x) (((x) >> 0) & 0x1)
+#define C_028A94_RESET_EN 0xFFFFFFFE
+#define R_028AA0_VGT_INSTANCE_STEP_RATE_0 0x028AA0
+#define S_028AA0_STEP_RATE(x) (((x) & 0xFFFFFFFF) << 0)
+#define G_028AA0_STEP_RATE(x) (((x) >> 0) & 0xFFFFFFFF)
+#define C_028AA0_STEP_RATE 0x00000000
+#define R_028AA4_VGT_INSTANCE_STEP_RATE_1 0x028AA4
+#define S_028AA4_STEP_RATE(x) (((x) & 0xFFFFFFFF) << 0)
+#define G_028AA4_STEP_RATE(x) (((x) >> 0) & 0xFFFFFFFF)
+#define C_028AA4_STEP_RATE 0x00000000
+#define R_028AB0_VGT_STRMOUT_EN 0x028AB0
+#define S_028AB0_STREAMOUT(x) (((x) & 0x1) << 0)
+#define G_028AB0_STREAMOUT(x) (((x) >> 0) & 0x1)
+#define C_028AB0_STREAMOUT 0xFFFFFFFE
+#define R_028AB4_VGT_REUSE_OFF 0x028AB4
+#define S_028AB4_REUSE_OFF(x) (((x) & 0x1) << 0)
+#define G_028AB4_REUSE_OFF(x) (((x) >> 0) & 0x1)
+#define C_028AB4_REUSE_OFF 0xFFFFFFFE
+#define R_028AB8_VGT_VTX_CNT_EN 0x028AB8
+#define S_028AB8_VTX_CNT_EN(x) (((x) & 0x1) << 0)
+#define G_028AB8_VTX_CNT_EN(x) (((x) >> 0) & 0x1)
+#define C_028AB8_VTX_CNT_EN 0xFFFFFFFE
+#define R_028B20_VGT_STRMOUT_BUFFER_EN 0x028B20
+#define S_028B20_BUFFER_0_EN(x) (((x) & 0x1) << 0)
+#define G_028B20_BUFFER_0_EN(x) (((x) >> 0) & 0x1)
+#define C_028B20_BUFFER_0_EN 0xFFFFFFFE
+#define S_028B20_BUFFER_1_EN(x) (((x) & 0x1) << 1)
+#define G_028B20_BUFFER_1_EN(x) (((x) >> 1) & 0x1)
+#define C_028B20_BUFFER_1_EN 0xFFFFFFFD
+#define S_028B20_BUFFER_2_EN(x) (((x) & 0x1) << 2)
+#define G_028B20_BUFFER_2_EN(x) (((x) >> 2) & 0x1)
+#define C_028B20_BUFFER_2_EN 0xFFFFFFFB
+#define S_028B20_BUFFER_3_EN(x) (((x) & 0x1) << 3)
+#define G_028B20_BUFFER_3_EN(x) (((x) >> 3) & 0x1)
+#define C_028B20_BUFFER_3_EN 0xFFFFFFF7
+#define R_028C20_PA_SC_AA_SAMPLE_LOCS_8S_WD1_MCTX 0x028C20
+#define S_028C20_S4_X(x) (((x) & 0xF) << 0)
+#define G_028C20_S4_X(x) (((x) >> 0) & 0xF)
+#define C_028C20_S4_X 0xFFFFFFF0
+#define S_028C20_S4_Y(x) (((x) & 0xF) << 4)
+#define G_028C20_S4_Y(x) (((x) >> 4) & 0xF)
+#define C_028C20_S4_Y 0xFFFFFF0F
+#define S_028C20_S5_X(x) (((x) & 0xF) << 8)
+#define G_028C20_S5_X(x) (((x) >> 8) & 0xF)
+#define C_028C20_S5_X 0xFFFFF0FF
+#define S_028C20_S5_Y(x) (((x) & 0xF) << 12)
+#define G_028C20_S5_Y(x) (((x) >> 12) & 0xF)
+#define C_028C20_S5_Y 0xFFFF0FFF
+#define S_028C20_S6_X(x) (((x) & 0xF) << 16)
+#define G_028C20_S6_X(x) (((x) >> 16) & 0xF)
+#define C_028C20_S6_X 0xFFF0FFFF
+#define S_028C20_S6_Y(x) (((x) & 0xF) << 20)
+#define G_028C20_S6_Y(x) (((x) >> 20) & 0xF)
+#define C_028C20_S6_Y 0xFF0FFFFF
+#define S_028C20_S7_X(x) (((x) & 0xF) << 24)
+#define G_028C20_S7_X(x) (((x) >> 24) & 0xF)
+#define C_028C20_S7_X 0xF0FFFFFF
+#define S_028C20_S7_Y(x) (((x) & 0xF) << 28)
+#define G_028C20_S7_Y(x) (((x) >> 28) & 0xF)
+#define C_028C20_S7_Y 0x0FFFFFFF
+#define R_028C30_CB_CLRCMP_CONTROL 0x028C30
+#define S_028C30_CLRCMP_FCN_SRC(x) (((x) & 0x7) << 0)
+#define G_028C30_CLRCMP_FCN_SRC(x) (((x) >> 0) & 0x7)
+#define C_028C30_CLRCMP_FCN_SRC 0xFFFFFFF8
+#define S_028C30_CLRCMP_FCN_DST(x) (((x) & 0x7) << 8)
+#define G_028C30_CLRCMP_FCN_DST(x) (((x) >> 8) & 0x7)
+#define C_028C30_CLRCMP_FCN_DST 0xFFFFF8FF
+#define S_028C30_CLRCMP_FCN_SEL(x) (((x) & 0x3) << 24)
+#define G_028C30_CLRCMP_FCN_SEL(x) (((x) >> 24) & 0x3)
+#define C_028C30_CLRCMP_FCN_SEL 0xFCFFFFFF
+#define R_028C34_CB_CLRCMP_SRC 0x028C34
+#define S_028C34_CLRCMP_SRC(x) (((x) & 0xFFFFFFFF) << 0)
+#define G_028C34_CLRCMP_SRC(x) (((x) >> 0) & 0xFFFFFFFF)
+#define C_028C34_CLRCMP_SRC 0x00000000
+#define R_028C38_CB_CLRCMP_DST 0x028C38
+#define S_028C38_CLRCMP_DST(x) (((x) & 0xFFFFFFFF) << 0)
+#define G_028C38_CLRCMP_DST(x) (((x) >> 0) & 0xFFFFFFFF)
+#define C_028C38_CLRCMP_DST 0x00000000
+#define R_028C3C_CB_CLRCMP_MSK 0x028C3C
+#define S_028C3C_CLRCMP_MSK(x) (((x) & 0xFFFFFFFF) << 0)
+#define G_028C3C_CLRCMP_MSK(x) (((x) >> 0) & 0xFFFFFFFF)
+#define C_028C3C_CLRCMP_MSK 0x00000000
+#define R_0085F0_CP_COHER_CNTL 0x0085F0
+#define S_0085F0_DEST_BASE_0_ENA(x) (((x) & 0x1) << 0)
+#define G_0085F0_DEST_BASE_0_ENA(x) (((x) >> 0) & 0x1)
+#define C_0085F0_DEST_BASE_0_ENA 0xFFFFFFFE
+#define S_0085F0_DEST_BASE_1_ENA(x) (((x) & 0x1) << 1)
+#define G_0085F0_DEST_BASE_1_ENA(x) (((x) >> 1) & 0x1)
+#define C_0085F0_DEST_BASE_1_ENA 0xFFFFFFFD
+#define S_0085F0_SO0_DEST_BASE_ENA(x) (((x) & 0x1) << 2)
+#define G_0085F0_SO0_DEST_BASE_ENA(x) (((x) >> 2) & 0x1)
+#define C_0085F0_SO0_DEST_BASE_ENA 0xFFFFFFFB
+#define S_0085F0_SO1_DEST_BASE_ENA(x) (((x) & 0x1) << 3)
+#define G_0085F0_SO1_DEST_BASE_ENA(x) (((x) >> 3) & 0x1)
+#define C_0085F0_SO1_DEST_BASE_ENA 0xFFFFFFF7
+#define S_0085F0_SO2_DEST_BASE_ENA(x) (((x) & 0x1) << 4)
+#define G_0085F0_SO2_DEST_BASE_ENA(x) (((x) >> 4) & 0x1)
+#define C_0085F0_SO2_DEST_BASE_ENA 0xFFFFFFEF
+#define S_0085F0_SO3_DEST_BASE_ENA(x) (((x) & 0x1) << 5)
+#define G_0085F0_SO3_DEST_BASE_ENA(x) (((x) >> 5) & 0x1)
+#define C_0085F0_SO3_DEST_BASE_ENA 0xFFFFFFDF
+#define S_0085F0_CB0_DEST_BASE_ENA(x) (((x) & 0x1) << 6)
+#define G_0085F0_CB0_DEST_BASE_ENA(x) (((x) >> 6) & 0x1)
+#define C_0085F0_CB0_DEST_BASE_ENA 0xFFFFFFBF
+#define S_0085F0_CB1_DEST_BASE_ENA(x) (((x) & 0x1) << 7)
+#define G_0085F0_CB1_DEST_BASE_ENA(x) (((x) >> 7) & 0x1)
+#define C_0085F0_CB1_DEST_BASE_ENA 0xFFFFFF7F
+#define S_0085F0_CB2_DEST_BASE_ENA(x) (((x) & 0x1) << 8)
+#define G_0085F0_CB2_DEST_BASE_ENA(x) (((x) >> 8) & 0x1)
+#define C_0085F0_CB2_DEST_BASE_ENA 0xFFFFFEFF
+#define S_0085F0_CB3_DEST_BASE_ENA(x) (((x) & 0x1) << 9)
+#define G_0085F0_CB3_DEST_BASE_ENA(x) (((x) >> 9) & 0x1)
+#define C_0085F0_CB3_DEST_BASE_ENA 0xFFFFFDFF
+#define S_0085F0_CB4_DEST_BASE_ENA(x) (((x) & 0x1) << 10)
+#define G_0085F0_CB4_DEST_BASE_ENA(x) (((x) >> 10) & 0x1)
+#define C_0085F0_CB4_DEST_BASE_ENA 0xFFFFFBFF
+#define S_0085F0_CB5_DEST_BASE_ENA(x) (((x) & 0x1) << 11)
+#define G_0085F0_CB5_DEST_BASE_ENA(x) (((x) >> 11) & 0x1)
+#define C_0085F0_CB5_DEST_BASE_ENA 0xFFFFF7FF
+#define S_0085F0_CB6_DEST_BASE_ENA(x) (((x) & 0x1) << 12)
+#define G_0085F0_CB6_DEST_BASE_ENA(x) (((x) >> 12) & 0x1)
+#define C_0085F0_CB6_DEST_BASE_ENA 0xFFFFEFFF
+#define S_0085F0_CB7_DEST_BASE_ENA(x) (((x) & 0x1) << 13)
+#define G_0085F0_CB7_DEST_BASE_ENA(x) (((x) >> 13) & 0x1)
+#define C_0085F0_CB7_DEST_BASE_ENA 0xFFFFDFFF
+#define S_0085F0_DB_DEST_BASE_ENA(x) (((x) & 0x1) << 14)
+#define G_0085F0_DB_DEST_BASE_ENA(x) (((x) >> 14) & 0x1)
+#define C_0085F0_DB_DEST_BASE_ENA 0xFFFFBFFF
+#define S_0085F0_CR_DEST_BASE_ENA(x) (((x) & 0x1) << 15)
+#define G_0085F0_CR_DEST_BASE_ENA(x) (((x) >> 15) & 0x1)
+#define C_0085F0_CR_DEST_BASE_ENA 0xFFFF7FFF
+#define S_0085F0_TC_ACTION_ENA(x) (((x) & 0x1) << 23)
+#define G_0085F0_TC_ACTION_ENA(x) (((x) >> 23) & 0x1)
+#define C_0085F0_TC_ACTION_ENA 0xFF7FFFFF
+#define S_0085F0_VC_ACTION_ENA(x) (((x) & 0x1) << 24)
+#define G_0085F0_VC_ACTION_ENA(x) (((x) >> 24) & 0x1)
+#define C_0085F0_VC_ACTION_ENA 0xFEFFFFFF
+#define S_0085F0_CB_ACTION_ENA(x) (((x) & 0x1) << 25)
+#define G_0085F0_CB_ACTION_ENA(x) (((x) >> 25) & 0x1)
+#define C_0085F0_CB_ACTION_ENA 0xFDFFFFFF
+#define S_0085F0_DB_ACTION_ENA(x) (((x) & 0x1) << 26)
+#define G_0085F0_DB_ACTION_ENA(x) (((x) >> 26) & 0x1)
+#define C_0085F0_DB_ACTION_ENA 0xFBFFFFFF
+#define S_0085F0_SH_ACTION_ENA(x) (((x) & 0x1) << 27)
+#define G_0085F0_SH_ACTION_ENA(x) (((x) >> 27) & 0x1)
+#define C_0085F0_SH_ACTION_ENA 0xF7FFFFFF
+#define S_0085F0_SMX_ACTION_ENA(x) (((x) & 0x1) << 28)
+#define G_0085F0_SMX_ACTION_ENA(x) (((x) >> 28) & 0x1)
+#define C_0085F0_SMX_ACTION_ENA 0xEFFFFFFF
+#define S_0085F0_CR0_ACTION_ENA(x) (((x) & 0x1) << 29)
+#define G_0085F0_CR0_ACTION_ENA(x) (((x) >> 29) & 0x1)
+#define C_0085F0_CR0_ACTION_ENA 0xDFFFFFFF
+#define S_0085F0_CR1_ACTION_ENA(x) (((x) & 0x1) << 30)
+#define G_0085F0_CR1_ACTION_ENA(x) (((x) >> 30) & 0x1)
+#define C_0085F0_CR1_ACTION_ENA 0xBFFFFFFF
+#define S_0085F0_CR2_ACTION_ENA(x) (((x) & 0x1) << 31)
+#define G_0085F0_CR2_ACTION_ENA(x) (((x) >> 31) & 0x1)
+#define C_0085F0_CR2_ACTION_ENA 0x7FFFFFFF
+
+
+#define R_02812C_CB_CLEAR_ALPHA 0x02812C
+#define S_02812C_CLEAR_ALPHA(x) (((x) & 0xFFFFFFFF) << 0)
+#define G_02812C_CLEAR_ALPHA(x) (((x) >> 0) & 0xFFFFFFFF)
+#define C_02812C_CLEAR_ALPHA 0x00000000
+#define R_028128_CB_CLEAR_BLUE 0x028128
+#define S_028128_CLEAR_BLUE(x) (((x) & 0xFFFFFFFF) << 0)
+#define G_028128_CLEAR_BLUE(x) (((x) >> 0) & 0xFFFFFFFF)
+#define C_028128_CLEAR_BLUE 0x00000000
+#define R_028124_CB_CLEAR_GREEN 0x028124
+#define S_028124_CLEAR_GREEN(x) (((x) & 0xFFFFFFFF) << 0)
+#define G_028124_CLEAR_GREEN(x) (((x) >> 0) & 0xFFFFFFFF)
+#define C_028124_CLEAR_GREEN 0x00000000
+#define R_028120_CB_CLEAR_RED 0x028120
+#define S_028120_CLEAR_RED(x) (((x) & 0xFFFFFFFF) << 0)
+#define G_028120_CLEAR_RED(x) (((x) >> 0) & 0xFFFFFFFF)
+#define C_028120_CLEAR_RED 0x00000000
+#define R_02842C_CB_FOG_BLUE 0x02842C
+#define S_02842C_FOG_BLUE(x) (((x) & 0xFFFFFFFF) << 0)
+#define G_02842C_FOG_BLUE(x) (((x) >> 0) & 0xFFFFFFFF)
+#define C_02842C_FOG_BLUE 0x00000000
+#define R_028428_CB_FOG_GREEN 0x028428
+#define S_028428_FOG_GREEN(x) (((x) & 0xFFFFFFFF) << 0)
+#define G_028428_FOG_GREEN(x) (((x) >> 0) & 0xFFFFFFFF)
+#define C_028428_FOG_GREEN 0x00000000
+#define R_028424_CB_FOG_RED 0x028424
+#define S_028424_FOG_RED(x) (((x) & 0xFFFFFFFF) << 0)
+#define G_028424_FOG_RED(x) (((x) >> 0) & 0xFFFFFFFF)
+#define C_028424_FOG_RED 0x00000000
+#define R_03C000_SQ_TEX_SAMPLER_WORD0_0 0x03C000
+#define S_03C000_CLAMP_X(x) (((x) & 0x7) << 0)
+#define G_03C000_CLAMP_X(x) (((x) >> 0) & 0x7)
+#define C_03C000_CLAMP_X 0xFFFFFFF8
+#define S_03C000_CLAMP_Y(x) (((x) & 0x7) << 3)
+#define G_03C000_CLAMP_Y(x) (((x) >> 3) & 0x7)
+#define C_03C000_CLAMP_Y 0xFFFFFFC7
+#define S_03C000_CLAMP_Z(x) (((x) & 0x7) << 6)
+#define G_03C000_CLAMP_Z(x) (((x) >> 6) & 0x7)
+#define C_03C000_CLAMP_Z 0xFFFFFE3F
+#define S_03C000_XY_MAG_FILTER(x) (((x) & 0x7) << 9)
+#define G_03C000_XY_MAG_FILTER(x) (((x) >> 9) & 0x7)
+#define C_03C000_XY_MAG_FILTER 0xFFFFF1FF
+#define S_03C000_XY_MIN_FILTER(x) (((x) & 0x7) << 12)
+#define G_03C000_XY_MIN_FILTER(x) (((x) >> 12) & 0x7)
+#define C_03C000_XY_MIN_FILTER 0xFFFF8FFF
+#define S_03C000_Z_FILTER(x) (((x) & 0x3) << 15)
+#define G_03C000_Z_FILTER(x) (((x) >> 15) & 0x3)
+#define C_03C000_Z_FILTER 0xFFFE7FFF
+#define S_03C000_MIP_FILTER(x) (((x) & 0x3) << 17)
+#define G_03C000_MIP_FILTER(x) (((x) >> 17) & 0x3)
+#define C_03C000_MIP_FILTER 0xFFF9FFFF
+#define S_03C000_BORDER_COLOR_TYPE(x) (((x) & 0x3) << 22)
+#define G_03C000_BORDER_COLOR_TYPE(x) (((x) >> 22) & 0x3)
+#define C_03C000_BORDER_COLOR_TYPE 0xFF3FFFFF
+#define S_03C000_POINT_SAMPLING_CLAMP(x) (((x) & 0x1) << 24)
+#define G_03C000_POINT_SAMPLING_CLAMP(x) (((x) >> 24) & 0x1)
+#define C_03C000_POINT_SAMPLING_CLAMP 0xFEFFFFFF
+#define S_03C000_TEX_ARRAY_OVERRIDE(x) (((x) & 0x1) << 25)
+#define G_03C000_TEX_ARRAY_OVERRIDE(x) (((x) >> 25) & 0x1)
+#define C_03C000_TEX_ARRAY_OVERRIDE 0xFDFFFFFF
+#define S_03C000_DEPTH_COMPARE_FUNCTION(x) (((x) & 0x7) << 26)
+#define G_03C000_DEPTH_COMPARE_FUNCTION(x) (((x) >> 26) & 0x7)
+#define C_03C000_DEPTH_COMPARE_FUNCTION 0xE3FFFFFF
+#define S_03C000_CHROMA_KEY(x) (((x) & 0x3) << 29)
+#define G_03C000_CHROMA_KEY(x) (((x) >> 29) & 0x3)
+#define C_03C000_CHROMA_KEY 0x9FFFFFFF
+#define S_03C000_LOD_USES_MINOR_AXIS(x) (((x) & 0x1) << 31)
+#define G_03C000_LOD_USES_MINOR_AXIS(x) (((x) >> 31) & 0x1)
+#define C_03C000_LOD_USES_MINOR_AXIS 0x7FFFFFFF
+#define R_03C004_SQ_TEX_SAMPLER_WORD1_0 0x03C004
+#define S_03C004_MIN_LOD(x) (((x) & 0x3FF) << 0)
+#define G_03C004_MIN_LOD(x) (((x) >> 0) & 0x3FF)
+#define C_03C004_MIN_LOD 0xFFFFFC00
+#define S_03C004_MAX_LOD(x) (((x) & 0x3FF) << 10)
+#define G_03C004_MAX_LOD(x) (((x) >> 10) & 0x3FF)
+#define C_03C004_MAX_LOD 0xFFF003FF
+#define S_03C004_LOD_BIAS(x) (((x) & 0xFFF) << 20)
+#define G_03C004_LOD_BIAS(x) (((x) >> 20) & 0xFFF)
+#define C_03C004_LOD_BIAS 0x000FFFFF
+#define R_03C008_SQ_TEX_SAMPLER_WORD2_0 0x03C008
+#define S_03C008_LOD_BIAS_SEC(x) (((x) & 0xFFF) << 0)
+#define G_03C008_LOD_BIAS_SEC(x) (((x) >> 0) & 0xFFF)
+#define C_03C008_LOD_BIAS_SEC 0xFFFFF000
+#define S_03C008_MC_COORD_TRUNCATE(x) (((x) & 0x1) << 12)
+#define G_03C008_MC_COORD_TRUNCATE(x) (((x) >> 12) & 0x1)
+#define C_03C008_MC_COORD_TRUNCATE 0xFFFFEFFF
+#define S_03C008_FORCE_DEGAMMA(x) (((x) & 0x1) << 13)
+#define G_03C008_FORCE_DEGAMMA(x) (((x) >> 13) & 0x1)
+#define C_03C008_FORCE_DEGAMMA 0xFFFFDFFF
+#define S_03C008_HIGH_PRECISION_FILTER(x) (((x) & 0x1) << 14)
+#define G_03C008_HIGH_PRECISION_FILTER(x) (((x) >> 14) & 0x1)
+#define C_03C008_HIGH_PRECISION_FILTER 0xFFFFBFFF
+#define S_03C008_PERF_MIP(x) (((x) & 0x7) << 15)
+#define G_03C008_PERF_MIP(x) (((x) >> 15) & 0x7)
+#define C_03C008_PERF_MIP 0xFFFC7FFF
+#define S_03C008_PERF_Z(x) (((x) & 0x3) << 18)
+#define G_03C008_PERF_Z(x) (((x) >> 18) & 0x3)
+#define C_03C008_PERF_Z 0xFFF3FFFF
+#define S_03C008_FETCH_4(x) (((x) & 0x1) << 26)
+#define G_03C008_FETCH_4(x) (((x) >> 26) & 0x1)
+#define C_03C008_FETCH_4 0xFBFFFFFF
+#define S_03C008_SAMPLE_IS_PCF(x) (((x) & 0x1) << 27)
+#define G_03C008_SAMPLE_IS_PCF(x) (((x) >> 27) & 0x1)
+#define C_03C008_SAMPLE_IS_PCF 0xF7FFFFFF
+#define S_03C008_TYPE(x) (((x) & 0x1) << 31)
+#define G_03C008_TYPE(x) (((x) >> 31) & 0x1)
+#define C_03C008_TYPE 0x7FFFFFFF
+#define R_00A40C_TD_PS_SAMPLER0_BORDER_ALPHA 0x00A40C
+#define S_00A40C_BORDER_ALPHA(x) (((x) & 0xFFFFFFFF) << 0)
+#define G_00A40C_BORDER_ALPHA(x) (((x) >> 0) & 0xFFFFFFFF)
+#define C_00A40C_BORDER_ALPHA 0x00000000
+#define R_00A408_TD_PS_SAMPLER0_BORDER_BLUE 0x00A408
+#define S_00A408_BORDER_BLUE(x) (((x) & 0xFFFFFFFF) << 0)
+#define G_00A408_BORDER_BLUE(x) (((x) >> 0) & 0xFFFFFFFF)
+#define C_00A408_BORDER_BLUE 0x00000000
+#define R_00A404_TD_PS_SAMPLER0_BORDER_GREEN 0x00A404
+#define S_00A404_BORDER_GREEN(x) (((x) & 0xFFFFFFFF) << 0)
+#define G_00A404_BORDER_GREEN(x) (((x) >> 0) & 0xFFFFFFFF)
+#define C_00A404_BORDER_GREEN 0x00000000
+#define R_00A400_TD_PS_SAMPLER0_BORDER_RED 0x00A400
+#define S_00A400_BORDER_RED(x) (((x) & 0xFFFFFFFF) << 0)
+#define G_00A400_BORDER_RED(x) (((x) >> 0) & 0xFFFFFFFF)
+#define C_00A400_BORDER_RED 0x00000000
+#define R_00A60C_TD_VS_SAMPLER0_BORDER_ALPHA 0x00A60C
+#define S_00A60C_BORDER_ALPHA(x) (((x) & 0xFFFFFFFF) << 0)
+#define G_00A60C_BORDER_ALPHA(x) (((x) >> 0) & 0xFFFFFFFF)
+#define C_00A60C_BORDER_ALPHA 0x00000000
+#define R_00A608_TD_VS_SAMPLER0_BORDER_BLUE 0x00A608
+#define S_00A608_BORDER_BLUE(x) (((x) & 0xFFFFFFFF) << 0)
+#define G_00A608_BORDER_BLUE(x) (((x) >> 0) & 0xFFFFFFFF)
+#define C_00A608_BORDER_BLUE 0x00000000
+#define R_00A604_TD_VS_SAMPLER0_BORDER_GREEN 0x00A604
+#define S_00A604_BORDER_GREEN(x) (((x) & 0xFFFFFFFF) << 0)
+#define G_00A604_BORDER_GREEN(x) (((x) >> 0) & 0xFFFFFFFF)
+#define C_00A604_BORDER_GREEN 0x00000000
+#define R_00A600_TD_VS_SAMPLER0_BORDER_RED 0x00A600
+#define S_00A600_BORDER_RED(x) (((x) & 0xFFFFFFFF) << 0)
+#define G_00A600_BORDER_RED(x) (((x) >> 0) & 0xFFFFFFFF)
+#define C_00A600_BORDER_RED 0x00000000
+#define R_00A80C_TD_GS_SAMPLER0_BORDER_ALPHA 0x00A80C
+#define S_00A80C_BORDER_ALPHA(x) (((x) & 0xFFFFFFFF) << 0)
+#define G_00A80C_BORDER_ALPHA(x) (((x) >> 0) & 0xFFFFFFFF)
+#define C_00A80C_BORDER_ALPHA 0x00000000
+#define R_00A808_TD_GS_SAMPLER0_BORDER_BLUE 0x00A808
+#define S_00A808_BORDER_BLUE(x) (((x) & 0xFFFFFFFF) << 0)
+#define G_00A808_BORDER_BLUE(x) (((x) >> 0) & 0xFFFFFFFF)
+#define C_00A808_BORDER_BLUE 0x00000000
+#define R_00A804_TD_GS_SAMPLER0_BORDER_GREEN 0x00A804
+#define S_00A804_BORDER_GREEN(x) (((x) & 0xFFFFFFFF) << 0)
+#define G_00A804_BORDER_GREEN(x) (((x) >> 0) & 0xFFFFFFFF)
+#define C_00A804_BORDER_GREEN 0x00000000
+#define R_00A800_TD_GS_SAMPLER0_BORDER_RED 0x00A800
+#define S_00A800_BORDER_RED(x) (((x) & 0xFFFFFFFF) << 0)
+#define G_00A800_BORDER_RED(x) (((x) >> 0) & 0xFFFFFFFF)
+#define C_00A800_BORDER_RED 0x00000000
+#define R_030000_SQ_ALU_CONSTANT0_0 0x030000
+#define S_030000_X(x) (((x) & 0xFFFFFFFF) << 0)
+#define G_030000_X(x) (((x) >> 0) & 0xFFFFFFFF)
+#define C_030000_X 0x00000000
+#define R_030004_SQ_ALU_CONSTANT1_0 0x030004
+#define S_030004_Y(x) (((x) & 0xFFFFFFFF) << 0)
+#define G_030004_Y(x) (((x) >> 0) & 0xFFFFFFFF)
+#define C_030004_Y 0x00000000
+#define R_030008_SQ_ALU_CONSTANT2_0 0x030008
+#define S_030008_Z(x) (((x) & 0xFFFFFFFF) << 0)
+#define G_030008_Z(x) (((x) >> 0) & 0xFFFFFFFF)
+#define C_030008_Z 0x00000000
+#define R_03000C_SQ_ALU_CONSTANT3_0 0x03000C
+#define S_03000C_W(x) (((x) & 0xFFFFFFFF) << 0)
+#define G_03000C_W(x) (((x) >> 0) & 0xFFFFFFFF)
+#define C_03000C_W 0x00000000
+#define R_0287E4_VGT_DMA_BASE_HI 0x0287E4
+#define R_0287E8_VGT_DMA_BASE 0x0287E8
+
+#endif
diff --git a/src/gallium/winsys/r600/drm/radeon.c b/src/gallium/winsys/r600/drm/radeon.c
new file mode 100644
index 0000000000..f2113c5807
--- /dev/null
+++ b/src/gallium/winsys/r600/drm/radeon.c
@@ -0,0 +1,195 @@
+/*
+ * Copyright © 2009 Jerome Glisse <glisse@freedesktop.org>
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include "xf86drm.h"
+#include "radeon_priv.h"
+#include "radeon_drm.h"
+#include "r600d.h"
+
+static int radeon_get_device(struct radeon *radeon)
+{
+ struct drm_radeon_info info;
+ int r;
+
+ radeon->device = 0;
+ info.request = RADEON_INFO_DEVICE_ID;
+ info.value = (uintptr_t)&radeon->device;
+ r = drmCommandWriteRead(radeon->fd, DRM_RADEON_INFO, &info,
+ sizeof(struct drm_radeon_info));
+ return r;
+}
+
+/* symbol missing drove me crazy hack to get symbol exported */
+static void fake(void)
+{
+ struct radeon_ctx *ctx;
+ struct radeon_draw *draw;
+
+ ctx = radeon_ctx(NULL);
+ draw = radeon_draw(NULL);
+}
+
+struct radeon *radeon_new(int fd, unsigned device)
+{
+ struct radeon *radeon;
+ int r;
+
+ radeon = calloc(1, sizeof(*radeon));
+ if (radeon == NULL) {
+ fake();
+ return NULL;
+ }
+ radeon->fd = fd;
+ radeon->device = device;
+ radeon->refcount = 1;
+ if (fd >= 0) {
+ r = radeon_get_device(radeon);
+ if (r) {
+ fprintf(stderr, "Failed to get device id\n");
+ return radeon_decref(radeon);
+ }
+ }
+ radeon->family = radeon_family_from_device(radeon->device);
+ if (radeon->family == CHIP_UNKNOWN) {
+ fprintf(stderr, "Unknown chipset 0x%04X\n", radeon->device);
+ return radeon_decref(radeon);
+ }
+ switch (radeon->family) {
+ case CHIP_R600:
+ case CHIP_RV610:
+ case CHIP_RV630:
+ case CHIP_RV670:
+ case CHIP_RV620:
+ case CHIP_RV635:
+ case CHIP_RS780:
+ case CHIP_RS880:
+ case CHIP_RV770:
+ case CHIP_RV730:
+ case CHIP_RV710:
+ case CHIP_RV740:
+ if (r600_init(radeon)) {
+ return radeon_decref(radeon);
+ }
+ break;
+ case CHIP_R100:
+ case CHIP_RV100:
+ case CHIP_RS100:
+ case CHIP_RV200:
+ case CHIP_RS200:
+ case CHIP_R200:
+ case CHIP_RV250:
+ case CHIP_RS300:
+ case CHIP_RV280:
+ case CHIP_R300:
+ case CHIP_R350:
+ case CHIP_RV350:
+ case CHIP_RV380:
+ case CHIP_R420:
+ case CHIP_R423:
+ case CHIP_RV410:
+ case CHIP_RS400:
+ case CHIP_RS480:
+ case CHIP_RS600:
+ case CHIP_RS690:
+ case CHIP_RS740:
+ case CHIP_RV515:
+ case CHIP_R520:
+ case CHIP_RV530:
+ case CHIP_RV560:
+ case CHIP_RV570:
+ case CHIP_R580:
+ case CHIP_CEDAR:
+ case CHIP_REDWOOD:
+ case CHIP_JUNIPER:
+ case CHIP_CYPRESS:
+ case CHIP_HEMLOCK:
+ default:
+ fprintf(stderr, "%s unknown or unsupported chipset 0x%04X\n",
+ __func__, radeon->device);
+ break;
+ }
+ return radeon;
+}
+
+struct radeon *radeon_incref(struct radeon *radeon)
+{
+ if (radeon == NULL)
+ return NULL;
+ radeon->refcount++;
+ return radeon;
+}
+
+struct radeon *radeon_decref(struct radeon *radeon)
+{
+ if (radeon == NULL)
+ return NULL;
+ if (--radeon->refcount > 0) {
+ return NULL;
+ }
+ drmClose(radeon->fd);
+ free(radeon);
+ return NULL;
+}
+
+int radeon_reg_id(struct radeon *radeon, unsigned offset, unsigned *typeid, unsigned *stateid, unsigned *id)
+{
+ unsigned i, j;
+
+ for (i = 0; i < radeon->ntype; i++) {
+ if (radeon->type[i].range_start) {
+ if (offset >= radeon->type[i].range_start && offset < radeon->type[i].range_end) {
+ *typeid = i;
+ j = offset - radeon->type[i].range_start;
+ j /= radeon->type[i].stride;
+ *stateid = radeon->type[i].id + j;
+ *id = (offset - radeon->type[i].range_start - radeon->type[i].stride * j) / 4;
+ return 0;
+ }
+ } else {
+ for (j = 0; j < radeon->type[i].nstates; j++) {
+ if (radeon->type[i].regs[j].offset == offset) {
+ *typeid = i;
+ *stateid = radeon->type[i].id;
+ *id = j;
+ return 0;
+ }
+ }
+ }
+ }
+ fprintf(stderr, "%s unknown register 0x%08X\n", __func__, offset);
+ return -EINVAL;
+}
+
+unsigned radeon_type_from_id(struct radeon *radeon, unsigned id)
+{
+ unsigned i;
+
+ for (i = 0; i < radeon->ntype - 1; i++) {
+ if (radeon->type[i].id == id)
+ return i;
+ if (id > radeon->type[i].id && id < radeon->type[i + 1].id)
+ return i;
+ }
+ if (radeon->type[i].id == id)
+ return i;
+ return -1;
+}
diff --git a/src/gallium/winsys/r600/drm/radeon_bo.c b/src/gallium/winsys/r600/drm/radeon_bo.c
new file mode 100644
index 0000000000..f259ae7fb5
--- /dev/null
+++ b/src/gallium/winsys/r600/drm/radeon_bo.c
@@ -0,0 +1,170 @@
+/*
+ * Copyright 2010 Jerome Glisse <glisse@freedesktop.org>
+ *
+ * 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
+ * on the rights to use, copy, modify, merge, publish, distribute, sub
+ * license, and/or sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * Jerome Glisse
+ */
+#define _FILE_OFFSET_BITS 64
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/mman.h>
+#include <errno.h>
+#include "radeon_priv.h"
+#include "xf86drm.h"
+#include "radeon_drm.h"
+
+struct radeon_bo *radeon_bo(struct radeon *radeon, unsigned handle,
+ unsigned size, unsigned alignment, void *ptr)
+{
+ struct radeon_bo *bo;
+ int r;
+
+ bo = calloc(1, sizeof(*bo));
+ if (bo == NULL) {
+ return NULL;
+ }
+ bo->size = size;
+ bo->handle = handle;
+ bo->refcount = 1;
+ bo->alignment = alignment;
+
+ if (handle) {
+ struct drm_gem_open open_arg;
+
+ memset(&open_arg, 0, sizeof(open_arg));
+ open_arg.name = handle;
+ r = drmIoctl(radeon->fd, DRM_IOCTL_GEM_OPEN, &open_arg);
+ if (r != 0) {
+ free(bo);
+ return NULL;
+ }
+ bo->handle = open_arg.handle;
+ bo->size = open_arg.size;
+ } else {
+ struct drm_radeon_gem_create args;
+
+ args.size = size;
+ args.alignment = alignment;
+ args.initial_domain = RADEON_GEM_DOMAIN_CPU;
+ args.flags = 0;
+ args.handle = 0;
+ r = drmCommandWriteRead(radeon->fd, DRM_RADEON_GEM_CREATE,
+ &args, sizeof(args));
+ bo->handle = args.handle;
+ if (r) {
+ fprintf(stderr, "Failed to allocate :\n");
+ fprintf(stderr, " size : %d bytes\n", size);
+ fprintf(stderr, " alignment : %d bytes\n", alignment);
+ free(bo);
+ return NULL;
+ }
+ }
+ if (ptr) {
+ if (radeon_bo_map(radeon, bo)) {
+ fprintf(stderr, "%s failed to copy data into bo\n", __func__);
+ return radeon_bo_decref(radeon, bo);
+ }
+ memcpy(bo->data, ptr, size);
+ radeon_bo_unmap(radeon, bo);
+ }
+ return bo;
+}
+
+int radeon_bo_map(struct radeon *radeon, struct radeon_bo *bo)
+{
+ struct drm_radeon_gem_mmap args;
+ void *ptr;
+ int r;
+
+ if (bo->map_count++ != 0) {
+ return 0;
+ }
+ /* Zero out args to make valgrind happy */
+ memset(&args, 0, sizeof(args));
+ args.handle = bo->handle;
+ args.offset = 0;
+ args.size = (uint64_t)bo->size;
+ r = drmCommandWriteRead(radeon->fd, DRM_RADEON_GEM_MMAP,
+ &args, sizeof(args));
+ if (r) {
+ fprintf(stderr, "error mapping %p 0x%08X (error = %d)\n",
+ bo, bo->handle, r);
+ return r;
+ }
+ ptr = mmap(0, args.size, PROT_READ|PROT_WRITE, MAP_SHARED, radeon->fd, args.addr_ptr);
+ if (ptr == MAP_FAILED) {
+ fprintf(stderr, "%s failed to map bo\n", __func__);
+ return -errno;
+ }
+ bo->data = ptr;
+ return 0;
+}
+
+void radeon_bo_unmap(struct radeon *radeon, struct radeon_bo *bo)
+{
+ if (--bo->map_count > 0) {
+ return;
+ }
+ munmap(bo->data, bo->size);
+ bo->data = NULL;
+}
+
+struct radeon_bo *radeon_bo_incref(struct radeon *radeon, struct radeon_bo *bo)
+{
+ bo->refcount++;
+ return bo;
+}
+
+struct radeon_bo *radeon_bo_decref(struct radeon *radeon, struct radeon_bo *bo)
+{
+ struct drm_gem_close args;
+
+ if (bo == NULL)
+ return NULL;
+ if (--bo->refcount > 0) {
+ return NULL;
+ }
+
+ munmap(bo->data, bo->size);
+ memset(&args, 0, sizeof(args));
+ args.handle = bo->handle;
+ drmIoctl(radeon->fd, DRM_IOCTL_GEM_CLOSE, &args);
+ memset(bo, 0, sizeof(struct radeon_bo));
+ free(bo);
+ return NULL;
+}
+
+int radeon_bo_wait(struct radeon *radeon, struct radeon_bo *bo)
+{
+ struct drm_radeon_gem_wait_idle args;
+ int ret;
+
+ /* Zero out args to make valgrind happy */
+ memset(&args, 0, sizeof(args));
+ args.handle = bo->handle;
+ do {
+ ret = drmCommandWriteRead(radeon->fd, DRM_RADEON_GEM_WAIT_IDLE,
+ &args, sizeof(args));
+ } while (ret == -EBUSY);
+ return ret;
+}
diff --git a/src/gallium/winsys/r600/drm/radeon_ctx.c b/src/gallium/winsys/r600/drm/radeon_ctx.c
new file mode 100644
index 0000000000..6b0eba0b28
--- /dev/null
+++ b/src/gallium/winsys/r600/drm/radeon_ctx.c
@@ -0,0 +1,406 @@
+/*
+ * Copyright 2010 Jerome Glisse <glisse@freedesktop.org>
+ *
+ * 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
+ * on the rights to use, copy, modify, merge, publish, distribute, sub
+ * license, and/or sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * Jerome Glisse
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "radeon_priv.h"
+#include "radeon_drm.h"
+#include "bof.h"
+
+int radeon_ctx_set_bo_new(struct radeon_ctx *ctx, struct radeon_bo *bo)
+{
+ void *ptr;
+
+ ptr = realloc(ctx->bo, sizeof(struct radeon_bo) * (ctx->nbo + 1));
+ if (ptr == NULL) {
+ return -ENOMEM;
+ }
+ ctx->bo = ptr;
+ ctx->bo[ctx->nbo] = bo;
+ ctx->nbo++;
+ return 0;
+}
+
+struct radeon_bo *radeon_ctx_get_bo(struct radeon_ctx *ctx, unsigned reloc)
+{
+ struct radeon_cs_reloc *greloc;
+ unsigned i;
+
+ greloc = (void *)(((u8 *)ctx->reloc) + reloc * 4);
+ for (i = 0; i < ctx->nbo; i++) {
+ if (ctx->bo[i]->handle == greloc->handle) {
+ return radeon_bo_incref(ctx->radeon, ctx->bo[i]);
+ }
+ }
+ fprintf(stderr, "%s no bo for reloc[%d 0x%08X] %d\n", __func__, reloc, greloc->handle, ctx->nbo);
+ return NULL;
+}
+
+void radeon_ctx_get_placement(struct radeon_ctx *ctx, unsigned reloc, u32 *placement)
+{
+ struct radeon_cs_reloc *greloc;
+ unsigned i;
+
+ placement[0] = 0;
+ placement[1] = 0;
+ greloc = (void *)(((u8 *)ctx->reloc) + reloc * 4);
+ for (i = 0; i < ctx->nbo; i++) {
+ if (ctx->bo[i]->handle == greloc->handle) {
+ placement[0] = greloc->read_domain | greloc->write_domain;
+ placement[1] = placement[0];
+ return;
+ }
+ }
+}
+
+struct radeon_ctx *radeon_ctx(struct radeon *radeon)
+{
+ struct radeon_ctx *ctx;
+
+ if (radeon == NULL)
+ return NULL;
+ ctx = calloc(1, sizeof(*ctx));
+ if (ctx == NULL)
+ return NULL;
+ ctx->radeon = radeon_incref(radeon);
+ return ctx;
+}
+
+struct radeon_ctx *radeon_ctx_incref(struct radeon_ctx *ctx)
+{
+ ctx->refcount++;
+ return ctx;
+}
+
+struct radeon_ctx *radeon_ctx_decref(struct radeon_ctx *ctx)
+{
+ unsigned i;
+
+ if (ctx == NULL)
+ return NULL;
+ if (--ctx->refcount > 0) {
+ return NULL;
+ }
+
+ for (i = 0; i < ctx->ndraw; i++) {
+ ctx->draw[i] = radeon_draw_decref(ctx->draw[i]);
+ }
+ for (i = 0; i < ctx->nbo; i++) {
+ ctx->bo[i] = radeon_bo_decref(ctx->radeon, ctx->bo[i]);
+ }
+ ctx->radeon = radeon_decref(ctx->radeon);
+ free(ctx->draw);
+ free(ctx->bo);
+ free(ctx->pm4);
+ free(ctx->reloc);
+ memset(ctx, 0, sizeof(*ctx));
+ free(ctx);
+ return NULL;
+}
+
+static int radeon_ctx_state_bo(struct radeon_ctx *ctx, struct radeon_state *state)
+{
+ unsigned i, j;
+ int r;
+
+ if (state == NULL)
+ return 0;
+ for (i = 0; i < state->nbo; i++) {
+ for (j = 0; j < ctx->nbo; j++) {
+ if (state->bo[i] == ctx->bo[j])
+ break;
+ }
+ if (j == ctx->nbo) {
+ radeon_bo_incref(ctx->radeon, state->bo[i]);
+ r = radeon_ctx_set_bo_new(ctx, state->bo[i]);
+ if (r)
+ return r;
+ }
+ }
+ return 0;
+}
+
+
+int radeon_ctx_submit(struct radeon_ctx *ctx)
+{
+ struct drm_radeon_cs drmib;
+ struct drm_radeon_cs_chunk chunks[2];
+ uint64_t chunk_array[2];
+ int r = 0;
+
+#if 0
+ for (r = 0; r < ctx->cpm4; r++) {
+ fprintf(stderr, "0x%08X\n", ctx->pm4[r]);
+ }
+#endif
+ drmib.num_chunks = 2;
+ drmib.chunks = (uint64_t)(uintptr_t)chunk_array;
+ chunks[0].chunk_id = RADEON_CHUNK_ID_IB;
+ chunks[0].length_dw = ctx->cpm4;
+ chunks[0].chunk_data = (uint64_t)(uintptr_t)ctx->pm4;
+ chunks[1].chunk_id = RADEON_CHUNK_ID_RELOCS;
+ chunks[1].length_dw = ctx->nreloc * sizeof(struct radeon_cs_reloc) / 4;
+ chunks[1].chunk_data = (uint64_t)(uintptr_t)ctx->reloc;
+ chunk_array[0] = (uint64_t)(uintptr_t)&chunks[0];
+ chunk_array[1] = (uint64_t)(uintptr_t)&chunks[1];
+#if 1
+ r = drmCommandWriteRead(ctx->radeon->fd, DRM_RADEON_CS, &drmib,
+ sizeof(struct drm_radeon_cs));
+#endif
+ return r;
+}
+
+static int radeon_ctx_reloc(struct radeon_ctx *ctx, struct radeon_bo *bo,
+ unsigned id, unsigned *placement)
+{
+ unsigned i;
+ struct radeon_cs_reloc *ptr;
+
+ for (i = 0; i < ctx->nreloc; i++) {
+ if (ctx->reloc[i].handle == bo->handle) {
+ ctx->pm4[id] = i * sizeof(struct radeon_cs_reloc) / 4;
+ return 0;
+ }
+ }
+ ptr = realloc(ctx->reloc, sizeof(struct radeon_cs_reloc) * (ctx->nreloc + 1));
+ if (ptr == NULL)
+ return -ENOMEM;
+ ctx->reloc = ptr;
+ ptr[ctx->nreloc].handle = bo->handle;
+ ptr[ctx->nreloc].read_domain = placement[0] | placement [1];
+ ptr[ctx->nreloc].write_domain = placement[0] | placement [1];
+ ptr[ctx->nreloc].flags = 0;
+ ctx->pm4[id] = ctx->nreloc * sizeof(struct radeon_cs_reloc) / 4;
+ ctx->nreloc++;
+ return 0;
+}
+
+static int radeon_ctx_state_schedule(struct radeon_ctx *ctx, struct radeon_state *state)
+{
+ unsigned i, rid, bid, cid;
+ int r;
+
+ if (state == NULL)
+ return 0;
+ memcpy(&ctx->pm4[ctx->id], state->pm4, state->cpm4 * 4);
+ for (i = 0; i < state->nreloc; i++) {
+ rid = state->reloc_pm4_id[i];
+ bid = state->reloc_bo_id[i];
+ cid = ctx->id + rid;
+ r = radeon_ctx_reloc(ctx, state->bo[bid], cid,
+ &state->placement[bid * 2]);
+ if (r) {
+ fprintf(stderr, "%s state %d failed to reloc\n", __func__, state->type);
+ return r;
+ }
+ }
+ ctx->id += state->cpm4;
+ return 0;
+}
+
+int radeon_ctx_set_draw_new(struct radeon_ctx *ctx, struct radeon_draw *draw)
+{
+ struct radeon_draw *pdraw = NULL;
+ struct radeon_draw **ndraw;
+ struct radeon_state *nstate, *ostate;
+ unsigned cpm4, i, cstate;
+ void *tmp;
+ int r = 0;
+
+ ndraw = realloc(ctx->draw, sizeof(void*) * (ctx->ndraw + 1));
+ if (ndraw == NULL)
+ return -ENOMEM;
+ ctx->draw = ndraw;
+ for (i = 0; i < draw->nstate; i++) {
+ r = radeon_ctx_state_bo(ctx, draw->state[i]);
+ if (r)
+ return r;
+ }
+ r = radeon_draw_check(draw);
+ if (r)
+ return r;
+ if (draw->cpm4 >= RADEON_CTX_MAX_PM4) {
+ fprintf(stderr, "%s single draw too big %d, max %d\n",
+ __func__, draw->cpm4, RADEON_CTX_MAX_PM4);
+ return -EINVAL;
+ }
+ tmp = realloc(ctx->state, (ctx->nstate + draw->nstate) * sizeof(void*));
+ if (tmp == NULL)
+ return -ENOMEM;
+ ctx->state = tmp;
+ pdraw = ctx->cdraw;
+ for (i = 0, cpm4 = 0, cstate = ctx->nstate; i < draw->nstate - 1; i++) {
+ nstate = draw->state[i];
+ if (nstate) {
+ if (pdraw && pdraw->state[i]) {
+ ostate = pdraw->state[i];
+ if (ostate->pm4_crc != nstate->pm4_crc) {
+ ctx->state[cstate++] = nstate;
+ cpm4 += nstate->cpm4;
+ }
+ } else {
+ ctx->state[cstate++] = nstate;
+ cpm4 += nstate->cpm4;
+ }
+ }
+ }
+ /* The last state is the draw state always add it */
+ if (draw->state[i] == NULL) {
+ fprintf(stderr, "%s no draw command\n", __func__);
+ return -EINVAL;
+ }
+ ctx->state[cstate++] = draw->state[i];
+ cpm4 += draw->state[i]->cpm4;
+ if ((ctx->draw_cpm4 + cpm4) > RADEON_CTX_MAX_PM4) {
+ /* need to flush */
+ return -EBUSY;
+ }
+ ctx->draw_cpm4 += cpm4;
+ ctx->nstate = cstate;
+ ctx->draw[ctx->ndraw++] = draw;
+ ctx->cdraw = draw;
+ return 0;
+}
+
+int radeon_ctx_set_draw(struct radeon_ctx *ctx, struct radeon_draw *draw)
+{
+ int r;
+
+ radeon_draw_incref(draw);
+ r = radeon_ctx_set_draw_new(ctx, draw);
+ if (r)
+ radeon_draw_decref(draw);
+ return r;
+}
+
+int radeon_ctx_pm4(struct radeon_ctx *ctx)
+{
+ unsigned i;
+ int r;
+
+ free(ctx->pm4);
+ ctx->cpm4 = 0;
+ ctx->pm4 = malloc(ctx->draw_cpm4 * 4);
+ if (ctx->pm4 == NULL)
+ return -EINVAL;
+ for (i = 0, ctx->id = 0; i < ctx->nstate; i++) {
+ r = radeon_ctx_state_schedule(ctx, ctx->state[i]);
+ if (r)
+ return r;
+ }
+ if (ctx->id != ctx->draw_cpm4) {
+ fprintf(stderr, "%s miss predicted pm4 size %d for %d\n",
+ __func__, ctx->draw_cpm4, ctx->id);
+ return -EINVAL;
+ }
+ ctx->cpm4 = ctx->draw_cpm4;
+ return 0;
+}
+
+void radeon_ctx_dump_bof(struct radeon_ctx *ctx, const char *file)
+{
+ bof_t *bcs, *blob, *array, *bo, *size, *handle, *device_id, *root;
+ unsigned i;
+
+ root = device_id = bcs = blob = array = bo = size = handle = NULL;
+ root = bof_object();
+ if (root == NULL)
+ goto out_err;
+ device_id = bof_int32(ctx->radeon->device);
+ if (device_id == NULL)
+ return;
+ if (bof_object_set(root, "device_id", device_id))
+ goto out_err;
+ bof_decref(device_id);
+ device_id = NULL;
+ /* dump relocs */
+printf("%d relocs\n", ctx->nreloc);
+ blob = bof_blob(ctx->nreloc * 16, ctx->reloc);
+ if (blob == NULL)
+ goto out_err;
+ if (bof_object_set(root, "reloc", blob))
+ goto out_err;
+ bof_decref(blob);
+ blob = NULL;
+ /* dump cs */
+printf("%d pm4\n", ctx->cpm4);
+ blob = bof_blob(ctx->cpm4 * 4, ctx->pm4);
+ if (blob == NULL)
+ goto out_err;
+ if (bof_object_set(root, "pm4", blob))
+ goto out_err;
+ bof_decref(blob);
+ blob = NULL;
+ /* dump bo */
+ array = bof_array();
+ if (array == NULL)
+ goto out_err;
+ for (i = 0; i < ctx->nbo; i++) {
+ bo = bof_object();
+ if (bo == NULL)
+ goto out_err;
+ size = bof_int32(ctx->bo[i]->size);
+printf("[%d] %d bo\n", i, size);
+ if (size == NULL)
+ goto out_err;
+ if (bof_object_set(bo, "size", size))
+ goto out_err;
+ bof_decref(size);
+ size = NULL;
+ handle = bof_int32(ctx->bo[i]->handle);
+ if (handle == NULL)
+ goto out_err;
+ if (bof_object_set(bo, "handle", handle))
+ goto out_err;
+ bof_decref(handle);
+ handle = NULL;
+ radeon_bo_map(ctx->radeon, ctx->bo[i]);
+ blob = bof_blob(ctx->bo[i]->size, ctx->bo[i]->data);
+ radeon_bo_unmap(ctx->radeon, ctx->bo[i]);
+ if (blob == NULL)
+ goto out_err;
+ if (bof_object_set(bo, "data", blob))
+ goto out_err;
+ bof_decref(blob);
+ blob = NULL;
+ if (bof_array_append(array, bo))
+ goto out_err;
+ bof_decref(bo);
+ bo = NULL;
+ }
+ if (bof_object_set(root, "bo", array))
+ goto out_err;
+ bof_dump_file(root, file);
+printf("done dump\n");
+out_err:
+ bof_decref(blob);
+ bof_decref(array);
+ bof_decref(bo);
+ bof_decref(size);
+ bof_decref(handle);
+ bof_decref(device_id);
+ bof_decref(root);
+}
diff --git a/src/gallium/winsys/r600/drm/radeon_draw.c b/src/gallium/winsys/r600/drm/radeon_draw.c
new file mode 100644
index 0000000000..4413ed79fb
--- /dev/null
+++ b/src/gallium/winsys/r600/drm/radeon_draw.c
@@ -0,0 +1,141 @@
+/*
+ * Copyright 2010 Jerome Glisse <glisse@freedesktop.org>
+ *
+ * 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
+ * on the rights to use, copy, modify, merge, publish, distribute, sub
+ * license, and/or sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * Jerome Glisse
+ */
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include "radeon_priv.h"
+
+/*
+ * draw functions
+ */
+struct radeon_draw *radeon_draw(struct radeon *radeon)
+{
+ struct radeon_draw *draw;
+
+ draw = calloc(1, sizeof(*draw));
+ if (draw == NULL)
+ return NULL;
+ draw->nstate = radeon->nstate;
+ draw->radeon = radeon;
+ draw->refcount = 1;
+ draw->state = calloc(1, sizeof(void*) * draw->nstate);
+ if (draw->state == NULL) {
+ free(draw);
+ return NULL;
+ }
+ return draw;
+}
+
+struct radeon_draw *radeon_draw_incref(struct radeon_draw *draw)
+{
+ draw->refcount++;
+ return draw;
+}
+
+struct radeon_draw *radeon_draw_decref(struct radeon_draw *draw)
+{
+ unsigned i;
+
+ if (draw == NULL)
+ return NULL;
+ if (--draw->refcount > 0)
+ return NULL;
+ for (i = 0; i < draw->nstate; i++) {
+ draw->state[i] = radeon_state_decref(draw->state[i]);
+ }
+ free(draw->state);
+ memset(draw, 0, sizeof(*draw));
+ free(draw);
+ return NULL;
+}
+
+int radeon_draw_set_new(struct radeon_draw *draw, struct radeon_state *state)
+{
+ if (state == NULL)
+ return 0;
+ if (state->type >= draw->radeon->ntype)
+ return -EINVAL;
+ draw->state[state->id] = radeon_state_decref(draw->state[state->id]);
+ draw->state[state->id] = state;
+ return 0;
+}
+
+int radeon_draw_set(struct radeon_draw *draw, struct radeon_state *state)
+{
+ if (state == NULL)
+ return 0;
+ radeon_state_incref(state);
+ return radeon_draw_set_new(draw, state);
+}
+
+int radeon_draw_check(struct radeon_draw *draw)
+{
+ unsigned i;
+ int r;
+
+ r = radeon_draw_pm4(draw);
+ if (r)
+ return r;
+ for (i = 0, draw->cpm4 = 0; i < draw->nstate; i++) {
+ if (draw->state[i]) {
+ draw->cpm4 += draw->state[i]->cpm4;
+ }
+ }
+ return 0;
+}
+
+struct radeon_draw *radeon_draw_duplicate(struct radeon_draw *draw)
+{
+ struct radeon_draw *ndraw;
+ unsigned i;
+
+ if (draw == NULL)
+ return NULL;
+ ndraw = radeon_draw(draw->radeon);
+ if (ndraw == NULL) {
+ return NULL;
+ }
+ for (i = 0; i < draw->nstate; i++) {
+ if (radeon_draw_set(ndraw, draw->state[i])) {
+ radeon_draw_decref(ndraw);
+ return NULL;
+ }
+ }
+ return ndraw;
+}
+
+int radeon_draw_pm4(struct radeon_draw *draw)
+{
+ unsigned i;
+ int r;
+
+ for (i = 0; i < draw->nstate; i++) {
+ r = radeon_state_pm4(draw->state[i]);
+ if (r)
+ return r;
+ }
+ return 0;
+}
diff --git a/src/gallium/winsys/r600/drm/radeon_pciid.c b/src/gallium/winsys/r600/drm/radeon_pciid.c
new file mode 100644
index 0000000000..dd6156d585
--- /dev/null
+++ b/src/gallium/winsys/r600/drm/radeon_pciid.c
@@ -0,0 +1,528 @@
+/*
+ * Copyright 2010 Jerome Glisse <glisse@freedesktop.org>
+ *
+ * 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
+ * on the rights to use, copy, modify, merge, publish, distribute, sub
+ * license, and/or sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * Jerome Glisse
+ */
+#include <stdlib.h>
+#include "radeon_priv.h"
+
+struct pci_id {
+ unsigned vendor;
+ unsigned device;
+ unsigned family;
+};
+
+struct pci_id radeon_pci_id[] = {
+ {0x1002, 0x3150, CHIP_RV380},
+ {0x1002, 0x3152, CHIP_RV380},
+ {0x1002, 0x3154, CHIP_RV380},
+ {0x1002, 0x3E50, CHIP_RV380},
+ {0x1002, 0x3E54, CHIP_RV380},
+ {0x1002, 0x4136, CHIP_RS100},
+ {0x1002, 0x4137, CHIP_RS200},
+ {0x1002, 0x4144, CHIP_R300},
+ {0x1002, 0x4145, CHIP_R300},
+ {0x1002, 0x4146, CHIP_R300},
+ {0x1002, 0x4147, CHIP_R300},
+ {0x1002, 0x4148, CHIP_R350},
+ {0x1002, 0x4149, CHIP_R350},
+ {0x1002, 0x414A, CHIP_R350},
+ {0x1002, 0x414B, CHIP_R350},
+ {0x1002, 0x4150, CHIP_RV350},
+ {0x1002, 0x4151, CHIP_RV350},
+ {0x1002, 0x4152, CHIP_RV350},
+ {0x1002, 0x4153, CHIP_RV350},
+ {0x1002, 0x4154, CHIP_RV350},
+ {0x1002, 0x4155, CHIP_RV350},
+ {0x1002, 0x4156, CHIP_RV350},
+ {0x1002, 0x4237, CHIP_RS200},
+ {0x1002, 0x4242, CHIP_R200},
+ {0x1002, 0x4243, CHIP_R200},
+ {0x1002, 0x4336, CHIP_RS100},
+ {0x1002, 0x4337, CHIP_RS200},
+ {0x1002, 0x4437, CHIP_RS200},
+ {0x1002, 0x4966, CHIP_RV250},
+ {0x1002, 0x4967, CHIP_RV250},
+ {0x1002, 0x4A48, CHIP_R420},
+ {0x1002, 0x4A49, CHIP_R420},
+ {0x1002, 0x4A4A, CHIP_R420},
+ {0x1002, 0x4A4B, CHIP_R420},
+ {0x1002, 0x4A4C, CHIP_R420},
+ {0x1002, 0x4A4D, CHIP_R420},
+ {0x1002, 0x4A4E, CHIP_R420},
+ {0x1002, 0x4A4F, CHIP_R420},
+ {0x1002, 0x4A50, CHIP_R420},
+ {0x1002, 0x4A54, CHIP_R420},
+ {0x1002, 0x4B48, CHIP_R420},
+ {0x1002, 0x4B49, CHIP_R420},
+ {0x1002, 0x4B4A, CHIP_R420},
+ {0x1002, 0x4B4B, CHIP_R420},
+ {0x1002, 0x4B4C, CHIP_R420},
+ {0x1002, 0x4C57, CHIP_RV200},
+ {0x1002, 0x4C58, CHIP_RV200},
+ {0x1002, 0x4C59, CHIP_RV100},
+ {0x1002, 0x4C5A, CHIP_RV100},
+ {0x1002, 0x4C64, CHIP_RV250},
+ {0x1002, 0x4C66, CHIP_RV250},
+ {0x1002, 0x4C67, CHIP_RV250},
+ {0x1002, 0x4E44, CHIP_R300},
+ {0x1002, 0x4E45, CHIP_R300},
+ {0x1002, 0x4E46, CHIP_R300},
+ {0x1002, 0x4E47, CHIP_R300},
+ {0x1002, 0x4E48, CHIP_R350},
+ {0x1002, 0x4E49, CHIP_R350},
+ {0x1002, 0x4E4A, CHIP_R350},
+ {0x1002, 0x4E4B, CHIP_R350},
+ {0x1002, 0x4E50, CHIP_RV350},
+ {0x1002, 0x4E51, CHIP_RV350},
+ {0x1002, 0x4E52, CHIP_RV350},
+ {0x1002, 0x4E53, CHIP_RV350},
+ {0x1002, 0x4E54, CHIP_RV350},
+ {0x1002, 0x4E56, CHIP_RV350},
+ {0x1002, 0x5144, CHIP_R100},
+ {0x1002, 0x5145, CHIP_R100},
+ {0x1002, 0x5146, CHIP_R100},
+ {0x1002, 0x5147, CHIP_R100},
+ {0x1002, 0x5148, CHIP_R200},
+ {0x1002, 0x514C, CHIP_R200},
+ {0x1002, 0x514D, CHIP_R200},
+ {0x1002, 0x5157, CHIP_RV200},
+ {0x1002, 0x5158, CHIP_RV200},
+ {0x1002, 0x5159, CHIP_RV100},
+ {0x1002, 0x515A, CHIP_RV100},
+ {0x1002, 0x515E, CHIP_RV100},
+ {0x1002, 0x5460, CHIP_RV380},
+ {0x1002, 0x5462, CHIP_RV380},
+ {0x1002, 0x5464, CHIP_RV380},
+ {0x1002, 0x5657, CHIP_RV380},
+ {0x1002, 0x5548, CHIP_R423},
+ {0x1002, 0x5549, CHIP_R423},
+ {0x1002, 0x554A, CHIP_R423},
+ {0x1002, 0x554B, CHIP_R423},
+ {0x1002, 0x554C, CHIP_R423},
+ {0x1002, 0x554D, CHIP_R423},
+ {0x1002, 0x554E, CHIP_R423},
+ {0x1002, 0x554F, CHIP_R423},
+ {0x1002, 0x5550, CHIP_R423},
+ {0x1002, 0x5551, CHIP_R423},
+ {0x1002, 0x5552, CHIP_R423},
+ {0x1002, 0x5554, CHIP_R423},
+ {0x1002, 0x564A, CHIP_RV410},
+ {0x1002, 0x564B, CHIP_RV410},
+ {0x1002, 0x564F, CHIP_RV410},
+ {0x1002, 0x5652, CHIP_RV410},
+ {0x1002, 0x5653, CHIP_RV410},
+ {0x1002, 0x5834, CHIP_RS300},
+ {0x1002, 0x5835, CHIP_RS300},
+ {0x1002, 0x5954, CHIP_RS480},
+ {0x1002, 0x5955, CHIP_RS480},
+ {0x1002, 0x5974, CHIP_RS480},
+ {0x1002, 0x5975, CHIP_RS480},
+ {0x1002, 0x5960, CHIP_RV280},
+ {0x1002, 0x5961, CHIP_RV280},
+ {0x1002, 0x5962, CHIP_RV280},
+ {0x1002, 0x5964, CHIP_RV280},
+ {0x1002, 0x5965, CHIP_RV280},
+ {0x1002, 0x5969, CHIP_RV100},
+ {0x1002, 0x5a41, CHIP_RS400},
+ {0x1002, 0x5a42, CHIP_RS400},
+ {0x1002, 0x5a61, CHIP_RS400},
+ {0x1002, 0x5a62, CHIP_RS400},
+ {0x1002, 0x5b60, CHIP_RV380},
+ {0x1002, 0x5b62, CHIP_RV380},
+ {0x1002, 0x5b63, CHIP_RV380},
+ {0x1002, 0x5b64, CHIP_RV380},
+ {0x1002, 0x5b65, CHIP_RV380},
+ {0x1002, 0x5c61, CHIP_RV280},
+ {0x1002, 0x5c63, CHIP_RV280},
+ {0x1002, 0x5d48, CHIP_R423},
+ {0x1002, 0x5d49, CHIP_R423},
+ {0x1002, 0x5d4a, CHIP_R423},
+ {0x1002, 0x5d4c, CHIP_R423},
+ {0x1002, 0x5d4d, CHIP_R423},
+ {0x1002, 0x5d4e, CHIP_R423},
+ {0x1002, 0x5d4f, CHIP_R423},
+ {0x1002, 0x5d50, CHIP_R423},
+ {0x1002, 0x5d52, CHIP_R423},
+ {0x1002, 0x5d57, CHIP_R423},
+ {0x1002, 0x5e48, CHIP_RV410},
+ {0x1002, 0x5e4a, CHIP_RV410},
+ {0x1002, 0x5e4b, CHIP_RV410},
+ {0x1002, 0x5e4c, CHIP_RV410},
+ {0x1002, 0x5e4d, CHIP_RV410},
+ {0x1002, 0x5e4f, CHIP_RV410},
+ {0x1002, 0x6880, CHIP_CYPRESS},
+ {0x1002, 0x6888, CHIP_CYPRESS},
+ {0x1002, 0x6889, CHIP_CYPRESS},
+ {0x1002, 0x688A, CHIP_CYPRESS},
+ {0x1002, 0x6898, CHIP_CYPRESS},
+ {0x1002, 0x6899, CHIP_CYPRESS},
+ {0x1002, 0x689c, CHIP_HEMLOCK},
+ {0x1002, 0x689d, CHIP_HEMLOCK},
+ {0x1002, 0x689e, CHIP_CYPRESS},
+ {0x1002, 0x68a0, CHIP_JUNIPER},
+ {0x1002, 0x68a1, CHIP_JUNIPER},
+ {0x1002, 0x68a8, CHIP_JUNIPER},
+ {0x1002, 0x68a9, CHIP_JUNIPER},
+ {0x1002, 0x68b0, CHIP_JUNIPER},
+ {0x1002, 0x68b8, CHIP_JUNIPER},
+ {0x1002, 0x68b9, CHIP_JUNIPER},
+ {0x1002, 0x68be, CHIP_JUNIPER},
+ {0x1002, 0x68c0, CHIP_REDWOOD},
+ {0x1002, 0x68c1, CHIP_REDWOOD},
+ {0x1002, 0x68c8, CHIP_REDWOOD},
+ {0x1002, 0x68c9, CHIP_REDWOOD},
+ {0x1002, 0x68d8, CHIP_REDWOOD},
+ {0x1002, 0x68d9, CHIP_REDWOOD},
+ {0x1002, 0x68da, CHIP_REDWOOD},
+ {0x1002, 0x68de, CHIP_REDWOOD},
+ {0x1002, 0x68e0, CHIP_CEDAR},
+ {0x1002, 0x68e1, CHIP_CEDAR},
+ {0x1002, 0x68e4, CHIP_CEDAR},
+ {0x1002, 0x68e5, CHIP_CEDAR},
+ {0x1002, 0x68e8, CHIP_CEDAR},
+ {0x1002, 0x68e9, CHIP_CEDAR},
+ {0x1002, 0x68f1, CHIP_CEDAR},
+ {0x1002, 0x68f8, CHIP_CEDAR},
+ {0x1002, 0x68f9, CHIP_CEDAR},
+ {0x1002, 0x68fe, CHIP_CEDAR},
+ {0x1002, 0x7100, CHIP_R520},
+ {0x1002, 0x7101, CHIP_R520},
+ {0x1002, 0x7102, CHIP_R520},
+ {0x1002, 0x7103, CHIP_R520},
+ {0x1002, 0x7104, CHIP_R520},
+ {0x1002, 0x7105, CHIP_R520},
+ {0x1002, 0x7106, CHIP_R520},
+ {0x1002, 0x7108, CHIP_R520},
+ {0x1002, 0x7109, CHIP_R520},
+ {0x1002, 0x710A, CHIP_R520},
+ {0x1002, 0x710B, CHIP_R520},
+ {0x1002, 0x710C, CHIP_R520},
+ {0x1002, 0x710E, CHIP_R520},
+ {0x1002, 0x710F, CHIP_R520},
+ {0x1002, 0x7140, CHIP_RV515},
+ {0x1002, 0x7141, CHIP_RV515},
+ {0x1002, 0x7142, CHIP_RV515},
+ {0x1002, 0x7143, CHIP_RV515},
+ {0x1002, 0x7144, CHIP_RV515},
+ {0x1002, 0x7145, CHIP_RV515},
+ {0x1002, 0x7146, CHIP_RV515},
+ {0x1002, 0x7147, CHIP_RV515},
+ {0x1002, 0x7149, CHIP_RV515},
+ {0x1002, 0x714A, CHIP_RV515},
+ {0x1002, 0x714B, CHIP_RV515},
+ {0x1002, 0x714C, CHIP_RV515},
+ {0x1002, 0x714D, CHIP_RV515},
+ {0x1002, 0x714E, CHIP_RV515},
+ {0x1002, 0x714F, CHIP_RV515},
+ {0x1002, 0x7151, CHIP_RV515},
+ {0x1002, 0x7152, CHIP_RV515},
+ {0x1002, 0x7153, CHIP_RV515},
+ {0x1002, 0x715E, CHIP_RV515},
+ {0x1002, 0x715F, CHIP_RV515},
+ {0x1002, 0x7180, CHIP_RV515},
+ {0x1002, 0x7181, CHIP_RV515},
+ {0x1002, 0x7183, CHIP_RV515},
+ {0x1002, 0x7186, CHIP_RV515},
+ {0x1002, 0x7187, CHIP_RV515},
+ {0x1002, 0x7188, CHIP_RV515},
+ {0x1002, 0x718A, CHIP_RV515},
+ {0x1002, 0x718B, CHIP_RV515},
+ {0x1002, 0x718C, CHIP_RV515},
+ {0x1002, 0x718D, CHIP_RV515},
+ {0x1002, 0x718F, CHIP_RV515},
+ {0x1002, 0x7193, CHIP_RV515},
+ {0x1002, 0x7196, CHIP_RV515},
+ {0x1002, 0x719B, CHIP_RV515},
+ {0x1002, 0x719F, CHIP_RV515},
+ {0x1002, 0x71C0, CHIP_RV530},
+ {0x1002, 0x71C1, CHIP_RV530},
+ {0x1002, 0x71C2, CHIP_RV530},
+ {0x1002, 0x71C3, CHIP_RV530},
+ {0x1002, 0x71C4, CHIP_RV530},
+ {0x1002, 0x71C5, CHIP_RV530},
+ {0x1002, 0x71C6, CHIP_RV530},
+ {0x1002, 0x71C7, CHIP_RV530},
+ {0x1002, 0x71CD, CHIP_RV530},
+ {0x1002, 0x71CE, CHIP_RV530},
+ {0x1002, 0x71D2, CHIP_RV530},
+ {0x1002, 0x71D4, CHIP_RV530},
+ {0x1002, 0x71D5, CHIP_RV530},
+ {0x1002, 0x71D6, CHIP_RV530},
+ {0x1002, 0x71DA, CHIP_RV530},
+ {0x1002, 0x71DE, CHIP_RV530},
+ {0x1002, 0x7200, CHIP_RV515},
+ {0x1002, 0x7210, CHIP_RV515},
+ {0x1002, 0x7211, CHIP_RV515},
+ {0x1002, 0x7240, CHIP_R580},
+ {0x1002, 0x7243, CHIP_R580},
+ {0x1002, 0x7244, CHIP_R580},
+ {0x1002, 0x7245, CHIP_R580},
+ {0x1002, 0x7246, CHIP_R580},
+ {0x1002, 0x7247, CHIP_R580},
+ {0x1002, 0x7248, CHIP_R580},
+ {0x1002, 0x7249, CHIP_R580},
+ {0x1002, 0x724A, CHIP_R580},
+ {0x1002, 0x724B, CHIP_R580},
+ {0x1002, 0x724C, CHIP_R580},
+ {0x1002, 0x724D, CHIP_R580},
+ {0x1002, 0x724E, CHIP_R580},
+ {0x1002, 0x724F, CHIP_R580},
+ {0x1002, 0x7280, CHIP_RV570},
+ {0x1002, 0x7281, CHIP_RV560},
+ {0x1002, 0x7283, CHIP_RV560},
+ {0x1002, 0x7284, CHIP_R580},
+ {0x1002, 0x7287, CHIP_RV560},
+ {0x1002, 0x7288, CHIP_RV570},
+ {0x1002, 0x7289, CHIP_RV570},
+ {0x1002, 0x728B, CHIP_RV570},
+ {0x1002, 0x728C, CHIP_RV570},
+ {0x1002, 0x7290, CHIP_RV560},
+ {0x1002, 0x7291, CHIP_RV560},
+ {0x1002, 0x7293, CHIP_RV560},
+ {0x1002, 0x7297, CHIP_RV560},
+ {0x1002, 0x7834, CHIP_RS300},
+ {0x1002, 0x7835, CHIP_RS300},
+ {0x1002, 0x791e, CHIP_RS690},
+ {0x1002, 0x791f, CHIP_RS690},
+ {0x1002, 0x793f, CHIP_RS600},
+ {0x1002, 0x7941, CHIP_RS600},
+ {0x1002, 0x7942, CHIP_RS600},
+ {0x1002, 0x796c, CHIP_RS740},
+ {0x1002, 0x796d, CHIP_RS740},
+ {0x1002, 0x796e, CHIP_RS740},
+ {0x1002, 0x796f, CHIP_RS740},
+ {0x1002, 0x9400, CHIP_R600},
+ {0x1002, 0x9401, CHIP_R600},
+ {0x1002, 0x9402, CHIP_R600},
+ {0x1002, 0x9403, CHIP_R600},
+ {0x1002, 0x9405, CHIP_R600},
+ {0x1002, 0x940A, CHIP_R600},
+ {0x1002, 0x940B, CHIP_R600},
+ {0x1002, 0x940F, CHIP_R600},
+ {0x1002, 0x94A0, CHIP_RV740},
+ {0x1002, 0x94A1, CHIP_RV740},
+ {0x1002, 0x94A3, CHIP_RV740},
+ {0x1002, 0x94B1, CHIP_RV740},
+ {0x1002, 0x94B3, CHIP_RV740},
+ {0x1002, 0x94B4, CHIP_RV740},
+ {0x1002, 0x94B5, CHIP_RV740},
+ {0x1002, 0x94B9, CHIP_RV740},
+ {0x1002, 0x9440, CHIP_RV770},
+ {0x1002, 0x9441, CHIP_RV770},
+ {0x1002, 0x9442, CHIP_RV770},
+ {0x1002, 0x9443, CHIP_RV770},
+ {0x1002, 0x9444, CHIP_RV770},
+ {0x1002, 0x9446, CHIP_RV770},
+ {0x1002, 0x944A, CHIP_RV770},
+ {0x1002, 0x944B, CHIP_RV770},
+ {0x1002, 0x944C, CHIP_RV770},
+ {0x1002, 0x944E, CHIP_RV770},
+ {0x1002, 0x9450, CHIP_RV770},
+ {0x1002, 0x9452, CHIP_RV770},
+ {0x1002, 0x9456, CHIP_RV770},
+ {0x1002, 0x945A, CHIP_RV770},
+ {0x1002, 0x945B, CHIP_RV770},
+ {0x1002, 0x9460, CHIP_RV770},
+ {0x1002, 0x9462, CHIP_RV770},
+ {0x1002, 0x946A, CHIP_RV770},
+ {0x1002, 0x946B, CHIP_RV770},
+ {0x1002, 0x947A, CHIP_RV770},
+ {0x1002, 0x947B, CHIP_RV770},
+ {0x1002, 0x9480, CHIP_RV730},
+ {0x1002, 0x9487, CHIP_RV730},
+ {0x1002, 0x9488, CHIP_RV730},
+ {0x1002, 0x9489, CHIP_RV730},
+ {0x1002, 0x948F, CHIP_RV730},
+ {0x1002, 0x9490, CHIP_RV730},
+ {0x1002, 0x9491, CHIP_RV730},
+ {0x1002, 0x9495, CHIP_RV730},
+ {0x1002, 0x9498, CHIP_RV730},
+ {0x1002, 0x949C, CHIP_RV730},
+ {0x1002, 0x949E, CHIP_RV730},
+ {0x1002, 0x949F, CHIP_RV730},
+ {0x1002, 0x94C0, CHIP_RV610},
+ {0x1002, 0x94C1, CHIP_RV610},
+ {0x1002, 0x94C3, CHIP_RV610},
+ {0x1002, 0x94C4, CHIP_RV610},
+ {0x1002, 0x94C5, CHIP_RV610},
+ {0x1002, 0x94C6, CHIP_RV610},
+ {0x1002, 0x94C7, CHIP_RV610},
+ {0x1002, 0x94C8, CHIP_RV610},
+ {0x1002, 0x94C9, CHIP_RV610},
+ {0x1002, 0x94CB, CHIP_RV610},
+ {0x1002, 0x94CC, CHIP_RV610},
+ {0x1002, 0x94CD, CHIP_RV610},
+ {0x1002, 0x9500, CHIP_RV670},
+ {0x1002, 0x9501, CHIP_RV670},
+ {0x1002, 0x9504, CHIP_RV670},
+ {0x1002, 0x9505, CHIP_RV670},
+ {0x1002, 0x9506, CHIP_RV670},
+ {0x1002, 0x9507, CHIP_RV670},
+ {0x1002, 0x9508, CHIP_RV670},
+ {0x1002, 0x9509, CHIP_RV670},
+ {0x1002, 0x950F, CHIP_RV670},
+ {0x1002, 0x9511, CHIP_RV670},
+ {0x1002, 0x9515, CHIP_RV670},
+ {0x1002, 0x9517, CHIP_RV670},
+ {0x1002, 0x9519, CHIP_RV670},
+ {0x1002, 0x9540, CHIP_RV710},
+ {0x1002, 0x9541, CHIP_RV710},
+ {0x1002, 0x9542, CHIP_RV710},
+ {0x1002, 0x954E, CHIP_RV710},
+ {0x1002, 0x954F, CHIP_RV710},
+ {0x1002, 0x9552, CHIP_RV710},
+ {0x1002, 0x9553, CHIP_RV710},
+ {0x1002, 0x9555, CHIP_RV710},
+ {0x1002, 0x9557, CHIP_RV710},
+ {0x1002, 0x9580, CHIP_RV630},
+ {0x1002, 0x9581, CHIP_RV630},
+ {0x1002, 0x9583, CHIP_RV630},
+ {0x1002, 0x9586, CHIP_RV630},
+ {0x1002, 0x9587, CHIP_RV630},
+ {0x1002, 0x9588, CHIP_RV630},
+ {0x1002, 0x9589, CHIP_RV630},
+ {0x1002, 0x958A, CHIP_RV630},
+ {0x1002, 0x958B, CHIP_RV630},
+ {0x1002, 0x958C, CHIP_RV630},
+ {0x1002, 0x958D, CHIP_RV630},
+ {0x1002, 0x958E, CHIP_RV630},
+ {0x1002, 0x958F, CHIP_RV630},
+ {0x1002, 0x9590, CHIP_RV635},
+ {0x1002, 0x9591, CHIP_RV635},
+ {0x1002, 0x9593, CHIP_RV635},
+ {0x1002, 0x9595, CHIP_RV635},
+ {0x1002, 0x9596, CHIP_RV635},
+ {0x1002, 0x9597, CHIP_RV635},
+ {0x1002, 0x9598, CHIP_RV635},
+ {0x1002, 0x9599, CHIP_RV635},
+ {0x1002, 0x959B, CHIP_RV635},
+ {0x1002, 0x95C0, CHIP_RV620},
+ {0x1002, 0x95C2, CHIP_RV620},
+ {0x1002, 0x95C4, CHIP_RV620},
+ {0x1002, 0x95C5, CHIP_RV620},
+ {0x1002, 0x95C6, CHIP_RV620},
+ {0x1002, 0x95C7, CHIP_RV620},
+ {0x1002, 0x95C9, CHIP_RV620},
+ {0x1002, 0x95CC, CHIP_RV620},
+ {0x1002, 0x95CD, CHIP_RV620},
+ {0x1002, 0x95CE, CHIP_RV620},
+ {0x1002, 0x95CF, CHIP_RV620},
+ {0x1002, 0x9610, CHIP_RS780},
+ {0x1002, 0x9611, CHIP_RS780},
+ {0x1002, 0x9612, CHIP_RS780},
+ {0x1002, 0x9613, CHIP_RS780},
+ {0x1002, 0x9614, CHIP_RS780},
+ {0x1002, 0x9615, CHIP_RS780},
+ {0x1002, 0x9616, CHIP_RS780},
+ {0x1002, 0x9710, CHIP_RS880},
+ {0x1002, 0x9711, CHIP_RS880},
+ {0x1002, 0x9712, CHIP_RS880},
+ {0x1002, 0x9713, CHIP_RS880},
+ {0x1002, 0x9714, CHIP_RS880},
+ {0x1002, 0x9715, CHIP_RS880},
+ {0, 0},
+};
+
+unsigned radeon_family_from_device(unsigned device)
+{
+ unsigned i;
+
+ for (i = 0; ; i++) {
+ if (!radeon_pci_id[i].vendor)
+ return CHIP_UNKNOWN;
+ if (radeon_pci_id[i].device == device)
+ return radeon_pci_id[i].family;
+ }
+ return CHIP_UNKNOWN;
+}
+
+int radeon_is_family_compatible(unsigned family1, unsigned family2)
+{
+ switch (family1) {
+ case CHIP_R600:
+ case CHIP_RV610:
+ case CHIP_RV630:
+ case CHIP_RV670:
+ case CHIP_RV620:
+ case CHIP_RV635:
+ case CHIP_RS780:
+ case CHIP_RS880:
+ case CHIP_RV770:
+ case CHIP_RV730:
+ case CHIP_RV710:
+ case CHIP_RV740:
+ switch (family2) {
+ case CHIP_R600:
+ case CHIP_RV610:
+ case CHIP_RV630:
+ case CHIP_RV670:
+ case CHIP_RV620:
+ case CHIP_RV635:
+ case CHIP_RS780:
+ case CHIP_RS880:
+ case CHIP_RV770:
+ case CHIP_RV730:
+ case CHIP_RV710:
+ case CHIP_RV740:
+ return 1;
+ default:
+ return 0;
+ }
+ break;
+ case CHIP_R100:
+ case CHIP_RV100:
+ case CHIP_RS100:
+ case CHIP_RV200:
+ case CHIP_RS200:
+ case CHIP_R200:
+ case CHIP_RV250:
+ case CHIP_RS300:
+ case CHIP_RV280:
+ case CHIP_R300:
+ case CHIP_R350:
+ case CHIP_RV350:
+ case CHIP_RV380:
+ case CHIP_R420:
+ case CHIP_R423:
+ case CHIP_RV410:
+ case CHIP_RS400:
+ case CHIP_RS480:
+ case CHIP_RS600:
+ case CHIP_RS690:
+ case CHIP_RS740:
+ case CHIP_RV515:
+ case CHIP_R520:
+ case CHIP_RV530:
+ case CHIP_RV560:
+ case CHIP_RV570:
+ case CHIP_R580:
+ case CHIP_CEDAR:
+ case CHIP_REDWOOD:
+ case CHIP_JUNIPER:
+ case CHIP_CYPRESS:
+ case CHIP_HEMLOCK:
+ default:
+ return 0;
+ }
+}
diff --git a/src/gallium/winsys/r600/drm/radeon_priv.h b/src/gallium/winsys/r600/drm/radeon_priv.h
new file mode 100644
index 0000000000..b91421f438
--- /dev/null
+++ b/src/gallium/winsys/r600/drm/radeon_priv.h
@@ -0,0 +1,130 @@
+/*
+ * Copyright © 2009 Jerome Glisse <glisse@freedesktop.org>
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+#ifndef RADEON_PRIV_H
+#define RADEON_PRIV_H
+
+#include <stdint.h>
+#include "xf86drm.h"
+#include "xf86drmMode.h"
+#include <errno.h>
+#include "radeon.h"
+
+struct radeon;
+struct radeon_ctx;
+
+/*
+ * radeon functions
+ */
+typedef int (*radeon_state_pm4_t)(struct radeon_state *state);
+struct radeon_register {
+ unsigned offset;
+ unsigned need_reloc;
+ unsigned bo_id;
+ char name[64];
+};
+
+struct radeon_type {
+ unsigned npm4;
+ unsigned id;
+ unsigned range_start;
+ unsigned range_end;
+ unsigned stride;
+ unsigned immediate;
+ char name[64];
+ unsigned nstates;
+ radeon_state_pm4_t pm4;
+ const struct radeon_register *regs;
+};
+
+struct radeon {
+ int fd;
+ int refcount;
+ unsigned device;
+ unsigned family;
+ unsigned nstate;
+ unsigned ntype;
+ const struct radeon_type *type;
+};
+
+extern struct radeon *radeon_new(int fd, unsigned device);
+extern struct radeon *radeon_incref(struct radeon *radeon);
+extern struct radeon *radeon_decref(struct radeon *radeon);
+extern unsigned radeon_family_from_device(unsigned device);
+extern int radeon_is_family_compatible(unsigned family1, unsigned family2);
+extern int radeon_reg_id(struct radeon *radeon, unsigned offset, unsigned *typeid, unsigned *stateid, unsigned *id);
+extern unsigned radeon_type_from_id(struct radeon *radeon, unsigned id);
+
+/*
+ * radeon context functions
+ */
+#pragma pack(1)
+struct radeon_cs_reloc {
+ uint32_t handle;
+ uint32_t read_domain;
+ uint32_t write_domain;
+ uint32_t flags;
+};
+#pragma pack()
+
+struct radeon_ctx {
+ int refcount;
+ struct radeon *radeon;
+ u32 *pm4;
+ u32 cpm4;
+ u32 draw_cpm4;
+ unsigned id;
+ unsigned next_id;
+ unsigned nreloc;
+ struct radeon_cs_reloc *reloc;
+ unsigned nbo;
+ struct radeon_bo **bo;
+ unsigned ndraw;
+ struct radeon_draw *cdraw;
+ struct radeon_draw **draw;
+ unsigned nstate;
+ struct radeon_state **state;
+};
+
+int radeon_ctx_set_bo_new(struct radeon_ctx *ctx, struct radeon_bo *bo);
+struct radeon_bo *radeon_ctx_get_bo(struct radeon_ctx *ctx, unsigned reloc);
+void radeon_ctx_get_placement(struct radeon_ctx *ctx, unsigned reloc, u32 *placement);
+int radeon_ctx_set_draw_new(struct radeon_ctx *ctx, struct radeon_draw *draw);
+int radeon_ctx_draw(struct radeon_ctx *ctx);
+
+/*
+ * r600/r700 context functions
+ */
+extern int r600_init(struct radeon *radeon);
+extern int r600_ctx_draw(struct radeon_ctx *ctx);
+extern int r600_ctx_next_reloc(struct radeon_ctx *ctx, unsigned *reloc);
+
+/*
+ * radeon state functions
+ */
+extern u32 radeon_state_register_get(struct radeon_state *state, unsigned offset);
+extern int radeon_state_register_set(struct radeon_state *state, unsigned offset, u32 value);
+extern struct radeon_state *radeon_state_duplicate(struct radeon_state *state);
+extern int radeon_state_replace_always(struct radeon_state *ostate, struct radeon_state *nstate);
+extern int radeon_state_pm4_generic(struct radeon_state *state);
+extern int radeon_state_reloc(struct radeon_state *state, unsigned id, unsigned bo_id);
+
+/*
+ * radeon draw functions
+ */
+extern int radeon_draw_pm4(struct radeon_draw *draw);
+
+#endif
diff --git a/src/gallium/winsys/r600/drm/radeon_state.c b/src/gallium/winsys/r600/drm/radeon_state.c
new file mode 100644
index 0000000000..308288557a
--- /dev/null
+++ b/src/gallium/winsys/r600/drm/radeon_state.c
@@ -0,0 +1,168 @@
+/*
+ * Copyright 2010 Jerome Glisse <glisse@freedesktop.org>
+ *
+ * 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
+ * on the rights to use, copy, modify, merge, publish, distribute, sub
+ * license, and/or sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * Jerome Glisse
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include "radeon_priv.h"
+
+/*
+ * state core functions
+ */
+struct radeon_state *radeon_state(struct radeon *radeon, u32 type, u32 id)
+{
+ struct radeon_state *state;
+
+ if (type > radeon->ntype) {
+ fprintf(stderr, "%s invalid type %d\n", __func__, type);
+ return NULL;
+ }
+ if (id > radeon->nstate) {
+ fprintf(stderr, "%s invalid state id %d\n", __func__, id);
+ return NULL;
+ }
+ state = calloc(1, sizeof(*state));
+ if (state == NULL)
+ return NULL;
+ state->radeon = radeon;
+ state->type = type;
+ state->id = id;
+ state->refcount = 1;
+ state->npm4 = radeon->type[type].npm4;
+ state->nstates = radeon->type[type].nstates;
+ state->states = calloc(1, state->nstates * 4);
+ state->pm4 = calloc(1, radeon->type[type].npm4 * 4);
+ if (state->states == NULL || state->pm4 == NULL) {
+ radeon_state_decref(state);
+ return NULL;
+ }
+ return state;
+}
+
+struct radeon_state *radeon_state_duplicate(struct radeon_state *state)
+{
+ struct radeon_state *nstate = radeon_state(state->radeon, state->type, state->id);
+ unsigned i;
+
+ if (state == NULL)
+ return NULL;
+ nstate->cpm4 = state->cpm4;
+ nstate->nbo = state->nbo;
+ nstate->nreloc = state->nreloc;
+ memcpy(nstate->states, state->states, state->nstates * 4);
+ memcpy(nstate->pm4, state->pm4, state->npm4 * 4);
+ memcpy(nstate->placement, state->placement, 8 * 4);
+ memcpy(nstate->reloc_pm4_id, state->reloc_pm4_id, 8 * 4);
+ memcpy(nstate->reloc_bo_id, state->reloc_bo_id, 8 * 4);
+ memcpy(nstate->bo_dirty, state->bo_dirty, 4 * 4);
+ for (i = 0; i < state->nbo; i++) {
+ nstate->bo[i] = radeon_bo_incref(state->radeon, state->bo[i]);
+ }
+ return nstate;
+}
+
+struct radeon_state *radeon_state_incref(struct radeon_state *state)
+{
+ state->refcount++;
+ return state;
+}
+
+struct radeon_state *radeon_state_decref(struct radeon_state *state)
+{
+ unsigned i;
+
+ if (state == NULL)
+ return NULL;
+ if (--state->refcount > 0) {
+ return NULL;
+ }
+ for (i = 0; i < state->nbo; i++) {
+ state->bo[i] = radeon_bo_decref(state->radeon, state->bo[i]);
+ }
+ free(state->immd);
+ free(state->states);
+ free(state->pm4);
+ memset(state, 0, sizeof(*state));
+ free(state);
+ return NULL;
+}
+
+int radeon_state_replace_always(struct radeon_state *ostate,
+ struct radeon_state *nstate)
+{
+ return 1;
+}
+
+int radeon_state_pm4_generic(struct radeon_state *state)
+{
+ return -EINVAL;
+}
+
+static u32 crc32(void *d, size_t len)
+{
+ u16 *data = (uint16_t*)d;
+ u32 sum1 = 0xffff, sum2 = 0xffff;
+
+ len = len >> 1;
+ while (len) {
+ unsigned tlen = len > 360 ? 360 : len;
+ len -= tlen;
+ do {
+ sum1 += *data++;
+ sum2 += sum1;
+ } while (--tlen);
+ sum1 = (sum1 & 0xffff) + (sum1 >> 16);
+ sum2 = (sum2 & 0xffff) + (sum2 >> 16);
+ }
+ /* Second reduction step to reduce sums to 16 bits */
+ sum1 = (sum1 & 0xffff) + (sum1 >> 16);
+ sum2 = (sum2 & 0xffff) + (sum2 >> 16);
+ return sum2 << 16 | sum1;
+}
+
+int radeon_state_pm4(struct radeon_state *state)
+{
+ int r;
+
+ if (state == NULL || state->cpm4)
+ return 0;
+ r = state->radeon->type[state->type].pm4(state);
+ if (r) {
+ fprintf(stderr, "%s failed to build PM4 for state(%d %d)\n",
+ __func__, state->type, state->id);
+ return r;
+ }
+ state->pm4_crc = crc32(state->pm4, state->cpm4 * 4);
+ return 0;
+}
+
+int radeon_state_reloc(struct radeon_state *state, unsigned id, unsigned bo_id)
+{
+ state->reloc_pm4_id[state->nreloc] = id;
+ state->reloc_bo_id[state->nreloc] = bo_id;
+ state->nreloc++;
+ return 0;
+}
diff --git a/src/gallium/winsys/radeon/drm/Makefile b/src/gallium/winsys/radeon/drm/Makefile
new file mode 100644
index 0000000000..7f69e39273
--- /dev/null
+++ b/src/gallium/winsys/radeon/drm/Makefile
@@ -0,0 +1,17 @@
+
+TOP = ../../../../..
+include $(TOP)/configs/current
+
+LIBNAME = radeonwinsys
+
+C_SOURCES = \
+ radeon_drm_buffer.c \
+ radeon_drm.c \
+ radeon_r300.c
+
+LIBRARY_INCLUDES = -I$(TOP)/src/gallium/drivers/r300 \
+ $(shell pkg-config libdrm --cflags-only-I)
+
+include ../../../Makefile.template
+
+symlinks:
diff --git a/src/gallium/winsys/radeon/drm/SConscript b/src/gallium/winsys/radeon/drm/SConscript
new file mode 100644
index 0000000000..60e409fe10
--- /dev/null
+++ b/src/gallium/winsys/radeon/drm/SConscript
@@ -0,0 +1,19 @@
+Import('*')
+
+env = env.Clone()
+
+radeon_sources = [
+ 'radeon_drm_buffer.c',
+ 'radeon_drm.c',
+ 'radeon_r300.c',
+]
+
+env.ParseConfig('pkg-config --cflags libdrm_radeon')
+env.Append(CPPPATH = '#/src/gallium/drivers/r300')
+
+radeonwinsys = env.ConvenienceLibrary(
+ target ='radeonwinsys',
+ source = radeon_sources,
+)
+
+Export('radeonwinsys')
diff --git a/src/gallium/winsys/radeon/drm/radeon_buffer.h b/src/gallium/winsys/radeon/drm/radeon_buffer.h
new file mode 100644
index 0000000000..73cb6a579b
--- /dev/null
+++ b/src/gallium/winsys/radeon/drm/radeon_buffer.h
@@ -0,0 +1,98 @@
+/*
+ * Copyright © 2008 Jérôme Glisse
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS, AUTHORS
+ * AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ */
+/*
+ * Authors:
+ * Jérôme Glisse <glisse@freedesktop.org>
+ */
+#ifndef RADEON_BUFFER_H
+#define RADEON_BUFFER_H
+
+#include <stdio.h>
+
+#include "pipe/p_defines.h"
+#include "util/u_inlines.h"
+
+#include "pipebuffer/pb_buffer.h"
+#include "pipebuffer/pb_bufmgr.h"
+
+#include "radeon_bo.h"
+#include "radeon_cs.h"
+
+#include "radeon_winsys.h"
+
+#define RADEON_USAGE_DOMAIN_GTT (1 << 29)
+#define RADEON_USAGE_DOMAIN_VRAM (1 << 30)
+
+#define RADEON_MAX_BOS 24
+
+static INLINE struct pb_buffer *
+radeon_pb_buffer(struct r300_winsys_buffer *buffer)
+{
+ return (struct pb_buffer *)buffer;
+}
+
+static INLINE struct r300_winsys_buffer *
+radeon_libdrm_winsys_buffer(struct pb_buffer *buffer)
+{
+ return (struct r300_winsys_buffer *)buffer;
+}
+
+struct pb_manager *
+radeon_drm_bufmgr_create(struct radeon_libdrm_winsys *rws);
+
+boolean radeon_drm_bufmgr_add_buffer(struct pb_buffer *_buf,
+ enum r300_buffer_domain rd,
+ enum r300_buffer_domain wd);
+
+
+void radeon_drm_bufmgr_write_reloc(struct pb_buffer *_buf,
+ enum r300_buffer_domain rd,
+ enum r300_buffer_domain wd,
+ uint32_t flags);
+
+struct pb_buffer *radeon_drm_bufmgr_create_buffer_from_handle(struct pb_manager *_mgr,
+ uint32_t handle);
+
+void radeon_drm_bufmgr_get_tiling(struct pb_buffer *_buf,
+ enum r300_buffer_tiling *microtiled,
+ enum r300_buffer_tiling *macrotiled);
+
+void radeon_drm_bufmgr_set_tiling(struct pb_buffer *_buf,
+ enum r300_buffer_tiling microtiled,
+ enum r300_buffer_tiling macrotiled,
+ uint32_t pitch);
+
+void radeon_drm_bufmgr_flush_maps(struct pb_manager *_mgr);
+
+boolean radeon_drm_bufmgr_get_handle(struct pb_buffer *_buf,
+ struct winsys_handle *whandle);
+
+boolean radeon_drm_bufmgr_is_buffer_referenced(struct pb_buffer *_buf,
+ enum r300_reference_domain domain);
+
+void radeon_drm_bufmgr_wait(struct pb_buffer *_buf);
+
+#endif
diff --git a/src/gallium/winsys/radeon/drm/radeon_drm.c b/src/gallium/winsys/radeon/drm/radeon_drm.c
new file mode 100644
index 0000000000..59f1b10230
--- /dev/null
+++ b/src/gallium/winsys/radeon/drm/radeon_drm.c
@@ -0,0 +1,192 @@
+/*
+ * Copyright © 2009 Corbin Simpson
+ * 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:
+ * Corbin Simpson <MostAwesomeDude@gmail.com>
+ * Joakim Sindholt <opensource@zhasha.com>
+ */
+
+#include "radeon_drm.h"
+#include "radeon_r300.h"
+#include "radeon_buffer.h"
+
+#include "r300_winsys.h"
+#include "trace/tr_drm.h"
+
+#include "util/u_memory.h"
+
+#include "xf86drm.h"
+#include <sys/ioctl.h>
+
+static struct radeon_libdrm_winsys *
+radeon_winsys_create(int fd)
+{
+ struct radeon_libdrm_winsys *rws;
+
+ rws = CALLOC_STRUCT(radeon_libdrm_winsys);
+ if (rws == NULL) {
+ return NULL;
+ }
+
+ rws->fd = fd;
+ return rws;
+}
+
+/* Helper function to do the ioctls needed for setup and init. */
+static void do_ioctls(int fd, struct radeon_libdrm_winsys* winsys)
+{
+ struct drm_radeon_gem_info gem_info = {0};
+ struct drm_radeon_info info = {0};
+ int target = 0;
+ int retval;
+ drmVersionPtr version;
+
+ info.value = (unsigned long)&target;
+
+ /* We do things in a specific order here.
+ *
+ * DRM version first. We need to be sure we're running on a KMS chipset.
+ * This is also for some features.
+ *
+ * Then, the PCI ID. This is essential and should return usable numbers
+ * for all Radeons. If this fails, we probably got handed an FD for some
+ * non-Radeon card.
+ *
+ * The GB and Z pipe requests should always succeed, but they might not
+ * return sensical values for all chipsets, but that's alright because
+ * the pipe drivers already know that.
+ *
+ * The GEM info is actually bogus on the kernel side, as well as our side
+ * (see radeon_gem_info_ioctl in radeon_gem.c) but that's alright because
+ * we don't actually use the info for anything yet. */
+
+ version = drmGetVersion(fd);
+ if (version->version_major != 2) {
+ fprintf(stderr, "%s: DRM version is %d.%d.%d but this driver is "
+ "only compatible with 2.x.x\n", __FUNCTION__,
+ version->version_major, version->version_minor,
+ version->version_patchlevel);
+ drmFreeVersion(version);
+ exit(1);
+ }
+
+/* XXX Remove this ifdef when libdrm version 2.4.19 becomes mandatory. */
+#ifdef RADEON_BO_FLAGS_MICRO_TILE_SQUARE
+ // Supported since 2.1.0.
+ winsys->squaretiling = version->version_major > 2 ||
+ version->version_minor >= 1;
+#endif
+
+ winsys->drm_2_3_0 = version->version_major > 2 ||
+ version->version_minor >= 3;
+
+ info.request = RADEON_INFO_DEVICE_ID;
+ retval = drmCommandWriteRead(fd, DRM_RADEON_INFO, &info, sizeof(info));
+ if (retval) {
+ fprintf(stderr, "%s: Failed to get PCI ID, "
+ "error number %d\n", __FUNCTION__, retval);
+ exit(1);
+ }
+ winsys->pci_id = target;
+
+ info.request = RADEON_INFO_NUM_GB_PIPES;
+ retval = drmCommandWriteRead(fd, DRM_RADEON_INFO, &info, sizeof(info));
+ if (retval) {
+ fprintf(stderr, "%s: Failed to get GB pipe count, "
+ "error number %d\n", __FUNCTION__, retval);
+ exit(1);
+ }
+ winsys->gb_pipes = target;
+
+ info.request = RADEON_INFO_NUM_Z_PIPES;
+ retval = drmCommandWriteRead(fd, DRM_RADEON_INFO, &info, sizeof(info));
+ if (retval) {
+ fprintf(stderr, "%s: Failed to get Z pipe count, "
+ "error number %d\n", __FUNCTION__, retval);
+ exit(1);
+ }
+ winsys->z_pipes = target;
+
+ retval = drmCommandWriteRead(fd, DRM_RADEON_GEM_INFO,
+ &gem_info, sizeof(gem_info));
+ if (retval) {
+ fprintf(stderr, "%s: Failed to get MM info, error number %d\n",
+ __FUNCTION__, retval);
+ exit(1);
+ }
+ winsys->gart_size = gem_info.gart_size;
+ winsys->vram_size = gem_info.vram_size;
+
+ debug_printf("radeon: Successfully grabbed chipset info from kernel!\n"
+ "radeon: DRM version: %d.%d.%d ID: 0x%04x GB: %d Z: %d\n"
+ "radeon: GART size: %d MB VRAM size: %d MB\n",
+ version->version_major, version->version_minor,
+ version->version_patchlevel, winsys->pci_id,
+ winsys->gb_pipes, winsys->z_pipes,
+ winsys->gart_size / 1024 / 1024,
+ winsys->vram_size / 1024 / 1024);
+
+ drmFreeVersion(version);
+}
+
+/* Create a pipe_screen. */
+struct pipe_screen* radeon_create_screen(struct drm_api* api, int drmFB)
+{
+ struct radeon_libdrm_winsys* rws;
+ boolean ret;
+
+ rws = radeon_winsys_create(drmFB);
+ if (!rws)
+ return NULL;
+
+ do_ioctls(drmFB, rws);
+
+ /* The state tracker can organize a softpipe fallback if no hw
+ * driver is found.
+ */
+ if (is_r3xx(rws->pci_id)) {
+ ret = radeon_setup_winsys(drmFB, rws);
+ if (ret == FALSE)
+ goto fail;
+ return r300_create_screen(&rws->base);
+ }
+
+fail:
+ FREE(rws);
+ return NULL;
+}
+
+static struct drm_api radeon_drm_api_hooks = {
+ .name = "radeon",
+ .driver_name = "radeon",
+ .create_screen = radeon_create_screen,
+ .destroy = NULL,
+};
+
+struct drm_api* drm_api_create()
+{
+ return trace_drm_create(&radeon_drm_api_hooks);
+}
diff --git a/src/gallium/winsys/radeon/drm/radeon_drm.h b/src/gallium/winsys/radeon/drm/radeon_drm.h
new file mode 100644
index 0000000000..3544c926d9
--- /dev/null
+++ b/src/gallium/winsys/radeon/drm/radeon_drm.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright © 2009 Corbin Simpson
+ * 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:
+ * Corbin Simpson <MostAwesomeDude@gmail.com>
+ */
+#ifndef RADEON_DRM_H
+#define RADEON_DRM_H
+
+#include "state_tracker/drm_api.h"
+
+
+struct pipe_screen* radeon_create_screen(struct drm_api* api, int drmFB);
+
+void radeon_destroy_drm_api(struct drm_api* api);
+
+/* Guess at whether this chipset should use r300g.
+ *
+ * I believe that this check is valid, but I haven't been exhaustive. */
+static INLINE boolean is_r3xx(int pciid)
+{
+ return (pciid > 0x3150) && (pciid < 0x796f);
+}
+
+#endif
diff --git a/src/gallium/winsys/radeon/drm/radeon_drm_buffer.c b/src/gallium/winsys/radeon/drm/radeon_drm_buffer.c
new file mode 100644
index 0000000000..a4b6cff33d
--- /dev/null
+++ b/src/gallium/winsys/radeon/drm/radeon_drm_buffer.c
@@ -0,0 +1,423 @@
+
+#include <sys/ioctl.h>
+#include "radeon_drm.h"
+#include "radeon_bo_gem.h"
+#include "radeon_cs_gem.h"
+#include "radeon_buffer.h"
+
+#include "util/u_inlines.h"
+#include "util/u_memory.h"
+#include "util/u_simple_list.h"
+#include "pipebuffer/pb_buffer.h"
+#include "pipebuffer/pb_bufmgr.h"
+
+#include "radeon_winsys.h"
+struct radeon_drm_bufmgr;
+
+struct radeon_drm_buffer {
+ struct pb_buffer base;
+ struct radeon_drm_bufmgr *mgr;
+
+ struct radeon_bo *bo;
+
+ boolean flinked;
+ uint32_t flink;
+ uint32_t tileflags;
+ uint32_t pitch;
+
+ struct radeon_drm_buffer *next, *prev;
+};
+
+extern const struct pb_vtbl radeon_drm_buffer_vtbl;
+
+
+static INLINE struct radeon_drm_buffer *
+radeon_drm_buffer(struct pb_buffer *buf)
+{
+ assert(buf);
+ assert(buf->vtbl == &radeon_drm_buffer_vtbl);
+ return (struct radeon_drm_buffer *)buf;
+}
+
+struct radeon_drm_bufmgr {
+ struct pb_manager base;
+ struct radeon_libdrm_winsys *rws;
+ struct radeon_drm_buffer buffer_map_list;
+};
+
+static INLINE struct radeon_drm_bufmgr *
+radeon_drm_bufmgr(struct pb_manager *mgr)
+{
+ assert(mgr);
+ return (struct radeon_drm_bufmgr *)mgr;
+}
+
+static void
+radeon_drm_buffer_destroy(struct pb_buffer *_buf)
+{
+ struct radeon_drm_buffer *buf = radeon_drm_buffer(_buf);
+
+ if (buf->bo->ptr != NULL) {
+ remove_from_list(buf);
+ radeon_bo_unmap(buf->bo);
+ buf->bo->ptr = NULL;
+ }
+ radeon_bo_unref(buf->bo);
+
+ FREE(buf);
+}
+
+static void *
+radeon_drm_buffer_map(struct pb_buffer *_buf,
+ unsigned flags)
+{
+ struct radeon_drm_buffer *buf = radeon_drm_buffer(_buf);
+ int write = 0;
+
+ if (flags & PIPE_TRANSFER_DONTBLOCK) {
+ if ((_buf->base.usage & PIPE_BIND_VERTEX_BUFFER) ||
+ (_buf->base.usage & PIPE_BIND_INDEX_BUFFER))
+ if (radeon_bo_is_referenced_by_cs(buf->bo, buf->mgr->rws->cs))
+ return NULL;
+ }
+
+ if (buf->bo->ptr != NULL)
+ return buf->bo->ptr;
+
+ if (flags & PIPE_TRANSFER_DONTBLOCK) {
+ uint32_t domain;
+ if (radeon_bo_is_busy(buf->bo, &domain))
+ return NULL;
+ }
+
+ if (radeon_bo_is_referenced_by_cs(buf->bo, buf->mgr->rws->cs)) {
+ buf->mgr->rws->flush_cb(buf->mgr->rws->flush_data);
+ }
+
+ if (flags & PIPE_TRANSFER_WRITE) {
+ write = 1;
+ }
+
+ if (radeon_bo_map(buf->bo, write)) {
+ return NULL;
+ }
+ insert_at_tail(&buf->mgr->buffer_map_list, buf);
+ return buf->bo->ptr;
+}
+
+static void
+radeon_drm_buffer_unmap(struct pb_buffer *_buf)
+{
+ (void)_buf;
+}
+
+static void
+radeon_drm_buffer_get_base_buffer(struct pb_buffer *buf,
+ struct pb_buffer **base_buf,
+ unsigned *offset)
+{
+ *base_buf = buf;
+ *offset = 0;
+}
+
+
+static enum pipe_error
+radeon_drm_buffer_validate(struct pb_buffer *_buf,
+ struct pb_validate *vl,
+ unsigned flags)
+{
+ /* Always pinned */
+ return PIPE_OK;
+}
+
+static void
+radeon_drm_buffer_fence(struct pb_buffer *buf,
+ struct pipe_fence_handle *fence)
+{
+}
+
+const struct pb_vtbl radeon_drm_buffer_vtbl = {
+ radeon_drm_buffer_destroy,
+ radeon_drm_buffer_map,
+ radeon_drm_buffer_unmap,
+ radeon_drm_buffer_validate,
+ radeon_drm_buffer_fence,
+ radeon_drm_buffer_get_base_buffer,
+};
+
+struct pb_buffer *radeon_drm_bufmgr_create_buffer_from_handle(struct pb_manager *_mgr,
+ uint32_t handle)
+{
+ struct radeon_drm_bufmgr *mgr = radeon_drm_bufmgr(_mgr);
+ struct radeon_libdrm_winsys *rws = mgr->rws;
+ struct radeon_drm_buffer *buf;
+ struct radeon_bo *bo;
+
+ bo = radeon_bo_open(rws->bom, handle, 0,
+ 0, 0, 0);
+ if (bo == NULL)
+ return NULL;
+
+ buf = CALLOC_STRUCT(radeon_drm_buffer);
+ if (!buf) {
+ radeon_bo_unref(bo);
+ return NULL;
+ }
+
+ make_empty_list(buf);
+
+ pipe_reference_init(&buf->base.base.reference, 1);
+ buf->base.base.alignment = 0;
+ buf->base.base.usage = PIPE_BIND_SAMPLER_VIEW;
+ buf->base.base.size = 0;
+ buf->base.vtbl = &radeon_drm_buffer_vtbl;
+ buf->mgr = mgr;
+
+ buf->bo = bo;
+
+ return &buf->base;
+}
+
+static struct pb_buffer *
+radeon_drm_bufmgr_create_buffer(struct pb_manager *_mgr,
+ pb_size size,
+ const struct pb_desc *desc)
+{
+ struct radeon_drm_bufmgr *mgr = radeon_drm_bufmgr(_mgr);
+ struct radeon_libdrm_winsys *rws = mgr->rws;
+ struct radeon_drm_buffer *buf;
+ uint32_t domain;
+
+ buf = CALLOC_STRUCT(radeon_drm_buffer);
+ if (!buf)
+ goto error1;
+
+ pipe_reference_init(&buf->base.base.reference, 1);
+ buf->base.base.alignment = desc->alignment;
+ buf->base.base.usage = desc->usage;
+ buf->base.base.size = size;
+ buf->base.vtbl = &radeon_drm_buffer_vtbl;
+ buf->mgr = mgr;
+
+ make_empty_list(buf);
+
+ domain =
+ (desc->usage & RADEON_USAGE_DOMAIN_GTT ? RADEON_GEM_DOMAIN_GTT : 0) |
+ (desc->usage & RADEON_USAGE_DOMAIN_VRAM ? RADEON_GEM_DOMAIN_VRAM : 0);
+
+ buf->bo = radeon_bo_open(rws->bom, 0, size,
+ desc->alignment, domain, 0);
+ if (buf->bo == NULL)
+ goto error2;
+
+ return &buf->base;
+
+ error2:
+ FREE(buf);
+ error1:
+ return NULL;
+}
+
+static void
+radeon_drm_bufmgr_flush(struct pb_manager *mgr)
+{
+ /* NOP */
+}
+
+static void
+radeon_drm_bufmgr_destroy(struct pb_manager *_mgr)
+{
+ struct radeon_drm_bufmgr *mgr = radeon_drm_bufmgr(_mgr);
+ FREE(mgr);
+}
+
+struct pb_manager *
+radeon_drm_bufmgr_create(struct radeon_libdrm_winsys *rws)
+{
+ struct radeon_drm_bufmgr *mgr;
+
+ mgr = CALLOC_STRUCT(radeon_drm_bufmgr);
+ if (!mgr)
+ return NULL;
+
+ mgr->base.destroy = radeon_drm_bufmgr_destroy;
+ mgr->base.create_buffer = radeon_drm_bufmgr_create_buffer;
+ mgr->base.flush = radeon_drm_bufmgr_flush;
+
+ mgr->rws = rws;
+ make_empty_list(&mgr->buffer_map_list);
+ return &mgr->base;
+}
+
+static struct radeon_drm_buffer *get_drm_buffer(struct pb_buffer *_buf)
+{
+ struct radeon_drm_buffer *buf;
+ if (_buf->vtbl == &radeon_drm_buffer_vtbl) {
+ buf = radeon_drm_buffer(_buf);
+ } else {
+ struct pb_buffer *base_buf;
+ pb_size offset;
+ pb_get_base_buffer(_buf, &base_buf, &offset);
+
+ buf = radeon_drm_buffer(base_buf);
+ }
+ return buf;
+}
+
+boolean radeon_drm_bufmgr_get_handle(struct pb_buffer *_buf,
+ struct winsys_handle *whandle)
+{
+ struct drm_gem_flink flink;
+ struct radeon_drm_buffer *buf = get_drm_buffer(_buf);
+
+ if (whandle->type == DRM_API_HANDLE_TYPE_SHARED) {
+ if (!buf->flinked) {
+ flink.handle = buf->bo->handle;
+
+ if (ioctl(buf->mgr->rws->fd, DRM_IOCTL_GEM_FLINK, &flink)) {
+ return FALSE;
+ }
+
+ buf->flinked = TRUE;
+ buf->flink = flink.name;
+ }
+ whandle->handle = buf->flink;
+ } else if (whandle->type == DRM_API_HANDLE_TYPE_KMS) {
+ whandle->handle = buf->bo->handle;
+ }
+ return TRUE;
+}
+
+void radeon_drm_bufmgr_get_tiling(struct pb_buffer *_buf,
+ enum r300_buffer_tiling *microtiled,
+ enum r300_buffer_tiling *macrotiled)
+{
+ struct radeon_drm_buffer *buf = get_drm_buffer(_buf);
+ uint32_t flags = 0, pitch;
+
+ radeon_bo_get_tiling(buf->bo, &flags, &pitch);
+
+ buf->tileflags = flags;
+ buf->pitch = pitch;
+
+ *microtiled = R300_BUFFER_LINEAR;
+ *macrotiled = R300_BUFFER_LINEAR;
+ if (flags & RADEON_BO_FLAGS_MICRO_TILE)
+ *microtiled = R300_BUFFER_TILED;
+
+ if (flags & RADEON_BO_FLAGS_MACRO_TILE)
+ *macrotiled = R300_BUFFER_TILED;
+}
+
+void radeon_drm_bufmgr_set_tiling(struct pb_buffer *_buf,
+ enum r300_buffer_tiling microtiled,
+ enum r300_buffer_tiling macrotiled,
+ uint32_t pitch)
+{
+ struct radeon_drm_buffer *buf = get_drm_buffer(_buf);
+ uint32_t flags = 0;
+ if (microtiled == R300_BUFFER_TILED)
+ flags |= RADEON_BO_FLAGS_MICRO_TILE;
+/* XXX Remove this ifdef when libdrm version 2.4.19 becomes mandatory. */
+#ifdef RADEON_BO_FLAGS_MICRO_TILE_SQUARE
+ else if (microtiled == R300_BUFFER_SQUARETILED)
+ flags |= RADEON_BO_FLAGS_MICRO_TILE_SQUARE;
+#endif
+ if (macrotiled == R300_BUFFER_TILED)
+ flags |= RADEON_BO_FLAGS_MACRO_TILE;
+
+ if (flags != buf->tileflags || pitch != buf->pitch) {
+ /* Tiling determines how DRM treats the buffer data.
+ * We must flush CS when changing it if the buffer is referenced. */
+ if (radeon_bo_is_referenced_by_cs(buf->bo, buf->mgr->rws->cs)) {
+ buf->mgr->rws->flush_cb(buf->mgr->rws->flush_data);
+ }
+
+ radeon_bo_set_tiling(buf->bo, flags, pitch);
+ }
+}
+
+static uint32_t gem_domain(enum r300_buffer_domain dom)
+{
+ uint32_t res = 0;
+
+ if (dom & R300_DOMAIN_GTT)
+ res |= RADEON_GEM_DOMAIN_GTT;
+ if (dom & R300_DOMAIN_VRAM)
+ res |= RADEON_GEM_DOMAIN_VRAM;
+ return res;
+}
+
+boolean radeon_drm_bufmgr_add_buffer(struct pb_buffer *_buf,
+ enum r300_buffer_domain rd,
+ enum r300_buffer_domain wd)
+{
+ struct radeon_drm_buffer *buf = get_drm_buffer(_buf);
+ uint32_t gem_rd = gem_domain(rd);
+ uint32_t gem_wd = gem_domain(wd);
+
+ radeon_cs_space_add_persistent_bo(buf->mgr->rws->cs, buf->bo,
+ gem_rd, gem_wd);
+ return TRUE;
+}
+
+void radeon_drm_bufmgr_write_reloc(struct pb_buffer *_buf,
+ enum r300_buffer_domain rd,
+ enum r300_buffer_domain wd,
+ uint32_t flags)
+{
+ struct radeon_drm_buffer *buf = get_drm_buffer(_buf);
+ int retval;
+ uint32_t gem_rd = gem_domain(rd);
+ uint32_t gem_wd = gem_domain(wd);
+
+ retval = radeon_cs_write_reloc(buf->mgr->rws->cs,
+ buf->bo, gem_rd, gem_wd, flags);
+ if (retval) {
+ debug_printf("radeon: Relocation of %p (%d, %d, %d) failed!\n",
+ buf, gem_rd, gem_wd, flags);
+ }
+}
+
+boolean radeon_drm_bufmgr_is_buffer_referenced(struct pb_buffer *_buf,
+ enum r300_reference_domain domain)
+{
+ struct radeon_drm_buffer *buf = get_drm_buffer(_buf);
+ uint32_t tmp;
+
+ if (domain & R300_REF_CS) {
+ if (radeon_bo_is_referenced_by_cs(buf->bo, buf->mgr->rws->cs)) {
+ return TRUE;
+ }
+ }
+
+ if (domain & R300_REF_HW) {
+ if (radeon_bo_is_busy(buf->bo, &tmp)) {
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+
+void radeon_drm_bufmgr_flush_maps(struct pb_manager *_mgr)
+{
+ struct radeon_drm_bufmgr *mgr = radeon_drm_bufmgr(_mgr);
+ struct radeon_drm_buffer *rpb, *t_rpb;
+
+ foreach_s(rpb, t_rpb, &mgr->buffer_map_list) {
+ radeon_bo_unmap(rpb->bo);
+ rpb->bo->ptr = NULL;
+ remove_from_list(rpb);
+ }
+
+ make_empty_list(&mgr->buffer_map_list);
+}
+
+void radeon_drm_bufmgr_wait(struct pb_buffer *_buf)
+{
+ struct radeon_drm_buffer *buf = get_drm_buffer(_buf);
+
+ radeon_bo_wait(buf->bo);
+}
diff --git a/src/gallium/winsys/radeon/drm/radeon_r300.c b/src/gallium/winsys/radeon/drm/radeon_r300.c
new file mode 100644
index 0000000000..d2d317dc20
--- /dev/null
+++ b/src/gallium/winsys/radeon/drm/radeon_r300.c
@@ -0,0 +1,369 @@
+/*
+ * Copyright 2008 Corbin Simpson <MostAwesomeDude@gmail.com>
+ *
+ * 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
+ * on the rights to use, copy, modify, merge, publish, distribute, sub
+ * license, and/or sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHOR(S) AND/OR THEIR 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. */
+
+#include "radeon_r300.h"
+#include "radeon_buffer.h"
+
+#include "radeon_bo_gem.h"
+#include "radeon_cs_gem.h"
+#include "state_tracker/drm_api.h"
+
+static struct r300_winsys_buffer *
+radeon_r300_winsys_buffer_create(struct r300_winsys_screen *rws,
+ unsigned alignment,
+ unsigned usage,
+ enum r300_buffer_domain domain,
+ unsigned size)
+{
+ struct radeon_libdrm_winsys *ws = radeon_winsys_screen(rws);
+ struct pb_desc desc;
+ struct pb_manager *provider;
+ struct pb_buffer *buffer;
+
+ /* XXX this is hackish, but it's the only way to pass these flags
+ * to the real create function. */
+ usage &= ~(RADEON_USAGE_DOMAIN_GTT | RADEON_USAGE_DOMAIN_VRAM);
+ if (domain & R300_DOMAIN_GTT)
+ usage |= RADEON_USAGE_DOMAIN_GTT;
+ if (domain & R300_DOMAIN_VRAM)
+ usage |= RADEON_USAGE_DOMAIN_VRAM;
+
+ memset(&desc, 0, sizeof(desc));
+ desc.alignment = alignment;
+ desc.usage = usage;
+
+ if (usage & PIPE_BIND_CONSTANT_BUFFER)
+ provider = ws->mman;
+ else if ((usage & PIPE_BIND_VERTEX_BUFFER) ||
+ (usage & PIPE_BIND_INDEX_BUFFER))
+ provider = ws->cman;
+ else
+ provider = ws->kman;
+ buffer = provider->create_buffer(provider, size, &desc);
+ if (!buffer)
+ return NULL;
+
+ return radeon_libdrm_winsys_buffer(buffer);
+}
+
+static void radeon_r300_winsys_buffer_destroy(struct r300_winsys_buffer *buf)
+{
+ struct pb_buffer *_buf = radeon_pb_buffer(buf);
+
+ pb_destroy(_buf);
+}
+static void radeon_r300_winsys_buffer_set_tiling(struct r300_winsys_screen *rws,
+ struct r300_winsys_buffer *buf,
+ uint32_t pitch,
+ enum r300_buffer_tiling microtiled,
+ enum r300_buffer_tiling macrotiled)
+{
+ struct pb_buffer *_buf = radeon_pb_buffer(buf);
+ radeon_drm_bufmgr_set_tiling(_buf, microtiled, macrotiled, pitch);
+}
+
+static void radeon_r300_winsys_buffer_get_tiling(struct r300_winsys_screen *rws,
+ struct r300_winsys_buffer *buf,
+ enum r300_buffer_tiling *microtiled,
+ enum r300_buffer_tiling *macrotiled)
+{
+ struct pb_buffer *_buf = radeon_pb_buffer(buf);
+ radeon_drm_bufmgr_get_tiling(_buf, microtiled, macrotiled);
+}
+
+static void *radeon_r300_winsys_buffer_map(struct r300_winsys_screen *ws,
+ struct r300_winsys_buffer *buf,
+ unsigned usage)
+{
+ struct pb_buffer *_buf = radeon_pb_buffer(buf);
+
+ return pb_map(_buf, usage);
+}
+
+static void radeon_r300_winsys_buffer_unmap(struct r300_winsys_screen *ws,
+ struct r300_winsys_buffer *buf)
+{
+ struct pb_buffer *_buf = radeon_pb_buffer(buf);
+
+ pb_unmap(_buf);
+}
+
+static void radeon_r300_winsys_buffer_wait(struct r300_winsys_screen *ws,
+ struct r300_winsys_buffer *buf)
+{
+ struct pb_buffer *_buf = radeon_pb_buffer(buf);
+ radeon_drm_bufmgr_wait(_buf);
+}
+
+static void radeon_r300_winsys_buffer_reference(struct r300_winsys_screen *rws,
+ struct r300_winsys_buffer **pdst,
+ struct r300_winsys_buffer *src)
+{
+ struct pb_buffer *_src = radeon_pb_buffer(src);
+ struct pb_buffer *_dst = radeon_pb_buffer(*pdst);
+
+ pb_reference(&_dst, _src);
+
+ *pdst = radeon_libdrm_winsys_buffer(_dst);
+}
+
+static boolean radeon_r300_winsys_is_buffer_referenced(struct r300_winsys_screen *rws,
+ struct r300_winsys_buffer *buf,
+ enum r300_reference_domain domain)
+{
+ struct pb_buffer *_buf = radeon_pb_buffer(buf);
+
+ return radeon_drm_bufmgr_is_buffer_referenced(_buf, domain);
+}
+
+static struct r300_winsys_buffer *radeon_r300_winsys_buffer_from_handle(struct r300_winsys_screen *rws,
+ unsigned handle)
+{
+ struct radeon_libdrm_winsys *ws = radeon_winsys_screen(rws);
+ struct pb_buffer *_buf;
+
+ _buf = radeon_drm_bufmgr_create_buffer_from_handle(ws->kman, handle);
+ return radeon_libdrm_winsys_buffer(_buf);
+}
+
+static boolean radeon_r300_winsys_buffer_get_handle(struct r300_winsys_screen *rws,
+ struct r300_winsys_buffer *buffer,
+ struct winsys_handle *whandle)
+{
+ struct pb_buffer *_buf = radeon_pb_buffer(buffer);
+ return radeon_drm_bufmgr_get_handle(_buf, whandle);
+}
+
+static void radeon_set_flush_cb(struct r300_winsys_screen *rws,
+ void (*flush_cb)(void *),
+ void *data)
+{
+ struct radeon_libdrm_winsys *ws = radeon_winsys_screen(rws);
+ ws->flush_cb = flush_cb;
+ ws->flush_data = data;
+ radeon_cs_space_set_flush(ws->cs, flush_cb, data);
+}
+
+static boolean radeon_add_buffer(struct r300_winsys_screen *rws,
+ struct r300_winsys_buffer *buf,
+ enum r300_buffer_domain rd,
+ enum r300_buffer_domain wd)
+{
+ struct pb_buffer *_buf = radeon_pb_buffer(buf);
+
+ return radeon_drm_bufmgr_add_buffer(_buf, rd, wd);
+}
+
+static boolean radeon_validate(struct r300_winsys_screen *rws)
+{
+ struct radeon_libdrm_winsys *ws = radeon_winsys_screen(rws);
+ if (radeon_cs_space_check(ws->cs) < 0) {
+ return FALSE;
+ }
+
+ /* Things are fine, we can proceed as normal. */
+ return TRUE;
+}
+
+static unsigned radeon_get_cs_free_dwords(struct r300_winsys_screen *rws)
+{
+ struct radeon_libdrm_winsys *ws = radeon_winsys_screen(rws);
+ struct radeon_cs *cs = ws->cs;
+
+ return cs->ndw - cs->cdw;
+}
+
+static uint32_t *radeon_get_cs_pointer(struct r300_winsys_screen *rws,
+ unsigned count)
+{
+ struct radeon_libdrm_winsys *ws = radeon_winsys_screen(rws);
+ struct radeon_cs *cs = ws->cs;
+ uint32_t *ptr = cs->packets + cs->cdw;
+
+ cs->cdw += count;
+ return ptr;
+}
+
+static void radeon_write_cs_dword(struct r300_winsys_screen *rws,
+ uint32_t dword)
+{
+ struct radeon_libdrm_winsys *ws = radeon_winsys_screen(rws);
+ radeon_cs_write_dword(ws->cs, dword);
+}
+
+static void radeon_write_cs_table(struct r300_winsys_screen *rws,
+ const void *table, unsigned count)
+{
+ struct radeon_libdrm_winsys *ws = radeon_winsys_screen(rws);
+ radeon_cs_write_table(ws->cs, table, count);
+}
+
+static void radeon_write_cs_reloc(struct r300_winsys_screen *rws,
+ struct r300_winsys_buffer *buf,
+ enum r300_buffer_domain rd,
+ enum r300_buffer_domain wd,
+ uint32_t flags)
+{
+ struct pb_buffer *_buf = radeon_pb_buffer(buf);
+ radeon_drm_bufmgr_write_reloc(_buf, rd, wd, flags);
+}
+
+static void radeon_reset_bos(struct r300_winsys_screen *rws)
+{
+ struct radeon_libdrm_winsys *ws = radeon_winsys_screen(rws);
+ radeon_cs_space_reset_bos(ws->cs);
+}
+
+static void radeon_flush_cs(struct r300_winsys_screen *rws)
+{
+ struct radeon_libdrm_winsys *ws = radeon_winsys_screen(rws);
+ int retval;
+
+ /* Don't flush a zero-sized CS. */
+ if (!ws->cs->cdw) {
+ return;
+ }
+
+ radeon_drm_bufmgr_flush_maps(ws->kman);
+ /* Emit the CS. */
+ retval = radeon_cs_emit(ws->cs);
+ if (retval) {
+ debug_printf("radeon: Bad CS, dumping...\n");
+ radeon_cs_print(ws->cs, stderr);
+ }
+
+ /* Reset CS.
+ * Someday, when we care about performance, we should really find a way
+ * to rotate between two or three CS objects so that the GPU can be
+ * spinning through one CS while another one is being filled. */
+ radeon_cs_erase(ws->cs);
+}
+
+static uint32_t radeon_get_value(struct r300_winsys_screen *rws,
+ enum r300_value_id id)
+{
+ struct radeon_libdrm_winsys *ws = (struct radeon_libdrm_winsys *)rws;
+
+ switch(id) {
+ case R300_VID_PCI_ID:
+ return ws->pci_id;
+ case R300_VID_GB_PIPES:
+ return ws->gb_pipes;
+ case R300_VID_Z_PIPES:
+ return ws->z_pipes;
+ case R300_VID_SQUARE_TILING_SUPPORT:
+ return ws->squaretiling;
+ case R300_VID_DRM_2_3_0:
+ return ws->drm_2_3_0;
+ }
+ return 0;
+}
+
+static void
+radeon_winsys_destroy(struct r300_winsys_screen *rws)
+{
+ struct radeon_libdrm_winsys *ws = (struct radeon_libdrm_winsys *)rws;
+ radeon_cs_destroy(ws->cs);
+
+ ws->cman->destroy(ws->cman);
+ ws->kman->destroy(ws->kman);
+ ws->mman->destroy(ws->mman);
+
+ radeon_bo_manager_gem_dtor(ws->bom);
+ radeon_cs_manager_gem_dtor(ws->csm);
+}
+
+boolean
+radeon_setup_winsys(int fd, struct radeon_libdrm_winsys* ws)
+{
+
+ ws->csm = radeon_cs_manager_gem_ctor(fd);
+ if (!ws->csm)
+ goto fail;
+ ws->bom = radeon_bo_manager_gem_ctor(fd);
+ if (!ws->bom)
+ goto fail;
+ ws->kman = radeon_drm_bufmgr_create(ws);
+ if (!ws->kman)
+ goto fail;
+
+ ws->cman = pb_cache_manager_create(ws->kman, 100000);
+ if (!ws->cman)
+ goto fail;
+
+ ws->mman = pb_malloc_bufmgr_create();
+ if (!ws->mman)
+ goto fail;
+
+ /* Size limit on IBs is 64 kibibytes. */
+ ws->cs = radeon_cs_create(ws->csm, 1024 * 64 / 4);
+ if (!ws->cs)
+ goto fail;
+ radeon_cs_set_limit(ws->cs,
+ RADEON_GEM_DOMAIN_GTT, ws->gart_size);
+ radeon_cs_set_limit(ws->cs,
+ RADEON_GEM_DOMAIN_VRAM, ws->vram_size);
+
+ ws->base.add_buffer = radeon_add_buffer;
+ ws->base.validate = radeon_validate;
+ ws->base.destroy = radeon_winsys_destroy;
+ ws->base.get_cs_free_dwords = radeon_get_cs_free_dwords;
+ ws->base.get_cs_pointer = radeon_get_cs_pointer;
+ ws->base.write_cs_dword = radeon_write_cs_dword;
+ ws->base.write_cs_table = radeon_write_cs_table;
+ ws->base.write_cs_reloc = radeon_write_cs_reloc;
+ ws->base.flush_cs = radeon_flush_cs;
+ ws->base.reset_bos = radeon_reset_bos;
+ ws->base.set_flush_cb = radeon_set_flush_cb;
+ ws->base.get_value = radeon_get_value;
+
+ ws->base.buffer_create = radeon_r300_winsys_buffer_create;
+ ws->base.buffer_destroy = radeon_r300_winsys_buffer_destroy;
+ ws->base.buffer_set_tiling = radeon_r300_winsys_buffer_set_tiling;
+ ws->base.buffer_get_tiling = radeon_r300_winsys_buffer_get_tiling;
+ ws->base.buffer_map = radeon_r300_winsys_buffer_map;
+ ws->base.buffer_unmap = radeon_r300_winsys_buffer_unmap;
+ ws->base.buffer_wait = radeon_r300_winsys_buffer_wait;
+ ws->base.buffer_reference = radeon_r300_winsys_buffer_reference;
+ ws->base.buffer_from_handle = radeon_r300_winsys_buffer_from_handle;
+ ws->base.buffer_get_handle = radeon_r300_winsys_buffer_get_handle;
+ ws->base.is_buffer_referenced = radeon_r300_winsys_is_buffer_referenced;
+ return TRUE;
+
+fail:
+ if (ws->csm)
+ radeon_cs_manager_gem_dtor(ws->csm);
+
+ if (ws->bom)
+ radeon_bo_manager_gem_dtor(ws->bom);
+
+ if (ws->cman)
+ ws->cman->destroy(ws->cman);
+ if (ws->kman)
+ ws->kman->destroy(ws->kman);
+ if (ws->mman)
+ ws->mman->destroy(ws->mman);
+
+ if (ws->cs)
+ radeon_cs_destroy(ws->cs);
+ return FALSE;
+}
diff --git a/src/gallium/winsys/radeon/drm/radeon_r300.h b/src/gallium/winsys/radeon/drm/radeon_r300.h
new file mode 100644
index 0000000000..2703464ad8
--- /dev/null
+++ b/src/gallium/winsys/radeon/drm/radeon_r300.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2008 Corbin Simpson <MostAwesomeDude@gmail.com>
+ *
+ * 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
+ * on the rights to use, copy, modify, merge, publish, distribute, sub
+ * license, and/or sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHOR(S) AND/OR THEIR 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. */
+
+#ifndef RADEON_R300_H
+#define RADEON_R300_H
+
+#include "radeon_winsys.h"
+
+boolean radeon_setup_winsys(int fd, struct radeon_libdrm_winsys* winsys);
+
+#endif /* RADEON_R300_H */
diff --git a/src/gallium/winsys/radeon/drm/radeon_winsys.h b/src/gallium/winsys/radeon/drm/radeon_winsys.h
new file mode 100644
index 0000000000..ca789be8e9
--- /dev/null
+++ b/src/gallium/winsys/radeon/drm/radeon_winsys.h
@@ -0,0 +1,93 @@
+/*
+ * Copyright © 2009 Corbin Simpson
+ * 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:
+ * Corbin Simpson <MostAwesomeDude@gmail.com>
+ */
+#ifndef RADEON_WINSYS_H
+#define RADEON_WINSYS_H
+
+#include "r300_winsys.h"
+
+struct radeon_libdrm_winsys {
+ /* Parent class. */
+ struct r300_winsys_screen base;
+
+ struct pb_manager *kman;
+
+ struct pb_manager *cman;
+
+ struct pb_manager *mman;
+
+ /* PCI ID */
+ uint32_t pci_id;
+
+ /* GB pipe count */
+ uint32_t gb_pipes;
+
+ /* Z pipe count (rv530 only) */
+ uint32_t z_pipes;
+
+ /* GART size. */
+ uint32_t gart_size;
+
+ /* VRAM size. */
+ uint32_t vram_size;
+
+ /* Square tiling support. */
+ boolean squaretiling;
+
+ /* DRM 2.3.0
+ * - R500 VAP regs
+ * - MSPOS regs
+ * - Fixed texture 3D size calculation
+ */
+ boolean drm_2_3_0;
+
+ /* DRM FD */
+ int fd;
+
+ /* Radeon BO manager. */
+ struct radeon_bo_manager *bom;
+
+ /* Radeon CS manager. */
+ struct radeon_cs_manager *csm;
+
+ /* Current CS. */
+ struct radeon_cs *cs;
+
+ /* Flush CB */
+ void (*flush_cb)(void *);
+ void *flush_data;
+};
+
+static INLINE struct radeon_libdrm_winsys *
+radeon_winsys_screen(struct r300_winsys_screen *base)
+{
+ return (struct radeon_libdrm_winsys *)base;
+}
+
+#endif
diff --git a/src/gallium/winsys/svga/drm/Makefile b/src/gallium/winsys/svga/drm/Makefile
new file mode 100644
index 0000000000..c2f59e01b0
--- /dev/null
+++ b/src/gallium/winsys/svga/drm/Makefile
@@ -0,0 +1,27 @@
+TOP = ../../../../..
+include $(TOP)/configs/current
+
+LIBNAME = svgadrm
+
+C_SOURCES = \
+ vmw_buffer.c \
+ vmw_context.c \
+ vmw_fence.c \
+ vmw_screen.c \
+ vmw_screen_dri.c \
+ vmw_screen_ioctl.c \
+ vmw_screen_pools.c \
+ vmw_screen_svga.c \
+ vmw_surface.c
+
+LIBRARY_INCLUDES = \
+ -I$(TOP)/src/gallium/drivers/svga \
+ -I$(TOP)/src/gallium/drivers/svga/include \
+ $(shell pkg-config libdrm --cflags-only-I)
+
+LIBRARY_DEFINES = \
+ -std=gnu99 -fvisibility=hidden \
+ -DHAVE_STDINT_H -D_FILE_OFFSET_BITS=64 \
+ $(shell pkg-config libdrm --cflags-only-other)
+
+include ../../../Makefile.template
diff --git a/src/gallium/winsys/svga/drm/SConscript b/src/gallium/winsys/svga/drm/SConscript
new file mode 100644
index 0000000000..3ad4c72572
--- /dev/null
+++ b/src/gallium/winsys/svga/drm/SConscript
@@ -0,0 +1,41 @@
+Import('*')
+
+env = env.Clone()
+
+env.ParseConfig('pkg-config --cflags libdrm')
+
+if env['gcc']:
+ env.Append(CCFLAGS = ['-fvisibility=hidden'])
+ env.Append(CPPDEFINES = [
+ 'HAVE_STDINT_H',
+ 'HAVE_SYS_TYPES_H',
+ '-D_FILE_OFFSET_BITS=64',
+ ])
+
+env.Prepend(CPPPATH = [
+ 'include',
+ '#/src/gallium/drivers/svga',
+ '#/src/gallium/drivers/svga/include',
+])
+
+env.Append(CPPDEFINES = [
+])
+
+sources = [
+ 'vmw_buffer.c',
+ 'vmw_context.c',
+ 'vmw_fence.c',
+ 'vmw_screen.c',
+ 'vmw_screen_dri.c',
+ 'vmw_screen_ioctl.c',
+ 'vmw_screen_pools.c',
+ 'vmw_screen_svga.c',
+ 'vmw_surface.c',
+]
+
+svgadrm = env.ConvenienceLibrary(
+ target = 'svgadrm',
+ source = sources,
+)
+
+Export('svgadrm')
diff --git a/src/gallium/winsys/svga/drm/vmw_buffer.c b/src/gallium/winsys/svga/drm/vmw_buffer.c
new file mode 100644
index 0000000000..eca174a6c5
--- /dev/null
+++ b/src/gallium/winsys/svga/drm/vmw_buffer.c
@@ -0,0 +1,274 @@
+/**********************************************************
+ * Copyright 2009 VMware, Inc. 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, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ **********************************************************/
+
+/**
+ * @file
+ * SVGA buffer manager for Guest Memory Regions (GMRs).
+ *
+ * GMRs are used for pixel and vertex data upload/download to/from the virtual
+ * SVGA hardware. There is a limited number of GMRs available, and
+ * creating/destroying them is also a slow operation so we must suballocate
+ * them.
+ *
+ * This file implements a pipebuffer library's buffer manager, so that we can
+ * use pipepbuffer's suballocation, fencing, and debugging facilities with GMRs.
+ *
+ * @author Jose Fonseca <jfonseca@vmware.com>
+ */
+
+
+#include "svga_cmd.h"
+
+#include "util/u_inlines.h"
+#include "util/u_memory.h"
+#include "pipebuffer/pb_buffer.h"
+#include "pipebuffer/pb_bufmgr.h"
+
+#include "svga_winsys.h"
+
+#include "vmw_screen.h"
+#include "vmw_buffer.h"
+
+
+struct vmw_gmr_bufmgr;
+
+
+struct vmw_gmr_buffer
+{
+ struct pb_buffer base;
+
+ struct vmw_gmr_bufmgr *mgr;
+
+ struct vmw_region *region;
+ void *map;
+
+#ifdef DEBUG
+ struct pipe_fence_handle *last_fence;
+#endif
+};
+
+
+extern const struct pb_vtbl vmw_gmr_buffer_vtbl;
+
+
+static INLINE struct vmw_gmr_buffer *
+vmw_gmr_buffer(struct pb_buffer *buf)
+{
+ assert(buf);
+ assert(buf->vtbl == &vmw_gmr_buffer_vtbl);
+ return (struct vmw_gmr_buffer *)buf;
+}
+
+
+struct vmw_gmr_bufmgr
+{
+ struct pb_manager base;
+
+ struct vmw_winsys_screen *vws;
+};
+
+
+static INLINE struct vmw_gmr_bufmgr *
+vmw_gmr_bufmgr(struct pb_manager *mgr)
+{
+ assert(mgr);
+ return (struct vmw_gmr_bufmgr *)mgr;
+}
+
+
+static void
+vmw_gmr_buffer_destroy(struct pb_buffer *_buf)
+{
+ struct vmw_gmr_buffer *buf = vmw_gmr_buffer(_buf);
+
+#ifdef DEBUG
+ if(buf->last_fence) {
+ struct svga_winsys_screen *sws = &buf->mgr->vws->base;
+ assert(sws->fence_signalled(sws, buf->last_fence, 0) == 0);
+ }
+#endif
+
+ vmw_ioctl_region_unmap(buf->region);
+
+ vmw_ioctl_region_destroy(buf->region);
+
+ FREE(buf);
+}
+
+
+static void *
+vmw_gmr_buffer_map(struct pb_buffer *_buf,
+ unsigned flags)
+{
+ struct vmw_gmr_buffer *buf = vmw_gmr_buffer(_buf);
+ return buf->map;
+}
+
+
+static void
+vmw_gmr_buffer_unmap(struct pb_buffer *_buf)
+{
+ /* Do nothing */
+ (void)_buf;
+}
+
+
+static void
+vmw_gmr_buffer_get_base_buffer(struct pb_buffer *buf,
+ struct pb_buffer **base_buf,
+ unsigned *offset)
+{
+ *base_buf = buf;
+ *offset = 0;
+}
+
+
+static enum pipe_error
+vmw_gmr_buffer_validate( struct pb_buffer *_buf,
+ struct pb_validate *vl,
+ unsigned flags )
+{
+ /* Always pinned */
+ return PIPE_OK;
+}
+
+
+static void
+vmw_gmr_buffer_fence( struct pb_buffer *_buf,
+ struct pipe_fence_handle *fence )
+{
+ /* We don't need to do anything, as the pipebuffer library
+ * will take care of delaying the destruction of fenced buffers */
+#ifdef DEBUG
+ struct vmw_gmr_buffer *buf = vmw_gmr_buffer(_buf);
+ if(fence)
+ buf->last_fence = fence;
+#endif
+}
+
+
+const struct pb_vtbl vmw_gmr_buffer_vtbl = {
+ vmw_gmr_buffer_destroy,
+ vmw_gmr_buffer_map,
+ vmw_gmr_buffer_unmap,
+ vmw_gmr_buffer_validate,
+ vmw_gmr_buffer_fence,
+ vmw_gmr_buffer_get_base_buffer
+};
+
+
+static struct pb_buffer *
+vmw_gmr_bufmgr_create_buffer(struct pb_manager *_mgr,
+ pb_size size,
+ const struct pb_desc *desc)
+{
+ struct vmw_gmr_bufmgr *mgr = vmw_gmr_bufmgr(_mgr);
+ struct vmw_winsys_screen *vws = mgr->vws;
+ struct vmw_gmr_buffer *buf;
+
+ buf = CALLOC_STRUCT(vmw_gmr_buffer);
+ if(!buf)
+ goto error1;
+
+ pipe_reference_init(&buf->base.base.reference, 1);
+ buf->base.base.alignment = desc->alignment;
+ buf->base.base.usage = desc->usage;
+ buf->base.base.size = size;
+ buf->base.vtbl = &vmw_gmr_buffer_vtbl;
+ buf->mgr = mgr;
+
+ buf->region = vmw_ioctl_region_create(vws, size);
+ if(!buf->region)
+ goto error2;
+
+ buf->map = vmw_ioctl_region_map(buf->region);
+ if(!buf->map)
+ goto error3;
+
+ return &buf->base;
+
+error3:
+ vmw_ioctl_region_destroy(buf->region);
+error2:
+ FREE(buf);
+error1:
+ return NULL;
+}
+
+
+static void
+vmw_gmr_bufmgr_flush(struct pb_manager *mgr)
+{
+ /* No-op */
+}
+
+
+static void
+vmw_gmr_bufmgr_destroy(struct pb_manager *_mgr)
+{
+ struct vmw_gmr_bufmgr *mgr = vmw_gmr_bufmgr(_mgr);
+ FREE(mgr);
+}
+
+
+struct pb_manager *
+vmw_gmr_bufmgr_create(struct vmw_winsys_screen *vws)
+{
+ struct vmw_gmr_bufmgr *mgr;
+
+ mgr = CALLOC_STRUCT(vmw_gmr_bufmgr);
+ if(!mgr)
+ return NULL;
+
+ mgr->base.destroy = vmw_gmr_bufmgr_destroy;
+ mgr->base.create_buffer = vmw_gmr_bufmgr_create_buffer;
+ mgr->base.flush = vmw_gmr_bufmgr_flush;
+
+ mgr->vws = vws;
+
+ return &mgr->base;
+}
+
+
+boolean
+vmw_gmr_bufmgr_region_ptr(struct pb_buffer *buf,
+ struct SVGAGuestPtr *ptr)
+{
+ struct pb_buffer *base_buf;
+ unsigned offset = 0;
+ struct vmw_gmr_buffer *gmr_buf;
+
+ pb_get_base_buffer( buf, &base_buf, &offset );
+
+ gmr_buf = vmw_gmr_buffer(base_buf);
+ if(!gmr_buf)
+ return FALSE;
+
+ *ptr = vmw_ioctl_region_ptr(gmr_buf->region);
+
+ ptr->offset += offset;
+
+ return TRUE;
+}
diff --git a/src/gallium/winsys/svga/drm/vmw_buffer.h b/src/gallium/winsys/svga/drm/vmw_buffer.h
new file mode 100644
index 0000000000..41fb4476da
--- /dev/null
+++ b/src/gallium/winsys/svga/drm/vmw_buffer.h
@@ -0,0 +1,65 @@
+/**********************************************************
+ * Copyright 2009 VMware, Inc. 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, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ **********************************************************/
+
+
+#ifndef VMW_BUFFER_H_
+#define VMW_BUFFER_H_
+
+#include <assert.h>
+#include "pipe/p_compiler.h"
+
+struct SVGAGuestPtr;
+struct pb_buffer;
+struct pb_manager;
+struct svga_winsys_buffer;
+struct svga_winsys_surface;
+struct vmw_winsys_screen;
+
+
+static INLINE struct pb_buffer *
+vmw_pb_buffer(struct svga_winsys_buffer *buffer)
+{
+ assert(buffer);
+ return (struct pb_buffer *)buffer;
+}
+
+
+static INLINE struct svga_winsys_buffer *
+vmw_svga_winsys_buffer(struct pb_buffer *buffer)
+{
+ assert(buffer);
+ return (struct svga_winsys_buffer *)buffer;
+}
+
+
+struct pb_manager *
+vmw_gmr_bufmgr_create(struct vmw_winsys_screen *vws);
+
+boolean
+vmw_gmr_bufmgr_region_ptr(struct pb_buffer *buf,
+ struct SVGAGuestPtr *ptr);
+
+
+#endif /* VMW_BUFFER_H_ */
diff --git a/src/gallium/winsys/svga/drm/vmw_context.c b/src/gallium/winsys/svga/drm/vmw_context.c
new file mode 100644
index 0000000000..11626ee637
--- /dev/null
+++ b/src/gallium/winsys/svga/drm/vmw_context.c
@@ -0,0 +1,416 @@
+/**********************************************************
+ * Copyright 2009 VMware, Inc. 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, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ **********************************************************/
+
+
+#include "svga_cmd.h"
+
+#include "util/u_debug.h"
+#include "util/u_memory.h"
+#include "util/u_debug_stack.h"
+#include "pipebuffer/pb_buffer.h"
+#include "pipebuffer/pb_validate.h"
+
+#include "svga_winsys.h"
+#include "vmw_context.h"
+#include "vmw_screen.h"
+#include "vmw_buffer.h"
+#include "vmw_surface.h"
+#include "vmw_fence.h"
+
+#define VMW_COMMAND_SIZE (64*1024)
+#define VMW_SURFACE_RELOCS (1024)
+#define VMW_REGION_RELOCS (512)
+
+#define VMW_MUST_FLUSH_STACK 8
+
+struct vmw_region_relocation
+{
+ struct SVGAGuestPtr *where;
+ struct pb_buffer *buffer;
+ /* TODO: put offset info inside where */
+ uint32 offset;
+};
+
+struct vmw_svga_winsys_context
+{
+ struct svga_winsys_context base;
+
+ struct vmw_winsys_screen *vws;
+
+#ifdef DEBUG
+ boolean must_flush;
+ struct debug_stack_frame must_flush_stack[VMW_MUST_FLUSH_STACK];
+#endif
+
+ struct {
+ uint8_t buffer[VMW_COMMAND_SIZE];
+ uint32_t size;
+ uint32_t used;
+ uint32_t reserved;
+ } command;
+
+ struct {
+ struct vmw_svga_winsys_surface *handles[VMW_SURFACE_RELOCS];
+ uint32_t size;
+ uint32_t used;
+ uint32_t staged;
+ uint32_t reserved;
+ } surface;
+
+ struct {
+ struct vmw_region_relocation relocs[VMW_REGION_RELOCS];
+ uint32_t size;
+ uint32_t used;
+ uint32_t staged;
+ uint32_t reserved;
+ } region;
+
+ struct pb_validate *validate;
+
+ uint32_t last_fence;
+
+ /**
+ * The amount of GMR that is referred by the commands currently batched
+ * in the context.
+ */
+ uint32_t seen_regions;
+
+ /**
+ * Whether this context should fail to reserve more commands, not because it
+ * ran out of command space, but because a substantial ammount of GMR was
+ * referred.
+ */
+ boolean preemptive_flush;
+
+ boolean throttle_set;
+ uint32_t throttle_us;
+};
+
+
+static INLINE struct vmw_svga_winsys_context *
+vmw_svga_winsys_context(struct svga_winsys_context *swc)
+{
+ assert(swc);
+ return (struct vmw_svga_winsys_context *)swc;
+}
+
+
+static INLINE unsigned
+vmw_translate_to_pb_flags(unsigned flags)
+{
+ unsigned f = 0;
+ if (flags & SVGA_RELOC_READ)
+ f |= PB_USAGE_GPU_READ;
+
+ if (flags & SVGA_RELOC_WRITE)
+ f |= PB_USAGE_GPU_WRITE;
+
+ return f;
+}
+
+static enum pipe_error
+vmw_swc_flush(struct svga_winsys_context *swc,
+ struct pipe_fence_handle **pfence)
+{
+ struct vmw_svga_winsys_context *vswc = vmw_svga_winsys_context(swc);
+ struct pipe_fence_handle *fence = NULL;
+ unsigned i;
+ enum pipe_error ret;
+ uint32_t throttle_us;
+
+ ret = pb_validate_validate(vswc->validate);
+ assert(ret == PIPE_OK);
+ if(ret == PIPE_OK) {
+
+ /* Apply relocations */
+ for(i = 0; i < vswc->region.used; ++i) {
+ struct vmw_region_relocation *reloc = &vswc->region.relocs[i];
+ struct SVGAGuestPtr ptr;
+
+ if(!vmw_gmr_bufmgr_region_ptr(reloc->buffer, &ptr))
+ assert(0);
+
+ ptr.offset += reloc->offset;
+
+ *reloc->where = ptr;
+ }
+
+ throttle_us = vswc->throttle_set ?
+ vswc->throttle_us : vswc->vws->default_throttle_us;
+
+ if (vswc->command.used)
+ vmw_ioctl_command(vswc->vws,
+ vswc->base.cid,
+ throttle_us,
+ vswc->command.buffer,
+ vswc->command.used,
+ &vswc->last_fence);
+
+ fence = vmw_pipe_fence(vswc->last_fence);
+
+ pb_validate_fence(vswc->validate, fence);
+ }
+
+ vswc->command.used = 0;
+ vswc->command.reserved = 0;
+
+ for(i = 0; i < vswc->surface.used + vswc->surface.staged; ++i) {
+ struct vmw_svga_winsys_surface *vsurf =
+ vswc->surface.handles[i];
+ p_atomic_dec(&vsurf->validated);
+ vmw_svga_winsys_surface_reference(&vswc->surface.handles[i], NULL);
+ }
+
+ vswc->surface.used = 0;
+ vswc->surface.reserved = 0;
+
+ for(i = 0; i < vswc->region.used + vswc->region.staged; ++i) {
+ pb_reference(&vswc->region.relocs[i].buffer, NULL);
+ }
+
+ vswc->region.used = 0;
+ vswc->region.reserved = 0;
+
+#ifdef DEBUG
+ vswc->must_flush = FALSE;
+#endif
+ vswc->preemptive_flush = FALSE;
+ vswc->seen_regions = 0;
+
+ if(pfence)
+ *pfence = fence;
+
+ return ret;
+}
+
+
+static void *
+vmw_swc_reserve(struct svga_winsys_context *swc,
+ uint32_t nr_bytes, uint32_t nr_relocs )
+{
+ struct vmw_svga_winsys_context *vswc = vmw_svga_winsys_context(swc);
+
+#ifdef DEBUG
+ /* Check if somebody forgot to check the previous failure */
+ if(vswc->must_flush) {
+ debug_printf("Forgot to flush:\n");
+ debug_backtrace_dump(vswc->must_flush_stack, VMW_MUST_FLUSH_STACK);
+ assert(!vswc->must_flush);
+ }
+#endif
+
+ assert(nr_bytes <= vswc->command.size);
+ if(nr_bytes > vswc->command.size)
+ return NULL;
+
+ if(vswc->preemptive_flush ||
+ vswc->command.used + nr_bytes > vswc->command.size ||
+ vswc->surface.used + nr_relocs > vswc->surface.size ||
+ vswc->region.used + nr_relocs > vswc->region.size) {
+#ifdef DEBUG
+ vswc->must_flush = TRUE;
+ debug_backtrace_capture(vswc->must_flush_stack, 1,
+ VMW_MUST_FLUSH_STACK);
+#endif
+ return NULL;
+ }
+
+ assert(vswc->command.used + nr_bytes <= vswc->command.size);
+ assert(vswc->surface.used + nr_relocs <= vswc->surface.size);
+ assert(vswc->region.used + nr_relocs <= vswc->region.size);
+
+ vswc->command.reserved = nr_bytes;
+ vswc->surface.reserved = nr_relocs;
+ vswc->surface.staged = 0;
+ vswc->region.reserved = nr_relocs;
+ vswc->region.staged = 0;
+
+ return vswc->command.buffer + vswc->command.used;
+}
+
+
+static void
+vmw_swc_surface_relocation(struct svga_winsys_context *swc,
+ uint32 *where,
+ struct svga_winsys_surface *surface,
+ unsigned flags)
+{
+ struct vmw_svga_winsys_context *vswc = vmw_svga_winsys_context(swc);
+ struct vmw_svga_winsys_surface *vsurf;
+
+ if(!surface) {
+ *where = SVGA3D_INVALID_ID;
+ return;
+ }
+
+ assert(vswc->surface.staged < vswc->surface.reserved);
+
+ vsurf = vmw_svga_winsys_surface(surface);
+
+ *where = vsurf->sid;
+
+ vmw_svga_winsys_surface_reference(&vswc->surface.handles[vswc->surface.used + vswc->surface.staged], vsurf);
+ p_atomic_inc(&vsurf->validated);
+ ++vswc->surface.staged;
+}
+
+
+static void
+vmw_swc_region_relocation(struct svga_winsys_context *swc,
+ struct SVGAGuestPtr *where,
+ struct svga_winsys_buffer *buffer,
+ uint32 offset,
+ unsigned flags)
+{
+ struct vmw_svga_winsys_context *vswc = vmw_svga_winsys_context(swc);
+ struct vmw_region_relocation *reloc;
+ unsigned translated_flags;
+ enum pipe_error ret;
+
+ assert(vswc->region.staged < vswc->region.reserved);
+
+ reloc = &vswc->region.relocs[vswc->region.used + vswc->region.staged];
+ reloc->where = where;
+ pb_reference(&reloc->buffer, vmw_pb_buffer(buffer));
+ reloc->offset = offset;
+
+ ++vswc->region.staged;
+
+ translated_flags = vmw_translate_to_pb_flags(flags);
+ ret = pb_validate_add_buffer(vswc->validate, reloc->buffer, translated_flags);
+ /* TODO: Update pipebuffer to reserve buffers and not fail here */
+ assert(ret == PIPE_OK);
+
+ /*
+ * Flush preemptively the FIFO commands to keep the GMR working set within
+ * the GMR pool size.
+ *
+ * This is necessary for applications like SPECviewperf that generate huge
+ * amounts of immediate vertex data, so that we don't pile up too much of
+ * that vertex data neither in the guest nor in the host.
+ *
+ * Note that in the current implementation if a region is referred twice in
+ * a command stream, it will be accounted twice. We could detect repeated
+ * regions and count only once, but there is no incentive to do that, since
+ * regions are typically short-lived; always referred in a single command;
+ * and at the worst we just flush the commands a bit sooner, which for the
+ * SVGA virtual device it's not a performance issue since flushing commands
+ * to the FIFO won't cause flushing in the host.
+ */
+ vswc->seen_regions += reloc->buffer->base.size;
+ if(vswc->seen_regions >= VMW_GMR_POOL_SIZE/2)
+ vswc->preemptive_flush = TRUE;
+}
+
+
+static void
+vmw_swc_commit(struct svga_winsys_context *swc)
+{
+ struct vmw_svga_winsys_context *vswc = vmw_svga_winsys_context(swc);
+
+ assert(vswc->command.reserved);
+ assert(vswc->command.used + vswc->command.reserved <= vswc->command.size);
+ vswc->command.used += vswc->command.reserved;
+ vswc->command.reserved = 0;
+
+ assert(vswc->surface.staged <= vswc->surface.reserved);
+ assert(vswc->surface.used + vswc->surface.staged <= vswc->surface.size);
+ vswc->surface.used += vswc->surface.staged;
+ vswc->surface.staged = 0;
+ vswc->surface.reserved = 0;
+
+ assert(vswc->region.staged <= vswc->region.reserved);
+ assert(vswc->region.used + vswc->region.staged <= vswc->region.size);
+ vswc->region.used += vswc->region.staged;
+ vswc->region.staged = 0;
+ vswc->region.reserved = 0;
+}
+
+
+static void
+vmw_swc_destroy(struct svga_winsys_context *swc)
+{
+ struct vmw_svga_winsys_context *vswc = vmw_svga_winsys_context(swc);
+ unsigned i;
+
+ for(i = 0; i < vswc->region.used; ++i) {
+ pb_reference(&vswc->region.relocs[i].buffer, NULL);
+ }
+
+ for(i = 0; i < vswc->surface.used; ++i) {
+ p_atomic_dec(&vswc->surface.handles[i]->validated);
+ vmw_svga_winsys_surface_reference(&vswc->surface.handles[i], NULL);
+ }
+ pb_validate_destroy(vswc->validate);
+ vmw_ioctl_context_destroy(vswc->vws, swc->cid);
+ FREE(vswc);
+}
+
+
+struct svga_winsys_context *
+vmw_svga_winsys_context_create(struct svga_winsys_screen *sws)
+{
+ struct vmw_winsys_screen *vws = vmw_winsys_screen(sws);
+ struct vmw_svga_winsys_context *vswc;
+
+ vswc = CALLOC_STRUCT(vmw_svga_winsys_context);
+ if(!vswc)
+ return NULL;
+
+ vswc->base.destroy = vmw_swc_destroy;
+ vswc->base.reserve = vmw_swc_reserve;
+ vswc->base.surface_relocation = vmw_swc_surface_relocation;
+ vswc->base.region_relocation = vmw_swc_region_relocation;
+ vswc->base.commit = vmw_swc_commit;
+ vswc->base.flush = vmw_swc_flush;
+
+ vswc->base.cid = vmw_ioctl_context_create(vws);
+
+ vswc->vws = vws;
+
+ vswc->command.size = VMW_COMMAND_SIZE;
+ vswc->surface.size = VMW_SURFACE_RELOCS;
+ vswc->region.size = VMW_REGION_RELOCS;
+
+ vswc->validate = pb_validate_create();
+ if(!vswc->validate) {
+ FREE(vswc);
+ return NULL;
+ }
+
+ return &vswc->base;
+}
+
+
+void
+vmw_svga_context_set_throttling(struct pipe_context *pipe,
+ uint32_t throttle_us)
+{
+ struct svga_winsys_context *swc = svga_winsys_context(pipe);
+ struct vmw_svga_winsys_context *vswc = vmw_svga_winsys_context(swc);
+
+ vswc->throttle_us = throttle_us;
+ vswc->throttle_set = TRUE;
+}
diff --git a/src/gallium/winsys/svga/drm/vmw_context.h b/src/gallium/winsys/svga/drm/vmw_context.h
new file mode 100644
index 0000000000..aed8b93734
--- /dev/null
+++ b/src/gallium/winsys/svga/drm/vmw_context.h
@@ -0,0 +1,59 @@
+/**********************************************************
+ * Copyright 2009 VMware, Inc. 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, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ **********************************************************/
+
+/**
+ * @author Jose Fonseca <jfonseca@vmware.com>
+ */
+
+
+#ifndef VMW_CONTEXT_H_
+#define VMW_CONTEXT_H_
+
+#include "pipe/p_compiler.h"
+
+struct svga_winsys_screen;
+struct svga_winsys_context;
+struct pipe_context;
+struct pipe_screen;
+
+#define VMW_DEBUG 0
+
+#if VMW_DEBUG
+#define vmw_printf debug_printf
+#define VMW_FUNC debug_printf("%s\n", __FUNCTION__)
+#else
+#define VMW_FUNC
+#define vmw_printf(...)
+#endif
+
+
+struct svga_winsys_context *
+vmw_svga_winsys_context_create(struct svga_winsys_screen *sws);
+
+void
+vmw_svga_context_set_throttling(struct pipe_context *pipe,
+ uint32_t throttle_us);
+
+#endif /* VMW_CONTEXT_H_ */
diff --git a/src/gallium/winsys/svga/drm/vmw_fence.c b/src/gallium/winsys/svga/drm/vmw_fence.c
new file mode 100644
index 0000000000..873dd51166
--- /dev/null
+++ b/src/gallium/winsys/svga/drm/vmw_fence.c
@@ -0,0 +1,108 @@
+/**********************************************************
+ * Copyright 2009 VMware, Inc. 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, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ **********************************************************/
+
+
+#include "util/u_memory.h"
+#include "pipebuffer/pb_buffer_fenced.h"
+
+#include "vmw_screen.h"
+#include "vmw_fence.h"
+
+
+
+struct vmw_fence_ops
+{
+ struct pb_fence_ops base;
+
+ struct vmw_winsys_screen *vws;
+};
+
+
+static INLINE struct vmw_fence_ops *
+vmw_fence_ops(struct pb_fence_ops *ops)
+{
+ assert(ops);
+ return (struct vmw_fence_ops *)ops;
+}
+
+
+static void
+vmw_fence_ops_fence_reference(struct pb_fence_ops *ops,
+ struct pipe_fence_handle **ptr,
+ struct pipe_fence_handle *fence)
+{
+ *ptr = fence;
+}
+
+
+static int
+vmw_fence_ops_fence_signalled(struct pb_fence_ops *ops,
+ struct pipe_fence_handle *fence,
+ unsigned flag)
+{
+ struct vmw_winsys_screen *vws = vmw_fence_ops(ops)->vws;
+ (void)flag;
+ return vmw_ioctl_fence_signalled(vws, vmw_fence(fence));
+}
+
+
+static int
+vmw_fence_ops_fence_finish(struct pb_fence_ops *ops,
+ struct pipe_fence_handle *fence,
+ unsigned flag)
+{
+ struct vmw_winsys_screen *vws = vmw_fence_ops(ops)->vws;
+ (void)flag;
+ return vmw_ioctl_fence_finish(vws, vmw_fence(fence));
+}
+
+
+static void
+vmw_fence_ops_destroy(struct pb_fence_ops *ops)
+{
+ FREE(ops);
+}
+
+
+struct pb_fence_ops *
+vmw_fence_ops_create(struct vmw_winsys_screen *vws)
+{
+ struct vmw_fence_ops *ops;
+
+ ops = CALLOC_STRUCT(vmw_fence_ops);
+ if(!ops)
+ return NULL;
+
+ ops->base.destroy = &vmw_fence_ops_destroy;
+ ops->base.fence_reference = &vmw_fence_ops_fence_reference;
+ ops->base.fence_signalled = &vmw_fence_ops_fence_signalled;
+ ops->base.fence_finish = &vmw_fence_ops_fence_finish;
+
+ ops->vws = vws;
+
+ return &ops->base;
+}
+
+
diff --git a/src/gallium/winsys/svga/drm/vmw_fence.h b/src/gallium/winsys/svga/drm/vmw_fence.h
new file mode 100644
index 0000000000..5357b4f61d
--- /dev/null
+++ b/src/gallium/winsys/svga/drm/vmw_fence.h
@@ -0,0 +1,59 @@
+/**********************************************************
+ * Copyright 2009 VMware, Inc. 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, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ **********************************************************/
+
+
+#ifndef VMW_FENCE_H_
+#define VMW_FENCE_H_
+
+
+#include "pipe/p_compiler.h"
+
+
+struct pipe_fence_handle;
+struct pb_fence_ops;
+struct vmw_winsys_screen;
+
+
+/** Cast from a pipe_fence_handle pointer into a SVGA fence */
+static INLINE uint32_t
+vmw_fence( struct pipe_fence_handle *fence )
+{
+ return (uint32_t)(uintptr_t)fence;
+}
+
+
+/** Cast from a SVGA fence number to pipe_fence_handle pointer */
+static INLINE struct pipe_fence_handle *
+vmw_pipe_fence( uint32_t fence )
+{
+ return (struct pipe_fence_handle *)(uintptr_t)fence;
+}
+
+
+struct pb_fence_ops *
+vmw_fence_ops_create(struct vmw_winsys_screen *vws);
+
+
+#endif /* VMW_FENCE_H_ */
diff --git a/src/gallium/winsys/svga/drm/vmw_screen.c b/src/gallium/winsys/svga/drm/vmw_screen.c
new file mode 100644
index 0000000000..51a4c55e5a
--- /dev/null
+++ b/src/gallium/winsys/svga/drm/vmw_screen.c
@@ -0,0 +1,87 @@
+/**********************************************************
+ * Copyright 2009 VMware, Inc. 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, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ **********************************************************/
+
+
+#include "vmw_screen.h"
+
+#include "vmw_context.h"
+
+#include "util/u_memory.h"
+#include "pipe/p_compiler.h"
+
+
+/* Called from vmw_drm_create_screen(), creates and initializes the
+ * vmw_winsys_screen structure, which is the main entity in this
+ * module.
+ */
+struct vmw_winsys_screen *
+vmw_winsys_create( int fd, boolean use_old_scanout_flag )
+{
+ struct vmw_winsys_screen *vws = CALLOC_STRUCT(vmw_winsys_screen);
+ if (!vws)
+ goto out_no_vws;
+
+ vws->ioctl.drm_fd = fd;
+ vws->use_old_scanout_flag = use_old_scanout_flag;
+ debug_printf("%s: use_old_scanout_flag == %s\n", __FUNCTION__,
+ use_old_scanout_flag ? "true" : "false");
+
+ if (!vmw_ioctl_init(vws))
+ goto out_no_ioctl;
+
+ if(!vmw_pools_init(vws))
+ goto out_no_pools;
+
+ if (!vmw_winsys_screen_init_svga(vws))
+ goto out_no_svga;
+
+ return vws;
+out_no_svga:
+ vmw_pools_cleanup(vws);
+out_no_pools:
+ vmw_ioctl_cleanup(vws);
+out_no_ioctl:
+ FREE(vws);
+out_no_vws:
+ return NULL;
+}
+
+void
+vmw_winsys_destroy(struct vmw_winsys_screen *vws)
+{
+ vmw_pools_cleanup(vws);
+ vmw_ioctl_cleanup(vws);
+ FREE(vws);
+}
+
+void
+vmw_winsys_screen_set_throttling(struct pipe_screen *screen,
+ uint32_t throttle_us)
+{
+ struct vmw_winsys_screen *vws =
+ vmw_winsys_screen(svga_winsys_screen(screen));
+
+ vws->default_throttle_us = throttle_us;
+}
diff --git a/src/gallium/winsys/svga/drm/vmw_screen.h b/src/gallium/winsys/svga/drm/vmw_screen.h
new file mode 100644
index 0000000000..b3de72df88
--- /dev/null
+++ b/src/gallium/winsys/svga/drm/vmw_screen.h
@@ -0,0 +1,144 @@
+/**********************************************************
+ * Copyright 2009 VMware, Inc. 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, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ **********************************************************/
+
+/**
+ * @file
+ * Common definitions for the VMware SVGA winsys.
+ *
+ * @author Jose Fonseca <jfonseca@vmware.com>
+ */
+
+
+#ifndef VMW_SCREEN_H_
+#define VMW_SCREEN_H_
+
+
+#include "pipe/p_compiler.h"
+#include "pipe/p_state.h"
+
+#include "svga_winsys.h"
+
+
+#define VMW_GMR_POOL_SIZE (16*1024*1024)
+
+
+struct pb_manager;
+struct vmw_region;
+
+
+struct vmw_winsys_screen
+{
+ struct svga_winsys_screen base;
+
+ boolean use_old_scanout_flag;
+ uint32_t default_throttle_us;
+
+ struct {
+ volatile uint32_t *fifo_map;
+ uint64_t last_fence;
+ int drm_fd;
+ } ioctl;
+
+ struct {
+ struct pb_manager *gmr;
+ struct pb_manager *gmr_mm;
+ struct pb_manager *gmr_fenced;
+ } pools;
+};
+
+
+static INLINE struct vmw_winsys_screen *
+vmw_winsys_screen(struct svga_winsys_screen *base)
+{
+ return (struct vmw_winsys_screen *)base;
+}
+
+/* */
+uint32
+vmw_ioctl_context_create(struct vmw_winsys_screen *vws);
+
+void
+vmw_ioctl_context_destroy(struct vmw_winsys_screen *vws,
+ uint32 cid);
+
+uint32
+vmw_ioctl_surface_create(struct vmw_winsys_screen *vws,
+ SVGA3dSurfaceFlags flags,
+ SVGA3dSurfaceFormat format,
+ SVGA3dSize size,
+ uint32 numFaces,
+ uint32 numMipLevels);
+
+void
+vmw_ioctl_surface_destroy(struct vmw_winsys_screen *vws,
+ uint32 sid);
+
+void
+vmw_ioctl_command(struct vmw_winsys_screen *vws,
+ int32_t cid,
+ uint32_t throttle_us,
+ void *commands,
+ uint32_t size,
+ uint32_t *fence);
+
+struct vmw_region *
+vmw_ioctl_region_create(struct vmw_winsys_screen *vws, uint32_t size);
+
+void
+vmw_ioctl_region_destroy(struct vmw_region *region);
+
+struct SVGAGuestPtr
+vmw_ioctl_region_ptr(struct vmw_region *region);
+
+void *
+vmw_ioctl_region_map(struct vmw_region *region);
+void
+vmw_ioctl_region_unmap(struct vmw_region *region);
+
+
+int
+vmw_ioctl_fence_finish(struct vmw_winsys_screen *vws,
+ uint32_t fence);
+
+int
+vmw_ioctl_fence_signalled(struct vmw_winsys_screen *vws,
+ uint32_t fence);
+
+
+/* Initialize parts of vmw_winsys_screen at startup:
+ */
+boolean vmw_ioctl_init(struct vmw_winsys_screen *vws);
+boolean vmw_pools_init(struct vmw_winsys_screen *vws);
+boolean vmw_winsys_screen_init_svga(struct vmw_winsys_screen *vws);
+
+void vmw_ioctl_cleanup(struct vmw_winsys_screen *vws);
+void vmw_pools_cleanup(struct vmw_winsys_screen *vws);
+
+struct vmw_winsys_screen *vmw_winsys_create(int fd, boolean use_old_scanout_flag);
+void vmw_winsys_destroy(struct vmw_winsys_screen *sws);
+void vmw_winsys_screen_set_throttling(struct pipe_screen *screen,
+ uint32_t throttle_us);
+
+#endif /* VMW_SCREEN_H_ */
diff --git a/src/gallium/winsys/svga/drm/vmw_screen_dri.c b/src/gallium/winsys/svga/drm/vmw_screen_dri.c
new file mode 100644
index 0000000000..fe28522691
--- /dev/null
+++ b/src/gallium/winsys/svga/drm/vmw_screen_dri.c
@@ -0,0 +1,267 @@
+/**********************************************************
+ * Copyright 2009 VMware, Inc. 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, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ **********************************************************/
+
+
+#include "pipe/p_compiler.h"
+#include "util/u_inlines.h"
+#include "util/u_memory.h"
+#include "util/u_format.h"
+#include "vmw_screen.h"
+
+#include "trace/tr_drm.h"
+
+#include "vmw_screen.h"
+#include "vmw_surface.h"
+#include "vmw_fence.h"
+#include "vmw_context.h"
+
+#include <state_tracker/drm_api.h>
+#include "vmwgfx_drm.h"
+#include <xf86drm.h>
+
+#include <stdio.h>
+
+struct dri1_api_version {
+ int major;
+ int minor;
+ int patch_level;
+};
+
+static struct svga_winsys_surface *
+vmw_drm_surface_from_handle(struct svga_winsys_screen *sws,
+ struct winsys_handle *whandle,
+ SVGA3dSurfaceFormat *format);
+static boolean
+vmw_drm_surface_get_handle(struct svga_winsys_screen *sws,
+ struct svga_winsys_surface *surface,
+ unsigned stride,
+ struct winsys_handle *whandle);
+
+static struct dri1_api_version drm_required = { 1, 0, 0 };
+static struct dri1_api_version drm_compat = { 1, 0, 0 };
+static struct dri1_api_version drm_scanout = { 0, 9, 0 };
+
+static boolean
+vmw_dri1_check_version(const struct dri1_api_version *cur,
+ const struct dri1_api_version *required,
+ const struct dri1_api_version *compat,
+ const char component[])
+{
+ if (cur->major > required->major && cur->major <= compat->major)
+ return TRUE;
+ if (cur->major == required->major && cur->minor >= required->minor)
+ return TRUE;
+
+ fprintf(stderr, "%s version failure.\n", component);
+ fprintf(stderr, "%s version is %d.%d.%d and this driver can only work\n"
+ "with versions %d.%d.x through %d.x.x.\n",
+ component,
+ cur->major,
+ cur->minor,
+ cur->patch_level, required->major, required->minor, compat->major);
+ return FALSE;
+}
+
+/* This is actually the entrypoint to the entire driver, called by the
+ * libGL (or EGL, or ...) code via the drm_api_hooks table at the
+ * bottom of the file.
+ */
+static struct pipe_screen *
+vmw_drm_create_screen(struct drm_api *drm_api, int fd)
+{
+ struct vmw_winsys_screen *vws;
+ struct pipe_screen *screen;
+ boolean use_old_scanout_flag = FALSE;
+
+ struct dri1_api_version drm_ver;
+ drmVersionPtr ver;
+
+ ver = drmGetVersion(fd);
+ if (ver == NULL)
+ return NULL;
+
+ drm_ver.major = ver->version_major;
+ drm_ver.minor = ver->version_minor;
+ drm_ver.patch_level = 0; /* ??? */
+
+ drmFreeVersion(ver);
+ if (!vmw_dri1_check_version(&drm_ver, &drm_required,
+ &drm_compat, "vmwgfx drm driver"))
+ return NULL;
+
+ if (!vmw_dri1_check_version(&drm_ver, &drm_scanout,
+ &drm_compat, "use old scanout field (not a error)"))
+ use_old_scanout_flag = TRUE;
+
+ vws = vmw_winsys_create( fd, use_old_scanout_flag );
+ if (!vws)
+ goto out_no_vws;
+
+ /* XXX do this properly */
+ vws->base.surface_from_handle = vmw_drm_surface_from_handle;
+ vws->base.surface_get_handle = vmw_drm_surface_get_handle;
+
+ screen = svga_screen_create( &vws->base );
+ if (!screen)
+ goto out_no_screen;
+
+ return screen;
+
+ /* Failure cases:
+ */
+out_no_screen:
+ vmw_winsys_destroy( vws );
+
+out_no_vws:
+ return NULL;
+}
+
+static INLINE boolean
+vmw_dri1_intersect_src_bbox(struct drm_clip_rect *dst,
+ int dst_x,
+ int dst_y,
+ const struct drm_clip_rect *src,
+ const struct drm_clip_rect *bbox)
+{
+ int xy1;
+ int xy2;
+
+ xy1 = ((int)src->x1 > (int)bbox->x1 + dst_x) ? src->x1 :
+ (int)bbox->x1 + dst_x;
+ xy2 = ((int)src->x2 < (int)bbox->x2 + dst_x) ? src->x2 :
+ (int)bbox->x2 + dst_x;
+ if (xy1 >= xy2 || xy1 < 0)
+ return FALSE;
+
+ dst->x1 = xy1;
+ dst->x2 = xy2;
+
+ xy1 = ((int)src->y1 > (int)bbox->y1 + dst_y) ? src->y1 :
+ (int)bbox->y1 + dst_y;
+ xy2 = ((int)src->y2 < (int)bbox->y2 + dst_y) ? src->y2 :
+ (int)bbox->y2 + dst_y;
+ if (xy1 >= xy2 || xy1 < 0)
+ return FALSE;
+
+ dst->y1 = xy1;
+ dst->y2 = xy2;
+ return TRUE;
+}
+
+static struct svga_winsys_surface *
+vmw_drm_surface_from_handle(struct svga_winsys_screen *sws,
+ struct winsys_handle *whandle,
+ SVGA3dSurfaceFormat *format)
+{
+ struct vmw_svga_winsys_surface *vsrf;
+ struct svga_winsys_surface *ssrf;
+ struct vmw_winsys_screen *vws = vmw_winsys_screen(sws);
+ union drm_vmw_surface_reference_arg arg;
+ struct drm_vmw_surface_arg *req = &arg.req;
+ struct drm_vmw_surface_create_req *rep = &arg.rep;
+ int ret;
+ int i;
+
+ /**
+ * The vmware device specific handle is the hardware SID.
+ * FIXME: We probably want to move this to the ioctl implementations.
+ */
+
+ memset(&arg, 0, sizeof(arg));
+ req->sid = whandle->handle;
+
+ ret = drmCommandWriteRead(vws->ioctl.drm_fd, DRM_VMW_REF_SURFACE,
+ &arg, sizeof(arg));
+
+ if (ret) {
+ fprintf(stderr, "Failed referencing shared surface. SID %d.\n"
+ "Error %d (%s).\n",
+ whandle->handle, ret, strerror(-ret));
+ return NULL;
+ }
+
+ if (rep->mip_levels[0] != 1) {
+ fprintf(stderr, "Incorrect number of mipmap levels on shared surface."
+ " SID %d, levels %d\n",
+ whandle->handle, rep->mip_levels[0]);
+ goto out_mip;
+ }
+
+ for (i=1; i < DRM_VMW_MAX_SURFACE_FACES; ++i) {
+ if (rep->mip_levels[i] != 0) {
+ fprintf(stderr, "Incorrect number of faces levels on shared surface."
+ " SID %d, face %d present.\n",
+ whandle->handle, i);
+ goto out_mip;
+ }
+ }
+
+ vsrf = CALLOC_STRUCT(vmw_svga_winsys_surface);
+ if (!vsrf)
+ goto out_mip;
+
+ pipe_reference_init(&vsrf->refcnt, 1);
+ p_atomic_set(&vsrf->validated, 0);
+ vsrf->screen = vws;
+ vsrf->sid = whandle->handle;
+ ssrf = svga_winsys_surface(vsrf);
+ *format = rep->format;
+
+ return ssrf;
+
+out_mip:
+ vmw_ioctl_surface_destroy(vws, whandle->handle);
+ return NULL;
+}
+
+static boolean
+vmw_drm_surface_get_handle(struct svga_winsys_screen *sws,
+ struct svga_winsys_surface *surface,
+ unsigned stride,
+ struct winsys_handle *whandle)
+{
+ struct vmw_svga_winsys_surface *vsrf;
+
+ if (!surface)
+ return FALSE;
+
+ vsrf = vmw_svga_winsys_surface(surface);
+ whandle->handle = vsrf->sid;
+ whandle->stride = stride;
+
+ return TRUE;
+}
+
+static struct drm_api vmw_drm_api_hooks = {
+ .name = "vmwgfx",
+ .driver_name = "vmwgfx",
+ .create_screen = vmw_drm_create_screen,
+ .destroy = NULL,
+};
+
+struct drm_api* drm_api_create()
+{
+ return trace_drm_create(&vmw_drm_api_hooks);
+}
diff --git a/src/gallium/winsys/svga/drm/vmw_screen_ioctl.c b/src/gallium/winsys/svga/drm/vmw_screen_ioctl.c
new file mode 100644
index 0000000000..d92ba389d3
--- /dev/null
+++ b/src/gallium/winsys/svga/drm/vmw_screen_ioctl.c
@@ -0,0 +1,531 @@
+/**********************************************************
+ * Copyright 2009 VMware, Inc. 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, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ **********************************************************/
+
+/**
+ * @file
+ *
+ * Wrappers for DRM ioctl functionlaity used by the rest of the vmw
+ * drm winsys.
+ *
+ * Based on svgaicd_escape.c
+ */
+
+
+#include "svga_cmd.h"
+#include "util/u_memory.h"
+#include "util/u_math.h"
+#include "svgadump/svga_dump.h"
+#include "vmw_screen.h"
+#include "vmw_context.h"
+#include "xf86drm.h"
+#include "vmwgfx_drm.h"
+
+#include <sys/mman.h>
+#include <errno.h>
+#include <unistd.h>
+
+struct vmw_region
+{
+ SVGAGuestPtr ptr;
+ uint32_t handle;
+ uint64_t map_handle;
+ void *data;
+ uint32_t map_count;
+ int drm_fd;
+ uint32_t size;
+};
+
+/* XXX: This isn't a real hardware flag, but just a hack for kernel to
+ * know about primary surfaces. In newer versions of the kernel
+ * interface the driver uses a special field.
+ */
+#define SVGA3D_SURFACE_HINT_SCANOUT (1 << 9)
+
+static void
+vmw_check_last_cmd(struct vmw_winsys_screen *vws)
+{
+ static uint32_t buffer[16384];
+ struct drm_vmw_fifo_debug_arg arg;
+ int ret;
+
+ return;
+ memset(&arg, 0, sizeof(arg));
+ arg.debug_buffer = (unsigned long)buffer;
+ arg.debug_buffer_size = 65536;
+
+ ret = drmCommandWriteRead(vws->ioctl.drm_fd, DRM_VMW_FIFO_DEBUG,
+ &arg, sizeof(arg));
+
+ if (ret) {
+ debug_printf("%s Ioctl error: \"%s\".\n", __FUNCTION__, strerror(-ret));
+ return;
+ }
+
+ if (arg.did_not_fit) {
+ debug_printf("%s Command did not fit completely.\n", __FUNCTION__);
+ }
+
+ svga_dump_commands(buffer, arg.used_size);
+}
+
+static void
+vmw_ioctl_fifo_unmap(struct vmw_winsys_screen *vws, void *mapping)
+{
+ VMW_FUNC;
+ (void)munmap(mapping, getpagesize());
+}
+
+
+static void *
+vmw_ioctl_fifo_map(struct vmw_winsys_screen *vws,
+ uint32_t fifo_offset )
+{
+ void *map;
+
+ VMW_FUNC;
+
+ map = mmap(NULL, getpagesize(), PROT_READ, MAP_SHARED,
+ vws->ioctl.drm_fd, fifo_offset);
+
+ if (map == MAP_FAILED) {
+ debug_printf("Map failed %s\n", strerror(errno));
+ return NULL;
+ }
+
+ vmw_printf("Fifo (min) is 0x%08x\n", ((uint32_t *) map)[SVGA_FIFO_MIN]);
+
+ return map;
+}
+
+uint32
+vmw_ioctl_context_create(struct vmw_winsys_screen *vws)
+{
+ struct drm_vmw_context_arg c_arg;
+ int ret;
+
+ VMW_FUNC;
+
+ ret = drmCommandRead(vws->ioctl.drm_fd, DRM_VMW_CREATE_CONTEXT,
+ &c_arg, sizeof(c_arg));
+
+ if (ret)
+ return -1;
+
+ vmw_check_last_cmd(vws);
+ vmw_printf("Context id is %d\n", c_arg.cid);
+
+ return c_arg.cid;
+}
+
+void
+vmw_ioctl_context_destroy(struct vmw_winsys_screen *vws, uint32 cid)
+{
+ struct drm_vmw_context_arg c_arg;
+
+ VMW_FUNC;
+
+ memset(&c_arg, 0, sizeof(c_arg));
+ c_arg.cid = cid;
+
+ (void)drmCommandWrite(vws->ioctl.drm_fd, DRM_VMW_UNREF_CONTEXT,
+ &c_arg, sizeof(c_arg));
+
+ vmw_check_last_cmd(vws);
+}
+
+uint32
+vmw_ioctl_surface_create(struct vmw_winsys_screen *vws,
+ SVGA3dSurfaceFlags flags,
+ SVGA3dSurfaceFormat format,
+ SVGA3dSize size,
+ uint32_t numFaces, uint32_t numMipLevels)
+{
+ union drm_vmw_surface_create_arg s_arg;
+ struct drm_vmw_surface_create_req *req = &s_arg.req;
+ struct drm_vmw_surface_arg *rep = &s_arg.rep;
+ struct drm_vmw_size sizes[DRM_VMW_MAX_SURFACE_FACES*
+ DRM_VMW_MAX_MIP_LEVELS];
+ struct drm_vmw_size *cur_size;
+ uint32_t iFace;
+ uint32_t iMipLevel;
+ int ret;
+
+ vmw_printf("%s flags %d format %d\n", __FUNCTION__, flags, format);
+
+ memset(&s_arg, 0, sizeof(s_arg));
+ if (vws->use_old_scanout_flag &&
+ (flags & SVGA3D_SURFACE_HINT_SCANOUT)) {
+ req->flags = (uint32_t) flags;
+ req->scanout = false;
+ } else if (flags & SVGA3D_SURFACE_HINT_SCANOUT) {
+ req->flags = (uint32_t) (flags & ~SVGA3D_SURFACE_HINT_SCANOUT);
+ req->scanout = true;
+ } else {
+ req->flags = (uint32_t) flags;
+ req->scanout = false;
+ }
+ req->format = (uint32_t) format;
+ req->shareable = 1;
+
+ assert(numFaces * numMipLevels < DRM_VMW_MAX_SURFACE_FACES*
+ DRM_VMW_MAX_MIP_LEVELS);
+ cur_size = sizes;
+ for (iFace = 0; iFace < numFaces; ++iFace) {
+ SVGA3dSize mipSize = size;
+
+ req->mip_levels[iFace] = numMipLevels;
+ for (iMipLevel = 0; iMipLevel < numMipLevels; ++iMipLevel) {
+ cur_size->width = mipSize.width;
+ cur_size->height = mipSize.height;
+ cur_size->depth = mipSize.depth;
+ mipSize.width = MAX2(mipSize.width >> 1, 1);
+ mipSize.height = MAX2(mipSize.height >> 1, 1);
+ mipSize.depth = MAX2(mipSize.depth >> 1, 1);
+ cur_size++;
+ }
+ }
+ for (iFace = numFaces; iFace < SVGA3D_MAX_SURFACE_FACES; ++iFace) {
+ req->mip_levels[iFace] = 0;
+ }
+
+ req->size_addr = (unsigned long)&sizes;
+
+ ret = drmCommandWriteRead(vws->ioctl.drm_fd, DRM_VMW_CREATE_SURFACE,
+ &s_arg, sizeof(s_arg));
+
+ if (ret)
+ return -1;
+
+ vmw_printf("Surface id is %d\n", rep->sid);
+ vmw_check_last_cmd(vws);
+
+ return rep->sid;
+}
+
+void
+vmw_ioctl_surface_destroy(struct vmw_winsys_screen *vws, uint32 sid)
+{
+ struct drm_vmw_surface_arg s_arg;
+
+ VMW_FUNC;
+
+ memset(&s_arg, 0, sizeof(s_arg));
+ s_arg.sid = sid;
+
+ (void)drmCommandWrite(vws->ioctl.drm_fd, DRM_VMW_UNREF_SURFACE,
+ &s_arg, sizeof(s_arg));
+ vmw_check_last_cmd(vws);
+
+}
+
+void
+vmw_ioctl_command(struct vmw_winsys_screen *vws, int32_t cid,
+ uint32_t throttle_us, void *commands, uint32_t size,
+ uint32_t *pfence)
+{
+ struct drm_vmw_execbuf_arg arg;
+ struct drm_vmw_fence_rep rep;
+ int ret;
+
+#ifdef DEBUG
+ {
+ static boolean firsttime = TRUE;
+ static boolean debug = FALSE;
+ static boolean skip = FALSE;
+ if (firsttime) {
+ debug = debug_get_bool_option("SVGA_DUMP_CMD", FALSE);
+ skip = debug_get_bool_option("SVGA_SKIP_CMD", FALSE);
+ }
+ if (debug) {
+ VMW_FUNC;
+ svga_dump_commands(commands, size);
+ }
+ firsttime = FALSE;
+ if (skip) {
+ size = 0;
+ }
+ }
+#endif
+
+ memset(&arg, 0, sizeof(arg));
+ memset(&rep, 0, sizeof(rep));
+
+ rep.error = -EFAULT;
+ arg.fence_rep = (unsigned long)&rep;
+ arg.commands = (unsigned long)commands;
+ arg.command_size = size;
+ arg.throttle_us = throttle_us;
+
+ do {
+ ret = drmCommandWrite(vws->ioctl.drm_fd, DRM_VMW_EXECBUF, &arg, sizeof(arg));
+ } while(ret == -ERESTART);
+ if (ret) {
+ debug_printf("%s error %s.\n", __FUNCTION__, strerror(-ret));
+ }
+ if (rep.error) {
+
+ /*
+ * Kernel has synced and put the last fence sequence in the FIFO
+ * register.
+ */
+
+ if (rep.error == -EFAULT)
+ rep.fence_seq = vws->ioctl.fifo_map[SVGA_FIFO_FENCE];
+
+ debug_printf("%s Fence error %s.\n", __FUNCTION__,
+ strerror(-rep.error));
+ }
+
+ vws->ioctl.last_fence = rep.fence_seq;
+
+ if (pfence)
+ *pfence = rep.fence_seq;
+ vmw_check_last_cmd(vws);
+
+}
+
+
+struct vmw_region *
+vmw_ioctl_region_create(struct vmw_winsys_screen *vws, uint32_t size)
+{
+ struct vmw_region *region;
+ union drm_vmw_alloc_dmabuf_arg arg;
+ struct drm_vmw_alloc_dmabuf_req *req = &arg.req;
+ struct drm_vmw_dmabuf_rep *rep = &arg.rep;
+ int ret;
+
+ vmw_printf("%s: size = %u\n", __FUNCTION__, size);
+
+ region = CALLOC_STRUCT(vmw_region);
+ if (!region)
+ goto out_err1;
+
+ memset(&arg, 0, sizeof(arg));
+ req->size = size;
+ do {
+ ret = drmCommandWriteRead(vws->ioctl.drm_fd, DRM_VMW_ALLOC_DMABUF, &arg,
+ sizeof(arg));
+ } while (ret == -ERESTART);
+
+ if (ret) {
+ debug_printf("IOCTL failed %d: %s\n", ret, strerror(-ret));
+ goto out_err1;
+ }
+
+ region->ptr.gmrId = rep->cur_gmr_id;
+ region->ptr.offset = rep->cur_gmr_offset;
+ region->data = NULL;
+ region->handle = rep->handle;
+ region->map_handle = rep->map_handle;
+ region->map_count = 0;
+ region->size = size;
+ region->drm_fd = vws->ioctl.drm_fd;
+
+ vmw_printf(" gmrId = %u, offset = %u\n",
+ region->ptr.gmrId, region->ptr.offset);
+
+ return region;
+
+ out_err1:
+ FREE(region);
+ return NULL;
+}
+
+void
+vmw_ioctl_region_destroy(struct vmw_region *region)
+{
+ struct drm_vmw_unref_dmabuf_arg arg;
+
+ vmw_printf("%s: gmrId = %u, offset = %u\n", __FUNCTION__,
+ region->ptr.gmrId, region->ptr.offset);
+
+ if (region->data) {
+ munmap(region->data, region->size);
+ region->data = NULL;
+ }
+
+ memset(&arg, 0, sizeof(arg));
+ arg.handle = region->handle;
+ drmCommandWrite(region->drm_fd, DRM_VMW_UNREF_DMABUF, &arg, sizeof(arg));
+
+ FREE(region);
+}
+
+SVGAGuestPtr
+vmw_ioctl_region_ptr(struct vmw_region *region)
+{
+ return region->ptr;
+}
+
+void *
+vmw_ioctl_region_map(struct vmw_region *region)
+{
+ void *map;
+
+ vmw_printf("%s: gmrId = %u, offset = %u\n", __FUNCTION__,
+ region->ptr.gmrId, region->ptr.offset);
+
+ if (region->data == NULL) {
+ map = mmap(NULL, region->size, PROT_READ | PROT_WRITE, MAP_SHARED,
+ region->drm_fd, region->map_handle);
+ if (map == MAP_FAILED) {
+ debug_printf("%s: Map failed.\n", __FUNCTION__);
+ return NULL;
+ }
+
+ region->data = map;
+ }
+
+ ++region->map_count;
+
+ return region->data;
+}
+
+void
+vmw_ioctl_region_unmap(struct vmw_region *region)
+{
+ vmw_printf("%s: gmrId = %u, offset = %u\n", __FUNCTION__,
+ region->ptr.gmrId, region->ptr.offset);
+ --region->map_count;
+}
+
+
+int
+vmw_ioctl_fence_signalled(struct vmw_winsys_screen *vws,
+ uint32_t fence)
+{
+ uint32_t expected;
+ uint32_t current;
+
+ assert(fence);
+ if(!fence)
+ return 0;
+
+ expected = fence;
+ current = vws->ioctl.fifo_map[SVGA_FIFO_FENCE];
+
+ if ((int32)(current - expected) >= 0)
+ return 0; /* fence passed */
+ else
+ return -1;
+}
+
+
+static void
+vmw_ioctl_sync(struct vmw_winsys_screen *vws,
+ uint32_t fence)
+{
+ uint32_t cur_fence;
+ struct drm_vmw_fence_wait_arg arg;
+ int ret;
+
+ vmw_printf("%s: fence = %lu\n", __FUNCTION__,
+ (unsigned long)fence);
+
+ cur_fence = vws->ioctl.fifo_map[SVGA_FIFO_FENCE];
+ vmw_printf("%s: Fence id read is 0x%08x\n", __FUNCTION__,
+ (unsigned int)cur_fence);
+
+ if ((cur_fence - fence) < (1 << 24))
+ return;
+
+ memset(&arg, 0, sizeof(arg));
+ arg.sequence = fence;
+
+ do {
+ ret = drmCommandWriteRead(vws->ioctl.drm_fd, DRM_VMW_FENCE_WAIT, &arg,
+ sizeof(arg));
+ } while (ret == -ERESTART);
+}
+
+
+int
+vmw_ioctl_fence_finish(struct vmw_winsys_screen *vws,
+ uint32_t fence)
+{
+ assert(fence);
+
+ if(fence) {
+ if(vmw_ioctl_fence_signalled(vws, fence) != 0) {
+ vmw_ioctl_sync(vws, fence);
+ }
+ }
+
+ return 0;
+}
+
+
+boolean
+vmw_ioctl_init(struct vmw_winsys_screen *vws)
+{
+ struct drm_vmw_getparam_arg gp_arg;
+ int ret;
+
+ VMW_FUNC;
+
+ memset(&gp_arg, 0, sizeof(gp_arg));
+ gp_arg.param = DRM_VMW_PARAM_3D;
+ ret = drmCommandWriteRead(vws->ioctl.drm_fd, DRM_VMW_GET_PARAM,
+ &gp_arg, sizeof(gp_arg));
+ if (ret || gp_arg.value == 0) {
+ debug_printf("No 3D enabled (%i, %s)\n", ret, strerror(-ret));
+ goto out_err1;
+ }
+
+ memset(&gp_arg, 0, sizeof(gp_arg));
+ gp_arg.param = DRM_VMW_PARAM_FIFO_OFFSET;
+ ret = drmCommandWriteRead(vws->ioctl.drm_fd, DRM_VMW_GET_PARAM,
+ &gp_arg, sizeof(gp_arg));
+
+ if (ret) {
+ debug_printf("GET_PARAM on %d returned %d: %s\n",
+ vws->ioctl.drm_fd, ret, strerror(-ret));
+ goto out_err1;
+ }
+
+ vmw_printf("Offset to map is 0x%08llx\n",
+ (unsigned long long)gp_arg.value);
+
+ vws->ioctl.fifo_map = vmw_ioctl_fifo_map(vws, gp_arg.value);
+ if (vws->ioctl.fifo_map == NULL)
+ goto out_err1;
+
+ vmw_printf("%s OK\n", __FUNCTION__);
+ return TRUE;
+
+ out_err1:
+ debug_printf("%s Failed\n", __FUNCTION__);
+ return FALSE;
+}
+
+
+
+void
+vmw_ioctl_cleanup(struct vmw_winsys_screen *vws)
+{
+ VMW_FUNC;
+
+ vmw_ioctl_fifo_unmap(vws, (void *)vws->ioctl.fifo_map);
+}
diff --git a/src/gallium/winsys/svga/drm/vmw_screen_pools.c b/src/gallium/winsys/svga/drm/vmw_screen_pools.c
new file mode 100644
index 0000000000..b9823d7857
--- /dev/null
+++ b/src/gallium/winsys/svga/drm/vmw_screen_pools.c
@@ -0,0 +1,97 @@
+/**********************************************************
+ * Copyright 2009 VMware, Inc. 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, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ **********************************************************/
+
+
+#include "vmw_screen.h"
+
+#include "vmw_buffer.h"
+#include "vmw_fence.h"
+
+#include "pipebuffer/pb_buffer.h"
+#include "pipebuffer/pb_bufmgr.h"
+
+void
+vmw_pools_cleanup(struct vmw_winsys_screen *vws)
+{
+ if(vws->pools.gmr_fenced)
+ vws->pools.gmr_fenced->destroy(vws->pools.gmr_fenced);
+
+ /* gmr_mm pool is already destroyed above */
+
+ if(vws->pools.gmr)
+ vws->pools.gmr->destroy(vws->pools.gmr);
+}
+
+
+boolean
+vmw_pools_init(struct vmw_winsys_screen *vws)
+{
+ vws->pools.gmr = vmw_gmr_bufmgr_create(vws);
+ if(!vws->pools.gmr)
+ goto error;
+
+ vws->pools.gmr_mm = mm_bufmgr_create(vws->pools.gmr,
+ VMW_GMR_POOL_SIZE,
+ 12 /* 4096 alignment */);
+ if(!vws->pools.gmr_mm)
+ goto error;
+
+ /*
+ * GMR buffers are typically shortlived, but it's possible that at a given
+ * instance a buffer is mapped. So to avoid stalling we tell pipebuffer to
+ * forbid creation of buffers beyond half the GMR pool size,
+ *
+ * XXX: It is unclear weather we want to limit the total amount of temporary
+ * malloc memory used to backup unvalidated GMR buffers. On one hand it is
+ * preferrable to fail an allocation than exhausting the guest memory with
+ * temporary data, but on the other hand it is possible that a stupid
+ * application creates large vertex buffers and does not use them for a long
+ * time -- since the svga pipe driver only emits the DMA uploads when a
+ * buffer is used for drawing this would effectively disabling swapping GMR
+ * buffers to memory. So far, the preemptively flush already seems to keep
+ * total allocated memory within relatively small numbers, so we don't
+ * limit.
+ */
+ vws->pools.gmr_fenced = fenced_bufmgr_create(
+ vws->pools.gmr_mm,
+ vmw_fence_ops_create(vws),
+ VMW_GMR_POOL_SIZE/2,
+ ~0);
+
+#ifdef DEBUG
+ vws->pools.gmr_fenced = pb_debug_manager_create(vws->pools.gmr_fenced,
+ 4096,
+ 4096);
+#endif
+ if(!vws->pools.gmr_fenced)
+ goto error;
+
+ return TRUE;
+
+error:
+ vmw_pools_cleanup(vws);
+ return FALSE;
+}
+
diff --git a/src/gallium/winsys/svga/drm/vmw_screen_svga.c b/src/gallium/winsys/svga/drm/vmw_screen_svga.c
new file mode 100644
index 0000000000..2b4e80f003
--- /dev/null
+++ b/src/gallium/winsys/svga/drm/vmw_screen_svga.c
@@ -0,0 +1,295 @@
+/**********************************************************
+ * Copyright 2009 VMware, Inc. 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, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ **********************************************************/
+
+/**
+ * @file
+ * This file implements the SVGA interface into this winsys, defined
+ * in drivers/svga/svga_winsys.h.
+ *
+ * @author Keith Whitwell
+ * @author Jose Fonseca
+ */
+
+
+#include "svga_cmd.h"
+#include "svga3d_caps.h"
+
+#include "util/u_inlines.h"
+#include "util/u_math.h"
+#include "util/u_memory.h"
+#include "pipebuffer/pb_buffer.h"
+#include "pipebuffer/pb_bufmgr.h"
+#include "svga_winsys.h"
+#include "vmw_context.h"
+#include "vmw_screen.h"
+#include "vmw_surface.h"
+#include "vmw_buffer.h"
+#include "vmw_fence.h"
+
+
+static struct svga_winsys_buffer *
+vmw_svga_winsys_buffer_create(struct svga_winsys_screen *sws,
+ unsigned alignment,
+ unsigned usage,
+ unsigned size)
+{
+ struct vmw_winsys_screen *vws = vmw_winsys_screen(sws);
+ struct pb_desc desc;
+ struct pb_manager *provider;
+ struct pb_buffer *buffer;
+
+ memset(&desc, 0, sizeof desc);
+ desc.alignment = alignment;
+ desc.usage = usage;
+
+ provider = vws->pools.gmr_fenced;
+
+ assert(provider);
+ buffer = provider->create_buffer(provider, size, &desc);
+ if(!buffer)
+ return NULL;
+
+ return vmw_svga_winsys_buffer(buffer);
+}
+
+
+static void *
+vmw_svga_winsys_buffer_map(struct svga_winsys_screen *sws,
+ struct svga_winsys_buffer *buf,
+ unsigned flags)
+{
+ (void)sws;
+ return pb_map(vmw_pb_buffer(buf), flags);
+}
+
+
+static void
+vmw_svga_winsys_buffer_unmap(struct svga_winsys_screen *sws,
+ struct svga_winsys_buffer *buf)
+{
+ (void)sws;
+ pb_unmap(vmw_pb_buffer(buf));
+}
+
+
+static void
+vmw_svga_winsys_buffer_destroy(struct svga_winsys_screen *sws,
+ struct svga_winsys_buffer *buf)
+{
+ struct pb_buffer *pbuf = vmw_pb_buffer(buf);
+ (void)sws;
+ pb_reference(&pbuf, NULL);
+}
+
+
+static void
+vmw_svga_winsys_fence_reference(struct svga_winsys_screen *sws,
+ struct pipe_fence_handle **pdst,
+ struct pipe_fence_handle *src)
+{
+ (void)sws;
+ *pdst = src;
+}
+
+
+static int
+vmw_svga_winsys_fence_signalled(struct svga_winsys_screen *sws,
+ struct pipe_fence_handle *fence,
+ unsigned flag)
+{
+ struct vmw_winsys_screen *vws = vmw_winsys_screen(sws);
+ (void)flag;
+ return vmw_ioctl_fence_signalled(vws, vmw_fence(fence));
+}
+
+
+static int
+vmw_svga_winsys_fence_finish(struct svga_winsys_screen *sws,
+ struct pipe_fence_handle *fence,
+ unsigned flag)
+{
+ struct vmw_winsys_screen *vws = vmw_winsys_screen(sws);
+ (void)flag;
+ return vmw_ioctl_fence_finish(vws, vmw_fence(fence));
+}
+
+
+
+static struct svga_winsys_surface *
+vmw_svga_winsys_surface_create(struct svga_winsys_screen *sws,
+ SVGA3dSurfaceFlags flags,
+ SVGA3dSurfaceFormat format,
+ SVGA3dSize size,
+ uint32 numFaces,
+ uint32 numMipLevels)
+{
+ struct vmw_winsys_screen *vws = vmw_winsys_screen(sws);
+ struct vmw_svga_winsys_surface *surface;
+
+ surface = CALLOC_STRUCT(vmw_svga_winsys_surface);
+ if(!surface)
+ goto no_surface;
+
+ pipe_reference_init(&surface->refcnt, 1);
+ p_atomic_set(&surface->validated, 0);
+ surface->screen = vws;
+ surface->sid = vmw_ioctl_surface_create(vws,
+ flags, format, size,
+ numFaces, numMipLevels);
+ if(surface->sid == SVGA3D_INVALID_ID)
+ goto no_sid;
+
+ return svga_winsys_surface(surface);
+
+no_sid:
+ FREE(surface);
+no_surface:
+ return NULL;
+}
+
+
+static boolean
+vmw_svga_winsys_surface_is_flushed(struct svga_winsys_screen *sws,
+ struct svga_winsys_surface *surface)
+{
+ struct vmw_svga_winsys_surface *vsurf = vmw_svga_winsys_surface(surface);
+ return (p_atomic_read(&vsurf->validated) == 0);
+}
+
+
+static void
+vmw_svga_winsys_surface_ref(struct svga_winsys_screen *sws,
+ struct svga_winsys_surface **pDst,
+ struct svga_winsys_surface *src)
+{
+ struct vmw_svga_winsys_surface *d_vsurf = vmw_svga_winsys_surface(*pDst);
+ struct vmw_svga_winsys_surface *s_vsurf = vmw_svga_winsys_surface(src);
+
+ vmw_svga_winsys_surface_reference(&d_vsurf, s_vsurf);
+ *pDst = svga_winsys_surface(d_vsurf);
+}
+
+
+static void
+vmw_svga_winsys_destroy(struct svga_winsys_screen *sws)
+{
+ struct vmw_winsys_screen *vws = vmw_winsys_screen(sws);
+
+ vmw_winsys_destroy(vws);
+}
+
+
+static boolean
+vmw_svga_winsys_get_cap(struct svga_winsys_screen *sws,
+ SVGA3dDevCapIndex index,
+ SVGA3dDevCapResult *result)
+{
+ struct vmw_winsys_screen *vws = vmw_winsys_screen(sws);
+ const uint32 *capsBlock;
+ const SVGA3dCapsRecord *capsRecord = NULL;
+ uint32 offset;
+ const SVGA3dCapPair *capArray;
+ int numCaps, first, last;
+
+ if(!vws->ioctl.fifo_map)
+ return FALSE;
+
+ if(vws->ioctl.fifo_map[SVGA_FIFO_3D_HWVERSION] < SVGA3D_HWVERSION_WS6_B1)
+ return FALSE;
+
+ /*
+ * Search linearly through the caps block records for the specified type.
+ */
+ capsBlock = (const uint32 *)&vws->ioctl.fifo_map[SVGA_FIFO_3D_CAPS];
+ for (offset = 0; capsBlock[offset] != 0; offset += capsBlock[offset]) {
+ const SVGA3dCapsRecord *record;
+ assert(offset < SVGA_FIFO_3D_CAPS_SIZE);
+ record = (const SVGA3dCapsRecord *) (capsBlock + offset);
+ if ((record->header.type >= SVGA3DCAPS_RECORD_DEVCAPS_MIN) &&
+ (record->header.type <= SVGA3DCAPS_RECORD_DEVCAPS_MAX) &&
+ (!capsRecord || (record->header.type > capsRecord->header.type))) {
+ capsRecord = record;
+ }
+ }
+
+ if(!capsRecord)
+ return FALSE;
+
+ /*
+ * Calculate the number of caps from the size of the record.
+ */
+ capArray = (const SVGA3dCapPair *) capsRecord->data;
+ numCaps = (int) ((capsRecord->header.length * sizeof(uint32) -
+ sizeof capsRecord->header) / (2 * sizeof(uint32)));
+
+ /*
+ * Binary-search for the cap with the specified index.
+ */
+ for (first = 0, last = numCaps - 1; first <= last; ) {
+ int mid = (first + last) / 2;
+
+ if ((SVGA3dDevCapIndex) capArray[mid][0] == index) {
+ /*
+ * Found it.
+ */
+ result->u = capArray[mid][1];
+ return TRUE;
+ }
+
+ /*
+ * Divide and conquer.
+ */
+ if ((SVGA3dDevCapIndex) capArray[mid][0] > index) {
+ last = mid - 1;
+ } else {
+ first = mid + 1;
+ }
+ }
+
+ return FALSE;
+}
+
+
+boolean
+vmw_winsys_screen_init_svga(struct vmw_winsys_screen *vws)
+{
+ vws->base.destroy = vmw_svga_winsys_destroy;
+ vws->base.get_cap = vmw_svga_winsys_get_cap;
+ vws->base.context_create = vmw_svga_winsys_context_create;
+ vws->base.surface_create = vmw_svga_winsys_surface_create;
+ vws->base.surface_is_flushed = vmw_svga_winsys_surface_is_flushed;
+ vws->base.surface_reference = vmw_svga_winsys_surface_ref;
+ vws->base.buffer_create = vmw_svga_winsys_buffer_create;
+ vws->base.buffer_map = vmw_svga_winsys_buffer_map;
+ vws->base.buffer_unmap = vmw_svga_winsys_buffer_unmap;
+ vws->base.buffer_destroy = vmw_svga_winsys_buffer_destroy;
+ vws->base.fence_reference = vmw_svga_winsys_fence_reference;
+ vws->base.fence_signalled = vmw_svga_winsys_fence_signalled;
+ vws->base.fence_finish = vmw_svga_winsys_fence_finish;
+
+ return TRUE;
+}
+
+
diff --git a/src/gallium/winsys/svga/drm/vmw_surface.c b/src/gallium/winsys/svga/drm/vmw_surface.c
new file mode 100644
index 0000000000..5f1b9ad577
--- /dev/null
+++ b/src/gallium/winsys/svga/drm/vmw_surface.c
@@ -0,0 +1,61 @@
+/**********************************************************
+ * Copyright 2009 VMware, Inc. 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, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ **********************************************************/
+
+
+#include "svga_cmd.h"
+#include "util/u_debug.h"
+#include "util/u_memory.h"
+
+#include "vmw_surface.h"
+#include "vmw_screen.h"
+
+void
+vmw_svga_winsys_surface_reference(struct vmw_svga_winsys_surface **pdst,
+ struct vmw_svga_winsys_surface *src)
+{
+ struct pipe_reference *src_ref;
+ struct pipe_reference *dst_ref;
+ struct vmw_svga_winsys_surface *dst;
+
+ if(pdst == NULL || *pdst == src)
+ return;
+
+ dst = *pdst;
+
+ src_ref = src ? &src->refcnt : NULL;
+ dst_ref = dst ? &dst->refcnt : NULL;
+
+ if (pipe_reference(dst_ref, src_ref)) {
+ vmw_ioctl_surface_destroy(dst->screen, dst->sid);
+#ifdef DEBUG
+ /* to detect dangling pointers */
+ assert(p_atomic_read(&dst->validated) == 0);
+ dst->sid = SVGA3D_INVALID_ID;
+#endif
+ FREE(dst);
+ }
+
+ *pdst = src;
+}
diff --git a/src/gallium/winsys/svga/drm/vmw_surface.h b/src/gallium/winsys/svga/drm/vmw_surface.h
new file mode 100644
index 0000000000..3d61595c28
--- /dev/null
+++ b/src/gallium/winsys/svga/drm/vmw_surface.h
@@ -0,0 +1,79 @@
+/**********************************************************
+ * Copyright 2009 VMware, Inc. 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, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ **********************************************************/
+
+/**
+ * @file
+ * Surfaces for VMware SVGA winsys.
+ *
+ * @author Jose Fonseca <jfonseca@vmware.com>
+ */
+
+
+#ifndef VMW_SURFACE_H_
+#define VMW_SURFACE_H_
+
+
+#include "pipe/p_compiler.h"
+#include "util/u_atomic.h"
+#include "util/u_inlines.h"
+
+#define VMW_MAX_PRESENTS 3
+
+
+
+struct vmw_svga_winsys_surface
+{
+ int32_t validated; /* atomic */
+ struct pipe_reference refcnt;
+
+ struct vmw_winsys_screen *screen;
+ uint32_t sid;
+
+ /* FIXME: make this thread safe */
+ unsigned next_present_no;
+ uint32_t present_fences[VMW_MAX_PRESENTS];
+};
+
+
+static INLINE struct svga_winsys_surface *
+svga_winsys_surface(struct vmw_svga_winsys_surface *surf)
+{
+ assert(!surf || surf->sid != SVGA3D_INVALID_ID);
+ return (struct svga_winsys_surface *)surf;
+}
+
+
+static INLINE struct vmw_svga_winsys_surface *
+vmw_svga_winsys_surface(struct svga_winsys_surface *surf)
+{
+ return (struct vmw_svga_winsys_surface *)surf;
+}
+
+
+void
+vmw_svga_winsys_surface_reference(struct vmw_svga_winsys_surface **pdst,
+ struct vmw_svga_winsys_surface *src);
+
+#endif /* VMW_SURFACE_H_ */
diff --git a/src/gallium/winsys/svga/drm/vmwgfx_drm.h b/src/gallium/winsys/svga/drm/vmwgfx_drm.h
new file mode 100644
index 0000000000..fbb1a8f9a2
--- /dev/null
+++ b/src/gallium/winsys/svga/drm/vmwgfx_drm.h
@@ -0,0 +1,571 @@
+/**************************************************************************
+ *
+ * Copyright © 2009 VMware, Inc., Palo Alto, CA., USA
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+#ifndef __VMWGFX_DRM_H__
+#define __VMWGFX_DRM_H__
+
+#define DRM_VMW_MAX_SURFACE_FACES 6
+#define DRM_VMW_MAX_MIP_LEVELS 24
+
+#define DRM_VMW_EXT_NAME_LEN 128
+
+#define DRM_VMW_GET_PARAM 0
+#define DRM_VMW_ALLOC_DMABUF 1
+#define DRM_VMW_UNREF_DMABUF 2
+#define DRM_VMW_CURSOR_BYPASS 3
+/* guarded by DRM_VMW_PARAM_NUM_STREAMS != 0*/
+#define DRM_VMW_CONTROL_STREAM 4
+#define DRM_VMW_CLAIM_STREAM 5
+#define DRM_VMW_UNREF_STREAM 6
+/* guarded by DRM_VMW_PARAM_3D == 1 */
+#define DRM_VMW_CREATE_CONTEXT 7
+#define DRM_VMW_UNREF_CONTEXT 8
+#define DRM_VMW_CREATE_SURFACE 9
+#define DRM_VMW_UNREF_SURFACE 10
+#define DRM_VMW_REF_SURFACE 11
+#define DRM_VMW_EXECBUF 12
+#define DRM_VMW_FIFO_DEBUG 13
+#define DRM_VMW_FENCE_WAIT 14
+/* guarded by minor version >= 2 */
+#define DRM_VMW_UPDATE_LAYOUT 15
+
+
+/*************************************************************************/
+/**
+ * DRM_VMW_GET_PARAM - get device information.
+ *
+ * DRM_VMW_PARAM_FIFO_OFFSET:
+ * Offset to use to map the first page of the FIFO read-only.
+ * The fifo is mapped using the mmap() system call on the drm device.
+ *
+ * DRM_VMW_PARAM_OVERLAY_IOCTL:
+ * Does the driver support the overlay ioctl.
+ */
+
+#define DRM_VMW_PARAM_NUM_STREAMS 0
+#define DRM_VMW_PARAM_NUM_FREE_STREAMS 1
+#define DRM_VMW_PARAM_3D 2
+#define DRM_VMW_PARAM_FIFO_OFFSET 3
+#define DRM_VMW_PARAM_HW_CAPS 4
+#define DRM_VMW_PARAM_FIFO_CAPS 5
+
+/**
+ * struct drm_vmw_getparam_arg
+ *
+ * @value: Returned value. //Out
+ * @param: Parameter to query. //In.
+ *
+ * Argument to the DRM_VMW_GET_PARAM Ioctl.
+ */
+
+struct drm_vmw_getparam_arg {
+ uint64_t value;
+ uint32_t param;
+ uint32_t pad64;
+};
+
+/*************************************************************************/
+/**
+ * DRM_VMW_CREATE_CONTEXT - Create a host context.
+ *
+ * Allocates a device unique context id, and queues a create context command
+ * for the host. Does not wait for host completion.
+ */
+
+/**
+ * struct drm_vmw_context_arg
+ *
+ * @cid: Device unique context ID.
+ *
+ * Output argument to the DRM_VMW_CREATE_CONTEXT Ioctl.
+ * Input argument to the DRM_VMW_UNREF_CONTEXT Ioctl.
+ */
+
+struct drm_vmw_context_arg {
+ int32_t cid;
+ uint32_t pad64;
+};
+
+/*************************************************************************/
+/**
+ * DRM_VMW_UNREF_CONTEXT - Create a host context.
+ *
+ * Frees a global context id, and queues a destroy host command for the host.
+ * Does not wait for host completion. The context ID can be used directly
+ * in the command stream and shows up as the same context ID on the host.
+ */
+
+/*************************************************************************/
+/**
+ * DRM_VMW_CREATE_SURFACE - Create a host suface.
+ *
+ * Allocates a device unique surface id, and queues a create surface command
+ * for the host. Does not wait for host completion. The surface ID can be
+ * used directly in the command stream and shows up as the same surface
+ * ID on the host.
+ */
+
+/**
+ * struct drm_wmv_surface_create_req
+ *
+ * @flags: Surface flags as understood by the host.
+ * @format: Surface format as understood by the host.
+ * @mip_levels: Number of mip levels for each face.
+ * An unused face should have 0 encoded.
+ * @size_addr: Address of a user-space array of sruct drm_vmw_size
+ * cast to an uint64_t for 32-64 bit compatibility.
+ * The size of the array should equal the total number of mipmap levels.
+ * @shareable: Boolean whether other clients (as identified by file descriptors)
+ * may reference this surface.
+ * @scanout: Boolean whether the surface is intended to be used as a
+ * scanout.
+ *
+ * Input data to the DRM_VMW_CREATE_SURFACE Ioctl.
+ * Output data from the DRM_VMW_REF_SURFACE Ioctl.
+ */
+
+struct drm_vmw_surface_create_req {
+ uint32_t flags;
+ uint32_t format;
+ uint32_t mip_levels[DRM_VMW_MAX_SURFACE_FACES];
+ uint64_t size_addr;
+ int32_t shareable;
+ int32_t scanout;
+};
+
+/**
+ * struct drm_wmv_surface_arg
+ *
+ * @sid: Surface id of created surface or surface to destroy or reference.
+ *
+ * Output data from the DRM_VMW_CREATE_SURFACE Ioctl.
+ * Input argument to the DRM_VMW_UNREF_SURFACE Ioctl.
+ * Input argument to the DRM_VMW_REF_SURFACE Ioctl.
+ */
+
+struct drm_vmw_surface_arg {
+ int32_t sid;
+ uint32_t pad64;
+};
+
+/**
+ * struct drm_vmw_size ioctl.
+ *
+ * @width - mip level width
+ * @height - mip level height
+ * @depth - mip level depth
+ *
+ * Description of a mip level.
+ * Input data to the DRM_WMW_CREATE_SURFACE Ioctl.
+ */
+
+struct drm_vmw_size {
+ uint32_t width;
+ uint32_t height;
+ uint32_t depth;
+ uint32_t pad64;
+};
+
+/**
+ * union drm_vmw_surface_create_arg
+ *
+ * @rep: Output data as described above.
+ * @req: Input data as described above.
+ *
+ * Argument to the DRM_VMW_CREATE_SURFACE Ioctl.
+ */
+
+union drm_vmw_surface_create_arg {
+ struct drm_vmw_surface_arg rep;
+ struct drm_vmw_surface_create_req req;
+};
+
+/*************************************************************************/
+/**
+ * DRM_VMW_REF_SURFACE - Reference a host surface.
+ *
+ * Puts a reference on a host surface with a give sid, as previously
+ * returned by the DRM_VMW_CREATE_SURFACE ioctl.
+ * A reference will make sure the surface isn't destroyed while we hold
+ * it and will allow the calling client to use the surface ID in the command
+ * stream.
+ *
+ * On successful return, the Ioctl returns the surface information given
+ * in the DRM_VMW_CREATE_SURFACE ioctl.
+ */
+
+/**
+ * union drm_vmw_surface_reference_arg
+ *
+ * @rep: Output data as described above.
+ * @req: Input data as described above.
+ *
+ * Argument to the DRM_VMW_REF_SURFACE Ioctl.
+ */
+
+union drm_vmw_surface_reference_arg {
+ struct drm_vmw_surface_create_req rep;
+ struct drm_vmw_surface_arg req;
+};
+
+/*************************************************************************/
+/**
+ * DRM_VMW_UNREF_SURFACE - Unreference a host surface.
+ *
+ * Clear a reference previously put on a host surface.
+ * When all references are gone, including the one implicitly placed
+ * on creation,
+ * a destroy surface command will be queued for the host.
+ * Does not wait for completion.
+ */
+
+/*************************************************************************/
+/**
+ * DRM_VMW_EXECBUF
+ *
+ * Submit a command buffer for execution on the host, and return a
+ * fence sequence that when signaled, indicates that the command buffer has
+ * executed.
+ */
+
+/**
+ * struct drm_vmw_execbuf_arg
+ *
+ * @commands: User-space address of a command buffer cast to an uint64_t.
+ * @command-size: Size in bytes of the command buffer.
+ * @throttle-us: Sleep until software is less than @throttle_us
+ * microseconds ahead of hardware. The driver may round this value
+ * to the nearest kernel tick.
+ * @fence_rep: User-space address of a struct drm_vmw_fence_rep cast to an
+ * uint64_t.
+ * @version: Allows expanding the execbuf ioctl parameters without breaking
+ * backwards compatibility, since user-space will always tell the kernel
+ * which version it uses.
+ * @flags: Execbuf flags. None currently.
+ *
+ * Argument to the DRM_VMW_EXECBUF Ioctl.
+ */
+
+#define DRM_VMW_EXECBUF_VERSION 0
+
+struct drm_vmw_execbuf_arg {
+ uint64_t commands;
+ uint32_t command_size;
+ uint32_t throttle_us;
+ uint64_t fence_rep;
+ uint32_t version;
+ uint32_t flags;
+};
+
+/**
+ * struct drm_vmw_fence_rep
+ *
+ * @fence_seq: Fence sequence associated with a command submission.
+ * @error: This member should've been set to -EFAULT on submission.
+ * The following actions should be take on completion:
+ * error == -EFAULT: Fence communication failed. The host is synchronized.
+ * Use the last fence id read from the FIFO fence register.
+ * error != 0 && error != -EFAULT:
+ * Fence submission failed. The host is synchronized. Use the fence_seq member.
+ * error == 0: All is OK, The host may not be synchronized.
+ * Use the fence_seq member.
+ *
+ * Input / Output data to the DRM_VMW_EXECBUF Ioctl.
+ */
+
+struct drm_vmw_fence_rep {
+ uint64_t fence_seq;
+ int32_t error;
+ uint32_t pad64;
+};
+
+/*************************************************************************/
+/**
+ * DRM_VMW_ALLOC_DMABUF
+ *
+ * Allocate a DMA buffer that is visible also to the host.
+ * NOTE: The buffer is
+ * identified by a handle and an offset, which are private to the guest, but
+ * useable in the command stream. The guest kernel may translate these
+ * and patch up the command stream accordingly. In the future, the offset may
+ * be zero at all times, or it may disappear from the interface before it is
+ * fixed.
+ *
+ * The DMA buffer may stay user-space mapped in the guest at all times,
+ * and is thus suitable for sub-allocation.
+ *
+ * DMA buffers are mapped using the mmap() syscall on the drm device.
+ */
+
+/**
+ * struct drm_vmw_alloc_dmabuf_req
+ *
+ * @size: Required minimum size of the buffer.
+ *
+ * Input data to the DRM_VMW_ALLOC_DMABUF Ioctl.
+ */
+
+struct drm_vmw_alloc_dmabuf_req {
+ uint32_t size;
+ uint32_t pad64;
+};
+
+/**
+ * struct drm_vmw_dmabuf_rep
+ *
+ * @map_handle: Offset to use in the mmap() call used to map the buffer.
+ * @handle: Handle unique to this buffer. Used for unreferencing.
+ * @cur_gmr_id: GMR id to use in the command stream when this buffer is
+ * referenced. See not above.
+ * @cur_gmr_offset: Offset to use in the command stream when this buffer is
+ * referenced. See note above.
+ *
+ * Output data from the DRM_VMW_ALLOC_DMABUF Ioctl.
+ */
+
+struct drm_vmw_dmabuf_rep {
+ uint64_t map_handle;
+ uint32_t handle;
+ uint32_t cur_gmr_id;
+ uint32_t cur_gmr_offset;
+ uint32_t pad64;
+};
+
+/**
+ * union drm_vmw_dmabuf_arg
+ *
+ * @req: Input data as described above.
+ * @rep: Output data as described above.
+ *
+ * Argument to the DRM_VMW_ALLOC_DMABUF Ioctl.
+ */
+
+union drm_vmw_alloc_dmabuf_arg {
+ struct drm_vmw_alloc_dmabuf_req req;
+ struct drm_vmw_dmabuf_rep rep;
+};
+
+/*************************************************************************/
+/**
+ * DRM_VMW_UNREF_DMABUF - Free a DMA buffer.
+ *
+ */
+
+/**
+ * struct drm_vmw_unref_dmabuf_arg
+ *
+ * @handle: Handle indicating what buffer to free. Obtained from the
+ * DRM_VMW_ALLOC_DMABUF Ioctl.
+ *
+ * Argument to the DRM_VMW_UNREF_DMABUF Ioctl.
+ */
+
+struct drm_vmw_unref_dmabuf_arg {
+ uint32_t handle;
+ uint32_t pad64;
+};
+
+/*************************************************************************/
+/**
+ * DRM_VMW_FIFO_DEBUG - Get last FIFO submission.
+ *
+ * This IOCTL copies the last FIFO submission directly out of the FIFO buffer.
+ */
+
+/**
+ * struct drm_vmw_fifo_debug_arg
+ *
+ * @debug_buffer: User space address of a debug_buffer cast to an uint64_t //In
+ * @debug_buffer_size: Size in bytes of debug buffer //In
+ * @used_size: Number of bytes copied to the buffer // Out
+ * @did_not_fit: Boolean indicating that the fifo contents did not fit. //Out
+ *
+ * Argument to the DRM_VMW_FIFO_DEBUG Ioctl.
+ */
+
+struct drm_vmw_fifo_debug_arg {
+ uint64_t debug_buffer;
+ uint32_t debug_buffer_size;
+ uint32_t used_size;
+ int32_t did_not_fit;
+ uint32_t pad64;
+};
+
+struct drm_vmw_fence_wait_arg {
+ uint64_t sequence;
+ uint64_t kernel_cookie;
+ int32_t cookie_valid;
+ int32_t pad64;
+};
+
+/*************************************************************************/
+/**
+ * DRM_VMW_CONTROL_STREAM - Control overlays, aka streams.
+ *
+ * This IOCTL controls the overlay units of the svga device.
+ * The SVGA overlay units does not work like regular hardware units in
+ * that they do not automaticaly read back the contents of the given dma
+ * buffer. But instead only read back for each call to this ioctl, and
+ * at any point between this call being made and a following call that
+ * either changes the buffer or disables the stream.
+ */
+
+/**
+ * struct drm_vmw_rect
+ *
+ * Defines a rectangle. Used in the overlay ioctl to define
+ * source and destination rectangle.
+ */
+
+struct drm_vmw_rect {
+ int32_t x;
+ int32_t y;
+ uint32_t w;
+ uint32_t h;
+};
+
+/**
+ * struct drm_vmw_control_stream_arg
+ *
+ * @stream_id: Stearm to control
+ * @enabled: If false all following arguments are ignored.
+ * @handle: Handle to buffer for getting data from.
+ * @format: Format of the overlay as understood by the host.
+ * @width: Width of the overlay.
+ * @height: Height of the overlay.
+ * @size: Size of the overlay in bytes.
+ * @pitch: Array of pitches, the two last are only used for YUV12 formats.
+ * @offset: Offset from start of dma buffer to overlay.
+ * @src: Source rect, must be within the defined area above.
+ * @dst: Destination rect, x and y may be negative.
+ *
+ * Argument to the DRM_VMW_CONTROL_STREAM Ioctl.
+ */
+
+struct drm_vmw_control_stream_arg {
+ uint32_t stream_id;
+ uint32_t enabled;
+
+ uint32_t flags;
+ uint32_t color_key;
+
+ uint32_t handle;
+ uint32_t offset;
+ int32_t format;
+ uint32_t size;
+ uint32_t width;
+ uint32_t height;
+ uint32_t pitch[3];
+
+ uint32_t pad64;
+ struct drm_vmw_rect src;
+ struct drm_vmw_rect dst;
+};
+
+/*************************************************************************/
+/**
+ * DRM_VMW_CURSOR_BYPASS - Give extra information about cursor bypass.
+ *
+ */
+
+#define DRM_VMW_CURSOR_BYPASS_ALL (1 << 0)
+#define DRM_VMW_CURSOR_BYPASS_FLAGS (1)
+
+/**
+ * struct drm_vmw_cursor_bypass_arg
+ *
+ * @flags: Flags.
+ * @crtc_id: Crtc id, only used if DMR_CURSOR_BYPASS_ALL isn't passed.
+ * @xpos: X position of cursor.
+ * @ypos: Y position of cursor.
+ * @xhot: X hotspot.
+ * @yhot: Y hotspot.
+ *
+ * Argument to the DRM_VMW_CURSOR_BYPASS Ioctl.
+ */
+
+struct drm_vmw_cursor_bypass_arg {
+ uint32_t flags;
+ uint32_t crtc_id;
+ int32_t xpos;
+ int32_t ypos;
+ int32_t xhot;
+ int32_t yhot;
+};
+
+/*************************************************************************/
+/**
+ * DRM_VMW_CLAIM_STREAM - Claim a single stream.
+ */
+
+/**
+ * struct drm_vmw_context_arg
+ *
+ * @stream_id: Device unique context ID.
+ *
+ * Output argument to the DRM_VMW_CREATE_CONTEXT Ioctl.
+ * Input argument to the DRM_VMW_UNREF_CONTEXT Ioctl.
+ */
+
+struct drm_vmw_stream_arg {
+ uint32_t stream_id;
+ uint32_t pad64;
+};
+
+/*************************************************************************/
+/**
+ * DRM_VMW_UNREF_STREAM - Unclaim a stream.
+ *
+ * Return a single stream that was claimed by this process. Also makes
+ * sure that the stream has been stopped.
+ */
+
+/*************************************************************************/
+/**
+ * DRM_VMW_UPDATE_LAYOUT - Update layout
+ *
+ * Updates the prefered modes and connection status for connectors. The
+ * command conisits of one drm_vmw_update_layout_arg pointing out a array
+ * of num_outputs drm_vmw_rect's.
+ */
+
+/**
+ * struct drm_vmw_update_layout_arg
+ *
+ * @num_outputs: number of active
+ * @rects: pointer to array of drm_vmw_rect
+ *
+ * Input argument to the DRM_VMW_UPDATE_LAYOUT Ioctl.
+ */
+
+struct drm_vmw_update_layout_arg {
+ uint32_t num_outputs;
+ uint32_t pad64;
+ uint64_t rects;
+};
+
+#endif
diff --git a/src/gallium/winsys/sw/Makefile b/src/gallium/winsys/sw/Makefile
new file mode 100644
index 0000000000..e9182ea5b1
--- /dev/null
+++ b/src/gallium/winsys/sw/Makefile
@@ -0,0 +1,12 @@
+# src/gallium/winsys/sw/Makefile
+TOP = ../../../..
+include $(TOP)/configs/current
+
+SUBDIRS = null wrapper
+
+default install clean:
+ @for dir in $(SUBDIRS) ; do \
+ if [ -d $$dir ] ; then \
+ (cd $$dir && $(MAKE) $@) || exit 1; \
+ fi \
+ done
diff --git a/src/gallium/winsys/sw/dri/Makefile b/src/gallium/winsys/sw/dri/Makefile
new file mode 100644
index 0000000000..a3fca6be88
--- /dev/null
+++ b/src/gallium/winsys/sw/dri/Makefile
@@ -0,0 +1,13 @@
+TOP = ../../../../..
+include $(TOP)/configs/current
+
+LIBNAME = swdri
+
+LIBRARY_INCLUDES =
+
+LIBRARY_DEFINES =
+
+C_SOURCES = \
+ dri_sw_winsys.c
+
+include ../../../Makefile.template
diff --git a/src/gallium/winsys/sw/dri/SConscript b/src/gallium/winsys/sw/dri/SConscript
new file mode 100644
index 0000000000..b255d725f9
--- /dev/null
+++ b/src/gallium/winsys/sw/dri/SConscript
@@ -0,0 +1,23 @@
+#######################################################################
+# SConscript for xlib winsys
+
+
+Import('*')
+
+if env['platform'] == 'linux':
+
+ env = env.Clone()
+
+ env.Append(CPPPATH = [
+ '#/src/gallium/include',
+ '#/src/gallium/auxiliary',
+ '#/src/gallium/drivers',
+ ])
+
+ ws_dri = env.ConvenienceLibrary(
+ target = 'ws_dri',
+ source = [
+ 'dri_sw_winsys.c',
+ ]
+ )
+ Export('ws_dri')
diff --git a/src/gallium/winsys/sw/dri/dri_sw_winsys.c b/src/gallium/winsys/sw/dri/dri_sw_winsys.c
new file mode 100644
index 0000000000..1bca827bd6
--- /dev/null
+++ b/src/gallium/winsys/sw/dri/dri_sw_winsys.c
@@ -0,0 +1,225 @@
+/**************************************************************************
+ *
+ * Copyright 2009, VMware, Inc.
+ * All Rights Reserved.
+ * Copyright 2010 George Sapountzis <gsapountzis@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL VMWARE 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.
+ *
+ **************************************************************************/
+
+#include "pipe/p_compiler.h"
+#include "pipe/p_format.h"
+#include "util/u_inlines.h"
+#include "util/u_format.h"
+#include "util/u_math.h"
+#include "util/u_memory.h"
+
+#include "state_tracker/sw_winsys.h"
+#include "dri_sw_winsys.h"
+
+
+struct dri_sw_displaytarget
+{
+ enum pipe_format format;
+ unsigned width;
+ unsigned height;
+ unsigned stride;
+
+ void *data;
+ void *mapped;
+};
+
+struct dri_sw_winsys
+{
+ struct sw_winsys base;
+
+ struct drisw_loader_funcs *lf;
+};
+
+static INLINE struct dri_sw_displaytarget *
+dri_sw_displaytarget( struct sw_displaytarget *dt )
+{
+ return (struct dri_sw_displaytarget *)dt;
+}
+
+static INLINE struct dri_sw_winsys *
+dri_sw_winsys( struct sw_winsys *ws )
+{
+ return (struct dri_sw_winsys *)ws;
+}
+
+
+static boolean
+dri_sw_is_displaytarget_format_supported( struct sw_winsys *ws,
+ unsigned tex_usage,
+ enum pipe_format format )
+{
+ /* TODO: check visuals or other sensible thing here */
+ return TRUE;
+}
+
+static struct sw_displaytarget *
+dri_sw_displaytarget_create(struct sw_winsys *winsys,
+ unsigned tex_usage,
+ enum pipe_format format,
+ unsigned width, unsigned height,
+ unsigned alignment,
+ unsigned *stride)
+{
+ struct dri_sw_displaytarget *dri_sw_dt;
+ unsigned nblocksy, size, format_stride;
+
+ dri_sw_dt = CALLOC_STRUCT(dri_sw_displaytarget);
+ if(!dri_sw_dt)
+ goto no_dt;
+
+ dri_sw_dt->format = format;
+ dri_sw_dt->width = width;
+ dri_sw_dt->height = height;
+
+ format_stride = util_format_get_stride(format, width);
+ dri_sw_dt->stride = align(format_stride, alignment);
+
+ nblocksy = util_format_get_nblocksy(format, height);
+ size = dri_sw_dt->stride * nblocksy;
+
+ dri_sw_dt->data = align_malloc(size, alignment);
+ if(!dri_sw_dt->data)
+ goto no_data;
+
+ *stride = dri_sw_dt->stride;
+ return (struct sw_displaytarget *)dri_sw_dt;
+
+no_data:
+ FREE(dri_sw_dt);
+no_dt:
+ return NULL;
+}
+
+static void
+dri_sw_displaytarget_destroy(struct sw_winsys *ws,
+ struct sw_displaytarget *dt)
+{
+ struct dri_sw_displaytarget *dri_sw_dt = dri_sw_displaytarget(dt);
+
+ if (dri_sw_dt->data) {
+ FREE(dri_sw_dt->data);
+ }
+
+ FREE(dri_sw_dt);
+}
+
+static void *
+dri_sw_displaytarget_map(struct sw_winsys *ws,
+ struct sw_displaytarget *dt,
+ unsigned flags)
+{
+ struct dri_sw_displaytarget *dri_sw_dt = dri_sw_displaytarget(dt);
+ dri_sw_dt->mapped = dri_sw_dt->data;
+ return dri_sw_dt->mapped;
+}
+
+static void
+dri_sw_displaytarget_unmap(struct sw_winsys *ws,
+ struct sw_displaytarget *dt)
+{
+ struct dri_sw_displaytarget *dri_sw_dt = dri_sw_displaytarget(dt);
+ dri_sw_dt->mapped = NULL;
+}
+
+static struct sw_displaytarget *
+dri_sw_displaytarget_from_handle(struct sw_winsys *winsys,
+ const struct pipe_resource *templ,
+ struct winsys_handle *whandle,
+ unsigned *stride)
+{
+ assert(0);
+ return NULL;
+}
+
+static boolean
+dri_sw_displaytarget_get_handle(struct sw_winsys *winsys,
+ struct sw_displaytarget *dt,
+ struct winsys_handle *whandle)
+{
+ assert(0);
+ return FALSE;
+}
+
+static void
+dri_sw_displaytarget_display(struct sw_winsys *ws,
+ struct sw_displaytarget *dt,
+ void *context_private)
+{
+ struct dri_sw_winsys *dri_sw_ws = dri_sw_winsys(ws);
+ struct dri_sw_displaytarget *dri_sw_dt = dri_sw_displaytarget(dt);
+ struct dri_drawable *dri_drawable = (struct dri_drawable *)context_private;
+ unsigned width, height;
+
+ /* Set the width to 'stride / cpp'.
+ *
+ * PutImage correctly clips to the width of the dst drawable.
+ */
+ width = dri_sw_dt->stride / util_format_get_blocksize(dri_sw_dt->format);
+
+ height = dri_sw_dt->height;
+
+ dri_sw_ws->lf->put_image(dri_drawable, dri_sw_dt->data, width, height);
+}
+
+
+static void
+dri_destroy_sw_winsys(struct sw_winsys *winsys)
+{
+ FREE(winsys);
+}
+
+struct sw_winsys *
+dri_create_sw_winsys(struct drisw_loader_funcs *lf)
+{
+ struct dri_sw_winsys *ws;
+
+ ws = CALLOC_STRUCT(dri_sw_winsys);
+ if (!ws)
+ return NULL;
+
+ ws->lf = lf;
+ ws->base.destroy = dri_destroy_sw_winsys;
+
+ ws->base.is_displaytarget_format_supported = dri_sw_is_displaytarget_format_supported;
+
+ /* screen texture functions */
+ ws->base.displaytarget_create = dri_sw_displaytarget_create;
+ ws->base.displaytarget_destroy = dri_sw_displaytarget_destroy;
+ ws->base.displaytarget_from_handle = dri_sw_displaytarget_from_handle;
+ ws->base.displaytarget_get_handle = dri_sw_displaytarget_get_handle;
+
+ /* texture functions */
+ ws->base.displaytarget_map = dri_sw_displaytarget_map;
+ ws->base.displaytarget_unmap = dri_sw_displaytarget_unmap;
+
+ ws->base.displaytarget_display = dri_sw_displaytarget_display;
+
+ return &ws->base;
+}
+
+/* vim: set sw=3 ts=8 sts=3 expandtab: */
diff --git a/src/gallium/winsys/sw/dri/dri_sw_winsys.h b/src/gallium/winsys/sw/dri/dri_sw_winsys.h
new file mode 100644
index 0000000000..329ac06a05
--- /dev/null
+++ b/src/gallium/winsys/sw/dri/dri_sw_winsys.h
@@ -0,0 +1,38 @@
+/**************************************************************************
+ *
+ * Copyright 2009, VMware, Inc.
+ * All Rights Reserved.
+ * Copyright 2010 George Sapountzis <gsapountzis@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL VMWARE 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.
+ *
+ **************************************************************************/
+
+#ifndef DRI_SW_WINSYS
+#define DRI_SW_WINSYS
+
+#include "state_tracker/drisw_api.h"
+
+struct sw_winsys;
+
+struct sw_winsys *dri_create_sw_winsys(struct drisw_loader_funcs *lf);
+
+#endif
diff --git a/src/gallium/winsys/sw/drm/Makefile b/src/gallium/winsys/sw/drm/Makefile
new file mode 100644
index 0000000000..79664536aa
--- /dev/null
+++ b/src/gallium/winsys/sw/drm/Makefile
@@ -0,0 +1,12 @@
+TOP = ../../../../..
+include $(TOP)/configs/current
+
+LIBNAME = swdrm
+
+C_SOURCES = sw_drm_api.c
+
+LIBRARY_INCLUDES =
+
+LIBRARY_DEFINES =
+
+include ../../../Makefile.template
diff --git a/src/gallium/winsys/sw/drm/SConscript b/src/gallium/winsys/sw/drm/SConscript
new file mode 100644
index 0000000000..15a2e05d5a
--- /dev/null
+++ b/src/gallium/winsys/sw/drm/SConscript
@@ -0,0 +1,21 @@
+#######################################################################
+# SConscript for xlib winsys
+
+
+Import('*')
+
+env = env.Clone()
+
+env.Append(CPPPATH = [
+ '#/src/gallium/include',
+ '#/src/gallium/auxiliary',
+ '#/src/gallium/drivers',
+])
+
+ws_drm = env.ConvenienceLibrary(
+ target = 'ws_drm',
+ source = [
+ 'sw_drm_api.c',
+ ]
+)
+Export('ws_drm')
diff --git a/src/gallium/winsys/sw/drm/sw_drm_api.c b/src/gallium/winsys/sw/drm/sw_drm_api.c
new file mode 100644
index 0000000000..7b86382619
--- /dev/null
+++ b/src/gallium/winsys/sw/drm/sw_drm_api.c
@@ -0,0 +1,103 @@
+/**********************************************************
+ * Copyright 2010 VMware, Inc. 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, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ **********************************************************/
+
+
+#include "util/u_memory.h"
+#include "softpipe/sp_public.h"
+#include "state_tracker/drm_api.h"
+#include "../../sw/wrapper/wrapper_sw_winsys.h"
+#include "sw_drm_api.h"
+
+
+/*
+ * Defines
+ */
+
+
+struct sw_drm_api
+{
+ struct drm_api base;
+ struct drm_api *api;
+ struct sw_winsys *sw;
+};
+
+static INLINE struct sw_drm_api *
+sw_drm_api(struct drm_api *api)
+{
+ return (struct sw_drm_api *)api;
+}
+
+
+/*
+ * Exported functions
+ */
+
+
+static struct pipe_screen *
+sw_drm_create_screen(struct drm_api *_api, int drmFD)
+{
+ struct sw_drm_api *swapi = sw_drm_api(_api);
+ struct drm_api *api = swapi->api;
+ struct sw_winsys *sww;
+ struct pipe_screen *screen;
+
+ screen = api->create_screen(api, drmFD);
+ if (!screen)
+ return NULL;
+
+ sww = wrapper_sw_winsys_warp_pipe_screen(screen);
+ if (!sww)
+ return NULL;
+
+ return softpipe_create_screen(sww);
+}
+
+static void
+sw_drm_destroy(struct drm_api *api)
+{
+ struct sw_drm_api *swapi = sw_drm_api(api);
+ if (swapi->api->destroy)
+ swapi->api->destroy(swapi->api);
+
+ FREE(swapi);
+}
+
+struct drm_api *
+sw_drm_api_create(struct drm_api *api)
+{
+ struct sw_drm_api *swapi = CALLOC_STRUCT(sw_drm_api);
+
+ if (!swapi)
+ return api;
+
+ swapi->base.name = api->name;
+ swapi->base.driver_name = api->driver_name;
+ swapi->base.create_screen = sw_drm_create_screen;
+ swapi->base.destroy = sw_drm_destroy;
+
+ swapi->api = api;
+
+ return &swapi->base;
+}
diff --git a/src/gallium/winsys/sw/drm/sw_drm_api.h b/src/gallium/winsys/sw/drm/sw_drm_api.h
new file mode 100644
index 0000000000..ce90a04ae0
--- /dev/null
+++ b/src/gallium/winsys/sw/drm/sw_drm_api.h
@@ -0,0 +1,34 @@
+/**********************************************************
+ * Copyright 2010 VMware, Inc. 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, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ **********************************************************/
+
+
+#ifndef SW_DRM_API_H
+#define SW_DRM_API_H
+
+struct drm_api;
+
+struct drm_api * sw_drm_api_create(struct drm_api *api);
+
+#endif
diff --git a/src/gallium/winsys/sw/fbdev/Makefile b/src/gallium/winsys/sw/fbdev/Makefile
new file mode 100644
index 0000000000..8832aab193
--- /dev/null
+++ b/src/gallium/winsys/sw/fbdev/Makefile
@@ -0,0 +1,13 @@
+TOP = ../../../../..
+include $(TOP)/configs/current
+
+LIBNAME = fbdev
+
+LIBRARY_INCLUDES =
+
+LIBRARY_DEFINES =
+
+C_SOURCES = \
+ fbdev_sw_winsys.c
+
+include ../../../Makefile.template
diff --git a/src/gallium/winsys/sw/fbdev/SConscript b/src/gallium/winsys/sw/fbdev/SConscript
new file mode 100644
index 0000000000..3b5b4ff1c0
--- /dev/null
+++ b/src/gallium/winsys/sw/fbdev/SConscript
@@ -0,0 +1,23 @@
+#######################################################################
+# SConscript for fbdev winsys
+
+
+Import('*')
+
+if env['platform'] == 'linux':
+
+ env = env.Clone()
+
+ env.Append(CPPPATH = [
+ '#/src/gallium/include',
+ '#/src/gallium/auxiliary',
+ '#/src/gallium/drivers',
+ ])
+
+ ws_fbdev = env.ConvenienceLibrary(
+ target = 'ws_fbdev',
+ source = [
+ 'fbdev_sw_winsys.c',
+ ]
+ )
+ Export('ws_fbdev')
diff --git a/src/gallium/winsys/sw/fbdev/fbdev_sw_winsys.c b/src/gallium/winsys/sw/fbdev/fbdev_sw_winsys.c
new file mode 100644
index 0000000000..f4f4cd7969
--- /dev/null
+++ b/src/gallium/winsys/sw/fbdev/fbdev_sw_winsys.c
@@ -0,0 +1,224 @@
+/*
+ * Mesa 3-D graphics library
+ * Version: 7.9
+ *
+ * Copyright (C) 2010 LunarG Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * Chia-I Wu <olv@lunarg.com>
+ */
+
+#include <sys/mman.h>
+#include <sys/ioctl.h>
+#include <linux/fb.h>
+
+#include "pipe/p_compiler.h"
+#include "util/u_format.h"
+#include "util/u_math.h"
+#include "util/u_memory.h"
+#include "state_tracker/sw_winsys.h"
+
+#include "fbdev_sw_winsys.h"
+
+struct fbdev_sw_displaytarget
+{
+ enum pipe_format format;
+ unsigned width;
+ unsigned height;
+ unsigned stride;
+
+ void *data;
+ void *mapped;
+};
+
+struct fbdev_sw_winsys
+{
+ struct sw_winsys base;
+
+ int fd;
+ enum pipe_format format;
+
+ struct fb_fix_screeninfo finfo;
+ void *fbmem;
+ unsigned rows;
+ unsigned stride;
+};
+
+static INLINE struct fbdev_sw_displaytarget *
+fbdev_sw_displaytarget(struct sw_displaytarget *dt)
+{
+ return (struct fbdev_sw_displaytarget *) dt;
+}
+
+static INLINE struct fbdev_sw_winsys *
+fbdev_sw_winsys(struct sw_winsys *ws)
+{
+ return (struct fbdev_sw_winsys *) ws;
+}
+
+static void
+fbdev_displaytarget_display(struct sw_winsys *ws,
+ struct sw_displaytarget *dt,
+ void *context_private)
+{
+ struct fbdev_sw_winsys *fbdev = fbdev_sw_winsys(ws);
+ struct fbdev_sw_displaytarget *fbdt = fbdev_sw_displaytarget(dt);
+ unsigned rows, len, i;
+
+ rows = MIN2(fbdt->height, fbdev->rows);
+ len = util_format_get_stride(fbdt->format, fbdt->width);
+ len = MIN2(len, fbdev->stride);
+
+ for (i = 0; i < rows; i++) {
+ void *dst = fbdev->fbmem + fbdev->stride * i;
+ void *src = fbdt->data + fbdt->stride * i;
+
+ memcpy(dst, src, len);
+ }
+}
+
+static void
+fbdev_displaytarget_unmap(struct sw_winsys *ws,
+ struct sw_displaytarget *dt)
+{
+ struct fbdev_sw_displaytarget *fbdt = fbdev_sw_displaytarget(dt);
+ fbdt->mapped = NULL;
+}
+
+static void *
+fbdev_displaytarget_map(struct sw_winsys *ws,
+ struct sw_displaytarget *dt,
+ unsigned flags)
+{
+ struct fbdev_sw_displaytarget *fbdt = fbdev_sw_displaytarget(dt);
+ fbdt->mapped = fbdt->data;
+ return fbdt->mapped;
+}
+
+static void
+fbdev_displaytarget_destroy(struct sw_winsys *ws,
+ struct sw_displaytarget *dt)
+{
+ struct fbdev_sw_displaytarget *fbdt = fbdev_sw_displaytarget(dt);
+
+ if (fbdt->data)
+ align_free(fbdt->data);
+
+ FREE(fbdt);
+}
+
+static struct sw_displaytarget *
+fbdev_displaytarget_create(struct sw_winsys *ws,
+ unsigned tex_usage,
+ enum pipe_format format,
+ unsigned width, unsigned height,
+ unsigned alignment,
+ unsigned *stride)
+{
+ struct fbdev_sw_winsys *fbdev = fbdev_sw_winsys(ws);
+ struct fbdev_sw_displaytarget *fbdt;
+ unsigned nblocksy, size, format_stride;
+
+ if (fbdev->format != format)
+ return NULL;
+
+ fbdt = CALLOC_STRUCT(fbdev_sw_displaytarget);
+ if (!fbdt)
+ return NULL;
+
+ fbdt->format = format;
+ fbdt->width = width;
+ fbdt->height = height;
+
+ format_stride = util_format_get_stride(format, width);
+ fbdt->stride = align(format_stride, alignment);
+
+ nblocksy = util_format_get_nblocksy(format, height);
+ size = fbdt->stride * nblocksy;
+
+ fbdt->data = align_malloc(size, alignment);
+ if (!fbdt->data) {
+ FREE(fbdt);
+ return NULL;
+ }
+
+ *stride = fbdt->stride;
+
+ return (struct sw_displaytarget *) fbdt;
+}
+
+static boolean
+fbdev_is_displaytarget_format_supported(struct sw_winsys *ws,
+ unsigned tex_usage,
+ enum pipe_format format)
+{
+ struct fbdev_sw_winsys *fbdev = fbdev_sw_winsys(ws);
+ return (fbdev->format == format);
+}
+
+static void
+fbdev_destroy(struct sw_winsys *ws)
+{
+ struct fbdev_sw_winsys *fbdev = fbdev_sw_winsys(ws);
+
+ munmap(fbdev->fbmem, fbdev->finfo.smem_len);
+ FREE(fbdev);
+}
+
+struct sw_winsys *
+fbdev_create_sw_winsys(int fd, enum pipe_format format)
+{
+ struct fbdev_sw_winsys *fbdev;
+
+ fbdev = CALLOC_STRUCT(fbdev_sw_winsys);
+ if (!fbdev)
+ return NULL;
+
+ fbdev->fd = fd;
+ fbdev->format = format;
+ if (ioctl(fbdev->fd, FBIOGET_FSCREENINFO, &fbdev->finfo)) {
+ FREE(fbdev);
+ return NULL;
+ }
+
+ fbdev->fbmem = mmap(0, fbdev->finfo.smem_len,
+ PROT_WRITE, MAP_SHARED, fbdev->fd, 0);
+ if (fbdev->fbmem == MAP_FAILED) {
+ FREE(fbdev);
+ return NULL;
+ }
+
+ fbdev->rows = fbdev->finfo.smem_len / fbdev->finfo.line_length;
+ fbdev->stride = fbdev->finfo.line_length;
+
+ fbdev->base.destroy = fbdev_destroy;
+ fbdev->base.is_displaytarget_format_supported =
+ fbdev_is_displaytarget_format_supported;
+
+ fbdev->base.displaytarget_create = fbdev_displaytarget_create;
+ fbdev->base.displaytarget_destroy = fbdev_displaytarget_destroy;
+ fbdev->base.displaytarget_map = fbdev_displaytarget_map;
+ fbdev->base.displaytarget_unmap = fbdev_displaytarget_unmap;
+
+ fbdev->base.displaytarget_display = fbdev_displaytarget_display;
+
+ return &fbdev->base;
+}
diff --git a/src/gallium/winsys/sw/fbdev/fbdev_sw_winsys.h b/src/gallium/winsys/sw/fbdev/fbdev_sw_winsys.h
new file mode 100644
index 0000000000..d958ab9db3
--- /dev/null
+++ b/src/gallium/winsys/sw/fbdev/fbdev_sw_winsys.h
@@ -0,0 +1,38 @@
+/*
+ * Mesa 3-D graphics library
+ * Version: 7.8
+ *
+ * Copyright (C) 2010 LunarG Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * Chia-I Wu <olv@lunarg.com>
+ */
+
+#ifndef FBDEV_SW_WINSYS
+#define FBDEV_SW_WINSYS
+
+struct sw_winsys;
+enum pipe_format;
+
+struct sw_winsys *
+fbdev_create_sw_winsys(int fd, enum pipe_format format);
+
+#endif /* FBDEV_SW_WINSYS */
diff --git a/src/gallium/winsys/sw/gdi/SConscript b/src/gallium/winsys/sw/gdi/SConscript
new file mode 100644
index 0000000000..1267fc6eea
--- /dev/null
+++ b/src/gallium/winsys/sw/gdi/SConscript
@@ -0,0 +1,23 @@
+#######################################################################
+# SConscript for xlib winsys
+
+
+Import('*')
+
+if env['platform'] == 'windows':
+
+ env = env.Clone()
+
+ env.Append(CPPPATH = [
+ '#/src/gallium/include',
+ '#/src/gallium/auxiliary',
+ '#/src/gallium/drivers',
+ ])
+
+ ws_gdi = env.ConvenienceLibrary(
+ target = 'ws_gdi',
+ source = [
+ 'gdi_sw_winsys.c',
+ ]
+ )
+ Export('ws_gdi')
diff --git a/src/gallium/winsys/sw/gdi/gdi_sw_winsys.c b/src/gallium/winsys/sw/gdi/gdi_sw_winsys.c
new file mode 100644
index 0000000000..2e12f6e6cc
--- /dev/null
+++ b/src/gallium/winsys/sw/gdi/gdi_sw_winsys.c
@@ -0,0 +1,247 @@
+/**************************************************************************
+ *
+ * Copyright 2009 VMware, Inc.
+ * 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.
+ *
+ *
+ **************************************************************************/
+
+/**
+ * @file
+ * GDI software rasterizer support.
+ *
+ * @author Jose Fonseca <jfonseca@vmware.com>
+ */
+
+
+#include <windows.h>
+
+#include "pipe/p_format.h"
+#include "pipe/p_context.h"
+#include "util/u_inlines.h"
+#include "util/u_format.h"
+#include "util/u_math.h"
+#include "util/u_memory.h"
+#include "state_tracker/sw_winsys.h"
+#include "gdi_sw_winsys.h"
+
+
+struct gdi_sw_displaytarget
+{
+ enum pipe_format format;
+ unsigned width;
+ unsigned height;
+ unsigned stride;
+
+ unsigned size;
+
+ void *data;
+
+ BITMAPINFO bmi;
+};
+
+
+/** Cast wrapper */
+static INLINE struct gdi_sw_displaytarget *
+gdi_sw_displaytarget( struct sw_displaytarget *buf )
+{
+ return (struct gdi_sw_displaytarget *)buf;
+}
+
+
+static boolean
+gdi_sw_is_displaytarget_format_supported( struct sw_winsys *ws,
+ unsigned tex_usage,
+ enum pipe_format format )
+{
+ switch(format) {
+ case PIPE_FORMAT_B8G8R8X8_UNORM:
+ case PIPE_FORMAT_B8G8R8A8_UNORM:
+ return TRUE;
+
+ /* TODO: Support other formats possible with BMPs, as described in
+ * http://msdn.microsoft.com/en-us/library/dd183376(VS.85).aspx */
+
+ default:
+ return FALSE;
+ }
+}
+
+
+static void *
+gdi_sw_displaytarget_map(struct sw_winsys *ws,
+ struct sw_displaytarget *dt,
+ unsigned flags )
+{
+ struct gdi_sw_displaytarget *gdt = gdi_sw_displaytarget(dt);
+
+ return gdt->data;
+}
+
+
+static void
+gdi_sw_displaytarget_unmap(struct sw_winsys *ws,
+ struct sw_displaytarget *dt )
+{
+
+}
+
+
+static void
+gdi_sw_displaytarget_destroy(struct sw_winsys *winsys,
+ struct sw_displaytarget *dt)
+{
+ struct gdi_sw_displaytarget *gdt = gdi_sw_displaytarget(dt);
+
+ align_free(gdt->data);
+ FREE(gdt);
+}
+
+
+static struct sw_displaytarget *
+gdi_sw_displaytarget_create(struct sw_winsys *winsys,
+ unsigned tex_usage,
+ enum pipe_format format,
+ unsigned width, unsigned height,
+ unsigned alignment,
+ unsigned *stride)
+{
+ struct gdi_sw_displaytarget *gdt;
+ unsigned cpp;
+ unsigned bpp;
+
+ gdt = CALLOC_STRUCT(gdi_sw_displaytarget);
+ if(!gdt)
+ goto no_gdt;
+
+ gdt->format = format;
+ gdt->width = width;
+ gdt->height = height;
+
+ bpp = util_format_get_blocksizebits(format);
+ cpp = util_format_get_blocksize(format);
+
+ gdt->stride = align(width * cpp, alignment);
+ gdt->size = gdt->stride * height;
+
+ gdt->data = align_malloc(gdt->size, alignment);
+ if(!gdt->data)
+ goto no_data;
+
+ gdt->bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
+ gdt->bmi.bmiHeader.biWidth = gdt->stride / cpp;
+ gdt->bmi.bmiHeader.biHeight= -(long)height;
+ gdt->bmi.bmiHeader.biPlanes = 1;
+ gdt->bmi.bmiHeader.biBitCount = bpp;
+ gdt->bmi.bmiHeader.biCompression = BI_RGB;
+ gdt->bmi.bmiHeader.biSizeImage = 0;
+ gdt->bmi.bmiHeader.biXPelsPerMeter = 0;
+ gdt->bmi.bmiHeader.biYPelsPerMeter = 0;
+ gdt->bmi.bmiHeader.biClrUsed = 0;
+ gdt->bmi.bmiHeader.biClrImportant = 0;
+
+ *stride = gdt->stride;
+ return (struct sw_displaytarget *)gdt;
+
+no_data:
+ FREE(gdt);
+no_gdt:
+ return NULL;
+}
+
+
+static struct sw_displaytarget *
+gdi_sw_displaytarget_from_handle(struct sw_winsys *winsys,
+ const struct pipe_resource *templet,
+ struct winsys_handle *whandle,
+ unsigned *stride)
+{
+ assert(0);
+ return NULL;
+}
+
+
+static boolean
+gdi_sw_displaytarget_get_handle(struct sw_winsys *winsys,
+ struct sw_displaytarget *dt,
+ struct winsys_handle *whandle)
+{
+ assert(0);
+ return FALSE;
+}
+
+
+void
+gdi_sw_display( struct sw_winsys *winsys,
+ struct sw_displaytarget *dt,
+ HDC hDC )
+{
+ struct gdi_sw_displaytarget *gdt = gdi_sw_displaytarget(dt);
+
+ StretchDIBits(hDC,
+ 0, 0, gdt->width, gdt->height,
+ 0, 0, gdt->width, gdt->height,
+ gdt->data, &gdt->bmi, 0, SRCCOPY);
+}
+
+static void
+gdi_sw_displaytarget_display(struct sw_winsys *winsys,
+ struct sw_displaytarget *dt,
+ void *context_private)
+{
+ /* nasty:
+ */
+ HDC hDC = (HDC)context_private;
+
+ gdi_sw_display(winsys, dt, hDC);
+}
+
+
+static void
+gdi_sw_destroy(struct sw_winsys *winsys)
+{
+ FREE(winsys);
+}
+
+struct sw_winsys *
+gdi_create_sw_winsys(void)
+{
+ static struct sw_winsys *winsys;
+
+ winsys = CALLOC_STRUCT(sw_winsys);
+ if(!winsys)
+ return NULL;
+
+ winsys->destroy = gdi_sw_destroy;
+ winsys->is_displaytarget_format_supported = gdi_sw_is_displaytarget_format_supported;
+ winsys->displaytarget_create = gdi_sw_displaytarget_create;
+ winsys->displaytarget_from_handle = gdi_sw_displaytarget_from_handle;
+ winsys->displaytarget_get_handle = gdi_sw_displaytarget_get_handle;
+ winsys->displaytarget_map = gdi_sw_displaytarget_map;
+ winsys->displaytarget_unmap = gdi_sw_displaytarget_unmap;
+ winsys->displaytarget_display = gdi_sw_displaytarget_display;
+ winsys->displaytarget_destroy = gdi_sw_displaytarget_destroy;
+
+ return winsys;
+}
+
diff --git a/src/gallium/winsys/sw/gdi/gdi_sw_winsys.h b/src/gallium/winsys/sw/gdi/gdi_sw_winsys.h
new file mode 100644
index 0000000000..4bbcb47848
--- /dev/null
+++ b/src/gallium/winsys/sw/gdi/gdi_sw_winsys.h
@@ -0,0 +1,16 @@
+#ifndef GDI_SW_WINSYS_H
+#define GDI_SW_WINSYS_H
+
+#include <windows.h>
+
+#include "pipe/p_compiler.h"
+#include "state_tracker/sw_winsys.h"
+
+void gdi_sw_display( struct sw_winsys *winsys,
+ struct sw_displaytarget *dt,
+ HDC hDC );
+
+struct sw_winsys *
+gdi_create_sw_winsys(void);
+
+#endif
diff --git a/src/gallium/winsys/sw/null/Makefile b/src/gallium/winsys/sw/null/Makefile
new file mode 100644
index 0000000000..b1882b582e
--- /dev/null
+++ b/src/gallium/winsys/sw/null/Makefile
@@ -0,0 +1,16 @@
+TOP = ../../../../..
+include $(TOP)/configs/current
+
+LIBNAME = ws_null
+
+LIBRARY_INCLUDES = \
+ -I$(TOP)/src/gallium/include \
+ -I$(TOP)/src/gallium/drivers \
+ -I$(TOP)/src/gallium/auxiliary
+
+C_SOURCES = \
+ null_sw_winsys.c
+
+include ../../../Makefile.template
+
+
diff --git a/src/gallium/winsys/sw/null/SConscript b/src/gallium/winsys/sw/null/SConscript
new file mode 100644
index 0000000000..21837dc60c
--- /dev/null
+++ b/src/gallium/winsys/sw/null/SConscript
@@ -0,0 +1,21 @@
+#######################################################################
+# SConscript for xlib winsys
+
+
+Import('*')
+
+env = env.Clone()
+
+env.Append(CPPPATH = [
+ '#/src/gallium/include',
+ '#/src/gallium/auxiliary',
+ '#/src/gallium/drivers',
+])
+
+ws_null = env.ConvenienceLibrary(
+ target = 'ws_null',
+ source = [
+ 'null_sw_winsys.c',
+ ]
+)
+Export('ws_null')
diff --git a/src/gallium/winsys/sw/null/null_sw_winsys.c b/src/gallium/winsys/sw/null/null_sw_winsys.c
new file mode 100644
index 0000000000..157efa9973
--- /dev/null
+++ b/src/gallium/winsys/sw/null/null_sw_winsys.c
@@ -0,0 +1,148 @@
+/**************************************************************************
+ *
+ * Copyright 2010 VMware, Inc.
+ * 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.
+ *
+ **************************************************************************/
+
+/**
+ * @file
+ * Null software rasterizer winsys.
+ *
+ * There is no present support. Framebuffer data needs to be obtained via
+ * transfers.
+ *
+ * @author Jose Fonseca
+ */
+
+
+#include "pipe/p_format.h"
+#include "util/u_memory.h"
+#include "state_tracker/sw_winsys.h"
+#include "null_sw_winsys.h"
+
+
+static boolean
+null_sw_is_displaytarget_format_supported(struct sw_winsys *ws,
+ unsigned tex_usage,
+ enum pipe_format format )
+{
+ return FALSE;
+}
+
+
+static void *
+null_sw_displaytarget_map(struct sw_winsys *ws,
+ struct sw_displaytarget *dt,
+ unsigned flags )
+{
+ assert(0);
+ return NULL;
+}
+
+
+static void
+null_sw_displaytarget_unmap(struct sw_winsys *ws,
+ struct sw_displaytarget *dt )
+{
+ assert(0);
+}
+
+
+static void
+null_sw_displaytarget_destroy(struct sw_winsys *winsys,
+ struct sw_displaytarget *dt)
+{
+ assert(0);
+}
+
+
+static struct sw_displaytarget *
+null_sw_displaytarget_create(struct sw_winsys *winsys,
+ unsigned tex_usage,
+ enum pipe_format format,
+ unsigned width, unsigned height,
+ unsigned alignment,
+ unsigned *stride)
+{
+ return NULL;
+}
+
+
+static struct sw_displaytarget *
+null_sw_displaytarget_from_handle(struct sw_winsys *winsys,
+ const struct pipe_resource *templet,
+ struct winsys_handle *whandle,
+ unsigned *stride)
+{
+ return NULL;
+}
+
+
+static boolean
+null_sw_displaytarget_get_handle(struct sw_winsys *winsys,
+ struct sw_displaytarget *dt,
+ struct winsys_handle *whandle)
+{
+ assert(0);
+ return FALSE;
+}
+
+
+static void
+null_sw_displaytarget_display(struct sw_winsys *winsys,
+ struct sw_displaytarget *dt,
+ void *context_private)
+{
+ assert(0);
+}
+
+
+static void
+null_sw_destroy(struct sw_winsys *winsys)
+{
+ FREE(winsys);
+}
+
+
+struct sw_winsys *
+null_sw_create(void)
+{
+ static struct sw_winsys *winsys;
+
+ winsys = CALLOC_STRUCT(sw_winsys);
+ if (!winsys)
+ return NULL;
+
+ winsys->destroy = null_sw_destroy;
+ winsys->is_displaytarget_format_supported = null_sw_is_displaytarget_format_supported;
+ winsys->displaytarget_create = null_sw_displaytarget_create;
+ winsys->displaytarget_from_handle = null_sw_displaytarget_from_handle;
+ winsys->displaytarget_get_handle = null_sw_displaytarget_get_handle;
+ winsys->displaytarget_map = null_sw_displaytarget_map;
+ winsys->displaytarget_unmap = null_sw_displaytarget_unmap;
+ winsys->displaytarget_display = null_sw_displaytarget_display;
+ winsys->displaytarget_destroy = null_sw_displaytarget_destroy;
+
+ return winsys;
+}
diff --git a/src/gallium/winsys/sw/null/null_sw_winsys.h b/src/gallium/winsys/sw/null/null_sw_winsys.h
new file mode 100644
index 0000000000..1986186feb
--- /dev/null
+++ b/src/gallium/winsys/sw/null/null_sw_winsys.h
@@ -0,0 +1,40 @@
+/**************************************************************************
+ *
+ * Copyright 2010 VMware, Inc.
+ * 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.
+ *
+ **************************************************************************/
+
+
+#ifndef NULL_SW_WINSYS_H_
+#define NULL_SW_WINSYS_H_
+
+
+struct sw_winsys;
+
+
+struct sw_winsys *
+null_sw_create(void);
+
+
+#endif /* NULL_SW_WINSYS_H_ */
diff --git a/src/gallium/winsys/sw/wrapper/Makefile b/src/gallium/winsys/sw/wrapper/Makefile
new file mode 100644
index 0000000000..4771fbcf70
--- /dev/null
+++ b/src/gallium/winsys/sw/wrapper/Makefile
@@ -0,0 +1,12 @@
+TOP = ../../../../..
+include $(TOP)/configs/current
+
+LIBNAME = wsw
+
+C_SOURCES = wrapper_sw_winsys.c
+
+LIBRARY_INCLUDES =
+
+LIBRARY_DEFINES =
+
+include ../../../Makefile.template
diff --git a/src/gallium/winsys/sw/wrapper/SConscript b/src/gallium/winsys/sw/wrapper/SConscript
new file mode 100644
index 0000000000..4c60488df0
--- /dev/null
+++ b/src/gallium/winsys/sw/wrapper/SConscript
@@ -0,0 +1,21 @@
+#######################################################################
+# SConscript for xlib winsys
+
+
+Import('*')
+
+env = env.Clone()
+
+env.Append(CPPPATH = [
+ '#/src/gallium/include',
+ '#/src/gallium/auxiliary',
+ '#/src/gallium/drivers',
+])
+
+ws_wrapper = env.ConvenienceLibrary(
+ target = 'ws_wrapper',
+ source = [
+ 'wrapper_sw_winsys.c',
+ ]
+)
+Export('ws_wrapper')
diff --git a/src/gallium/winsys/sw/wrapper/wrapper_sw_winsys.c b/src/gallium/winsys/sw/wrapper/wrapper_sw_winsys.c
new file mode 100644
index 0000000000..b997abda9b
--- /dev/null
+++ b/src/gallium/winsys/sw/wrapper/wrapper_sw_winsys.c
@@ -0,0 +1,300 @@
+/**********************************************************
+ * Copyright 2010 VMware, Inc. 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, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ **********************************************************/
+
+
+#include "wrapper_sw_winsys.h"
+
+#include "pipe/p_format.h"
+#include "pipe/p_state.h"
+
+#include "state_tracker/sw_winsys.h"
+
+#include "util/u_memory.h"
+#include "util/u_inlines.h"
+
+/*
+ * This code wraps a pipe_screen and exposes a sw_winsys interface for use
+ * with software resterizers. This code is used by the DRM based winsys to
+ * allow access to the drm driver.
+ *
+ * We must borrow the whole stack because only the pipe screen knows how
+ * to decode the content of a buffer. Or how to create a buffer that
+ * can still be used by drivers using real hardware (as the case is
+ * with software st/xorg but hw st/dri).
+ *
+ * We also need a pipe context for the transfers.
+ */
+
+struct wrapper_sw_winsys
+{
+ struct sw_winsys base;
+ struct pipe_screen *screen;
+ struct pipe_context *pipe;
+};
+
+struct wrapper_sw_displaytarget
+{
+ struct wrapper_sw_winsys *winsys;
+ struct pipe_resource *tex;
+ struct pipe_transfer *transfer;
+
+ unsigned width;
+ unsigned height;
+ unsigned map_count;
+ unsigned stride; /**< because we give stride at create */
+ void *ptr;
+};
+
+static INLINE struct wrapper_sw_winsys *
+wrapper_sw_winsys(struct sw_winsys *ws)
+{
+ return (struct wrapper_sw_winsys *)ws;
+}
+
+static INLINE struct wrapper_sw_displaytarget *
+wrapper_sw_displaytarget(struct sw_displaytarget *dt)
+{
+ return (struct wrapper_sw_displaytarget *)dt;
+}
+
+
+/*
+ * Functions
+ */
+
+
+static boolean
+wsw_dt_get_stride(struct wrapper_sw_displaytarget *wdt, unsigned *stride)
+{
+ struct pipe_context *pipe = wdt->winsys->pipe;
+ struct pipe_resource *tex = wdt->tex;
+ struct pipe_transfer *tr;
+
+ tr = pipe_get_transfer(pipe, tex, 0, 0, 0,
+ PIPE_TRANSFER_READ_WRITE,
+ 0, 0, wdt->width, wdt->height);
+ if (!tr)
+ return FALSE;
+
+ *stride = tr->stride;
+ wdt->stride = tr->stride;
+
+ pipe->transfer_destroy(pipe, tr);
+
+ return TRUE;
+}
+
+static struct sw_displaytarget *
+wsw_dt_wrap_texture(struct wrapper_sw_winsys *wsw,
+ struct pipe_resource *tex, unsigned *stride)
+{
+ struct wrapper_sw_displaytarget *wdt = CALLOC_STRUCT(wrapper_sw_displaytarget);
+ if (!wdt)
+ goto err_unref;
+
+ wdt->tex = tex;
+ wdt->winsys = wsw;
+
+ if (!wsw_dt_get_stride(wdt, stride))
+ goto err_free;
+
+ return (struct sw_displaytarget *)wdt;
+
+err_free:
+ FREE(wdt);
+err_unref:
+ pipe_resource_reference(&tex, NULL);
+ return NULL;
+}
+
+static struct sw_displaytarget *
+wsw_dt_create(struct sw_winsys *ws,
+ unsigned bind,
+ enum pipe_format format,
+ unsigned width, unsigned height,
+ unsigned alignment,
+ unsigned *stride)
+{
+ struct wrapper_sw_winsys *wsw = wrapper_sw_winsys(ws);
+ struct pipe_resource templ;
+ struct pipe_resource *tex;
+
+ /*
+ * XXX Why don't we just get the template.
+ */
+ memset(&templ, 0, sizeof(templ));
+ templ.target = PIPE_TEXTURE_2D;
+ templ.width0 = width;
+ templ.height0 = height;
+ templ.format = format;
+ templ.bind = bind;
+
+ /* XXX alignment: we can't do anything about this */
+
+ tex = wsw->screen->resource_create(wsw->screen, &templ);
+ if (!tex)
+ return NULL;
+
+ return wsw_dt_wrap_texture(wsw, tex, stride);
+}
+
+static struct sw_displaytarget *
+wsw_dt_from_handle(struct sw_winsys *ws,
+ const struct pipe_resource *templ,
+ struct winsys_handle *whandle,
+ unsigned *stride)
+{
+ struct wrapper_sw_winsys *wsw = wrapper_sw_winsys(ws);
+ struct pipe_resource *tex;
+
+ tex = wsw->screen->resource_from_handle(wsw->screen, templ, whandle);
+ if (!tex)
+ return NULL;
+
+ return wsw_dt_wrap_texture(wsw, tex, stride);
+}
+
+static boolean
+wsw_dt_get_handle(struct sw_winsys *ws,
+ struct sw_displaytarget *dt,
+ struct winsys_handle *whandle)
+{
+ struct wrapper_sw_winsys *wsw = wrapper_sw_winsys(ws);
+ struct wrapper_sw_displaytarget *wdt = wrapper_sw_displaytarget(dt);
+ struct pipe_resource *tex = wdt->tex;
+
+ return wsw->screen->resource_get_handle(wsw->screen, tex, whandle);
+}
+
+static void *
+wsw_dt_map(struct sw_winsys *ws,
+ struct sw_displaytarget *dt,
+ unsigned flags)
+{
+ struct wrapper_sw_displaytarget *wdt = wrapper_sw_displaytarget(dt);
+ struct pipe_context *pipe = wdt->winsys->pipe;
+ struct pipe_resource *tex = wdt->tex;
+ struct pipe_transfer *tr;
+ void *ptr;
+
+ if (!wdt->map_count) {
+
+ assert(!wdt->transfer);
+
+ tr = pipe_get_transfer(pipe, tex, 0, 0, 0,
+ PIPE_TRANSFER_READ_WRITE,
+ 0, 0, wdt->width, wdt->height);
+ if (!tr)
+ return NULL;
+
+ ptr = pipe->transfer_map(pipe, tr);
+ if (!ptr)
+ goto err;
+
+ wdt->transfer = tr;
+ wdt->ptr = ptr;
+
+ /* XXX Handle this case */
+ assert(tr->stride == wdt->stride);
+ }
+
+ wdt->map_count++;
+
+ return wdt->ptr;
+
+err:
+ pipe->transfer_destroy(pipe, tr);
+ return NULL;
+}
+
+static void
+wsw_dt_unmap(struct sw_winsys *ws,
+ struct sw_displaytarget *dt)
+{
+ struct wrapper_sw_displaytarget *wdt = wrapper_sw_displaytarget(dt);
+ struct pipe_context *pipe = wdt->winsys->pipe;
+
+ assert(wdt->transfer);
+
+ wdt->map_count--;
+
+ if (wdt->map_count)
+ return;
+
+ pipe->transfer_unmap(pipe, wdt->transfer);
+ pipe->transfer_destroy(pipe, wdt->transfer);
+ wdt->transfer = NULL;
+}
+
+static void
+wsw_dt_destroy(struct sw_winsys *ws,
+ struct sw_displaytarget *dt)
+{
+ struct wrapper_sw_displaytarget *wdt = wrapper_sw_displaytarget(dt);
+
+ pipe_resource_reference(&wdt->tex, NULL);
+
+ FREE(wdt);
+}
+
+static void
+wsw_destroy(struct sw_winsys *ws)
+{
+ struct wrapper_sw_winsys *wsw = wrapper_sw_winsys(ws);
+
+ wsw->pipe->destroy(wsw->pipe);
+ wsw->screen->destroy(wsw->screen);
+
+ FREE(wsw);
+}
+
+struct sw_winsys *
+wrapper_sw_winsys_warp_pipe_screen(struct pipe_screen *screen)
+{
+ struct wrapper_sw_winsys *wsw = CALLOC_STRUCT(wrapper_sw_winsys);
+
+ if (!wsw)
+ goto err;
+
+ wsw->base.displaytarget_create = wsw_dt_create;
+ wsw->base.displaytarget_from_handle = wsw_dt_from_handle;
+ wsw->base.displaytarget_get_handle = wsw_dt_get_handle;
+ wsw->base.displaytarget_map = wsw_dt_map;
+ wsw->base.displaytarget_unmap = wsw_dt_unmap;
+ wsw->base.displaytarget_destroy = wsw_dt_destroy;
+ wsw->base.destroy = wsw_destroy;
+
+ wsw->screen = screen;
+ wsw->pipe = screen->context_create(screen, NULL);
+ if (!wsw->pipe)
+ goto err_free;
+
+ return &wsw->base;
+
+err_free:
+ FREE(wsw);
+err:
+ return NULL;
+}
diff --git a/src/gallium/winsys/sw/wrapper/wrapper_sw_winsys.h b/src/gallium/winsys/sw/wrapper/wrapper_sw_winsys.h
new file mode 100644
index 0000000000..b5c25a3c50
--- /dev/null
+++ b/src/gallium/winsys/sw/wrapper/wrapper_sw_winsys.h
@@ -0,0 +1,35 @@
+/**********************************************************
+ * Copyright 2010 VMware, Inc. 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, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ **********************************************************/
+
+
+#ifndef WRAPPER_SW_WINSYS
+#define WRAPPER_SW_WINSYS
+
+struct sw_winsys;
+struct pipe_screen;
+
+struct sw_winsys *wrapper_sw_winsys_warp_pipe_screen(struct pipe_screen *screen);
+
+#endif
diff --git a/src/gallium/winsys/sw/xlib/Makefile b/src/gallium/winsys/sw/xlib/Makefile
new file mode 100644
index 0000000000..c669389928
--- /dev/null
+++ b/src/gallium/winsys/sw/xlib/Makefile
@@ -0,0 +1,17 @@
+TOP = ../../../../..
+include $(TOP)/configs/current
+
+LIBNAME = ws_xlib
+
+LIBRARY_INCLUDES = \
+ -I$(TOP)/src/gallium/include \
+ -I$(TOP)/src/gallium/drivers \
+ -I$(TOP)/src/gallium/auxiliary \
+ $(X11_CFLAGS)
+
+C_SOURCES = \
+ xlib_sw_winsys.c
+
+include ../../../Makefile.template
+
+
diff --git a/src/gallium/winsys/sw/xlib/SConscript b/src/gallium/winsys/sw/xlib/SConscript
new file mode 100644
index 0000000000..2af6153b4c
--- /dev/null
+++ b/src/gallium/winsys/sw/xlib/SConscript
@@ -0,0 +1,23 @@
+#######################################################################
+# SConscript for xlib winsys
+
+
+Import('*')
+
+if env['platform'] == 'linux':
+
+ env = env.Clone()
+
+ env.Append(CPPPATH = [
+ '#/src/gallium/include',
+ '#/src/gallium/auxiliary',
+ '#/src/gallium/drivers',
+ ])
+
+ ws_xlib = env.ConvenienceLibrary(
+ target = 'ws_xlib',
+ source = [
+ 'xlib_sw_winsys.c',
+ ]
+ )
+ Export('ws_xlib')
diff --git a/src/gallium/winsys/sw/xlib/xlib_sw_winsys.c b/src/gallium/winsys/sw/xlib/xlib_sw_winsys.c
new file mode 100644
index 0000000000..b78f537c12
--- /dev/null
+++ b/src/gallium/winsys/sw/xlib/xlib_sw_winsys.c
@@ -0,0 +1,473 @@
+/**************************************************************************
+ *
+ * Copyright 2007 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:
+ * Keith Whitwell
+ * Brian Paul
+ */
+
+#include "pipe/p_format.h"
+#include "pipe/p_context.h"
+#include "util/u_inlines.h"
+#include "util/u_format.h"
+#include "util/u_math.h"
+#include "util/u_memory.h"
+
+#include "state_tracker/xlib_sw_winsys.h"
+
+#include <X11/Xlib.h>
+#include <X11/Xlibint.h>
+#include <X11/Xutil.h>
+#include <sys/ipc.h>
+#include <sys/shm.h>
+#include <X11/extensions/XShm.h>
+
+DEBUG_GET_ONCE_BOOL_OPTION(xlib_no_shm, "XLIB_NO_SHM", FALSE)
+
+/**
+ * Display target for Xlib winsys.
+ * Low-level OS/window system memory buffer
+ */
+struct xm_displaytarget
+{
+ enum pipe_format format;
+ unsigned width;
+ unsigned height;
+ unsigned stride;
+
+ void *data;
+ void *mapped;
+
+ Display *display;
+ Visual *visual;
+ XImage *tempImage;
+ GC gc;
+
+ /* This is the last drawable that this display target was presented
+ * against. May need to recreate gc, tempImage when this changes??
+ */
+ Drawable drawable;
+
+ XShmSegmentInfo shminfo;
+ int shm;
+};
+
+
+/**
+ * Subclass of sw_winsys for Xlib winsys
+ */
+struct xlib_sw_winsys
+{
+ struct sw_winsys base;
+
+
+
+ Display *display;
+};
+
+
+
+/** Cast wrapper */
+static INLINE struct xm_displaytarget *
+xm_displaytarget( struct sw_displaytarget *dt )
+{
+ return (struct xm_displaytarget *)dt;
+}
+
+
+/**
+ * X Shared Memory Image extension code
+ */
+
+static volatile int mesaXErrorFlag = 0;
+
+/**
+ * Catches potential Xlib errors.
+ */
+static int
+mesaHandleXError(Display *dpy, XErrorEvent *event)
+{
+ (void) dpy;
+ (void) event;
+ mesaXErrorFlag = 1;
+ return 0;
+}
+
+
+static char *alloc_shm(struct xm_displaytarget *buf, unsigned size)
+{
+ XShmSegmentInfo *const shminfo = & buf->shminfo;
+
+ shminfo->shmid = -1;
+ shminfo->shmaddr = (char *) -1;
+
+ shminfo->shmid = shmget(IPC_PRIVATE, size, IPC_CREAT|0777);
+ if (shminfo->shmid < 0) {
+ return NULL;
+ }
+
+ shminfo->shmaddr = (char *) shmat(shminfo->shmid, 0, 0);
+ if (shminfo->shmaddr == (char *) -1) {
+ shmctl(shminfo->shmid, IPC_RMID, 0);
+ return NULL;
+ }
+
+ shminfo->readOnly = False;
+ return shminfo->shmaddr;
+}
+
+
+/**
+ * Allocate a shared memory XImage back buffer for the given XMesaBuffer.
+ */
+static void
+alloc_shm_ximage(struct xm_displaytarget *xm_dt,
+ struct xlib_drawable *xmb,
+ unsigned width, unsigned height)
+{
+ /*
+ * We have to do a _lot_ of error checking here to be sure we can
+ * really use the XSHM extension. It seems different servers trigger
+ * errors at different points if the extension won't work. Therefore
+ * we have to be very careful...
+ */
+ int (*old_handler)(Display *, XErrorEvent *);
+
+ xm_dt->tempImage = XShmCreateImage(xm_dt->display,
+ xmb->visual,
+ xmb->depth,
+ ZPixmap,
+ NULL,
+ &xm_dt->shminfo,
+ width, height);
+ if (xm_dt->tempImage == NULL) {
+ xm_dt->shm = 0;
+ return;
+ }
+
+
+ mesaXErrorFlag = 0;
+ old_handler = XSetErrorHandler(mesaHandleXError);
+ /* This may trigger the X protocol error we're ready to catch: */
+ XShmAttach(xm_dt->display, &xm_dt->shminfo);
+ XSync(xm_dt->display, False);
+
+ if (mesaXErrorFlag) {
+ /* we are on a remote display, this error is normal, don't print it */
+ XFlush(xm_dt->display);
+ mesaXErrorFlag = 0;
+ XDestroyImage(xm_dt->tempImage);
+ xm_dt->tempImage = NULL;
+ xm_dt->shm = 0;
+ (void) XSetErrorHandler(old_handler);
+ return;
+ }
+
+ xm_dt->shm = 1;
+}
+
+
+static void
+alloc_ximage(struct xm_displaytarget *xm_dt,
+ struct xlib_drawable *xmb,
+ unsigned width, unsigned height)
+{
+ if (xm_dt->shm) {
+ alloc_shm_ximage(xm_dt, xmb, width, height);
+ return;
+ }
+
+ xm_dt->tempImage = XCreateImage(xm_dt->display,
+ xmb->visual,
+ xmb->depth,
+ ZPixmap, 0,
+ NULL, width, height,
+ 8, 0);
+}
+
+static boolean
+xm_is_displaytarget_format_supported( struct sw_winsys *ws,
+ unsigned tex_usage,
+ enum pipe_format format )
+{
+ /* TODO: check visuals or other sensible thing here */
+ return TRUE;
+}
+
+
+static void *
+xm_displaytarget_map(struct sw_winsys *ws,
+ struct sw_displaytarget *dt,
+ unsigned flags)
+{
+ struct xm_displaytarget *xm_dt = xm_displaytarget(dt);
+ xm_dt->mapped = xm_dt->data;
+ return xm_dt->mapped;
+}
+
+static void
+xm_displaytarget_unmap(struct sw_winsys *ws,
+ struct sw_displaytarget *dt)
+{
+ struct xm_displaytarget *xm_dt = xm_displaytarget(dt);
+ xm_dt->mapped = NULL;
+}
+
+static void
+xm_displaytarget_destroy(struct sw_winsys *ws,
+ struct sw_displaytarget *dt)
+{
+ struct xm_displaytarget *xm_dt = xm_displaytarget(dt);
+
+ if (xm_dt->data) {
+ if (xm_dt->shminfo.shmid >= 0) {
+ shmdt(xm_dt->shminfo.shmaddr);
+ shmctl(xm_dt->shminfo.shmid, IPC_RMID, 0);
+
+ xm_dt->shminfo.shmid = -1;
+ xm_dt->shminfo.shmaddr = (char *) -1;
+ }
+ else {
+ FREE(xm_dt->data);
+ if (xm_dt->tempImage && xm_dt->tempImage->data == xm_dt->data) {
+ xm_dt->tempImage->data = NULL;
+ }
+ xm_dt->data = NULL;
+ }
+ }
+
+ if (xm_dt->tempImage) {
+ XDestroyImage(xm_dt->tempImage);
+ xm_dt->tempImage = NULL;
+ }
+
+ if (xm_dt->gc)
+ XFreeGC(xm_dt->display, xm_dt->gc);
+
+ FREE(xm_dt);
+}
+
+
+/**
+ * Display/copy the image in the surface into the X window specified
+ * by the XMesaBuffer.
+ */
+static void
+xlib_sw_display(struct xlib_drawable *xlib_drawable,
+ struct sw_displaytarget *dt)
+{
+ static boolean no_swap = 0;
+ static boolean firsttime = 1;
+ struct xm_displaytarget *xm_dt = xm_displaytarget(dt);
+ Display *display = xm_dt->display;
+ XImage *ximage;
+
+ if (firsttime) {
+ no_swap = getenv("SP_NO_RAST") != NULL;
+ firsttime = 0;
+ }
+
+ if (no_swap)
+ return;
+
+ if (xm_dt->drawable != xlib_drawable->drawable) {
+ if (xm_dt->gc) {
+ XFreeGC( display, xm_dt->gc );
+ xm_dt->gc = NULL;
+ }
+
+ if (xm_dt->tempImage) {
+ XDestroyImage( xm_dt->tempImage );
+ xm_dt->tempImage = NULL;
+ }
+
+ xm_dt->drawable = xlib_drawable->drawable;
+ }
+
+ if (xm_dt->tempImage == NULL) {
+ assert(util_format_get_blockwidth(xm_dt->format) == 1);
+ assert(util_format_get_blockheight(xm_dt->format) == 1);
+ alloc_ximage(xm_dt, xlib_drawable,
+ xm_dt->stride / util_format_get_blocksize(xm_dt->format),
+ xm_dt->height);
+ if (!xm_dt->tempImage)
+ return;
+ }
+
+ if (xm_dt->gc == NULL) {
+ xm_dt->gc = XCreateGC( display, xlib_drawable->drawable, 0, NULL );
+ XSetFunction( display, xm_dt->gc, GXcopy );
+ }
+
+ if (xm_dt->shm)
+ {
+ ximage = xm_dt->tempImage;
+ ximage->data = xm_dt->data;
+
+ /* _debug_printf("XSHM\n"); */
+ XShmPutImage(xm_dt->display, xlib_drawable->drawable, xm_dt->gc,
+ ximage, 0, 0, 0, 0, xm_dt->width, xm_dt->height, False);
+ }
+ else {
+ /* display image in Window */
+ ximage = xm_dt->tempImage;
+ ximage->data = xm_dt->data;
+
+ /* check that the XImage has been previously initialized */
+ assert(ximage->format);
+ assert(ximage->bitmap_unit);
+
+ /* update XImage's fields */
+ ximage->width = xm_dt->width;
+ ximage->height = xm_dt->height;
+ ximage->bytes_per_line = xm_dt->stride;
+
+ /* _debug_printf("XPUT\n"); */
+ XPutImage(xm_dt->display, xlib_drawable->drawable, xm_dt->gc,
+ ximage, 0, 0, 0, 0, xm_dt->width, xm_dt->height);
+ }
+
+ XFlush(xm_dt->display);
+}
+
+/**
+ * Display/copy the image in the surface into the X window specified
+ * by the XMesaBuffer.
+ */
+static void
+xm_displaytarget_display(struct sw_winsys *ws,
+ struct sw_displaytarget *dt,
+ void *context_private)
+{
+ struct xlib_drawable *xlib_drawable = (struct xlib_drawable *)context_private;
+ xlib_sw_display(xlib_drawable, dt);
+}
+
+
+static struct sw_displaytarget *
+xm_displaytarget_create(struct sw_winsys *winsys,
+ unsigned tex_usage,
+ enum pipe_format format,
+ unsigned width, unsigned height,
+ unsigned alignment,
+ unsigned *stride)
+{
+ struct xm_displaytarget *xm_dt;
+ unsigned nblocksy, size;
+
+ xm_dt = CALLOC_STRUCT(xm_displaytarget);
+ if(!xm_dt)
+ goto no_xm_dt;
+
+ xm_dt->display = ((struct xlib_sw_winsys *)winsys)->display;
+ xm_dt->format = format;
+ xm_dt->width = width;
+ xm_dt->height = height;
+
+ nblocksy = util_format_get_nblocksy(format, height);
+ xm_dt->stride = align(util_format_get_stride(format, width), alignment);
+ size = xm_dt->stride * nblocksy;
+
+ if (!debug_get_option_xlib_no_shm()) {
+ xm_dt->data = alloc_shm(xm_dt, size);
+ if (xm_dt->data) {
+ xm_dt->shm = TRUE;
+ }
+ }
+
+ if(!xm_dt->data) {
+ xm_dt->data = align_malloc(size, alignment);
+ if(!xm_dt->data)
+ goto no_data;
+ }
+
+ *stride = xm_dt->stride;
+ return (struct sw_displaytarget *)xm_dt;
+
+no_data:
+ FREE(xm_dt);
+no_xm_dt:
+ return NULL;
+}
+
+
+static struct sw_displaytarget *
+xm_displaytarget_from_handle(struct sw_winsys *winsys,
+ const struct pipe_resource *templet,
+ struct winsys_handle *whandle,
+ unsigned *stride)
+{
+ assert(0);
+ return NULL;
+}
+
+
+static boolean
+xm_displaytarget_get_handle(struct sw_winsys *winsys,
+ struct sw_displaytarget *dt,
+ struct winsys_handle *whandle)
+{
+ assert(0);
+ return FALSE;
+}
+
+
+static void
+xm_destroy( struct sw_winsys *ws )
+{
+ FREE(ws);
+}
+
+
+struct sw_winsys *
+xlib_create_sw_winsys( Display *display )
+{
+ struct xlib_sw_winsys *ws;
+
+ ws = CALLOC_STRUCT(xlib_sw_winsys);
+ if (!ws)
+ return NULL;
+
+ ws->display = display;
+ ws->base.destroy = xm_destroy;
+
+ ws->base.is_displaytarget_format_supported = xm_is_displaytarget_format_supported;
+
+ ws->base.displaytarget_create = xm_displaytarget_create;
+ ws->base.displaytarget_from_handle = xm_displaytarget_from_handle;
+ ws->base.displaytarget_get_handle = xm_displaytarget_get_handle;
+ ws->base.displaytarget_map = xm_displaytarget_map;
+ ws->base.displaytarget_unmap = xm_displaytarget_unmap;
+ ws->base.displaytarget_destroy = xm_displaytarget_destroy;
+
+ ws->base.displaytarget_display = xm_displaytarget_display;
+
+ return &ws->base;
+}
+