xf86-video-intel: 7 commits - configure.ac src/sna/gen3_render.c src/sna/gen7_render.c src/sna/kgem.c src/sna/kgem_debug.c src/sna/kgem_debug_gen7.c src/sna/kgem_debug.h src/sna/Makefile.am src/sna/sna_accel.c src/sna/sna_dri.c src/sna/sna_driver.c src/sna/sna.h

Chris Wilson ickle at kemper.freedesktop.org
Thu Nov 10 16:17:20 PST 2011


 configure.ac              |    1 
 src/sna/Makefile.am       |    1 
 src/sna/gen3_render.c     |    5 
 src/sna/gen7_render.c     |    1 
 src/sna/kgem.c            |    2 
 src/sna/kgem_debug.c      |   10 
 src/sna/kgem_debug.h      |    3 
 src/sna/kgem_debug_gen7.c |  747 ++++++++++++++++++++++++++++++++++++++++++++++
 src/sna/sna.h             |   22 -
 src/sna/sna_accel.c       |  175 ++++++----
 src/sna/sna_dri.c         |   32 +
 src/sna/sna_driver.c      |   39 +-
 12 files changed, 924 insertions(+), 114 deletions(-)

New commits:
commit 8f50950f467eb2440009a807081f3ba2c9db209b
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Thu Nov 10 15:58:36 2011 +0000

    sna/gen7: Remove stray no-op from GEN7_3DSTATE_SBE
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/gen7_render.c b/src/sna/gen7_render.c
index 7947749..d0bd545 100644
--- a/src/sna/gen7_render.c
+++ b/src/sna/gen7_render.c
@@ -770,7 +770,6 @@ gen7_emit_sf(struct sna *sna, Bool has_mask)
 		  1 << GEN7_SBE_URB_ENTRY_READ_LENGTH_SHIFT |
 		  1 << GEN7_SBE_URB_ENTRY_READ_OFFSET_SHIFT);
 	OUT_BATCH(0);
-	OUT_BATCH(0);
 	OUT_BATCH(0); /* dw4 */
 	OUT_BATCH(0);
 	OUT_BATCH(0);
commit 6a8338fc08a1b7e5e2c6722baa87cff3915b6ef9
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Thu Nov 10 15:11:13 2011 +0000

    sna: Begin debugging gen7
    
    This is the stub of the decoder, sufficient to give details of the ops
    within the batch and to keep the debugger happy.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/Makefile.am b/src/sna/Makefile.am
index 2a10801..ac60988 100644
--- a/src/sna/Makefile.am
+++ b/src/sna/Makefile.am
@@ -98,6 +98,7 @@ libsna_la_SOURCES += \
 	kgem_debug_gen4.c \
 	kgem_debug_gen5.c \
 	kgem_debug_gen6.c \
+	kgem_debug_gen7.c \
 	$(NULL)
 endif
 
diff --git a/src/sna/kgem_debug.c b/src/sna/kgem_debug.c
index ad0a533..e833a6f 100644
--- a/src/sna/kgem_debug.c
+++ b/src/sna/kgem_debug.c
@@ -368,7 +368,10 @@ decode_2d(struct kgem *kgem, uint32_t offset)
 
 static int (*decode_3d(int gen))(struct kgem*, uint32_t)
 {
-	if (gen >= 60) {
+	if (gen >= 80) {
+	} else if (gen >= 70) {
+		return kgem_gen7_decode_3d;
+	} else if (gen >= 60) {
 		return kgem_gen6_decode_3d;
 	} else if (gen >= 50) {
 		return kgem_gen5_decode_3d;
@@ -384,7 +387,10 @@ static int (*decode_3d(int gen))(struct kgem*, uint32_t)
 
 static void (*finish_state(int gen))(struct kgem*)
 {
-	if (gen >= 60) {
+	if (gen >= 80) {
+	} else if (gen >= 70) {
+		return kgem_gen7_finish_state;
+	} else if (gen >= 60) {
 		return kgem_gen6_finish_state;
 	} else if (gen >= 50) {
 		return kgem_gen5_finish_state;
diff --git a/src/sna/kgem_debug.h b/src/sna/kgem_debug.h
index 9211dcb..82d6f66 100644
--- a/src/sna/kgem_debug.h
+++ b/src/sna/kgem_debug.h
@@ -13,6 +13,9 @@ struct kgem_bo *
 kgem_debug_get_bo_for_reloc_entry(struct kgem *kgem,
 				  struct drm_i915_gem_relocation_entry *reloc);
 
+int kgem_gen7_decode_3d(struct kgem *kgem, uint32_t offset);
+void kgem_gen7_finish_state(struct kgem *kgem);
+
 int kgem_gen6_decode_3d(struct kgem *kgem, uint32_t offset);
 void kgem_gen6_finish_state(struct kgem *kgem);
 
diff --git a/src/sna/kgem_debug_gen7.c b/src/sna/kgem_debug_gen7.c
new file mode 100644
index 0000000..f6a4975
--- /dev/null
+++ b/src/sna/kgem_debug_gen7.c
@@ -0,0 +1,747 @@
+/*
+ * Copyright © 2007-2011 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Authors:
+ *    Eric Anholt <eric at anholt.net>
+ *    Chris Wilson <chris"chris-wilson.co.uk>
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <sys/mman.h>
+#include <assert.h>
+
+#include "sna.h"
+#include "sna_reg.h"
+#include "gen7_render.h"
+
+#include "kgem_debug.h"
+
+static struct state {
+	struct vertex_buffer {
+		int handle;
+		void *base;
+		const char *ptr;
+		int pitch;
+
+		struct kgem_bo *current;
+	} vb[33];
+	struct vertex_elements {
+		int buffer;
+		int offset;
+		bool valid;
+		uint32_t type;
+		uint8_t swizzle[4];
+	} ve[33];
+	int num_ve;
+
+	struct dynamic_state {
+		struct kgem_bo *current;
+		void *base, *ptr;
+	} dynamic_state;
+} state;
+
+static void gen7_update_vertex_buffer(struct kgem *kgem, const uint32_t *data)
+{
+	uint32_t reloc = sizeof(uint32_t) * (&data[1] - kgem->batch);
+	struct kgem_bo *bo = NULL;
+	void *base, *ptr;
+	int i;
+
+	for (i = 0; i < kgem->nreloc; i++)
+		if (kgem->reloc[i].offset == reloc)
+			break;
+	assert(i < kgem->nreloc);
+	reloc = kgem->reloc[i].target_handle;
+
+	if (reloc == 0) {
+		base = kgem->batch;
+	} else {
+		list_for_each_entry(bo, &kgem->next_request->buffers, request)
+			if (bo->handle == reloc)
+				break;
+		assert(&bo->request != &kgem->next_request->buffers);
+		base = kgem_bo_map(kgem, bo, PROT_READ);
+	}
+	ptr = (char *)base + kgem->reloc[i].delta;
+
+	i = data[0] >> 26;
+	if (state.vb[i].current)
+		munmap(state.vb[i].base, state.vb[i].current->size);
+
+	state.vb[i].current = bo;
+	state.vb[i].base = base;
+	state.vb[i].ptr = ptr;
+	state.vb[i].pitch = data[0] & 0x7ff;
+}
+
+static void gen7_update_dynamic_buffer(struct kgem *kgem, const uint32_t offset)
+{
+	uint32_t reloc = sizeof(uint32_t) * offset;
+	struct kgem_bo *bo = NULL;
+	void *base, *ptr;
+	int i;
+
+	if ((kgem->batch[offset] & 1) == 0)
+		return;
+
+	for (i = 0; i < kgem->nreloc; i++)
+		if (kgem->reloc[i].offset == reloc)
+			break;
+	if(i < kgem->nreloc) {
+		reloc = kgem->reloc[i].target_handle;
+
+		if (reloc == 0) {
+			base = kgem->batch;
+		} else {
+			list_for_each_entry(bo, &kgem->next_request->buffers, request)
+				if (bo->handle == reloc)
+					break;
+			assert(&bo->request != &kgem->next_request->buffers);
+			base = kgem_bo_map(kgem, bo, PROT_READ);
+		}
+		ptr = (char *)base + (kgem->reloc[i].delta & ~1);
+	} else {
+		bo = NULL;
+		base = NULL;
+		ptr = NULL;
+	}
+
+	if (state.dynamic_state.current)
+		munmap(state.dynamic_state.base, state.dynamic_state.current->size);
+
+	state.dynamic_state.current = bo;
+	state.dynamic_state.base = base;
+	state.dynamic_state.ptr = ptr;
+}
+
+static uint32_t
+get_ve_component(uint32_t data, int component)
+{
+	return (data >> (16 + (3 - component) * 4)) & 0x7;
+}
+
+static void gen7_update_vertex_elements(struct kgem *kgem, int id, const uint32_t *data)
+{
+	state.ve[id].buffer = data[0] >> 26;
+	state.ve[id].valid = !!(data[0] & (1 << 25));
+	state.ve[id].type = (data[0] >> 16) & 0x1ff;
+	state.ve[id].offset = data[0] & 0x7ff;
+	state.ve[id].swizzle[0] = get_ve_component(data[1], 0);
+	state.ve[id].swizzle[1] = get_ve_component(data[1], 1);
+	state.ve[id].swizzle[2] = get_ve_component(data[1], 2);
+	state.ve[id].swizzle[3] = get_ve_component(data[1], 3);
+}
+
+static void gen7_update_sf_state(struct kgem *kgem, uint32_t *data)
+{
+	state.num_ve = 1 + ((data[1] >> 22) & 0x3f);
+}
+
+static void vertices_sint16_out(const struct vertex_elements *ve, const int16_t *v, int max)
+{
+	int c;
+
+	ErrorF("(");
+	for (c = 0; c < max; c++) {
+		switch (ve->swizzle[c]) {
+		case 0: ErrorF("#"); break;
+		case 1: ErrorF("%d", v[c]); break;
+		case 2: ErrorF("0.0"); break;
+		case 3: ErrorF("1.0"); break;
+		case 4: ErrorF("0x1"); break;
+		case 5: break;
+		default: ErrorF("?");
+		}
+		if (c < 3)
+			ErrorF(", ");
+	}
+	for (; c < 4; c++) {
+		switch (ve->swizzle[c]) {
+		case 0: ErrorF("#"); break;
+		case 1: ErrorF("1.0"); break;
+		case 2: ErrorF("0.0"); break;
+		case 3: ErrorF("1.0"); break;
+		case 4: ErrorF("0x1"); break;
+		case 5: break;
+		default: ErrorF("?");
+		}
+		if (c < 3)
+			ErrorF(", ");
+	}
+	ErrorF(")");
+}
+
+static void vertices_float_out(const struct vertex_elements *ve, const float *f, int max)
+{
+	int c, o;
+
+	ErrorF("(");
+	for (c = o = 0; c < 4 && o < max; c++) {
+		switch (ve->swizzle[c]) {
+		case 0: ErrorF("#"); break;
+		case 1: ErrorF("%f", f[o++]); break;
+		case 2: ErrorF("0.0"); break;
+		case 3: ErrorF("1.0"); break;
+		case 4: ErrorF("0x1"); break;
+		case 5: break;
+		default: ErrorF("?");
+		}
+		if (c < 3)
+			ErrorF(", ");
+	}
+	for (; c < 4; c++) {
+		switch (ve->swizzle[c]) {
+		case 0: ErrorF("#"); break;
+		case 1: ErrorF("1.0"); break;
+		case 2: ErrorF("0.0"); break;
+		case 3: ErrorF("1.0"); break;
+		case 4: ErrorF("0x1"); break;
+		case 5: break;
+		default: ErrorF("?");
+		}
+		if (c < 3)
+			ErrorF(", ");
+	}
+	ErrorF(")");
+}
+
+static void ve_out(const struct vertex_elements *ve, const void *ptr)
+{
+	switch (ve->type) {
+	case GEN7_SURFACEFORMAT_R32_FLOAT:
+		vertices_float_out(ve, ptr, 1);
+		break;
+	case GEN7_SURFACEFORMAT_R32G32_FLOAT:
+		vertices_float_out(ve, ptr, 2);
+		break;
+	case GEN7_SURFACEFORMAT_R32G32B32_FLOAT:
+		vertices_float_out(ve, ptr, 3);
+		break;
+	case GEN7_SURFACEFORMAT_R32G32B32A32_FLOAT:
+		vertices_float_out(ve, ptr, 4);
+		break;
+	case GEN7_SURFACEFORMAT_R16_SINT:
+		vertices_sint16_out(ve, ptr, 1);
+		break;
+	case GEN7_SURFACEFORMAT_R16G16_SINT:
+		vertices_sint16_out(ve, ptr, 2);
+		break;
+	case GEN7_SURFACEFORMAT_R16G16B16A16_SINT:
+		vertices_sint16_out(ve, ptr, 4);
+		break;
+	case GEN7_SURFACEFORMAT_R16_SSCALED:
+		vertices_sint16_out(ve, ptr, 1);
+		break;
+	case GEN7_SURFACEFORMAT_R16G16_SSCALED:
+		vertices_sint16_out(ve, ptr, 2);
+		break;
+	case GEN7_SURFACEFORMAT_R16G16B16A16_SSCALED:
+		vertices_sint16_out(ve, ptr, 4);
+		break;
+	}
+}
+
+static void indirect_vertex_out(struct kgem *kgem, uint32_t v)
+{
+	int i = 1;
+
+	do {
+		const struct vertex_elements *ve = &state.ve[i];
+		const struct vertex_buffer *vb = &state.vb[ve->buffer];
+		const void *ptr = vb->ptr + v * vb->pitch + ve->offset;
+
+		if (!ve->valid)
+			continue;
+
+		ve_out(ve, ptr);
+
+		while (++i <= state.num_ve && !state.ve[i].valid)
+			;
+
+		if (i <= state.num_ve)
+			ErrorF(", ");
+	} while (i <= state.num_ve);
+}
+
+static void primitive_out(struct kgem *kgem, uint32_t *data)
+{
+	int n;
+
+	assert((data[0] & (1<<15)) == 0); /* XXX index buffers */
+
+	for (n = 0; n < data[1]; n++) {
+		int v = data[2] + n;
+		ErrorF("	[%d:%d] = ", n, v);
+		indirect_vertex_out(kgem, v);
+		ErrorF("\n");
+	}
+}
+
+static void finish_vertex_buffers(struct kgem *kgem)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(state.vb); i++)
+		if (state.vb[i].current)
+			munmap(state.vb[i].base, state.vb[i].current->size);
+}
+
+static void finish_state(struct kgem *kgem)
+{
+	finish_vertex_buffers(kgem);
+
+	if (state.dynamic_state.current)
+		munmap(state.dynamic_state.base, state.dynamic_state.current->size);
+
+	memset(&state, 0, sizeof(state));
+}
+
+static void
+state_base_out(uint32_t *data, uint32_t offset, unsigned int index,
+	       char *name)
+{
+    if (data[index] & 1)
+	kgem_debug_print(data, offset, index,
+		  "%s state base address 0x%08x\n",
+		  name, data[index] & ~1);
+    else
+	kgem_debug_print(data, offset, index,
+		  "%s state base not updated\n",
+		  name);
+}
+
+static void
+state_max_out(uint32_t *data, uint32_t offset, unsigned int index,
+	      char *name)
+{
+	if (data[index] == 1)
+		kgem_debug_print(data, offset, index,
+			  "%s state upper bound disabled\n", name);
+	else if (data[index] & 1)
+		kgem_debug_print(data, offset, index,
+			  "%s state upper bound 0x%08x\n",
+			  name, data[index] & ~1);
+	else
+		kgem_debug_print(data, offset, index,
+			  "%s state upper bound not updated\n",
+			  name);
+}
+
+static const char *
+get_965_surfacetype(unsigned int surfacetype)
+{
+	switch (surfacetype) {
+	case 0: return "1D";
+	case 1: return "2D";
+	case 2: return "3D";
+	case 3: return "CUBE";
+	case 4: return "BUFFER";
+	case 7: return "NULL";
+	default: return "unknown";
+	}
+}
+
+static const char *
+get_965_depthformat(unsigned int depthformat)
+{
+	switch (depthformat) {
+	case 0: return "s8_z24float";
+	case 1: return "z32float";
+	case 2: return "z24s8";
+	case 5: return "z16";
+	default: return "unknown";
+	}
+}
+
+static const char *
+get_965_element_component(uint32_t data, int component)
+{
+	uint32_t component_control = (data >> (16 + (3 - component) * 4)) & 0x7;
+
+	switch (component_control) {
+	case 0:
+		return "nostore";
+	case 1:
+		switch (component) {
+		case 0: return "X";
+		case 1: return "Y";
+		case 2: return "Z";
+		case 3: return "W";
+		default: return "fail";
+		}
+	case 2:
+		return "0.0";
+	case 3:
+		return "1.0";
+	case 4:
+		return "0x1";
+	case 5:
+		return "VID";
+	default:
+		return "fail";
+	}
+}
+
+static const char *
+get_965_prim_type(uint32_t data)
+{
+	uint32_t primtype = (data >> 10) & 0x1f;
+
+	switch (primtype) {
+	case 0x01: return "point list";
+	case 0x02: return "line list";
+	case 0x03: return "line strip";
+	case 0x04: return "tri list";
+	case 0x05: return "tri strip";
+	case 0x06: return "tri fan";
+	case 0x07: return "quad list";
+	case 0x08: return "quad strip";
+	case 0x09: return "line list adj";
+	case 0x0a: return "line strip adj";
+	case 0x0b: return "tri list adj";
+	case 0x0c: return "tri strip adj";
+	case 0x0d: return "tri strip reverse";
+	case 0x0e: return "polygon";
+	case 0x0f: return "rect list";
+	case 0x10: return "line loop";
+	case 0x11: return "point list bf";
+	case 0x12: return "line strip cont";
+	case 0x13: return "line strip bf";
+	case 0x14: return "line strip cont bf";
+	case 0x15: return "tri fan no stipple";
+	default: return "fail";
+	}
+}
+
+struct reloc {
+	struct kgem_bo *bo;
+	void *base;
+};
+
+static void *
+get_reloc(struct kgem *kgem,
+	  void *base, const uint32_t *reloc,
+	  struct reloc *r)
+{
+	uint32_t delta = *reloc;
+
+	memset(r, 0, sizeof(*r));
+
+	if (base == 0) {
+		uint32_t handle = sizeof(uint32_t) * (reloc - kgem->batch);
+		struct kgem_bo *bo = NULL;
+		int i;
+
+		for (i = 0; i < kgem->nreloc; i++)
+			if (kgem->reloc[i].offset == handle)
+				break;
+		assert(i < kgem->nreloc);
+		handle = kgem->reloc[i].target_handle;
+		delta = kgem->reloc[i].delta;
+
+		if (handle == 0) {
+			base = kgem->batch;
+		} else {
+			list_for_each_entry(bo, &kgem->next_request->buffers, request)
+				if (bo->handle == handle)
+					break;
+			assert(&bo->request != &kgem->next_request->buffers);
+			base = kgem_bo_map(kgem, bo, PROT_READ);
+			r->bo = bo;
+			r->base = base;
+		}
+	}
+
+	return (char *)base + (delta & ~3);
+}
+
+static void
+put_reloc(struct kgem *kgem, struct reloc *r)
+{
+	if (r->bo != NULL)
+		munmap(r->base, r->bo->size);
+}
+
+static const char *
+gen7_filter_to_string(uint32_t filter)
+{
+	switch (filter) {
+	default:
+	case GEN7_MAPFILTER_NEAREST: return "nearest";
+	case GEN7_MAPFILTER_LINEAR: return "linear";
+	}
+}
+
+static const char *
+gen7_repeat_to_string(uint32_t repeat)
+{
+	switch (repeat) {
+	default:
+	case GEN7_TEXCOORDMODE_CLAMP_BORDER: return "border";
+	case GEN7_TEXCOORDMODE_WRAP: return "wrap";
+	case GEN7_TEXCOORDMODE_CLAMP: return "clamp";
+	case GEN7_TEXCOORDMODE_MIRROR: return "mirror";
+	}
+}
+
+static void
+gen7_decode_sampler_state(struct kgem *kgem, const uint32_t *reloc)
+{
+	const struct gen7_sampler_state *ss;
+	struct reloc r;
+	const char *min, *mag;
+	const char *s_wrap, *t_wrap, *r_wrap;
+
+	ss = get_reloc(kgem, state.dynamic_state.ptr, reloc, &r);
+
+	min = gen7_filter_to_string(ss->ss0.min_filter);
+	mag = gen7_filter_to_string(ss->ss0.mag_filter);
+
+	s_wrap = gen7_repeat_to_string(ss->ss3.s_wrap_mode);
+	t_wrap = gen7_repeat_to_string(ss->ss3.t_wrap_mode);
+	r_wrap = gen7_repeat_to_string(ss->ss3.r_wrap_mode);
+
+	ErrorF("  Sampler 0:\n");
+	ErrorF("    filter: min=%s, mag=%s\n", min, mag);
+	ErrorF("    wrap: s=%s, t=%s, r=%s\n", s_wrap, t_wrap, r_wrap);
+
+	ss++;
+	min = gen7_filter_to_string(ss->ss0.min_filter);
+	mag = gen7_filter_to_string(ss->ss0.mag_filter);
+
+	s_wrap = gen7_repeat_to_string(ss->ss3.s_wrap_mode);
+	t_wrap = gen7_repeat_to_string(ss->ss3.t_wrap_mode);
+	r_wrap = gen7_repeat_to_string(ss->ss3.r_wrap_mode);
+
+	ErrorF("  Sampler 1:\n");
+	ErrorF("    filter: min=%s, mag=%s\n", min, mag);
+	ErrorF("    wrap: s=%s, t=%s, r=%s\n", s_wrap, t_wrap, r_wrap);
+
+	put_reloc(kgem, &r);
+}
+
+static const char *
+gen7_blend_factor_to_string(uint32_t v)
+{
+	switch (v) {
+#define C(x) case GEN7_BLENDFACTOR_##x: return #x;
+		C(ONE);
+		C(SRC_COLOR);
+		C(SRC_ALPHA);
+		C(DST_ALPHA);
+		C(DST_COLOR);
+		C(SRC_ALPHA_SATURATE);
+		C(CONST_COLOR);
+		C(CONST_ALPHA);
+		C(SRC1_COLOR);
+		C(SRC1_ALPHA);
+		C(ZERO);
+		C(INV_SRC_COLOR);
+		C(INV_SRC_ALPHA);
+		C(INV_DST_ALPHA);
+		C(INV_DST_COLOR);
+		C(INV_CONST_COLOR);
+		C(INV_CONST_ALPHA);
+		C(INV_SRC1_COLOR);
+		C(INV_SRC1_ALPHA);
+#undef C
+	default: return "???";
+	}
+}
+
+static const char *
+gen7_blend_function_to_string(uint32_t v)
+{
+	switch (v) {
+#define C(x) case GEN7_BLENDFUNCTION_##x: return #x;
+		C(ADD);
+		C(SUBTRACT);
+		C(REVERSE_SUBTRACT);
+		C(MIN);
+		C(MAX);
+#undef C
+	default: return "???";
+	}
+}
+
+static void
+gen7_decode_blend(struct kgem *kgem, const uint32_t *reloc)
+{
+	const struct gen7_blend_state *blend;
+	struct reloc r;
+	const char *dst, *src;
+	const char *func;
+
+	blend = get_reloc(kgem, state.dynamic_state.ptr, reloc, &r);
+
+	dst = gen7_blend_factor_to_string(blend->blend0.dest_blend_factor);
+	src = gen7_blend_factor_to_string(blend->blend0.source_blend_factor);
+	func = gen7_blend_function_to_string(blend->blend0.blend_func);
+
+	ErrorF("  Blend (%s): function %s, src=%s, dst=%s\n",
+	       blend->blend0.blend_enable ? "enabled" : "disabled",
+	       func, src, dst);
+
+	put_reloc(kgem, &r);
+}
+
+int kgem_gen7_decode_3d(struct kgem *kgem, uint32_t offset)
+{
+	static const struct {
+		uint32_t opcode;
+		int min_len;
+		int max_len;
+		const char *name;
+	} opcodes[] = {
+		{ 0x6101, 6, 6, "STATE_BASE_ADDRESS" },
+		{ 0x6102, 2, 2 , "STATE_SIP" },
+		{ 0x6104, 1, 1, "3DSTATE_PIPELINE_SELECT" },
+		{ 0x780a, 3, 3, "3DSTATE_INDEX_BUFFER" },
+		{ 0x7900, 4, 4, "3DSTATE_DRAWING_RECTANGLE" },
+	};
+	uint32_t *data = kgem->batch + offset;
+	uint32_t op;
+	unsigned int len;
+	int i, j;
+	char *desc1 = NULL;
+	const char *name;
+
+	len = (data[0] & 0xff) + 2;
+	op = (data[0] & 0xffff0000) >> 16;
+	switch (op) {
+	case 0x6101:
+		i = 0;
+		kgem_debug_print(data, offset, i++, "STATE_BASE_ADDRESS\n");
+		assert(len == 10);
+
+		state_base_out(data, offset, i++, "general");
+		state_base_out(data, offset, i++, "surface");
+		state_base_out(data, offset, i++, "dynamic");
+		state_base_out(data, offset, i++, "indirect");
+		state_base_out(data, offset, i++, "instruction");
+
+		state_max_out(data, offset, i++, "general");
+		state_max_out(data, offset, i++, "dynamic");
+		state_max_out(data, offset, i++, "indirect");
+		state_max_out(data, offset, i++, "instruction");
+
+		gen7_update_dynamic_buffer(kgem, offset + 3);
+
+		return len;
+
+	case 0x7808:
+		assert((len - 1) % 4 == 0);
+		kgem_debug_print(data, offset, 0, "3DSTATE_VERTEX_BUFFERS\n");
+
+		for (i = 1; i < len;) {
+			gen7_update_vertex_buffer(kgem, data + i);
+
+			kgem_debug_print(data, offset, i, "buffer %d: %s, pitch %db\n",
+				  data[i] >> 26,
+				  data[i] & (1 << 20) ? "random" : "sequential",
+				  data[i] & 0x07ff);
+			i++;
+			kgem_debug_print(data, offset, i++, "buffer address\n");
+			kgem_debug_print(data, offset, i++, "max index\n");
+			kgem_debug_print(data, offset, i++, "mbz\n");
+		}
+		return len;
+
+	case 0x7809:
+		assert((len + 1) % 2 == 0);
+		kgem_debug_print(data, offset, 0, "3DSTATE_VERTEX_ELEMENTS\n");
+
+		for (i = 1; i < len;) {
+			gen7_update_vertex_elements(kgem, (i - 1)/2, data + i);
+
+			kgem_debug_print(data, offset, i, "buffer %d: %svalid, type 0x%04x, "
+				  "src offset 0x%04x bytes\n",
+				  data[i] >> 26,
+				  data[i] & (1 << 25) ? "" : "in",
+				  (data[i] >> 16) & 0x1ff,
+				  data[i] & 0x07ff);
+			i++;
+			kgem_debug_print(data, offset, i, "(%s, %s, %s, %s), "
+				  "dst offset 0x%02x bytes\n",
+				  get_965_element_component(data[i], 0),
+				  get_965_element_component(data[i], 1),
+				  get_965_element_component(data[i], 2),
+				  get_965_element_component(data[i], 3),
+				  (data[i] & 0xff) * 4);
+			i++;
+		}
+		return len;
+
+	case 0x780a:
+		assert(len == 3);
+		kgem_debug_print(data, offset, 0, "3DSTATE_INDEX_BUFFER\n");
+		kgem_debug_print(data, offset, 1, "beginning buffer address\n");
+		kgem_debug_print(data, offset, 2, "ending buffer address\n");
+		return len;
+
+	case 0x7b00:
+		assert(len == 6);
+		kgem_debug_print(data, offset, 0,
+			  "3DPRIMITIVE: %s %s\n",
+			  get_965_prim_type(data[0]),
+			  (data[0] & (1 << 15)) ? "random" : "sequential");
+		kgem_debug_print(data, offset, 1, "vertex count\n");
+		kgem_debug_print(data, offset, 2, "start vertex\n");
+		kgem_debug_print(data, offset, 3, "instance count\n");
+		kgem_debug_print(data, offset, 4, "start instance\n");
+		kgem_debug_print(data, offset, 5, "index bias\n");
+		primitive_out(kgem, data);
+		return len;
+	}
+
+	/* For the rest, just dump the bytes */
+	name = NULL;
+	for (i = 0; i < ARRAY_SIZE(opcodes); i++)
+		if (op == opcodes[i].opcode) {
+			name = opcodes[i].name;
+			break;
+		}
+
+	len = (data[0] & 0xff) + 2;
+	if (name == NULL) {
+		kgem_debug_print(data, offset, 0, "unknown\n");
+	} else {
+		kgem_debug_print(data, offset, 0, "%s\n", opcodes[i].name);
+		if (opcodes[i].max_len > 1) {
+			assert(len >= opcodes[i].min_len &&
+					len <= opcodes[i].max_len);
+		}
+	}
+	for (i = 1; i < len; i++)
+		kgem_debug_print(data, offset, i, "dword %d\n", i);
+
+	return len;
+}
+
+void kgem_gen7_finish_state(struct kgem *kgem)
+{
+	finish_state(kgem);
+}
commit 2309f19638f8b2c35eb60fb44fa988aa5aaab57f
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Thu Nov 10 11:57:21 2011 +0000

    sna/dri: Apply the damage for fullscreen async blits
    
    Otherwise gnome-shell forgets to update. Eventually, I'll get the async
    pageflipping bits merged into the Xserver and this path and its extra
    bw wastage will be history! But still I'll be undermined by the
    compositor, grrr.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna_dri.c b/src/sna/sna_dri.c
index f0fcb94..61a7b12 100644
--- a/src/sna/sna_dri.c
+++ b/src/sna/sna_dri.c
@@ -351,22 +351,25 @@ static void sna_dri_reference_buffer(DRI2Buffer2Ptr buffer)
 static void damage(PixmapPtr pixmap, RegionPtr region)
 {
 	struct sna_pixmap *priv;
-	BoxPtr box;
 
 	priv = sna_pixmap(pixmap);
 	if (priv->gpu_only)
 		return;
 
-	box = RegionExtents(region);
-	if (RegionNumRects(region) == 1 &&
-	    box->x1 <= 0 && box->y1 <= 0 &&
-	    box->x2 >= pixmap->drawable.width &&
-	    box->y2 >= pixmap->drawable.height) {
+	if (region == NULL) {
+damage_all:
 		sna_damage_all(&priv->gpu_damage,
 			       pixmap->drawable.width,
 			       pixmap->drawable.height);
 		sna_damage_destroy(&priv->cpu_damage);
 	} else {
+		BoxPtr box = RegionExtents(region);
+		if (region->data == NULL &&
+		    box->x1 <= 0 && box->y1 <= 0 &&
+		    box->x2 >= pixmap->drawable.width &&
+		    box->y2 >= pixmap->drawable.height)
+			goto damage_all;
+
 		sna_damage_add(&priv->gpu_damage, region);
 		sna_damage_subtract(&priv->cpu_damage, region);
 	}
@@ -402,12 +405,13 @@ sna_dri_copy(struct sna *sna, DrawablePtr draw, RegionPtr region,
 	int16_t dx, dy, sx, sy;
 	int n;
 
-	DBG(("%s: dst -- attachment=%d, name=%d, handle=%d [screen=%d]\n",
+	DBG(("%s: dst -- attachment=%d, name=%d, handle=%d [screen=%d, sync=%d]\n",
 	     __FUNCTION__,
 	     dst_buffer->attachment,
 	     dst_buffer->name,
 	     dst_priv->bo->handle,
-	     sna_pixmap_get_bo(sna->front)->handle));
+	     sna_pixmap_get_bo(sna->front)->handle,
+	     sync));
 	DBG(("%s: src -- attachment=%d, name=%d, handle=%d\n",
 	     __FUNCTION__,
 	     src_buffer->attachment,
@@ -486,11 +490,14 @@ sna_dri_copy(struct sna *sna, DrawablePtr draw, RegionPtr region,
 		kgem_set_mode(&sna->kgem, KGEM_RENDER);
 	}
 
+	damage(dst, region);
 	if (region) {
 		boxes = REGION_RECTS(region);
 		n = REGION_NUM_RECTS(region);
 		assert(n);
 	} else {
+		pixman_region_init_rects(&clip, &box, 1);
+		region = &clip;
 		boxes = &box;
 		n = 1;
 	}
@@ -513,12 +520,9 @@ sna_dri_copy(struct sna *sna, DrawablePtr draw, RegionPtr region,
 	if (flush) /* STAT! */
 		kgem_submit(&sna->kgem);
 
-	if (region) {
-		pixman_region_translate(region, dx, dy);
-		DamageRegionAppend(&dst->drawable, region);
-		DamageRegionProcessPending(&dst->drawable);
-		damage(dst, region);
-	}
+	pixman_region_translate(region, dx, dy);
+	DamageRegionAppend(&dst->drawable, region);
+	DamageRegionProcessPending(&dst->drawable);
 
 	if (region == &clip)
 		pixman_region_fini(&clip);
commit e65c2c54f5efcec16e97085dbc41042007c39151
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Thu Nov 10 11:37:46 2011 +0000

    sna: Store the sna pointer on the pixmap for cheap lookups
    
    A large part of the function preamble overhead is the multi-indirection
    lookup for retrieving the sna pointer. We can eliminate most of these by
    storing a pointer on the Pixmap as well, which we often need to lookup
    anyway.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna.h b/src/sna/sna.h
index d79e9a8..4ed2658 100644
--- a/src/sna/sna.h
+++ b/src/sna/sna.h
@@ -146,14 +146,15 @@ struct sna_pixmap {
 	uint8_t gpu :1;
 };
 
-extern DevPrivateKey sna_window_key;
+extern DevPrivateKeyRec sna_private_index;
+extern DevPrivateKeyRec sna_pixmap_index;
 
 static inline PixmapPtr get_window_pixmap(WindowPtr window)
 {
 #if 0
 	return window->drawable.pScreen->GetWindowPixmap(window)
 #else
-	return dixGetPrivate(&window->devPrivates, sna_window_key);
+	return *(void **)window->devPrivates;
 #endif
 }
 
@@ -165,11 +166,9 @@ static inline PixmapPtr get_drawable_pixmap(DrawablePtr drawable)
 		return get_window_pixmap((WindowPtr)drawable);
 }
 
-extern DevPrivateKeyRec sna_pixmap_index;
-
 static inline struct sna_pixmap *sna_pixmap(PixmapPtr pixmap)
 {
-	return dixGetPrivate(&pixmap->devPrivates, &sna_pixmap_index);
+	return ((void **)pixmap->devPrivates)[1];
 }
 
 static inline struct sna_pixmap *sna_pixmap_from_drawable(DrawablePtr drawable)
@@ -177,11 +176,6 @@ static inline struct sna_pixmap *sna_pixmap_from_drawable(DrawablePtr drawable)
 	return sna_pixmap(get_drawable_pixmap(drawable));
 }
 
-static inline void sna_set_pixmap(PixmapPtr pixmap, struct sna_pixmap *sna)
-{
-	dixSetPrivate(&pixmap->devPrivates, &sna_pixmap_index, sna);
-}
-
 struct sna_gc {
 	long changes;
 	long serial;
@@ -191,7 +185,7 @@ extern DevPrivateKeyRec sna_gc_index;
 
 static inline struct sna_gc *sna_gc(GCPtr gc)
 {
-	return dixGetPrivateAddr(&gc->devPrivates, &sna_gc_index);
+	return (struct sna_gc *)gc->devPrivates;
 }
 
 enum {
@@ -327,6 +321,12 @@ to_sna_from_screen(ScreenPtr screen)
 }
 
 static inline struct sna *
+to_sna_from_pixmap(PixmapPtr pixmap)
+{
+	return *(void **)pixmap->devPrivates;
+}
+
+static inline struct sna *
 to_sna_from_drawable(DrawablePtr drawable)
 {
 	return to_sna_from_screen(drawable->pScreen);
diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c
index 26116cd..02f2fe0 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -62,9 +62,6 @@
 #define USE_ZERO_SPANS 1
 #define USE_BO_FOR_SCRATCH_PIXMAP 1
 
-DevPrivateKeyRec sna_pixmap_index;
-DevPrivateKeyRec sna_gc_index;
-DevPrivateKey sna_window_key;
 static int sna_font_key;
 
 static const uint8_t copy_ROP[] = {
@@ -173,7 +170,7 @@ static void sna_pixmap_destroy_gpu_bo(struct sna *sna, struct sna_pixmap *priv)
 
 static Bool sna_destroy_private(PixmapPtr pixmap, struct sna_pixmap *priv)
 {
-	struct sna *sna = to_sna_from_drawable(&pixmap->drawable);
+	struct sna *sna = to_sna_from_pixmap(pixmap);
 
 	list_del(&priv->list);
 
@@ -210,7 +207,7 @@ static Bool sna_destroy_private(PixmapPtr pixmap, struct sna_pixmap *priv)
 
 static uint32_t sna_pixmap_choose_tiling(PixmapPtr pixmap)
 {
-	struct sna *sna = to_sna_from_drawable(&pixmap->drawable);
+	struct sna *sna = to_sna_from_pixmap(pixmap);
 	uint32_t tiling, bit;
 
 	/* Use tiling by default, but disable per user request */
@@ -232,6 +229,11 @@ static uint32_t sna_pixmap_choose_tiling(PixmapPtr pixmap)
 				  pixmap->drawable.bitsPerPixel);
 }
 
+static inline void sna_set_pixmap(PixmapPtr pixmap, struct sna_pixmap *sna)
+{
+	dixSetPrivate(&pixmap->devPrivates, &sna_pixmap_index, sna);
+}
+
 static struct sna_pixmap *_sna_pixmap_attach(PixmapPtr pixmap)
 {
 	struct sna_pixmap *priv;
@@ -268,7 +270,7 @@ struct sna_pixmap *sna_pixmap_attach(PixmapPtr pixmap)
 		break;
 
 	default:
-		sna = to_sna_from_drawable(&pixmap->drawable);
+		sna = to_sna_from_pixmap(pixmap);
 		if (!kgem_can_create_2d(&sna->kgem,
 					pixmap->drawable.width,
 					pixmap->drawable.height,
@@ -281,6 +283,22 @@ struct sna_pixmap *sna_pixmap_attach(PixmapPtr pixmap)
 	return _sna_pixmap_attach(pixmap);
 }
 
+static inline PixmapPtr
+create_pixmap(struct sna *sna, ScreenPtr screen,
+	      int width, int height, int depth,
+	      unsigned usage)
+{
+	PixmapPtr pixmap;
+
+	pixmap = fbCreatePixmap(screen, width, height, depth, usage);
+	if (pixmap == NullPixmap)
+		return NullPixmap;
+
+	assert(sna_private_index.offset == 0);
+	dixSetPrivate(&pixmap->devPrivates, &sna_private_index, sna);
+	return pixmap;
+}
+
 static PixmapPtr
 sna_pixmap_create_scratch(ScreenPtr screen,
 			  int width, int height, int depth,
@@ -299,8 +317,8 @@ sna_pixmap_create_scratch(ScreenPtr screen,
 
 	tiling = kgem_choose_tiling(&sna->kgem, tiling, width, height, bpp);
 	if (!kgem_can_create_2d(&sna->kgem, width, height, bpp, tiling))
-		return fbCreatePixmap(screen, width, height, depth,
-				      CREATE_PIXMAP_USAGE_SCRATCH);
+		return create_pixmap(sna, screen, width, height, depth,
+				     CREATE_PIXMAP_USAGE_SCRATCH);
 
 	/* you promise never to access this via the cpu... */
 	if (sna->freed_pixmap) {
@@ -312,8 +330,8 @@ sna_pixmap_create_scratch(ScreenPtr screen,
 		list_init(&priv->list);
 		priv->pixmap = pixmap;
 	} else {
-		pixmap = fbCreatePixmap(screen, 0, 0, depth,
-					CREATE_PIXMAP_USAGE_SCRATCH);
+		pixmap = create_pixmap(sna, screen, 0, 0, depth,
+				       CREATE_PIXMAP_USAGE_SCRATCH);
 		if (!pixmap)
 			return NullPixmap;
 
@@ -359,7 +377,9 @@ static PixmapPtr sna_create_pixmap(ScreenPtr screen,
 						 width, height, depth,
 						 I915_TILING_X);
 #else
-		return fbCreatePixmap(screen, width, height, depth, usage);
+		return create_pixmap(to_sna_from_screen(screen), screen,
+				     width, height, depth,
+				     usage),
 #endif
 
 	if (usage == SNA_CREATE_SCRATCH)
@@ -379,7 +399,8 @@ static PixmapPtr sna_create_pixmap(ScreenPtr screen,
 
 	/* XXX could use last deferred free? */
 
-	pixmap = fbCreatePixmap(screen, width, height, depth, usage);
+	pixmap = create_pixmap(to_sna_from_screen(screen), screen,
+			       width, height, depth, usage);
 	if (pixmap == NullPixmap)
 		return NullPixmap;
 
@@ -437,7 +458,7 @@ static inline void list_move(struct list *list, struct list *head)
 void
 sna_pixmap_move_to_cpu(PixmapPtr pixmap, bool write)
 {
-	struct sna *sna = to_sna_from_drawable(&pixmap->drawable);
+	struct sna *sna = to_sna_from_pixmap(pixmap);
 	struct sna_pixmap *priv;
 
 	DBG(("%s(pixmap=%p, write=%d)\n", __FUNCTION__, pixmap, write));
@@ -532,8 +553,8 @@ sna_drawable_move_region_to_cpu(DrawablePtr drawable,
 				RegionPtr region,
 				Bool write)
 {
-	struct sna *sna = to_sna_from_drawable(drawable);
 	PixmapPtr pixmap = get_drawable_pixmap(drawable);
+	struct sna *sna = to_sna_from_pixmap(pixmap);
 	struct sna_pixmap *priv;
 	int16_t dx, dy;
 
@@ -677,7 +698,7 @@ done:
 static void
 sna_pixmap_move_area_to_gpu(PixmapPtr pixmap, BoxPtr box)
 {
-	struct sna *sna = to_sna_from_drawable(&pixmap->drawable);
+	struct sna *sna = to_sna_from_pixmap(pixmap);
 	struct sna_pixmap *priv = sna_pixmap(pixmap);
 	RegionRec i, r;
 
@@ -878,8 +899,8 @@ sna_pixmap_create_upload(ScreenPtr screen,
 	    !kgem_can_create_2d(&sna->kgem,
 				width, height, bpp,
 				I915_TILING_NONE))
-		return fbCreatePixmap(screen, width, height, depth,
-				      CREATE_PIXMAP_USAGE_SCRATCH);
+		return create_pixmap(sna, screen, width, height, depth,
+				     CREATE_PIXMAP_USAGE_SCRATCH);
 
 	if (sna->freed_pixmap) {
 		pixmap = sna->freed_pixmap;
@@ -887,8 +908,8 @@ sna_pixmap_create_upload(ScreenPtr screen,
 
 		priv = sna_pixmap(pixmap);
 	} else {
-		pixmap = fbCreatePixmap(screen, 0, 0, depth,
-					CREATE_PIXMAP_USAGE_SCRATCH);
+		pixmap = create_pixmap(sna, screen, 0, 0, depth,
+				       CREATE_PIXMAP_USAGE_SCRATCH);
 		if (!pixmap)
 			return NullPixmap;
 
@@ -946,7 +967,7 @@ sna_pixmap_force_to_gpu(PixmapPtr pixmap)
 	}
 
 	if (priv->gpu_bo == NULL) {
-		struct sna *sna = to_sna_from_drawable(&pixmap->drawable);
+		struct sna *sna = to_sna_from_pixmap(pixmap);
 		unsigned flags;
 
 		flags = 0;
@@ -976,7 +997,7 @@ sna_pixmap_force_to_gpu(PixmapPtr pixmap)
 struct sna_pixmap *
 sna_pixmap_move_to_gpu(PixmapPtr pixmap)
 {
-	struct sna *sna = to_sna_from_drawable(&pixmap->drawable);
+	struct sna *sna = to_sna_from_pixmap(pixmap);
 	struct sna_pixmap *priv;
 	BoxPtr box;
 	int n;
@@ -1239,8 +1260,8 @@ static Bool
 sna_put_image_upload_blt(DrawablePtr drawable, GCPtr gc, RegionPtr region,
 			 int x, int y, int w, int h, char *bits, int stride)
 {
-	struct sna *sna = to_sna_from_drawable(drawable);
 	PixmapPtr pixmap = get_drawable_pixmap(drawable);
+	struct sna *sna = to_sna_from_pixmap(pixmap);
 	struct sna_pixmap *priv = sna_pixmap(pixmap);
 	struct kgem_bo *src_bo;
 	Bool ok = FALSE;
@@ -1302,8 +1323,8 @@ static Bool
 sna_put_zpixmap_blt(DrawablePtr drawable, GCPtr gc, RegionPtr region,
 		    int x, int y, int w, int  h, char *bits, int stride)
 {
-	struct sna *sna = to_sna_from_drawable(drawable);
 	PixmapPtr pixmap = get_drawable_pixmap(drawable);
+	struct sna *sna = to_sna_from_pixmap(pixmap);
 	struct sna_pixmap *priv = sna_pixmap(pixmap);
 	char *dst_bits;
 	int dst_stride;
@@ -1415,8 +1436,8 @@ static Bool
 sna_put_xybitmap_blt(DrawablePtr drawable, GCPtr gc, RegionPtr region,
 		    int x, int y, int w, int  h, char *bits)
 {
-	struct sna *sna = to_sna_from_drawable(drawable);
 	PixmapPtr pixmap = get_drawable_pixmap(drawable);
+	struct sna *sna = to_sna_from_pixmap(pixmap);
 	struct sna_pixmap *priv = sna_pixmap(pixmap);
 	struct sna_damage **damage;
 	BoxRec *box;
@@ -1531,8 +1552,8 @@ static Bool
 sna_put_xypixmap_blt(DrawablePtr drawable, GCPtr gc, RegionPtr region,
 		    int x, int y, int w, int  h, int left,char *bits)
 {
-	struct sna *sna = to_sna_from_drawable(drawable);
 	PixmapPtr pixmap = get_drawable_pixmap(drawable);
+	struct sna *sna = to_sna_from_pixmap(pixmap);
 	struct sna_pixmap *priv = sna_pixmap(pixmap);
 	struct sna_damage **damage;
 	struct kgem_bo *bo = priv->gpu_bo;
@@ -1662,8 +1683,8 @@ sna_put_image(DrawablePtr drawable, GCPtr gc, int depth,
 	      int x, int y, int w, int h, int left, int format,
 	      char *bits)
 {
-	struct sna *sna = to_sna_from_drawable(drawable);
 	PixmapPtr pixmap = get_drawable_pixmap(drawable);
+	struct sna *sna = to_sna_from_pixmap(pixmap);
 	struct sna_pixmap *priv = sna_pixmap(pixmap);
 	RegionRec region;
 	int16_t dx, dy;
@@ -1767,8 +1788,8 @@ sna_self_copy_boxes(DrawablePtr src, DrawablePtr dst, GCPtr gc,
 		    Bool reverse, Bool upsidedown, Pixel bitplane,
 		    void *closure)
 {
-	struct sna *sna = to_sna_from_drawable(src);
 	PixmapPtr pixmap = get_drawable_pixmap(src);
+	struct sna *sna = to_sna_from_pixmap(pixmap);
 	struct sna_pixmap *priv = sna_pixmap(pixmap);
 	int alu = gc ? gc->alu : GXcopy;
 	int16_t tx, ty;
@@ -1864,11 +1885,11 @@ sna_copy_boxes(DrawablePtr src, DrawablePtr dst, GCPtr gc,
 	       Bool reverse, Bool upsidedown, Pixel bitplane,
 	       void *closure)
 {
-	struct sna *sna = to_sna_from_drawable(dst);
 	PixmapPtr src_pixmap = get_drawable_pixmap(src);
-	PixmapPtr dst_pixmap = get_drawable_pixmap(dst);
 	struct sna_pixmap *src_priv = sna_pixmap(src_pixmap);
+	PixmapPtr dst_pixmap = get_drawable_pixmap(dst);
 	struct sna_pixmap *dst_priv = sna_pixmap(dst_pixmap);
+	struct sna *sna = to_sna_from_pixmap(src_pixmap);
 	int alu = gc ? gc->alu : GXcopy;
 	int16_t src_dx, src_dy;
 	int16_t dst_dx, dst_dy;
@@ -2287,8 +2308,8 @@ sna_fill_spans_blt(DrawablePtr drawable,
 		   DDXPointPtr pt, int *width, int sorted,
 		   const BoxRec *extents, unsigned clipped)
 {
-	struct sna *sna = to_sna_from_drawable(drawable);
 	PixmapPtr pixmap = get_drawable_pixmap(drawable);
+	struct sna *sna = to_sna_from_pixmap(pixmap);
 	int16_t dx, dy;
 	struct sna_fill_op fill;
 	BoxRec box[512], *b = box, *const last_box = box + ARRAY_SIZE(box);
@@ -2652,7 +2673,8 @@ static void
 sna_fill_spans(DrawablePtr drawable, GCPtr gc, int n,
 	       DDXPointPtr pt, int *width, int sorted)
 {
-	struct sna *sna = to_sna_from_drawable(drawable);
+	PixmapPtr pixmap = get_drawable_pixmap(drawable);
+	struct sna *sna = to_sna_from_pixmap(pixmap);
 	RegionRec region;
 	unsigned flags;
 
@@ -2682,7 +2704,7 @@ sna_fill_spans(DrawablePtr drawable, GCPtr gc, int n,
 		goto fallback;
 
 	if (gc->fillStyle == FillSolid) {
-		struct sna_pixmap *priv = sna_pixmap_from_drawable(drawable);
+		struct sna_pixmap *priv = sna_pixmap(pixmap);
 		struct sna_damage **damage;
 
 		DBG(("%s: trying solid fill [alu=%d, pixel=%08lx] blt paths\n",
@@ -2702,7 +2724,7 @@ sna_fill_spans(DrawablePtr drawable, GCPtr gc, int n,
 				       &region.extents, flags & 2))
 			return;
 	} else {
-		struct sna_pixmap *priv = sna_pixmap_from_drawable(drawable);
+		struct sna_pixmap *priv = sna_pixmap(pixmap);
 		struct sna_damage **damage;
 
 		/* Try converting these to a set of rectangles instead */
@@ -2787,8 +2809,8 @@ sna_copy_bitmap_blt(DrawablePtr _bitmap, DrawablePtr drawable, GCPtr gc,
 		    Bool reverse, Bool upsidedown, Pixel bitplane,
 		    void *closure)
 {
-	struct sna *sna = to_sna_from_drawable(drawable);
 	PixmapPtr pixmap = get_drawable_pixmap(drawable);
+	struct sna *sna = to_sna_from_pixmap(pixmap);
 	struct sna_pixmap *priv = sna_pixmap(pixmap);
 	PixmapPtr bitmap = (PixmapPtr)_bitmap;
 	uint32_t br00, br13;
@@ -2942,10 +2964,10 @@ sna_copy_plane_blt(DrawablePtr source, DrawablePtr drawable, GCPtr gc,
 		   Bool reverse, Bool upsidedown, Pixel bitplane,
 		   void *closure)
 {
-	struct sna *sna = to_sna_from_drawable(drawable);
 	PixmapPtr dst_pixmap = get_drawable_pixmap(drawable);
 	PixmapPtr src_pixmap = get_drawable_pixmap(source);
 	struct sna_pixmap *priv = sna_pixmap(dst_pixmap);
+	struct sna *sna = to_sna_from_pixmap(dst_pixmap);
 	int16_t dx, dy;
 	int bit = ffs(bitplane) - 1;
 	uint32_t br00, br13;
@@ -3148,7 +3170,8 @@ sna_copy_plane(DrawablePtr src, DrawablePtr dst, GCPtr gc,
 	       int dst_x, int dst_y,
 	       unsigned long bit)
 {
-	struct sna *sna = to_sna_from_drawable(dst);
+	PixmapPtr pixmap = get_drawable_pixmap(dst);
+	struct sna *sna = to_sna_from_pixmap(pixmap);
 	RegionRec region;
 	struct sna_damage **damage;
 
@@ -3174,7 +3197,7 @@ sna_copy_plane(DrawablePtr src, DrawablePtr dst, GCPtr gc,
 		goto fallback;
 
 	if (sna_drawable_use_gpu_bo(dst, &region.extents, &damage)) {
-		struct sna_pixmap *priv = sna_pixmap(get_drawable_pixmap(dst));
+		struct sna_pixmap *priv = sna_pixmap(pixmap);
 		if (priv->gpu_bo->tiling != I915_TILING_Y) {
 			RegionUninit(&region);
 			return miDoCopy(src, dst, gc,
@@ -3207,9 +3230,8 @@ sna_poly_point_blt(DrawablePtr drawable,
 		   GCPtr gc, int mode, int n, DDXPointPtr pt,
 		   bool clipped)
 {
-	struct sna *sna = to_sna_from_drawable(drawable);
 	PixmapPtr pixmap = get_drawable_pixmap(drawable);
-	RegionPtr clip = fbGetCompositeClip(gc);
+	struct sna *sna = to_sna_from_pixmap(pixmap);
 	BoxRec box[512], *b = box, * const last_box = box + ARRAY_SIZE(box);
 	struct sna_fill_op fill;
 	DDXPointRec last;
@@ -3252,6 +3274,8 @@ sna_poly_point_blt(DrawablePtr drawable,
 			b = box;
 		} while (n);
 	} else {
+		RegionPtr clip = fbGetCompositeClip(gc);
+
 		while (n--) {
 			int x, y;
 
@@ -3322,7 +3346,8 @@ static void
 sna_poly_point(DrawablePtr drawable, GCPtr gc,
 	       int mode, int n, DDXPointPtr pt)
 {
-	struct sna *sna = to_sna_from_drawable(drawable);
+	PixmapPtr pixmap = get_drawable_pixmap(drawable);
+	struct sna *sna = to_sna_from_pixmap(pixmap);
 	RegionRec region;
 	unsigned flags;
 
@@ -3348,7 +3373,7 @@ sna_poly_point(DrawablePtr drawable, GCPtr gc,
 
 	if (gc->fillStyle == FillSolid &&
 	    PM_IS_SOLID(drawable, gc->planemask)) {
-		struct sna_pixmap *priv = sna_pixmap_from_drawable(drawable);
+		struct sna_pixmap *priv = sna_pixmap(pixmap);
 		struct sna_damage **damage;
 
 		DBG(("%s: trying solid fill [%08lx] blt paths\n",
@@ -3397,8 +3422,8 @@ sna_poly_zero_line_blt(DrawablePtr drawable,
 		&&damage_offset,
 	};
 
-	struct sna *sna = to_sna_from_drawable(drawable);
 	PixmapPtr pixmap = get_drawable_pixmap(drawable);
+	struct sna *sna = to_sna_from_pixmap(pixmap);
 	int x2, y2, xstart, ystart;
 	int oc2, pt2_clipped = 0;
 	unsigned int bias = miGetZeroLineBias(drawable->pScreen);
@@ -3770,8 +3795,8 @@ sna_poly_line_blt(DrawablePtr drawable,
 		  GCPtr gc, int mode, int n, DDXPointPtr pt,
 		  const BoxRec *extents, bool clipped)
 {
-	struct sna *sna = to_sna_from_drawable(drawable);
 	PixmapPtr pixmap = get_drawable_pixmap(drawable);
+	struct sna *sna = to_sna_from_pixmap(pixmap);
 	BoxRec boxes[512], *b = boxes, * const last_box = boxes + ARRAY_SIZE(boxes);
 	struct sna_fill_op fill;
 	DDXPointRec last;
@@ -4041,7 +4066,8 @@ static void
 sna_poly_line(DrawablePtr drawable, GCPtr gc,
 	      int mode, int n, DDXPointPtr pt)
 {
-	struct sna *sna = to_sna_from_drawable(drawable);
+	PixmapPtr pixmap = get_drawable_pixmap(drawable);
+	struct sna *sna = to_sna_from_pixmap(pixmap);
 	RegionRec region;
 	unsigned flags;
 
@@ -4075,7 +4101,7 @@ sna_poly_line(DrawablePtr drawable, GCPtr gc,
 	if (gc->fillStyle == FillSolid && gc->lineStyle == LineSolid &&
 	    (gc->lineWidth == 0 || (gc->lineWidth == 1 && (n == 1 || gc->alu == GXcopy))) &&
 	    PM_IS_SOLID(drawable, gc->planemask)) {
-		struct sna_pixmap *priv = sna_pixmap_from_drawable(drawable);
+		struct sna_pixmap *priv = sna_pixmap(pixmap);
 		struct sna_damage **damage;
 
 		DBG(("%s: trying solid fill [%08lx]\n",
@@ -4162,8 +4188,8 @@ sna_poly_segment_blt(DrawablePtr drawable,
 		     GCPtr gc, int n, xSegment *seg,
 		     const BoxRec *extents, unsigned clipped)
 {
-	struct sna *sna = to_sna_from_drawable(drawable);
 	PixmapPtr pixmap = get_drawable_pixmap(drawable);
+	struct sna *sna = to_sna_from_pixmap(pixmap);
 	BoxRec boxes[512], *b = boxes, * const last_box = boxes + ARRAY_SIZE(boxes);
 	struct sna_fill_op fill;
 	int16_t dx, dy;
@@ -4421,8 +4447,8 @@ sna_poly_zero_segment_blt(DrawablePtr drawable,
 		&&damage_offset,
 	};
 
-	struct sna *sna = to_sna_from_drawable(drawable);
 	PixmapPtr pixmap = get_drawable_pixmap(drawable);
+	struct sna *sna = to_sna_from_pixmap(pixmap);
 	unsigned int bias = miGetZeroLineBias(drawable->pScreen);
 	struct sna_fill_op fill;
 	RegionRec clip;
@@ -4816,7 +4842,8 @@ sna_poly_segment_extents(DrawablePtr drawable, GCPtr gc,
 static void
 sna_poly_segment(DrawablePtr drawable, GCPtr gc, int n, xSegment *seg)
 {
-	struct sna *sna = to_sna_from_drawable(drawable);
+	PixmapPtr pixmap = get_drawable_pixmap(drawable);
+	struct sna *sna = to_sna_from_pixmap(pixmap);
 	RegionRec region;
 	unsigned flags;
 
@@ -4852,7 +4879,7 @@ sna_poly_segment(DrawablePtr drawable, GCPtr gc, int n, xSegment *seg)
 	    gc->lineStyle == LineSolid &&
 	    gc->lineWidth <= 1 &&
 	    PM_IS_SOLID(drawable, gc->planemask)) {
-		struct sna_pixmap *priv = sna_pixmap_from_drawable(drawable);
+		struct sna_pixmap *priv = sna_pixmap(pixmap);
 		struct sna_damage **damage;
 
 		DBG(("%s: trying blt solid fill [%08lx] paths\n",
@@ -4981,8 +5008,8 @@ sna_poly_rectangle_blt(DrawablePtr drawable,
 		       GCPtr gc, int n, xRectangle *r,
 		       const BoxRec *extents, unsigned clipped)
 {
-	struct sna *sna = to_sna_from_drawable(drawable);
 	PixmapPtr pixmap = get_drawable_pixmap(drawable);
+	struct sna *sna = to_sna_from_pixmap(pixmap);
 	struct sna_fill_op fill;
 	BoxRec boxes[512], *b = boxes, *const last_box = boxes+ARRAY_SIZE(boxes);
 	int16_t dx, dy;
@@ -5407,7 +5434,8 @@ done:
 static void
 sna_poly_rectangle(DrawablePtr drawable, GCPtr gc, int n, xRectangle *r)
 {
-	struct sna *sna = to_sna_from_drawable(drawable);
+	PixmapPtr pixmap = get_drawable_pixmap(drawable);
+	struct sna *sna = to_sna_from_pixmap(pixmap);
 	RegionRec region;
 	unsigned flags;
 
@@ -5441,7 +5469,7 @@ sna_poly_rectangle(DrawablePtr drawable, GCPtr gc, int n, xRectangle *r)
 	if (gc->lineStyle == LineSolid &&
 	    gc->joinStyle == JoinMiter &&
 	    PM_IS_SOLID(drawable, gc->planemask)) {
-		struct sna_pixmap *priv = sna_pixmap_from_drawable(drawable);
+		struct sna_pixmap *priv = sna_pixmap(pixmap);
 		struct sna_damage **damage;
 
 		DBG(("%s: trying blt solid fill [%08lx] paths\n",
@@ -5546,7 +5574,8 @@ arc_to_spans(GCPtr gc, int n)
 static void
 sna_poly_arc(DrawablePtr drawable, GCPtr gc, int n, xArc *arc)
 {
-	struct sna *sna = to_sna_from_drawable(drawable);
+	PixmapPtr pixmap = get_drawable_pixmap(drawable);
+	struct sna *sna = to_sna_from_pixmap(pixmap);
 	RegionRec region;
 
 	DBG(("%s(n=%d, lineWidth=%d\n", __FUNCTION__, n, gc->lineWidth));
@@ -5609,8 +5638,8 @@ sna_poly_fill_rect_blt(DrawablePtr drawable,
 		       const BoxRec *extents,
 		       bool clipped)
 {
-	struct sna *sna = to_sna_from_drawable(drawable);
 	PixmapPtr pixmap = get_drawable_pixmap(drawable);
+	struct sna *sna = to_sna_from_pixmap(pixmap);
 	struct sna_fill_op fill;
 	BoxRec boxes[512], *b = boxes, *const last_box = boxes+ARRAY_SIZE(boxes);
 	int16_t dx, dy;
@@ -5792,8 +5821,8 @@ sna_poly_fill_rect_tiled_blt(DrawablePtr drawable,
 			     GCPtr gc, int n, xRectangle *rect,
 			     const BoxRec *extents, unsigned clipped)
 {
-	struct sna *sna = to_sna_from_drawable(drawable);
 	PixmapPtr pixmap = get_drawable_pixmap(drawable);
+	struct sna *sna = to_sna_from_pixmap(pixmap);
 	PixmapPtr tile = gc->tile.pixmap;
 	const DDXPointRec * const origin = &gc->patOrg;
 	struct sna_copy_op copy;
@@ -6000,8 +6029,8 @@ sna_poly_fill_rect_stippled_8x8_blt(DrawablePtr drawable,
 				    GCPtr gc, int n, xRectangle *r,
 				    const BoxRec *extents, unsigned clipped)
 {
-	struct sna *sna = to_sna_from_drawable(drawable);
 	PixmapPtr pixmap = get_drawable_pixmap(drawable);
+	struct sna *sna = to_sna_from_pixmap(pixmap);
 	uint32_t pat[2] = {0, 0}, br00, br13;
 	int16_t dx, dy;
 
@@ -6192,8 +6221,8 @@ sna_poly_fill_rect_stippled_1_blt(DrawablePtr drawable,
 				  GCPtr gc, int n, xRectangle *r,
 				  const BoxRec *extents, unsigned clipped)
 {
-	struct sna *sna = to_sna_from_drawable(drawable);
 	PixmapPtr pixmap = get_drawable_pixmap(drawable);
+	struct sna *sna = to_sna_from_pixmap(pixmap);
 	struct sna_pixmap *priv = sna_pixmap(pixmap);
 	PixmapPtr stipple = gc->stipple;
 	const DDXPointRec *origin = &gc->patOrg;
@@ -6696,7 +6725,8 @@ sna_poly_fill_rect_extents(DrawablePtr drawable, GCPtr gc,
 static void
 sna_poly_fill_rect(DrawablePtr draw, GCPtr gc, int n, xRectangle *rect)
 {
-	struct sna *sna = to_sna_from_drawable(draw);
+	PixmapPtr pixmap = get_drawable_pixmap(draw);
+	struct sna *sna = to_sna_from_pixmap(pixmap);
 	RegionRec region;
 	unsigned flags;
 
@@ -6732,7 +6762,7 @@ sna_poly_fill_rect(DrawablePtr draw, GCPtr gc, int n, xRectangle *rect)
 	if (gc->fillStyle == FillSolid ||
 	    (gc->fillStyle == FillTiled && gc->tileIsPixel) ||
 	    (gc->fillStyle == FillOpaqueStippled && gc->bgPixel == gc->fgPixel)) {
-		struct sna_pixmap *priv = sna_pixmap_from_drawable(draw);
+		struct sna_pixmap *priv = sna_pixmap(pixmap);
 		struct sna_damage **damage;
 		uint32_t color = gc->fillStyle == FillTiled ? gc->tile.pixel : gc->fgPixel;
 
@@ -6753,7 +6783,7 @@ sna_poly_fill_rect(DrawablePtr draw, GCPtr gc, int n, xRectangle *rect)
 					   &region.extents, flags & 2))
 			return;
 	} else if (gc->fillStyle == FillTiled) {
-		struct sna_pixmap *priv = sna_pixmap_from_drawable(draw);
+		struct sna_pixmap *priv = sna_pixmap(pixmap);
 		struct sna_damage **damage;
 
 		DBG(("%s: tiled fill, testing for blt\n", __FUNCTION__));
@@ -6772,7 +6802,7 @@ sna_poly_fill_rect(DrawablePtr draw, GCPtr gc, int n, xRectangle *rect)
 						 &region.extents, flags & 2))
 			return;
 	} else {
-		struct sna_pixmap *priv = sna_pixmap_from_drawable(draw);
+		struct sna_pixmap *priv = sna_pixmap(pixmap);
 		struct sna_damage **damage;
 
 		DBG(("%s: stippled fill, testing for blt\n", __FUNCTION__));
@@ -6911,8 +6941,8 @@ sna_glyph_blt(DrawablePtr drawable, GCPtr gc,
 	      RegionRec *clip,
 	      bool transparent)
 {
-	struct sna *sna = to_sna_from_drawable(drawable);
 	PixmapPtr pixmap = get_drawable_pixmap(drawable);
+	struct sna *sna = to_sna_from_pixmap(pixmap);
 	struct sna_pixmap *priv = sna_pixmap(pixmap);
 	struct kgem_bo *bo;
 	struct sna_damage **damage;
@@ -7470,8 +7500,8 @@ sna_reversed_glyph_blt(DrawablePtr drawable, GCPtr gc,
 		       RegionPtr clip,
 		       bool transparent)
 {
-	struct sna *sna = to_sna_from_drawable(drawable);
 	PixmapPtr pixmap = get_drawable_pixmap(drawable);
+	struct sna *sna = to_sna_from_pixmap(pixmap);
 	struct sna_pixmap *priv = sna_pixmap(pixmap);
 	const BoxRec *extents, *last_extents;
 	uint32_t *b;
@@ -7634,7 +7664,8 @@ sna_image_glyph(DrawablePtr drawable, GCPtr gc,
 		int x, int y, unsigned int n,
 		CharInfoPtr *info, pointer base)
 {
-	struct sna *sna = to_sna_from_drawable(drawable);
+	PixmapPtr pixmap = get_drawable_pixmap(drawable);
+	struct sna *sna = to_sna_from_pixmap(pixmap);
 	ExtentInfoRec extents;
 	RegionRec region;
 	struct sna_damage **damage;
@@ -7693,7 +7724,8 @@ sna_poly_glyph(DrawablePtr drawable, GCPtr gc,
 	       int x, int y, unsigned int n,
 	       CharInfoPtr *info, pointer base)
 {
-	struct sna *sna = to_sna_from_drawable(drawable);
+	PixmapPtr pixmap = get_drawable_pixmap(drawable);
+	struct sna *sna = to_sna_from_pixmap(pixmap);
 	ExtentInfoRec extents;
 	RegionRec region;
 	struct sna_damage **damage;
@@ -7753,8 +7785,8 @@ sna_push_pixels_solid_blt(GCPtr gc,
 			  DrawablePtr drawable,
 			  RegionPtr region)
 {
-	struct sna *sna = to_sna_from_drawable(drawable);
 	PixmapPtr pixmap = get_drawable_pixmap(drawable);
+	struct sna *sna = to_sna_from_pixmap(pixmap);
 	struct sna_pixmap *priv = sna_pixmap(pixmap);
 	struct sna_damage **damage;
 	BoxRec *box;
@@ -8009,8 +8041,8 @@ sna_get_spans(DrawablePtr drawable, int wMax,
 static void
 sna_copy_window(WindowPtr win, DDXPointRec origin, RegionPtr src)
 {
-	struct sna *sna = to_sna_from_drawable(&win->drawable);
-	PixmapPtr pixmap = fbGetWindowPixmap(win);
+	PixmapPtr pixmap = get_window_pixmap(win);
+	struct sna *sna = to_sna_from_pixmap(pixmap);
 	RegionRec dst;
 	int dx, dy;
 
@@ -8292,19 +8324,12 @@ Bool sna_accel_init(ScreenPtr screen, struct sna *sna)
 {
 	const char *backend;
 
-	if (!dixRegisterPrivateKey(&sna_pixmap_index, PRIVATE_PIXMAP, 0))
-		return FALSE;
-	if (!dixRegisterPrivateKey(&sna_gc_index, PRIVATE_GC, sizeof(struct sna_gc)))
-		return FALSE;
-
 	if (!AddCallback(&FlushCallback, sna_accel_flush_callback, sna))
 		return FALSE;
 
 	if (!sna_glyphs_init(screen))
 		return FALSE;
 
-	sna_window_key = fbGetWinPrivateKey();
-
 	sna_font_key = AllocateFontPrivateIndex();
 	screen->RealizeFont = sna_realize_font;
 	screen->UnrealizeFont = sna_unrealize_font;
diff --git a/src/sna/sna_driver.c b/src/sna/sna_driver.c
index 98819f6..e14ad1e 100644
--- a/src/sna/sna_driver.c
+++ b/src/sna/sna_driver.c
@@ -80,6 +80,10 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
 #define DBG(x) ErrorF x
 #endif
 
+DevPrivateKeyRec sna_private_index;
+DevPrivateKeyRec sna_pixmap_index;
+DevPrivateKeyRec sna_gc_index;
+
 static OptionInfoRec sna_options[] = {
    {OPTION_TILING_FB,	"LinearFramebuffer",	OPTV_BOOLEAN,	{0},	FALSE},
    {OPTION_TILING_2D,	"Tiling",	OPTV_BOOLEAN,	{0},	TRUE},
@@ -798,6 +802,24 @@ static Bool sna_close_screen(int scrnIndex, ScreenPtr screen)
 }
 
 static Bool
+sna_register_all_privates(void)
+{
+	if (!dixRegisterPrivateKey(&sna_private_index, PRIVATE_PIXMAP, 0))
+		return FALSE;
+	assert(sna_private_index.offset == 0);
+
+	if (!dixRegisterPrivateKey(&sna_pixmap_index, PRIVATE_PIXMAP, 0))
+		return FALSE;
+	assert(sna_pixmap_index.offset == sizeof(void*));
+
+	if (!dixRegisterPrivateKey(&sna_gc_index, PRIVATE_GC, sizeof(struct sna_gc)))
+		return FALSE;
+	assert(sna_gc_index.offset == 0);
+
+	return TRUE;
+}
+
+static Bool
 sna_screen_init(int scrnIndex, ScreenPtr screen, int argc, char **argv)
 {
 	ScrnInfoPtr scrn = xf86Screens[screen->myNum];
@@ -807,14 +829,10 @@ sna_screen_init(int scrnIndex, ScreenPtr screen, int argc, char **argv)
 
 	DBG(("%s\n", __FUNCTION__));
 
-	scrn->videoRam = device->regions[2].size / 1024;
+	if (!sna_register_all_privates())
+		return FALSE;
 
-#ifdef DRI2
-	sna->directRenderingOpen = sna_dri_open(sna, screen);
-	if (sna->directRenderingOpen)
-		xf86DrvMsg(scrn->scrnIndex, X_INFO,
-			   "direct rendering: DRI2 Enabled\n");
-#endif
+	scrn->videoRam = device->regions[2].size / 1024;
 
 	miClearVisualTypes();
 	if (!miSetVisualTypes(scrn->depth,
@@ -829,6 +847,7 @@ sna_screen_init(int scrnIndex, ScreenPtr screen, int argc, char **argv)
 			  scrn->xDpi, scrn->yDpi,
 			  scrn->displayWidth, scrn->bitsPerPixel))
 		return FALSE;
+	assert(fbGetWinPrivateKey()->offset == 0);
 
 	if (scrn->bitsPerPixel > 8) {
 		/* Fixup RGB ordering */
@@ -908,6 +927,12 @@ sna_screen_init(int scrnIndex, ScreenPtr screen, int argc, char **argv)
 	xf86DPMSInit(screen, xf86DPMSSet, 0);
 
 	sna_video_init(sna, screen);
+#ifdef DRI2
+	sna->directRenderingOpen = sna_dri_open(sna, screen);
+	if (sna->directRenderingOpen)
+		xf86DrvMsg(scrn->scrnIndex, X_INFO,
+			   "direct rendering: DRI2 Enabled\n");
+#endif
 
 	if (serverGeneration == 1)
 		xf86ShowUnusedOptions(scrn->scrnIndex, scrn->options);
commit bddac63de2d26c6ad4ade2f0a038d756f7a41424
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Thu Nov 10 10:55:13 2011 +0000

    sna: Defer purging a target buffer
    
    This is to keep the sanity checks upon the caches happy by keeping a
    potential flush out of the inactive cache.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/kgem.c b/src/sna/kgem.c
index 8d2295a..701c2c2 100644
--- a/src/sna/kgem.c
+++ b/src/sna/kgem.c
@@ -602,7 +602,7 @@ static void __kgem_bo_destroy(struct kgem *kgem, struct kgem_bo *bo)
 	if(!bo->reusable)
 		goto destroy;
 
-	if (bo->purgeable && !bo->rq) {
+	if (bo->purgeable && !bo->rq && !bo->needs_flush) {
 		assert(!bo->purged);
 
 		if (!gem_madvise(kgem->fd, bo->handle, I915_MADV_DONTNEED)) {
commit 9083f7edcb05b1deb7a77c9c5a8b54fe73176648
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Thu Nov 10 10:51:32 2011 +0000

    sna/gen3: Fixup some false asserts
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/gen3_render.c b/src/sna/gen3_render.c
index 8e978c2..54ccb93 100644
--- a/src/sna/gen3_render.c
+++ b/src/sna/gen3_render.c
@@ -948,11 +948,11 @@ gen3_composite_emit_shader(struct sna *sna,
 		case SHADER_OPACITY:
 			gen3_fs_dcl(FS_T0 + t);
 			break;
-		case SHADER_NONE:
 		case SHADER_ZERO:
 		case SHADER_BLACK:
-		case SHADER_WHITE:
 			assert(0);
+		case SHADER_NONE:
+		case SHADER_WHITE:
 			break;
 		}
 
@@ -1043,7 +1043,6 @@ gen3_composite_emit_shader(struct sna *sna,
 		case SHADER_ZERO:
 		case SHADER_BLACK:
 		case SHADER_WHITE:
-			assert(0);
 		case SHADER_NONE:
 			break;
 		}
commit ea01f7681901e3181204d3117fc0a23655de631f
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Thu Nov 10 10:51:01 2011 +0000

    configure: Force full-debug builds to disable compiler optimisations

diff --git a/configure.ac b/configure.ac
index 102a25a..fccab56 100644
--- a/configure.ac
+++ b/configure.ac
@@ -235,6 +235,7 @@ if test "x$DEBUG" != xno; then
 fi
 if test "x$DEBUG" = xfull; then
 	AC_DEFINE(HAS_DEBUG_FULL,1,[Enable all debugging])
+        CFLAGS="$CFLAGS -O0 -ggdb3"
 fi
 
 AC_CHECK_HEADERS([sys/timerfd.h])


More information about the xorg-commit mailing list