xf86-video-intel: 3 commits - src/i965_3d.c src/i965_render.c src/i965_video.c src/intel_batchbuffer.c src/intel_dri.c src/intel_driver.c src/intel_driver.h src/intel_hwmc.c src/intel_memory.c src/intel_module.c src/intel_uxa.c src/intel_video.c src/sna/brw src/sna/g4x_render.c src/sna/gen2_render.c src/sna/gen4_render.c src/sna/gen7_render.c src/sna/kgem.c src/sna/kgem_debug.c src/sna/kgem_debug_gen6.c src/sna/kgem.h src/sna/Makefile.am src/sna/sna_accel.c src/sna/sna_blt.c src/sna/sna_display.c src/sna/sna_dri.c src/sna/sna_driver.c src/sna/sna_glyphs.c src/sna/sna.h src/sna/sna_io.c src/sna/sna_render.c src/sna/sna_render.h src/sna/sna_video.c src/sna/sna_video_hwmc.c src/sna/sna_video_overlay.c src/sna/sna_video_sprite.c src/sna/sna_video_textured.c

Chris Wilson ickle at kemper.freedesktop.org
Fri Nov 30 04:56:31 PST 2012


 src/i965_3d.c                |    4 
 src/i965_render.c            |   32 
 src/i965_video.c             |    6 
 src/intel_batchbuffer.c      |    6 
 src/intel_dri.c              |   10 
 src/intel_driver.c           |   14 
 src/intel_driver.h           |    8 
 src/intel_hwmc.c             |    6 
 src/intel_memory.c           |    6 
 src/intel_module.c           |   30 
 src/intel_uxa.c              |    8 
 src/intel_video.c            |   48 
 src/sna/Makefile.am          |    1 
 src/sna/brw/brw_disasm.c     |   43 
 src/sna/brw/brw_eu.c         |    2 
 src/sna/brw/brw_eu.h         |    4 
 src/sna/brw/brw_eu_emit.c    |  132 -
 src/sna/brw/brw_wm.c         |   64 
 src/sna/g4x_render.c         | 3693 -------------------------------------------
 src/sna/gen2_render.c        |    6 
 src/sna/gen4_render.c        |  284 +--
 src/sna/gen7_render.c        |    6 
 src/sna/kgem.c               |   78 
 src/sna/kgem.h               |    6 
 src/sna/kgem_debug.c         |   34 
 src/sna/kgem_debug_gen6.c    |    8 
 src/sna/sna.h                |    1 
 src/sna/sna_accel.c          |   61 
 src/sna/sna_blt.c            |   26 
 src/sna/sna_display.c        |    8 
 src/sna/sna_dri.c            |    4 
 src/sna/sna_driver.c         |    2 
 src/sna/sna_glyphs.c         |    4 
 src/sna/sna_io.c             |    8 
 src/sna/sna_render.c         |    2 
 src/sna/sna_render.h         |    1 
 src/sna/sna_video.c          |    6 
 src/sna/sna_video_hwmc.c     |   16 
 src/sna/sna_video_overlay.c  |    8 
 src/sna/sna_video_sprite.c   |    2 
 src/sna/sna_video_textured.c |    2 
 41 files changed, 481 insertions(+), 4209 deletions(-)

New commits:
commit 1aee8acacfe5869a072d9f20f3b8290b16683260
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Fri Nov 30 12:17:25 2012 +0000

    sna: Unify gen4 acceleration again
    
    After disabling render-to-Y, 965g seems just as happy with the new code
    paths as g4x.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/Makefile.am b/src/sna/Makefile.am
index 9f3d579..306996b 100644
--- a/src/sna/Makefile.am
+++ b/src/sna/Makefile.am
@@ -72,7 +72,6 @@ libsna_la_SOURCES = \
 	gen3_render.c \
 	gen3_render.h \
 	gen4_render.c \
-	g4x_render.c \
 	gen4_render.h \
 	gen5_render.c \
 	gen5_render.h \
diff --git a/src/sna/g4x_render.c b/src/sna/g4x_render.c
deleted file mode 100644
index 70faab7..0000000
--- a/src/sna/g4x_render.c
+++ /dev/null
@@ -1,3693 +0,0 @@
-/*
- * Copyright © 2006,2008,2011 Intel Corporation
- * Copyright © 2007 Red Hat, 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 (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:
- *    Wang Zhenyu <zhenyu.z.wang at sna.com>
- *    Eric Anholt <eric at anholt.net>
- *    Carl Worth <cworth at redhat.com>
- *    Keith Packard <keithp at keithp.com>
- *    Chris Wilson <chris at chris-wilson.co.uk>
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "sna.h"
-#include "sna_reg.h"
-#include "sna_render.h"
-#include "sna_render_inline.h"
-#include "sna_video.h"
-
-#include "brw/brw.h"
-#include "gen4_render.h"
-
-/* gen4 has a serious issue with its shaders that we need to flush
- * after every rectangle... So until that is resolved, prefer
- * the BLT engine.
- */
-#define PREFER_BLT 1
-#define FORCE_SPANS 0
-
-#define NO_COMPOSITE 0
-#define NO_COMPOSITE_SPANS 0
-#define NO_COPY 0
-#define NO_COPY_BOXES 0
-#define NO_FILL 0
-#define NO_FILL_ONE 0
-#define NO_FILL_BOXES 0
-#define NO_VIDEO 0
-
-#define GEN4_GRF_BLOCKS(nreg)    ((nreg + 15) / 16 - 1)
-
-/* Set up a default static partitioning of the URB, which is supposed to
- * allow anything we would want to do, at potentially lower performance.
- */
-#define URB_CS_ENTRY_SIZE     1
-#define URB_CS_ENTRIES	      0
-
-#define URB_VS_ENTRY_SIZE     1
-#define URB_VS_ENTRIES	      32
-
-#define URB_GS_ENTRY_SIZE     0
-#define URB_GS_ENTRIES	      0
-
-#define URB_CLIP_ENTRY_SIZE   0
-#define URB_CLIP_ENTRIES      0
-
-#define URB_SF_ENTRY_SIZE     2
-#define URB_SF_ENTRIES	      64
-
-/*
- * this program computes dA/dx and dA/dy for the texture coordinates along
- * with the base texture coordinate. It was extracted from the Mesa driver
- */
-
-#define SF_KERNEL_NUM_GRF 16
-#define PS_KERNEL_NUM_GRF 32
-
-#define G4X_MAX_SF_THREADS 24
-#define G4X_MAX_WM_THREADS 50
-
-static const uint32_t ps_kernel_packed_static[][4] = {
-#include "exa_wm_xy.g4b"
-#include "exa_wm_src_affine.g4b"
-#include "exa_wm_src_sample_argb.g4b"
-#include "exa_wm_yuv_rgb.g4b"
-#include "exa_wm_write.g4b"
-};
-
-static const uint32_t ps_kernel_planar_static[][4] = {
-#include "exa_wm_xy.g4b"
-#include "exa_wm_src_affine.g4b"
-#include "exa_wm_src_sample_planar.g4b"
-#include "exa_wm_yuv_rgb.g4b"
-#include "exa_wm_write.g4b"
-};
-
-#define NOKERNEL(kernel_enum, func, masked) \
-    [kernel_enum] = {func, 0, masked}
-#define KERNEL(kernel_enum, kernel, masked) \
-    [kernel_enum] = {&kernel, sizeof(kernel), masked}
-static const struct wm_kernel_info {
-	const void *data;
-	unsigned int size;
-	bool has_mask;
-} wm_kernels[] = {
-	NOKERNEL(WM_KERNEL, brw_wm_kernel__affine, false),
-	NOKERNEL(WM_KERNEL_P, brw_wm_kernel__projective, false),
-
-	NOKERNEL(WM_KERNEL_MASK, brw_wm_kernel__affine_mask, true),
-	NOKERNEL(WM_KERNEL_MASK_P, brw_wm_kernel__projective_mask, true),
-
-	NOKERNEL(WM_KERNEL_MASKCA, brw_wm_kernel__affine_mask_ca, true),
-	NOKERNEL(WM_KERNEL_MASKCA_P, brw_wm_kernel__projective_mask_ca, true),
-
-	NOKERNEL(WM_KERNEL_MASKSA, brw_wm_kernel__affine_mask_sa, true),
-	NOKERNEL(WM_KERNEL_MASKSA_P, brw_wm_kernel__projective_mask_sa, true),
-
-	NOKERNEL(WM_KERNEL_OPACITY, brw_wm_kernel__affine_opacity, true),
-	NOKERNEL(WM_KERNEL_OPACITY_P, brw_wm_kernel__projective_opacity, true),
-
-	KERNEL(WM_KERNEL_VIDEO_PLANAR, ps_kernel_planar_static, false),
-	KERNEL(WM_KERNEL_VIDEO_PACKED, ps_kernel_packed_static, false),
-};
-#undef KERNEL
-
-static const struct blendinfo {
-	bool src_alpha;
-	uint32_t src_blend;
-	uint32_t dst_blend;
-} g4x_blend_op[] = {
-	/* Clear */	{0, GEN4_BLENDFACTOR_ZERO, GEN4_BLENDFACTOR_ZERO},
-	/* Src */	{0, GEN4_BLENDFACTOR_ONE, GEN4_BLENDFACTOR_ZERO},
-	/* Dst */	{0, GEN4_BLENDFACTOR_ZERO, GEN4_BLENDFACTOR_ONE},
-	/* Over */	{1, GEN4_BLENDFACTOR_ONE, GEN4_BLENDFACTOR_INV_SRC_ALPHA},
-	/* OverReverse */ {0, GEN4_BLENDFACTOR_INV_DST_ALPHA, GEN4_BLENDFACTOR_ONE},
-	/* In */	{0, GEN4_BLENDFACTOR_DST_ALPHA, GEN4_BLENDFACTOR_ZERO},
-	/* InReverse */	{1, GEN4_BLENDFACTOR_ZERO, GEN4_BLENDFACTOR_SRC_ALPHA},
-	/* Out */	{0, GEN4_BLENDFACTOR_INV_DST_ALPHA, GEN4_BLENDFACTOR_ZERO},
-	/* OutReverse */ {1, GEN4_BLENDFACTOR_ZERO, GEN4_BLENDFACTOR_INV_SRC_ALPHA},
-	/* Atop */	{1, GEN4_BLENDFACTOR_DST_ALPHA, GEN4_BLENDFACTOR_INV_SRC_ALPHA},
-	/* AtopReverse */ {1, GEN4_BLENDFACTOR_INV_DST_ALPHA, GEN4_BLENDFACTOR_SRC_ALPHA},
-	/* Xor */	{1, GEN4_BLENDFACTOR_INV_DST_ALPHA, GEN4_BLENDFACTOR_INV_SRC_ALPHA},
-	/* Add */	{0, GEN4_BLENDFACTOR_ONE, GEN4_BLENDFACTOR_ONE},
-};
-
-/**
- * Highest-valued BLENDFACTOR used in g4x_blend_op.
- *
- * This leaves out GEN4_BLENDFACTOR_INV_DST_COLOR,
- * GEN4_BLENDFACTOR_INV_CONST_{COLOR,ALPHA},
- * GEN4_BLENDFACTOR_INV_SRC1_{COLOR,ALPHA}
- */
-#define GEN4_BLENDFACTOR_COUNT (GEN4_BLENDFACTOR_INV_DST_ALPHA + 1)
-
-#define BLEND_OFFSET(s, d) \
-	(((s) * GEN4_BLENDFACTOR_COUNT + (d)) * 64)
-
-#define SAMPLER_OFFSET(sf, se, mf, me, k) \
-	((((((sf) * EXTEND_COUNT + (se)) * FILTER_COUNT + (mf)) * EXTEND_COUNT + (me)) * KERNEL_COUNT + (k)) * 64)
-
-static void
-g4x_emit_pipelined_pointers(struct sna *sna,
-			    const struct sna_composite_op *op,
-			    int blend, int kernel);
-
-#define OUT_BATCH(v) batch_emit(sna, v)
-#define OUT_VERTEX(x,y) vertex_emit_2s(sna, x,y)
-#define OUT_VERTEX_F(v) vertex_emit(sna, v)
-
-#define GEN4_MAX_3D_SIZE 8192
-
-static inline bool too_large(int width, int height)
-{
-	return width > GEN4_MAX_3D_SIZE || height > GEN4_MAX_3D_SIZE;
-}
-
-static int
-g4x_choose_composite_kernel(int op, bool has_mask, bool is_ca, bool is_affine)
-{
-	int base;
-
-	if (has_mask) {
-		if (is_ca) {
-			if (g4x_blend_op[op].src_alpha)
-				base = WM_KERNEL_MASKSA;
-			else
-				base = WM_KERNEL_MASKCA;
-		} else
-			base = WM_KERNEL_MASK;
-	} else
-		base = WM_KERNEL;
-
-	return base + !is_affine;
-}
-
-static void g4x_magic_ca_pass(struct sna *sna,
-			      const struct sna_composite_op *op)
-{
-	struct gen4_render_state *state = &sna->render_state.gen4;
-
-	if (!op->need_magic_ca_pass)
-		return;
-
-	DBG(("%s: CA fixup\n", __FUNCTION__));
-	assert(op->mask.bo != NULL);
-	assert(op->has_component_alpha);
-
-	g4x_emit_pipelined_pointers(sna, op, PictOpAdd,
-				     g4x_choose_composite_kernel(PictOpAdd,
-								  true, true, op->is_affine));
-
-	OUT_BATCH(GEN4_3DPRIMITIVE |
-		  GEN4_3DPRIMITIVE_VERTEX_SEQUENTIAL |
-		  (_3DPRIM_RECTLIST << GEN4_3DPRIMITIVE_TOPOLOGY_SHIFT) |
-		  (0 << 9) |
-		  4);
-	OUT_BATCH(sna->render.vertex_index - sna->render.vertex_start);
-	OUT_BATCH(sna->render.vertex_start);
-	OUT_BATCH(1);	/* single instance */
-	OUT_BATCH(0);	/* start instance location */
-	OUT_BATCH(0);	/* index buffer offset, ignored */
-
-	state->last_primitive = sna->kgem.nbatch;
-}
-
-static void g4x_vertex_flush(struct sna *sna)
-{
-	if (sna->render_state.gen4.vertex_offset == 0)
-		return;
-
-	DBG(("%s[%x] = %d\n", __FUNCTION__,
-	     4*sna->render_state.gen4.vertex_offset,
-	     sna->render.vertex_index - sna->render.vertex_start));
-	sna->kgem.batch[sna->render_state.gen4.vertex_offset] =
-		sna->render.vertex_index - sna->render.vertex_start;
-	sna->render_state.gen4.vertex_offset = 0;
-}
-
-static int g4x_vertex_finish(struct sna *sna)
-{
-	struct kgem_bo *bo;
-	unsigned int i;
-
-	assert(sna->render.vertex_used);
-	assert(sna->render.nvertex_reloc);
-
-	/* Note: we only need dword alignment (currently) */
-
-	bo = sna->render.vbo;
-	if (bo) {
-		g4x_vertex_flush(sna);
-
-		for (i = 0; i < sna->render.nvertex_reloc; i++) {
-			DBG(("%s: reloc[%d] = %d\n", __FUNCTION__,
-			     i, sna->render.vertex_reloc[i]));
-
-			sna->kgem.batch[sna->render.vertex_reloc[i]] =
-				kgem_add_reloc(&sna->kgem,
-					       sna->render.vertex_reloc[i], bo,
-					       I915_GEM_DOMAIN_VERTEX << 16,
-					       0);
-		}
-
-		sna->render.vbo = NULL;
-		sna->render.nvertex_reloc = 0;
-		sna->render.vertex_used = 0;
-		sna->render.vertex_index = 0;
-		sna->render_state.gen4.vb_id = 0;
-
-		kgem_bo_destroy(&sna->kgem, bo);
-	}
-
-	sna->render.vertices = NULL;
-	sna->render.vbo = kgem_create_linear(&sna->kgem,
-					     256*1024, CREATE_GTT_MAP);
-	if (sna->render.vbo)
-		sna->render.vertices = kgem_bo_map(&sna->kgem, sna->render.vbo);
-	if (sna->render.vertices == NULL) {
-		if (sna->render.vbo)
-			kgem_bo_destroy(&sna->kgem, sna->render.vbo);
-		sna->render.vbo = NULL;
-		return 0;
-	}
-
-	if (sna->render.vertex_used) {
-		memcpy(sna->render.vertices,
-		       sna->render.vertex_data,
-		       sizeof(float)*sna->render.vertex_used);
-	}
-	sna->render.vertex_size = 64 * 1024 - 1;
-	return sna->render.vertex_size - sna->render.vertex_used;
-}
-
-static void g4x_vertex_close(struct sna *sna)
-{
-	struct kgem_bo *bo, *free_bo = NULL;
-	unsigned int i, delta = 0;
-
-	assert(sna->render_state.gen4.vertex_offset == 0);
-	if (!sna->render_state.gen4.vb_id)
-		return;
-
-	DBG(("%s: used=%d, vbo active? %d\n",
-	     __FUNCTION__, sna->render.vertex_used, sna->render.vbo != NULL));
-
-	bo = sna->render.vbo;
-	if (bo) {
-		if (sna->render.vertex_size - sna->render.vertex_used < 64) {
-			DBG(("%s: discarding full vbo\n", __FUNCTION__));
-			sna->render.vbo = NULL;
-			sna->render.vertices = sna->render.vertex_data;
-			sna->render.vertex_size = ARRAY_SIZE(sna->render.vertex_data);
-			free_bo = bo;
-		} else if (IS_CPU_MAP(bo->map)) {
-			DBG(("%s: converting CPU map to GTT\n", __FUNCTION__));
-			sna->render.vertices =
-				kgem_bo_map__gtt(&sna->kgem, sna->render.vbo);
-			if (sna->render.vertices == NULL) {
-				sna->render.vbo = NULL;
-				sna->render.vertices = sna->render.vertex_data;
-				sna->render.vertex_size = ARRAY_SIZE(sna->render.vertex_data);
-				free_bo = bo;
-			}
-		}
-	} else {
-		if (sna->kgem.nbatch + sna->render.vertex_used <= sna->kgem.surface) {
-			DBG(("%s: copy to batch: %d @ %d\n", __FUNCTION__,
-			     sna->render.vertex_used, sna->kgem.nbatch));
-			memcpy(sna->kgem.batch + sna->kgem.nbatch,
-			       sna->render.vertex_data,
-			       sna->render.vertex_used * 4);
-			delta = sna->kgem.nbatch * 4;
-			bo = NULL;
-			sna->kgem.nbatch += sna->render.vertex_used;
-		} else {
-			bo = kgem_create_linear(&sna->kgem,
-						4*sna->render.vertex_used, 0);
-			if (bo && !kgem_bo_write(&sna->kgem, bo,
-						 sna->render.vertex_data,
-						 4*sna->render.vertex_used)) {
-				kgem_bo_destroy(&sna->kgem, bo);
-				bo = NULL;
-			}
-			DBG(("%s: new vbo: %d\n", __FUNCTION__,
-			     sna->render.vertex_used));
-			free_bo = bo;
-		}
-	}
-
-	assert(sna->render.nvertex_reloc);
-	for (i = 0; i < sna->render.nvertex_reloc; i++) {
-		DBG(("%s: reloc[%d] = %d\n", __FUNCTION__,
-		     i, sna->render.vertex_reloc[i]));
-
-		sna->kgem.batch[sna->render.vertex_reloc[i]] =
-			kgem_add_reloc(&sna->kgem,
-				       sna->render.vertex_reloc[i], bo,
-				       I915_GEM_DOMAIN_VERTEX << 16,
-				       delta);
-	}
-	sna->render.nvertex_reloc = 0;
-
-	if (sna->render.vbo == NULL) {
-		sna->render.vertex_used = 0;
-		sna->render.vertex_index = 0;
-	}
-
-	if (free_bo)
-		kgem_bo_destroy(&sna->kgem, free_bo);
-}
-
-
-static uint32_t g4x_get_blend(int op,
-			      bool has_component_alpha,
-			      uint32_t dst_format)
-{
-	uint32_t src, dst;
-
-	src = g4x_blend_op[op].src_blend;
-	dst = g4x_blend_op[op].dst_blend;
-
-	/* If there's no dst alpha channel, adjust the blend op so that we'll treat
-	 * it as always 1.
-	 */
-	if (PICT_FORMAT_A(dst_format) == 0) {
-		if (src == GEN4_BLENDFACTOR_DST_ALPHA)
-			src = GEN4_BLENDFACTOR_ONE;
-		else if (src == GEN4_BLENDFACTOR_INV_DST_ALPHA)
-			src = GEN4_BLENDFACTOR_ZERO;
-	}
-
-	/* If the source alpha is being used, then we should only be in a
-	 * case where the source blend factor is 0, and the source blend
-	 * value is the mask channels multiplied by the source picture's alpha.
-	 */
-	if (has_component_alpha && g4x_blend_op[op].src_alpha) {
-		if (dst == GEN4_BLENDFACTOR_SRC_ALPHA)
-			dst = GEN4_BLENDFACTOR_SRC_COLOR;
-		else if (dst == GEN4_BLENDFACTOR_INV_SRC_ALPHA)
-			dst = GEN4_BLENDFACTOR_INV_SRC_COLOR;
-	}
-
-	DBG(("blend op=%d, dst=%x [A=%d] => src=%d, dst=%d => offset=%x\n",
-	     op, dst_format, PICT_FORMAT_A(dst_format),
-	     src, dst, BLEND_OFFSET(src, dst)));
-	return BLEND_OFFSET(src, dst);
-}
-
-static uint32_t g4x_get_card_format(PictFormat format)
-{
-	switch (format) {
-	default:
-		return -1;
-	case PICT_a8r8g8b8:
-		return GEN4_SURFACEFORMAT_B8G8R8A8_UNORM;
-	case PICT_x8r8g8b8:
-		return GEN4_SURFACEFORMAT_B8G8R8X8_UNORM;
-	case PICT_a8b8g8r8:
-		return GEN4_SURFACEFORMAT_R8G8B8A8_UNORM;
-	case PICT_x8b8g8r8:
-		return GEN4_SURFACEFORMAT_R8G8B8X8_UNORM;
-	case PICT_a2r10g10b10:
-		return GEN4_SURFACEFORMAT_B10G10R10A2_UNORM;
-	case PICT_x2r10g10b10:
-		return GEN4_SURFACEFORMAT_B10G10R10X2_UNORM;
-	case PICT_r8g8b8:
-		return GEN4_SURFACEFORMAT_R8G8B8_UNORM;
-	case PICT_r5g6b5:
-		return GEN4_SURFACEFORMAT_B5G6R5_UNORM;
-	case PICT_a1r5g5b5:
-		return GEN4_SURFACEFORMAT_B5G5R5A1_UNORM;
-	case PICT_a8:
-		return GEN4_SURFACEFORMAT_A8_UNORM;
-	case PICT_a4r4g4b4:
-		return GEN4_SURFACEFORMAT_B4G4R4A4_UNORM;
-	}
-}
-
-static uint32_t g4x_get_dest_format(PictFormat format)
-{
-	switch (format) {
-	default:
-		return -1;
-	case PICT_a8r8g8b8:
-	case PICT_x8r8g8b8:
-		return GEN4_SURFACEFORMAT_B8G8R8A8_UNORM;
-	case PICT_a8b8g8r8:
-	case PICT_x8b8g8r8:
-		return GEN4_SURFACEFORMAT_R8G8B8A8_UNORM;
-	case PICT_a2r10g10b10:
-	case PICT_x2r10g10b10:
-		return GEN4_SURFACEFORMAT_B10G10R10A2_UNORM;
-	case PICT_r5g6b5:
-		return GEN4_SURFACEFORMAT_B5G6R5_UNORM;
-	case PICT_x1r5g5b5:
-	case PICT_a1r5g5b5:
-		return GEN4_SURFACEFORMAT_B5G5R5A1_UNORM;
-	case PICT_a8:
-		return GEN4_SURFACEFORMAT_A8_UNORM;
-	case PICT_a4r4g4b4:
-	case PICT_x4r4g4b4:
-		return GEN4_SURFACEFORMAT_B4G4R4A4_UNORM;
-	}
-}
-
-static bool g4x_check_dst_format(PictFormat format)
-{
-	if (g4x_get_dest_format(format) != -1)
-		return true;
-
-	DBG(("%s: unhandled format: %x\n", __FUNCTION__, (int)format));
-	return false;
-}
-
-static bool g4x_check_format(uint32_t format)
-{
-	if (g4x_get_card_format(format) != -1)
-		return true;
-
-	DBG(("%s: unhandled format: %x\n", __FUNCTION__, (int)format));
-	return false;
-}
-
-typedef struct gen4_surface_state_padded {
-	struct gen4_surface_state state;
-	char pad[32 - sizeof(struct gen4_surface_state)];
-} gen4_surface_state_padded;
-
-static void null_create(struct sna_static_stream *stream)
-{
-	/* A bunch of zeros useful for legacy border color and depth-stencil */
-	sna_static_stream_map(stream, 64, 64);
-}
-
-static void
-sampler_state_init(struct gen4_sampler_state *sampler_state,
-		   sampler_filter_t filter,
-		   sampler_extend_t extend)
-{
-	sampler_state->ss0.lod_preclamp = 1;	/* GL mode */
-
-	/* We use the legacy mode to get the semantics specified by
-	 * the Render extension. */
-	sampler_state->ss0.border_color_mode = GEN4_BORDER_COLOR_MODE_LEGACY;
-
-	switch (filter) {
-	default:
-	case SAMPLER_FILTER_NEAREST:
-		sampler_state->ss0.min_filter = GEN4_MAPFILTER_NEAREST;
-		sampler_state->ss0.mag_filter = GEN4_MAPFILTER_NEAREST;
-		break;
-	case SAMPLER_FILTER_BILINEAR:
-		sampler_state->ss0.min_filter = GEN4_MAPFILTER_LINEAR;
-		sampler_state->ss0.mag_filter = GEN4_MAPFILTER_LINEAR;
-		break;
-	}
-
-	switch (extend) {
-	default:
-	case SAMPLER_EXTEND_NONE:
-		sampler_state->ss1.r_wrap_mode = GEN4_TEXCOORDMODE_CLAMP_BORDER;
-		sampler_state->ss1.s_wrap_mode = GEN4_TEXCOORDMODE_CLAMP_BORDER;
-		sampler_state->ss1.t_wrap_mode = GEN4_TEXCOORDMODE_CLAMP_BORDER;
-		break;
-	case SAMPLER_EXTEND_REPEAT:
-		sampler_state->ss1.r_wrap_mode = GEN4_TEXCOORDMODE_WRAP;
-		sampler_state->ss1.s_wrap_mode = GEN4_TEXCOORDMODE_WRAP;
-		sampler_state->ss1.t_wrap_mode = GEN4_TEXCOORDMODE_WRAP;
-		break;
-	case SAMPLER_EXTEND_PAD:
-		sampler_state->ss1.r_wrap_mode = GEN4_TEXCOORDMODE_CLAMP;
-		sampler_state->ss1.s_wrap_mode = GEN4_TEXCOORDMODE_CLAMP;
-		sampler_state->ss1.t_wrap_mode = GEN4_TEXCOORDMODE_CLAMP;
-		break;
-	case SAMPLER_EXTEND_REFLECT:
-		sampler_state->ss1.r_wrap_mode = GEN4_TEXCOORDMODE_MIRROR;
-		sampler_state->ss1.s_wrap_mode = GEN4_TEXCOORDMODE_MIRROR;
-		sampler_state->ss1.t_wrap_mode = GEN4_TEXCOORDMODE_MIRROR;
-		break;
-	}
-}
-
-static uint32_t g4x_filter(uint32_t filter)
-{
-	switch (filter) {
-	default:
-		assert(0);
-	case PictFilterNearest:
-		return SAMPLER_FILTER_NEAREST;
-	case PictFilterBilinear:
-		return SAMPLER_FILTER_BILINEAR;
-	}
-}
-
-static uint32_t g4x_check_filter(PicturePtr picture)
-{
-	switch (picture->filter) {
-	case PictFilterNearest:
-	case PictFilterBilinear:
-		return true;
-	default:
-		DBG(("%s: unknown filter: %s [%d]\n",
-		     __FUNCTION__,
-		     PictureGetFilterName(picture->filter),
-		     picture->filter));
-		return false;
-	}
-}
-
-static uint32_t g4x_repeat(uint32_t repeat)
-{
-	switch (repeat) {
-	default:
-		assert(0);
-	case RepeatNone:
-		return SAMPLER_EXTEND_NONE;
-	case RepeatNormal:
-		return SAMPLER_EXTEND_REPEAT;
-	case RepeatPad:
-		return SAMPLER_EXTEND_PAD;
-	case RepeatReflect:
-		return SAMPLER_EXTEND_REFLECT;
-	}
-}
-
-static bool g4x_check_repeat(PicturePtr picture)
-{
-	if (!picture->repeat)
-		return true;
-
-	switch (picture->repeatType) {
-	case RepeatNone:
-	case RepeatNormal:
-	case RepeatPad:
-	case RepeatReflect:
-		return true;
-	default:
-		DBG(("%s: unknown repeat: %d\n",
-		     __FUNCTION__, picture->repeatType));
-		return false;
-	}
-}
-
-/**
- * Sets up the common fields for a surface state buffer for the given
- * picture in the given surface state buffer.
- */
-static uint32_t
-g4x_bind_bo(struct sna *sna,
-	    struct kgem_bo *bo,
-	    uint32_t width,
-	    uint32_t height,
-	    uint32_t format,
-	    bool is_dst)
-{
-	struct gen4_surface_state *ss;
-	uint32_t domains;
-	uint16_t offset;
-
-	assert(sna->kgem.gen != 040 || !kgem_bo_is_snoop(bo));
-
-	/* After the first bind, we manage the cache domains within the batch */
-	offset = kgem_bo_get_binding(bo, format);
-	if (offset) {
-		if (is_dst)
-			kgem_bo_mark_dirty(bo);
-		return offset * sizeof(uint32_t);
-	}
-
-	offset = sna->kgem.surface -=
-		sizeof(struct gen4_surface_state_padded) / sizeof(uint32_t);
-	ss = memset(sna->kgem.batch + offset, 0, sizeof(*ss));
-
-	ss->ss0.surface_type = GEN4_SURFACE_2D;
-	ss->ss0.surface_format = format;
-
-	if (is_dst)
-		domains = I915_GEM_DOMAIN_RENDER << 16 | I915_GEM_DOMAIN_RENDER;
-	else
-		domains = I915_GEM_DOMAIN_SAMPLER << 16;
-
-	ss->ss0.data_return_format = GEN4_SURFACERETURNFORMAT_FLOAT32;
-	ss->ss0.color_blend = 1;
-	ss->ss1.base_addr =
-		kgem_add_reloc(&sna->kgem, offset + 1, bo, domains, 0);
-
-	ss->ss2.height = height - 1;
-	ss->ss2.width  = width - 1;
-	ss->ss3.pitch  = bo->pitch - 1;
-	ss->ss3.tiled_surface = bo->tiling != I915_TILING_NONE;
-	ss->ss3.tile_walk     = bo->tiling == I915_TILING_Y;
-
-	kgem_bo_set_binding(bo, format, offset);
-
-	DBG(("[%x] bind bo(handle=%d, addr=%d), format=%d, width=%d, height=%d, pitch=%d, tiling=%d -> %s\n",
-	     offset, bo->handle, ss->ss1.base_addr,
-	     ss->ss0.surface_format, width, height, bo->pitch, bo->tiling,
-	     domains & 0xffff ? "render" : "sampler"));
-
-	return offset * sizeof(uint32_t);
-}
-
-fastcall static void
-g4x_emit_composite_primitive_solid(struct sna *sna,
-				   const struct sna_composite_op *op,
-				   const struct sna_composite_rectangles *r)
-{
-	float *v;
-	union {
-		struct sna_coordinate p;
-		float f;
-	} dst;
-
-	v = sna->render.vertices + sna->render.vertex_used;
-	sna->render.vertex_used += 9;
-
-	dst.p.x = r->dst.x + r->width;
-	dst.p.y = r->dst.y + r->height;
-	v[0] = dst.f;
-	v[1] = 1.;
-	v[2] = 1.;
-
-	dst.p.x = r->dst.x;
-	v[3] = dst.f;
-	v[4] = 0.;
-	v[5] = 1.;
-
-	dst.p.y = r->dst.y;
-	v[6] = dst.f;
-	v[7] = 0.;
-	v[8] = 0.;
-}
-
-fastcall static void
-g4x_emit_composite_primitive_identity_source(struct sna *sna,
-					     const struct sna_composite_op *op,
-					     const struct sna_composite_rectangles *r)
-{
-	const float *sf = op->src.scale;
-	float sx, sy, *v;
-	union {
-		struct sna_coordinate p;
-		float f;
-	} dst;
-
-	v = sna->render.vertices + sna->render.vertex_used;
-	sna->render.vertex_used += 9;
-
-	sx = r->src.x + op->src.offset[0];
-	sy = r->src.y + op->src.offset[1];
-
-	dst.p.x = r->dst.x + r->width;
-	dst.p.y = r->dst.y + r->height;
-	v[0] = dst.f;
-	v[1] = (sx + r->width) * sf[0];
-	v[2] = (sy + r->height) * sf[1];
-
-	dst.p.x = r->dst.x;
-	v[3] = dst.f;
-	v[4] = sx * sf[0];
-	v[5] = v[2];
-
-	dst.p.y = r->dst.y;
-	v[6] = dst.f;
-	v[7] = v[4];
-	v[8] = sy * sf[1];
-}
-
-fastcall static void
-g4x_emit_composite_primitive_affine_source(struct sna *sna,
-					   const struct sna_composite_op *op,
-					   const struct sna_composite_rectangles *r)
-{
-	union {
-		struct sna_coordinate p;
-		float f;
-	} dst;
-	float *v;
-
-	v = sna->render.vertices + sna->render.vertex_used;
-	sna->render.vertex_used += 9;
-
-	dst.p.x = r->dst.x + r->width;
-	dst.p.y = r->dst.y + r->height;
-	v[0] = dst.f;
-	_sna_get_transformed_coordinates(op->src.offset[0] + r->src.x + r->width,
-					 op->src.offset[1] + r->src.y + r->height,
-					 op->src.transform,
-					 &v[1], &v[2]);
-	v[1] *= op->src.scale[0];
-	v[2] *= op->src.scale[1];
-
-	dst.p.x = r->dst.x;
-	v[3] = dst.f;
-	_sna_get_transformed_coordinates(op->src.offset[0] + r->src.x,
-					 op->src.offset[1] + r->src.y + r->height,
-					 op->src.transform,
-					 &v[4], &v[5]);
-	v[4] *= op->src.scale[0];
-	v[5] *= op->src.scale[1];
-
-	dst.p.y = r->dst.y;
-	v[6] = dst.f;
-	_sna_get_transformed_coordinates(op->src.offset[0] + r->src.x,
-					 op->src.offset[1] + r->src.y,
-					 op->src.transform,
-					 &v[7], &v[8]);
-	v[7] *= op->src.scale[0];
-	v[8] *= op->src.scale[1];
-}
-
-fastcall static void
-g4x_emit_composite_primitive_identity_source_mask(struct sna *sna,
-						  const struct sna_composite_op *op,
-						  const struct sna_composite_rectangles *r)
-{
-	union {
-		struct sna_coordinate p;
-		float f;
-	} dst;
-	float src_x, src_y;
-	float msk_x, msk_y;
-	float w, h;
-	float *v;
-
-	src_x = r->src.x + op->src.offset[0];
-	src_y = r->src.y + op->src.offset[1];
-	msk_x = r->mask.x + op->mask.offset[0];
-	msk_y = r->mask.y + op->mask.offset[1];
-	w = r->width;
-	h = r->height;
-
-	v = sna->render.vertices + sna->render.vertex_used;
-	sna->render.vertex_used += 15;
-
-	dst.p.x = r->dst.x + r->width;
-	dst.p.y = r->dst.y + r->height;
-	v[0] = dst.f;
-	v[1] = (src_x + w) * op->src.scale[0];
-	v[2] = (src_y + h) * op->src.scale[1];
-	v[3] = (msk_x + w) * op->mask.scale[0];
-	v[4] = (msk_y + h) * op->mask.scale[1];
-
-	dst.p.x = r->dst.x;
-	v[5] = dst.f;
-	v[6] = src_x * op->src.scale[0];
-	v[7] = v[2];
-	v[8] = msk_x * op->mask.scale[0];
-	v[9] = v[4];
-
-	dst.p.y = r->dst.y;
-	v[10] = dst.f;
-	v[11] = v[6];
-	v[12] = src_y * op->src.scale[1];
-	v[13] = v[8];
-	v[14] = msk_y * op->mask.scale[1];
-}
-
-fastcall static void
-g4x_emit_composite_primitive(struct sna *sna,
-			     const struct sna_composite_op *op,
-			     const struct sna_composite_rectangles *r)
-{
-	float src_x[3], src_y[3], src_w[3], mask_x[3], mask_y[3], mask_w[3];
-	bool is_affine = op->is_affine;
-	const float *src_sf = op->src.scale;
-	const float *mask_sf = op->mask.scale;
-	bool has_mask = op->u.gen4.ve_id & 2;
-
-	if (is_affine) {
-		sna_get_transformed_coordinates(r->src.x + op->src.offset[0],
-						r->src.y + op->src.offset[1],
-						op->src.transform,
-						&src_x[0],
-						&src_y[0]);
-
-		sna_get_transformed_coordinates(r->src.x + op->src.offset[0],
-						r->src.y + op->src.offset[1] + r->height,
-						op->src.transform,
-						&src_x[1],
-						&src_y[1]);
-
-		sna_get_transformed_coordinates(r->src.x + op->src.offset[0] + r->width,
-						r->src.y + op->src.offset[1] + r->height,
-						op->src.transform,
-						&src_x[2],
-						&src_y[2]);
-	} else {
-		sna_get_transformed_coordinates_3d(r->src.x + op->src.offset[0],
-						   r->src.y + op->src.offset[1],
-						   op->src.transform,
-						   &src_x[0],
-						   &src_y[0],
-						   &src_w[0]);
-		sna_get_transformed_coordinates_3d(r->src.x + op->src.offset[0],
-						   r->src.y + op->src.offset[1] + r->height,
-						   op->src.transform,
-						   &src_x[1],
-						   &src_y[1],
-						   &src_w[1]);
-		sna_get_transformed_coordinates_3d(r->src.x + op->src.offset[0] + r->width,
-						   r->src.y + op->src.offset[1] + r->height,
-						   op->src.transform,
-						   &src_x[2],
-						   &src_y[2],
-						   &src_w[2]);
-	}
-
-	if (has_mask) {
-		if (is_affine) {
-			sna_get_transformed_coordinates(r->mask.x + op->mask.offset[0],
-							r->mask.y + op->mask.offset[1],
-							op->mask.transform,
-							&mask_x[0],
-							&mask_y[0]);
-
-			sna_get_transformed_coordinates(r->mask.x + op->mask.offset[0],
-							r->mask.y + op->mask.offset[1] + r->height,
-							op->mask.transform,
-							&mask_x[1],
-							&mask_y[1]);
-
-			sna_get_transformed_coordinates(r->mask.x + op->mask.offset[0] + r->width,
-							r->mask.y + op->mask.offset[1] + r->height,
-							op->mask.transform,
-							&mask_x[2],
-							&mask_y[2]);
-		} else {
-			sna_get_transformed_coordinates_3d(r->mask.x + op->mask.offset[0],
-							   r->mask.y + op->mask.offset[1],
-							   op->mask.transform,
-							   &mask_x[0],
-							   &mask_y[0],
-							   &mask_w[0]);
-			sna_get_transformed_coordinates_3d(r->mask.x + op->mask.offset[0],
-							   r->mask.y + op->mask.offset[1] + r->height,
-							   op->mask.transform,
-							   &mask_x[1],
-							   &mask_y[1],
-							   &mask_w[1]);
-			sna_get_transformed_coordinates_3d(r->mask.x + op->mask.offset[0] + r->width,
-							   r->mask.y + op->mask.offset[1] + r->height,
-							   op->mask.transform,
-							   &mask_x[2],
-							   &mask_y[2],
-							   &mask_w[2]);
-		}
-	}
-
-	OUT_VERTEX(r->dst.x + r->width, r->dst.y + r->height);
-	OUT_VERTEX_F(src_x[2] * src_sf[0]);
-	OUT_VERTEX_F(src_y[2] * src_sf[1]);
-	if (!is_affine)
-		OUT_VERTEX_F(src_w[2]);
-	if (has_mask) {
-		OUT_VERTEX_F(mask_x[2] * mask_sf[0]);
-		OUT_VERTEX_F(mask_y[2] * mask_sf[1]);
-		if (!is_affine)
-			OUT_VERTEX_F(mask_w[2]);
-	}
-
-	OUT_VERTEX(r->dst.x, r->dst.y + r->height);
-	OUT_VERTEX_F(src_x[1] * src_sf[0]);
-	OUT_VERTEX_F(src_y[1] * src_sf[1]);
-	if (!is_affine)
-		OUT_VERTEX_F(src_w[1]);
-	if (has_mask) {
-		OUT_VERTEX_F(mask_x[1] * mask_sf[0]);
-		OUT_VERTEX_F(mask_y[1] * mask_sf[1]);
-		if (!is_affine)
-			OUT_VERTEX_F(mask_w[1]);
-	}
-
-	OUT_VERTEX(r->dst.x, r->dst.y);
-	OUT_VERTEX_F(src_x[0] * src_sf[0]);
-	OUT_VERTEX_F(src_y[0] * src_sf[1]);
-	if (!is_affine)
-		OUT_VERTEX_F(src_w[0]);
-	if (has_mask) {
-		OUT_VERTEX_F(mask_x[0] * mask_sf[0]);
-		OUT_VERTEX_F(mask_y[0] * mask_sf[1]);
-		if (!is_affine)
-			OUT_VERTEX_F(mask_w[0]);
-	}
-}
-
-static void g4x_emit_vertex_buffer(struct sna *sna,
-				   const struct sna_composite_op *op)
-{
-	int id = op->u.gen4.ve_id;
-
-	OUT_BATCH(GEN4_3DSTATE_VERTEX_BUFFERS | 3);
-	OUT_BATCH((id << VB0_BUFFER_INDEX_SHIFT) | VB0_VERTEXDATA |
-		  (4*op->floats_per_vertex << VB0_BUFFER_PITCH_SHIFT));
-	sna->render.vertex_reloc[sna->render.nvertex_reloc++] = sna->kgem.nbatch;
-	OUT_BATCH(0);
-	OUT_BATCH(0);
-	OUT_BATCH(0);
-
-	sna->render_state.gen4.vb_id |= 1 << id;
-}
-
-static void g4x_emit_primitive(struct sna *sna)
-{
-	if (sna->kgem.nbatch == sna->render_state.gen4.last_primitive) {
-		sna->render_state.gen4.vertex_offset = sna->kgem.nbatch - 5;
-		return;
-	}
-
-	OUT_BATCH(GEN4_3DPRIMITIVE |
-		  GEN4_3DPRIMITIVE_VERTEX_SEQUENTIAL |
-		  (_3DPRIM_RECTLIST << GEN4_3DPRIMITIVE_TOPOLOGY_SHIFT) |
-		  (0 << 9) |
-		  4);
-	sna->render_state.gen4.vertex_offset = sna->kgem.nbatch;
-	OUT_BATCH(0);	/* vertex count, to be filled in later */
-	OUT_BATCH(sna->render.vertex_index);
-	OUT_BATCH(1);	/* single instance */
-	OUT_BATCH(0);	/* start instance location */
-	OUT_BATCH(0);	/* index buffer offset, ignored */
-	sna->render.vertex_start = sna->render.vertex_index;
-
-	sna->render_state.gen4.last_primitive = sna->kgem.nbatch;
-}
-
-static bool g4x_rectangle_begin(struct sna *sna,
-				const struct sna_composite_op *op)
-{
-	int id = op->u.gen4.ve_id;
-	int ndwords;
-
-	/* 7xpipelined pointers + 6xprimitive + 1xflush */
-	ndwords = op->need_magic_ca_pass? 20 : 6;
-	if ((sna->render_state.gen4.vb_id & (1 << id)) == 0)
-		ndwords += 5;
-
-	if (!kgem_check_batch(&sna->kgem, ndwords))
-		return false;
-
-	if ((sna->render_state.gen4.vb_id & (1 << id)) == 0)
-		g4x_emit_vertex_buffer(sna, op);
-	if (sna->render_state.gen4.vertex_offset == 0)
-		g4x_emit_primitive(sna);
-
-	return true;
-}
-
-static int g4x_get_rectangles__flush(struct sna *sna,
-				     const struct sna_composite_op *op)
-{
-	if (!kgem_check_batch(&sna->kgem, op->need_magic_ca_pass ? 25 : 6))
-		return 0;
-	if (!kgem_check_reloc_and_exec(&sna->kgem, 1))
-		return 0;
-
-	if (op->need_magic_ca_pass && sna->render.vbo)
-		return 0;
-
-	return g4x_vertex_finish(sna);
-}
-
-inline static int g4x_get_rectangles(struct sna *sna,
-				     const struct sna_composite_op *op,
-				     int want,
-				     void (*emit_state)(struct sna *sna, const struct sna_composite_op *op))
-{
-	int rem;
-
-start:
-	rem = vertex_space(sna);
-	if (rem < op->floats_per_rect) {
-		DBG(("flushing vbo for %s: %d < %d\n",
-		     __FUNCTION__, rem, op->floats_per_rect));
-		rem = g4x_get_rectangles__flush(sna, op);
-		if (unlikely(rem == 0))
-			goto flush;
-	}
-
-	if (unlikely(sna->render_state.gen4.vertex_offset == 0 &&
-		     !g4x_rectangle_begin(sna, op)))
-		goto flush;
-
-	if (want > 1 && want * op->floats_per_rect > rem)
-		want = rem / op->floats_per_rect;
-
-	sna->render.vertex_index += 3*want;
-	return want;
-
-flush:
-	if (sna->render_state.gen4.vertex_offset) {
-		g4x_vertex_flush(sna);
-		g4x_magic_ca_pass(sna, op);
-	}
-	_kgem_submit(&sna->kgem);
-	emit_state(sna, op);
-	goto start;
-}
-
-static uint32_t *
-g4x_composite_get_binding_table(struct sna *sna,
-				uint16_t *offset)
-{
-	sna->kgem.surface -=
-		sizeof(struct gen4_surface_state_padded) / sizeof(uint32_t);
-
-	DBG(("%s(%x)\n", __FUNCTION__, 4*sna->kgem.surface));
-
-	/* Clear all surplus entries to zero in case of prefetch */
-	*offset = sna->kgem.surface;
-	return memset(sna->kgem.batch + sna->kgem.surface,
-		      0, sizeof(struct gen4_surface_state_padded));
-}
-
-static void
-g4x_emit_urb(struct sna *sna)
-{
-	int urb_vs_start, urb_vs_size;
-	int urb_gs_start, urb_gs_size;
-	int urb_clip_start, urb_clip_size;
-	int urb_sf_start, urb_sf_size;
-	int urb_cs_start, urb_cs_size;
-
-	if (!sna->render_state.gen4.needs_urb)
-		return;
-
-	urb_vs_start = 0;
-	urb_vs_size = URB_VS_ENTRIES * URB_VS_ENTRY_SIZE;
-	urb_gs_start = urb_vs_start + urb_vs_size;
-	urb_gs_size = URB_GS_ENTRIES * URB_GS_ENTRY_SIZE;
-	urb_clip_start = urb_gs_start + urb_gs_size;
-	urb_clip_size = URB_CLIP_ENTRIES * URB_CLIP_ENTRY_SIZE;
-	urb_sf_start = urb_clip_start + urb_clip_size;
-	urb_sf_size = URB_SF_ENTRIES * URB_SF_ENTRY_SIZE;
-	urb_cs_start = urb_sf_start + urb_sf_size;
-	urb_cs_size = URB_CS_ENTRIES * URB_CS_ENTRY_SIZE;
-
-	OUT_BATCH(GEN4_URB_FENCE |
-		  UF0_CS_REALLOC |
-		  UF0_SF_REALLOC |
-		  UF0_CLIP_REALLOC |
-		  UF0_GS_REALLOC |
-		  UF0_VS_REALLOC |
-		  1);
-	OUT_BATCH(((urb_clip_start + urb_clip_size) << UF1_CLIP_FENCE_SHIFT) |
-		  ((urb_gs_start + urb_gs_size) << UF1_GS_FENCE_SHIFT) |
-		  ((urb_vs_start + urb_vs_size) << UF1_VS_FENCE_SHIFT));
-	OUT_BATCH(((urb_cs_start + urb_cs_size) << UF2_CS_FENCE_SHIFT) |
-		  ((urb_sf_start + urb_sf_size) << UF2_SF_FENCE_SHIFT));
-
-	/* Constant buffer state */
-	OUT_BATCH(GEN4_CS_URB_STATE | 0);
-	OUT_BATCH((URB_CS_ENTRY_SIZE - 1) << 4 | URB_CS_ENTRIES << 0);
-
-	sna->render_state.gen4.needs_urb = false;
-}
-
-static void
-g4x_emit_state_base_address(struct sna *sna)
-{
-	assert(sna->render_state.gen4.general_bo->proxy == NULL);
-	OUT_BATCH(GEN4_STATE_BASE_ADDRESS | 4);
-	OUT_BATCH(kgem_add_reloc(&sna->kgem, /* general */
-				 sna->kgem.nbatch,
-				 sna->render_state.gen4.general_bo,
-				 I915_GEM_DOMAIN_INSTRUCTION << 16,
-				 BASE_ADDRESS_MODIFY));
-	OUT_BATCH(kgem_add_reloc(&sna->kgem, /* surface */
-				 sna->kgem.nbatch,
-				 NULL,
-				 I915_GEM_DOMAIN_INSTRUCTION << 16,
-				 BASE_ADDRESS_MODIFY));
-	OUT_BATCH(0); /* media */
-
-	/* upper bounds, all disabled */
-	OUT_BATCH(BASE_ADDRESS_MODIFY);
-	OUT_BATCH(0);
-}
-
-static void
-g4x_emit_invariant(struct sna *sna)
-{
-	assert(sna->kgem.surface == sna->kgem.batch_size);
-
-	if (sna->kgem.gen >= 045)
-		OUT_BATCH(NEW_PIPELINE_SELECT | PIPELINE_SELECT_3D);
-	else
-		OUT_BATCH(GEN4_PIPELINE_SELECT | PIPELINE_SELECT_3D);
-
-	g4x_emit_state_base_address(sna);
-
-	sna->render_state.gen4.needs_invariant = false;
-}
-
-static void
-g4x_get_batch(struct sna *sna)
-{
-	kgem_set_mode(&sna->kgem, KGEM_RENDER);
-
-	if (!kgem_check_batch_with_surfaces(&sna->kgem, 150, 4)) {
-		DBG(("%s: flushing batch: %d < %d+%d\n",
-		     __FUNCTION__, sna->kgem.surface - sna->kgem.nbatch,
-		     150, 4*8));
-		kgem_submit(&sna->kgem);
-		_kgem_set_mode(&sna->kgem, KGEM_RENDER);
-	}
-
-	if (sna->render_state.gen4.needs_invariant)
-		g4x_emit_invariant(sna);
-}
-
-static void
-g4x_align_vertex(struct sna *sna, const struct sna_composite_op *op)
-{
-	assert(op->floats_per_rect == 3*op->floats_per_vertex);
-	if (op->floats_per_vertex != sna->render_state.gen4.floats_per_vertex) {
-		if (sna->render.vertex_size - sna->render.vertex_used < 2*op->floats_per_rect)
-			g4x_vertex_finish(sna);
-
-		DBG(("aligning vertex: was %d, now %d floats per vertex, %d->%d\n",
-		     sna->render_state.gen4.floats_per_vertex,
-		     op->floats_per_vertex,
-		     sna->render.vertex_index,
-		     (sna->render.vertex_used + op->floats_per_vertex - 1) / op->floats_per_vertex));
-		sna->render.vertex_index = (sna->render.vertex_used + op->floats_per_vertex - 1) / op->floats_per_vertex;
-		sna->render.vertex_used = sna->render.vertex_index * op->floats_per_vertex;
-		sna->render_state.gen4.floats_per_vertex = op->floats_per_vertex;
-	}
-}
-
-static void
-g4x_emit_binding_table(struct sna *sna, uint16_t offset)
-{
-	if (sna->render_state.gen4.surface_table == offset)
-		return;
-
-	sna->render_state.gen4.surface_table = offset;
-
-	/* Binding table pointers */
-	OUT_BATCH(GEN4_3DSTATE_BINDING_TABLE_POINTERS | 4);
-	OUT_BATCH(0);		/* vs */
-	OUT_BATCH(0);		/* gs */
-	OUT_BATCH(0);		/* clip */
-	OUT_BATCH(0);		/* sf */
-	/* Only the PS uses the binding table */
-	OUT_BATCH(offset*4);
-}
-
-static void
-g4x_emit_pipelined_pointers(struct sna *sna,
-			    const struct sna_composite_op *op,
-			    int blend, int kernel)
-{
-	uint16_t sp, bp;
-	uint32_t key;
-
-	DBG(("%s: has_mask=%d, src=(%d, %d), mask=(%d, %d),kernel=%d, blend=%d, ca=%d, format=%x\n",
-	     __FUNCTION__, op->u.gen4.ve_id & 2,
-	     op->src.filter, op->src.repeat,
-	     op->mask.filter, op->mask.repeat,
-	     kernel, blend, op->has_component_alpha, (int)op->dst.format));
-
-	sp = SAMPLER_OFFSET(op->src.filter, op->src.repeat,
-			    op->mask.filter, op->mask.repeat,
-			    kernel);
-	bp = g4x_get_blend(blend, op->has_component_alpha, op->dst.format);
-
-	DBG(("%s: sp=%d, bp=%d\n", __FUNCTION__, sp, bp));
-	key = sp | (uint32_t)bp << 16;
-	if (key == sna->render_state.gen4.last_pipelined_pointers)
-		return;
-
-	OUT_BATCH(GEN4_3DSTATE_PIPELINED_POINTERS | 5);
-	OUT_BATCH(sna->render_state.gen4.vs);
-	OUT_BATCH(GEN4_GS_DISABLE); /* passthrough */
-	OUT_BATCH(GEN4_CLIP_DISABLE); /* passthrough */
-	OUT_BATCH(sna->render_state.gen4.sf[1]);
-	OUT_BATCH(sna->render_state.gen4.wm + sp);
-	OUT_BATCH(sna->render_state.gen4.cc + bp);
-
-	sna->render_state.gen4.last_pipelined_pointers = key;
-	g4x_emit_urb(sna);
-}
-
-static bool
-g4x_emit_drawing_rectangle(struct sna *sna, const struct sna_composite_op *op)
-{
-	uint32_t limit = (op->dst.height - 1) << 16 | (op->dst.width - 1);
-	uint32_t offset = (uint16_t)op->dst.y << 16 | (uint16_t)op->dst.x;
-
-	assert(!too_large(op->dst.x, op->dst.y));
-	assert(!too_large(op->dst.width, op->dst.height));
-
-	if (sna->render_state.gen4.drawrect_limit == limit &&
-	    sna->render_state.gen4.drawrect_offset == offset)
-		return true;
-
-	sna->render_state.gen4.drawrect_offset = offset;
-	sna->render_state.gen4.drawrect_limit = limit;
-
-	OUT_BATCH(GEN4_3DSTATE_DRAWING_RECTANGLE | (4 - 2));
-	OUT_BATCH(0);
-	OUT_BATCH(limit);
-	OUT_BATCH(offset);
-	return false;
-}
-
-static void
-g4x_emit_vertex_elements(struct sna *sna,
-			 const struct sna_composite_op *op)
-{
-	/*
-	 * vertex data in vertex buffer
-	 *    position: (x, y)
-	 *    texture coordinate 0: (u0, v0) if (is_affine is true) else (u0, v0, w0)
-	 *    texture coordinate 1 if (has_mask is true): same as above
-	 */
-	struct gen4_render_state *render = &sna->render_state.gen4;
-	int id = op->u.gen4.ve_id;
-	uint32_t w_component;
-	uint32_t src_format;
-	int selem;
-
-	if (render->ve_id == id)
-		return;
-
-	render->ve_id = id;
-
-	if (id & 1) {
-		src_format = GEN4_SURFACEFORMAT_R32G32_FLOAT;
-		w_component = GEN4_VFCOMPONENT_STORE_1_FLT;
-		selem = 2;
-	} else {
-		src_format = GEN4_SURFACEFORMAT_R32G32B32_FLOAT;
-		w_component = GEN4_VFCOMPONENT_STORE_SRC;
-		selem = 3;
-	}
-
-	/* The VUE layout
-	 *    dword 0-3: position (x, y, 1.0, 1.0),
-	 *    dword 4-7: texture coordinate 0 (u0, v0, w0, 1.0)
-	 *    [optional] dword 8-11: texture coordinate 1 (u1, v1, w1, 1.0)
-	 */
-	OUT_BATCH(GEN4_3DSTATE_VERTEX_ELEMENTS | (2 * (1 + 2) - 1));
-
-	/* x,y */
-	OUT_BATCH(id << VE0_VERTEX_BUFFER_INDEX_SHIFT | VE0_VALID |
-		  GEN4_SURFACEFORMAT_R16G16_SSCALED << VE0_FORMAT_SHIFT |
-		  0 << VE0_OFFSET_SHIFT); /* offsets vb in bytes */
-	OUT_BATCH(GEN4_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_0_SHIFT |
-		  GEN4_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_1_SHIFT |
-		  GEN4_VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_2_SHIFT |
-		  GEN4_VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_3_SHIFT |
-		  (1*4) << VE1_DESTINATION_ELEMENT_OFFSET_SHIFT);       /* VUE offset in dwords */
-
-	/* u0, v0, w0 */
-	OUT_BATCH(id << VE0_VERTEX_BUFFER_INDEX_SHIFT | VE0_VALID |
-		  src_format << VE0_FORMAT_SHIFT |
-		  4 << VE0_OFFSET_SHIFT);	/* offset vb in bytes */
-	OUT_BATCH(GEN4_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_0_SHIFT |
-		  GEN4_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_1_SHIFT |
-		  w_component << VE1_VFCOMPONENT_2_SHIFT |
-		  GEN4_VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_3_SHIFT |
-		  (2*4) << VE1_DESTINATION_ELEMENT_OFFSET_SHIFT);       /* VUE offset in dwords */
-
-	/* u1, v1, w1 */
-	OUT_BATCH(id << VE0_VERTEX_BUFFER_INDEX_SHIFT | VE0_VALID |
-		  src_format << VE0_FORMAT_SHIFT |
-		  ((1 + selem) * 4) << VE0_OFFSET_SHIFT); /* vb offset in bytes */
-	if (id & 2) {
-		OUT_BATCH(GEN4_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_0_SHIFT |
-			  GEN4_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_1_SHIFT |
-			  w_component << VE1_VFCOMPONENT_2_SHIFT |
-			  GEN4_VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_3_SHIFT |
-			  (3*4) << VE1_DESTINATION_ELEMENT_OFFSET_SHIFT);       /* VUE offset in dwords */
-	} else {
-		OUT_BATCH(GEN4_VFCOMPONENT_STORE_0 << VE1_VFCOMPONENT_0_SHIFT |
-			  GEN4_VFCOMPONENT_STORE_0 << VE1_VFCOMPONENT_1_SHIFT |
-			  GEN4_VFCOMPONENT_STORE_0 << VE1_VFCOMPONENT_2_SHIFT |
-			  GEN4_VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_3_SHIFT |
-			  (3*4) << VE1_DESTINATION_ELEMENT_OFFSET_SHIFT);       /* VUE offset in dwords */
-	}
-}
-
-static void
-g4x_emit_state(struct sna *sna,
-	       const struct sna_composite_op *op,
-	       uint16_t wm_binding_table)
-{
-	bool flush;
-
-	flush = wm_binding_table & 1;
-	if (kgem_bo_is_dirty(op->src.bo) || kgem_bo_is_dirty(op->mask.bo)) {
-		DBG(("%s: flushing dirty (%d, %d), forced? %d\n", __FUNCTION__,
-		     kgem_bo_is_dirty(op->src.bo),
-		     kgem_bo_is_dirty(op->mask.bo),
-		     flush));
-		OUT_BATCH(MI_FLUSH);
-		kgem_clear_dirty(&sna->kgem);
-		kgem_bo_mark_dirty(op->dst.bo);
-		flush = false;
-	}
-	flush &= g4x_emit_drawing_rectangle(sna, op);
-	if (flush && op->op > PictOpSrc)
-		OUT_BATCH(MI_FLUSH | MI_INHIBIT_RENDER_CACHE_FLUSH);
-
-	g4x_emit_binding_table(sna, wm_binding_table & ~1);
-	g4x_emit_pipelined_pointers(sna, op, op->op, op->u.gen4.wm_kernel);
-	g4x_emit_vertex_elements(sna, op);
-}
-
-static void
-g4x_bind_surfaces(struct sna *sna,
-		  const struct sna_composite_op *op)
-{
-	bool dirty = kgem_bo_is_dirty(op->dst.bo);
-	uint32_t *binding_table;
-	uint16_t offset;
-
-	g4x_get_batch(sna);
-
-	binding_table = g4x_composite_get_binding_table(sna, &offset);
-
-	binding_table[0] =
-		g4x_bind_bo(sna,
-			    op->dst.bo, op->dst.width, op->dst.height,
-			    g4x_get_dest_format(op->dst.format),
-			    true);
-	binding_table[1] =
-		g4x_bind_bo(sna,
-			     op->src.bo, op->src.width, op->src.height,
-			     op->src.card_format,
-			     false);
-	if (op->mask.bo) {
-		assert(op->u.gen4.ve_id & 2);
-		binding_table[2] =
-			g4x_bind_bo(sna,
-				     op->mask.bo,
-				     op->mask.width,
-				     op->mask.height,
-				     op->mask.card_format,
-				     false);
-	}
-
-	if (sna->kgem.surface == offset &&
-	    *(uint64_t *)(sna->kgem.batch + sna->render_state.gen4.surface_table) == *(uint64_t*)binding_table &&
-	    (op->mask.bo == NULL ||
-	     sna->kgem.batch[sna->render_state.gen4.surface_table+2] == binding_table[2])) {
-		sna->kgem.surface += sizeof(struct gen4_surface_state_padded) / sizeof(uint32_t);
-		offset = sna->render_state.gen4.surface_table;
-	}
-
-	g4x_emit_state(sna, op, offset | dirty);
-}
-
-fastcall static void
-g4x_render_composite_blt(struct sna *sna,
-			 const struct sna_composite_op *op,
-			 const struct sna_composite_rectangles *r)
-{
-	DBG(("%s: src=(%d, %d)+(%d, %d), mask=(%d, %d)+(%d, %d), dst=(%d, %d)+(%d, %d), size=(%d, %d)\n",
-	     __FUNCTION__,
-	     r->src.x, r->src.y, op->src.offset[0], op->src.offset[1],
-	     r->mask.x, r->mask.y, op->mask.offset[0], op->mask.offset[1],
-	     r->dst.x, r->dst.y, op->dst.x, op->dst.y,
-	     r->width, r->height));
-
-	g4x_get_rectangles(sna, op, 1, g4x_bind_surfaces);
-	op->prim_emit(sna, op, r);
-}
-
-fastcall static void
-g4x_render_composite_box(struct sna *sna,
-			 const struct sna_composite_op *op,
-			 const BoxRec *box)
-{
-	struct sna_composite_rectangles r;
-
-	DBG(("  %s: (%d, %d), (%d, %d)\n",
-	     __FUNCTION__,
-	     box->x1, box->y1, box->x2, box->y2));
-
-	g4x_get_rectangles(sna, op, 1, g4x_bind_surfaces);
-
-	r.dst.x = box->x1;
-	r.dst.y = box->y1;
-	r.width  = box->x2 - box->x1;
-	r.height = box->y2 - box->y1;
-	r.mask = r.src = r.dst;
-
-	op->prim_emit(sna, op, &r);
-}
-
-static void
-g4x_render_composite_boxes(struct sna *sna,
-			   const struct sna_composite_op *op,
-			   const BoxRec *box, int nbox)
-{
-	DBG(("%s(%d) delta=(%d, %d), src=(%d, %d)/(%d, %d), mask=(%d, %d)/(%d, %d)\n",
-	     __FUNCTION__, nbox, op->dst.x, op->dst.y,
-	     op->src.offset[0], op->src.offset[1],
-	     op->src.width, op->src.height,
-	     op->mask.offset[0], op->mask.offset[1],
-	     op->mask.width, op->mask.height));
-
-	do {
-		int nbox_this_time;
-
-		nbox_this_time = g4x_get_rectangles(sna, op, nbox,
-						     g4x_bind_surfaces);
-		nbox -= nbox_this_time;
-
-		do {
-			struct sna_composite_rectangles r;
-
-			DBG(("  %s: (%d, %d), (%d, %d)\n",
-			     __FUNCTION__,
-			     box->x1, box->y1, box->x2, box->y2));
-
-			r.dst.x = box->x1;
-			r.dst.y = box->y1;
-			r.width  = box->x2 - box->x1;
-			r.height = box->y2 - box->y1;
-			r.mask = r.src = r.dst;
-			op->prim_emit(sna, op, &r);
-			box++;
-		} while (--nbox_this_time);
-	} while (nbox);
-}
-
-#ifndef MAX
-#define MAX(a,b) ((a) > (b) ? (a) : (b))
-#endif
-
-static uint32_t g4x_bind_video_source(struct sna *sna,
-				      struct kgem_bo *src_bo,
-				      uint32_t src_offset,
-				      int src_width,
-				      int src_height,
-				      int src_pitch,
-				      uint32_t src_surf_format)
-{
-	struct gen4_surface_state *ss;
-
-	sna->kgem.surface -= sizeof(struct gen4_surface_state_padded) / sizeof(uint32_t);
-
-	ss = memset(sna->kgem.batch + sna->kgem.surface, 0, sizeof(*ss));
-	ss->ss0.surface_type = GEN4_SURFACE_2D;
-	ss->ss0.surface_format = src_surf_format;
-	ss->ss0.color_blend = 1;
-
-	ss->ss1.base_addr =
-		kgem_add_reloc(&sna->kgem,
-			       sna->kgem.surface + 1,
-			       src_bo,
-			       I915_GEM_DOMAIN_SAMPLER << 16,
-			       src_offset);
-
-	ss->ss2.width  = src_width - 1;
-	ss->ss2.height = src_height - 1;
-	ss->ss3.pitch  = src_pitch - 1;
-
-	return sna->kgem.surface * sizeof(uint32_t);
-}
-
-static void g4x_video_bind_surfaces(struct sna *sna,
-				    const struct sna_composite_op *op)
-{
-	bool dirty = kgem_bo_is_dirty(op->dst.bo);
-	struct sna_video_frame *frame = op->priv;
-	uint32_t src_surf_format;
-	uint32_t src_surf_base[6];
-	int src_width[6];
-	int src_height[6];
-	int src_pitch[6];
-	uint32_t *binding_table;
-	uint16_t offset;
-	int n_src, n;
-
-	src_surf_base[0] = 0;
-	src_surf_base[1] = 0;
-	src_surf_base[2] = frame->VBufOffset;
-	src_surf_base[3] = frame->VBufOffset;
-	src_surf_base[4] = frame->UBufOffset;
-	src_surf_base[5] = frame->UBufOffset;
-
-	if (is_planar_fourcc(frame->id)) {
-		src_surf_format = GEN4_SURFACEFORMAT_R8_UNORM;
-		src_width[1]  = src_width[0]  = frame->width;
-		src_height[1] = src_height[0] = frame->height;
-		src_pitch[1]  = src_pitch[0]  = frame->pitch[1];
-		src_width[4]  = src_width[5]  = src_width[2]  = src_width[3] =
-			frame->width / 2;
-		src_height[4] = src_height[5] = src_height[2] = src_height[3] =
-			frame->height / 2;
-		src_pitch[4]  = src_pitch[5]  = src_pitch[2]  = src_pitch[3] =
-			frame->pitch[0];
-		n_src = 6;
-	} else {
-		if (frame->id == FOURCC_UYVY)
-			src_surf_format = GEN4_SURFACEFORMAT_YCRCB_SWAPY;
-		else
-			src_surf_format = GEN4_SURFACEFORMAT_YCRCB_NORMAL;
-
-		src_width[0]  = frame->width;
-		src_height[0] = frame->height;
-		src_pitch[0]  = frame->pitch[0];
-		n_src = 1;
-	}
-
-	g4x_get_batch(sna);
-
-	binding_table = g4x_composite_get_binding_table(sna, &offset);
-
-	binding_table[0] =
-		g4x_bind_bo(sna,
-			     op->dst.bo, op->dst.width, op->dst.height,
-			     g4x_get_dest_format(op->dst.format),
-			     true);
-	for (n = 0; n < n_src; n++) {
-		binding_table[1+n] =
-			g4x_bind_video_source(sna,
-					       frame->bo,
-					       src_surf_base[n],
-					       src_width[n],
-					       src_height[n],
-					       src_pitch[n],
-					       src_surf_format);
-	}
-
-	g4x_emit_state(sna, op, offset | dirty);
-}
-
-static bool
-g4x_render_video(struct sna *sna,
-		 struct sna_video *video,
-		 struct sna_video_frame *frame,
-		 RegionPtr dstRegion,
-		 short src_w, short src_h,
-		 short drw_w, short drw_h,
-		 PixmapPtr pixmap)
-{
-	struct sna_composite_op tmp;
-	int nbox, dxo, dyo, pix_xoff, pix_yoff;
-	float src_scale_x, src_scale_y;
-	struct sna_pixmap *priv;
-	BoxPtr box;
-
-	DBG(("%s: %dx%d -> %dx%d\n", __FUNCTION__, src_w, src_h, drw_w, drw_h));
-
-	priv = sna_pixmap_force_to_gpu(pixmap, MOVE_READ | MOVE_WRITE);
-	if (priv == NULL)
-		return false;
-
-	memset(&tmp, 0, sizeof(tmp));
-
-	tmp.op = PictOpSrc;
-	tmp.dst.pixmap = pixmap;
-	tmp.dst.width  = pixmap->drawable.width;
-	tmp.dst.height = pixmap->drawable.height;
-	tmp.dst.format = sna_format_for_depth(pixmap->drawable.depth);
-	tmp.dst.bo = priv->gpu_bo;
-
-	tmp.src.filter = SAMPLER_FILTER_BILINEAR;
-	tmp.src.repeat = SAMPLER_EXTEND_PAD;
-	tmp.src.bo = frame->bo;
-	tmp.mask.bo = NULL;
-	tmp.u.gen4.wm_kernel =
-		is_planar_fourcc(frame->id) ? WM_KERNEL_VIDEO_PLANAR : WM_KERNEL_VIDEO_PACKED;
-	tmp.u.gen4.ve_id = 1;
-	tmp.is_affine = true;
-	tmp.floats_per_vertex = 3;
-	tmp.floats_per_rect = 9;
-	tmp.priv = frame;
-
-	if (!kgem_check_bo(&sna->kgem, tmp.dst.bo, frame->bo, NULL)) {
-		kgem_submit(&sna->kgem);
-		assert(kgem_check_bo(&sna->kgem, tmp.dst.bo, frame->bo, NULL));
-	}
-
-	g4x_video_bind_surfaces(sna, &tmp);
-	g4x_align_vertex(sna, &tmp);
-
-	/* Set up the offset for translating from the given region (in screen
-	 * coordinates) to the backing pixmap.
-	 */
-#ifdef COMPOSITE
-	pix_xoff = -pixmap->screen_x + pixmap->drawable.x;
-	pix_yoff = -pixmap->screen_y + pixmap->drawable.y;
-#else
-	pix_xoff = 0;
-	pix_yoff = 0;
-#endif
-
-	dxo = dstRegion->extents.x1;
-	dyo = dstRegion->extents.y1;
-
-	/* Use normalized texture coordinates */
-	src_scale_x = ((float)src_w / frame->width) / (float)drw_w;
-	src_scale_y = ((float)src_h / frame->height) / (float)drw_h;
-
-	box = REGION_RECTS(dstRegion);
-	nbox = REGION_NUM_RECTS(dstRegion);
-	while (nbox--) {
-		BoxRec r;
-
-		r.x1 = box->x1 + pix_xoff;
-		r.x2 = box->x2 + pix_xoff;
-		r.y1 = box->y1 + pix_yoff;
-		r.y2 = box->y2 + pix_yoff;
-
-		g4x_get_rectangles(sna, &tmp, 1, g4x_video_bind_surfaces);
-
-		OUT_VERTEX(r.x2, r.y2);
-		OUT_VERTEX_F((box->x2 - dxo) * src_scale_x);
-		OUT_VERTEX_F((box->y2 - dyo) * src_scale_y);
-
-		OUT_VERTEX(r.x1, r.y2);
-		OUT_VERTEX_F((box->x1 - dxo) * src_scale_x);
-		OUT_VERTEX_F((box->y2 - dyo) * src_scale_y);
-
-		OUT_VERTEX(r.x1, r.y1);
-		OUT_VERTEX_F((box->x1 - dxo) * src_scale_x);
-		OUT_VERTEX_F((box->y1 - dyo) * src_scale_y);
-
-		if (!DAMAGE_IS_ALL(priv->gpu_damage)) {
-			sna_damage_add_box(&priv->gpu_damage, &r);
-			sna_damage_subtract_box(&priv->cpu_damage, &r);
-		}
-		box++;
-	}
-	priv->clear = false;
-
-	g4x_vertex_flush(sna);
-	return true;
-}
-
-static bool
-g4x_composite_solid_init(struct sna *sna,
-			 struct sna_composite_channel *channel,
-			 uint32_t color)
-{
-	channel->filter = PictFilterNearest;
-	channel->repeat = RepeatNormal;
-	channel->is_affine = true;
-	channel->is_solid  = true;
-	channel->transform = NULL;
-	channel->width  = 1;
-	channel->height = 1;
-	channel->card_format = GEN4_SURFACEFORMAT_B8G8R8A8_UNORM;
-
-	channel->bo = sna_render_get_solid(sna, color);
-
-	channel->scale[0]  = channel->scale[1]  = 1;
-	channel->offset[0] = channel->offset[1] = 0;
-	return channel->bo != NULL;
-}
-
-static bool
-g4x_composite_linear_init(struct sna *sna,
-			  PicturePtr picture,
-			  struct sna_composite_channel *channel,
-			  int x, int y,
-			  int w, int h,
-			  int dst_x, int dst_y)
-{
-	PictLinearGradient *linear =
-		(PictLinearGradient *)picture->pSourcePict;
-	pixman_fixed_t tx, ty;
-	float x0, y0, sf;
-	float dx, dy;
-
-	DBG(("%s: p1=(%f, %f), p2=(%f, %f), src=(%d, %d), dst=(%d, %d), size=(%d, %d)\n",
-	     __FUNCTION__,
-	     pixman_fixed_to_double(linear->p1.x), pixman_fixed_to_double(linear->p1.y),
-	     pixman_fixed_to_double(linear->p2.x), pixman_fixed_to_double(linear->p2.y),
-	     x, y, dst_x, dst_y, w, h));
-
-	if (linear->p2.x == linear->p1.x && linear->p2.y == linear->p1.y)
-		return 0;
-
-	if (!sna_transform_is_affine(picture->transform)) {
-		DBG(("%s: fallback due to projective transform\n",
-		     __FUNCTION__));
-		return sna_render_picture_fixup(sna, picture, channel,
-						x, y, w, h, dst_x, dst_y);
-	}
-
-	channel->bo = sna_render_get_gradient(sna, (PictGradient *)linear);
-	if (!channel->bo)
-		return 0;
-
-	channel->filter = PictFilterNearest;
-	channel->repeat = picture->repeat ? picture->repeatType : RepeatNone;
-	channel->width  = channel->bo->pitch / 4;
-	channel->height = 1;
-	channel->pict_format = PICT_a8r8g8b8;
-
-	channel->scale[0]  = channel->scale[1]  = 1;
-	channel->offset[0] = channel->offset[1] = 0;
-
-	if (sna_transform_is_translation(picture->transform, &tx, &ty)) {
-		dx = pixman_fixed_to_double(linear->p2.x - linear->p1.x);
-		dy = pixman_fixed_to_double(linear->p2.y - linear->p1.y);
-
-		x0 = pixman_fixed_to_double(linear->p1.x);
-		y0 = pixman_fixed_to_double(linear->p1.y);
-
-		if (tx | ty) {
-			x0 -= pixman_fixed_to_double(tx);
-			y0 -= pixman_fixed_to_double(ty);
-		}
-	} else {
-		struct pixman_f_vector p1, p2;
-		struct pixman_f_transform m, inv;
-
-		pixman_f_transform_from_pixman_transform(&m, picture->transform);
-		DBG(("%s: transform = [%f %f %f, %f %f %f, %f %f %f]\n",
-		     __FUNCTION__,
-		     m.m[0][0], m.m[0][1], m.m[0][2],
-		     m.m[1][0], m.m[1][1], m.m[1][2],
-		     m.m[2][0], m.m[2][1], m.m[2][2]));
-		if (!pixman_f_transform_invert(&inv, &m))
-			return 0;
-
-		p1.v[0] = pixman_fixed_to_double(linear->p1.x);
-		p1.v[1] = pixman_fixed_to_double(linear->p1.y);
-		p1.v[2] = 1.;
-		pixman_f_transform_point(&inv, &p1);
-
-		p2.v[0] = pixman_fixed_to_double(linear->p2.x);
-		p2.v[1] = pixman_fixed_to_double(linear->p2.y);
-		p2.v[2] = 1.;
-		pixman_f_transform_point(&inv, &p2);
-
-		DBG(("%s: untransformed: p1=(%f, %f, %f), p2=(%f, %f, %f)\n",
-		     __FUNCTION__,
-		     p1.v[0], p1.v[1], p1.v[2],
-		     p2.v[0], p2.v[1], p2.v[2]));
-
-		dx = p2.v[0] - p1.v[0];
-		dy = p2.v[1] - p1.v[1];
-
-		x0 = p1.v[0];
-		y0 = p1.v[1];
-	}
-
-	sf = dx*dx + dy*dy;
-	dx /= sf;
-	dy /= sf;
-
-	channel->embedded_transform.matrix[0][0] = pixman_double_to_fixed(dx);
-	channel->embedded_transform.matrix[0][1] = pixman_double_to_fixed(dy);
-	channel->embedded_transform.matrix[0][2] = -pixman_double_to_fixed(dx*(x0+dst_x-x) + dy*(y0+dst_y-y));
-
-	channel->embedded_transform.matrix[1][0] = 0;
-	channel->embedded_transform.matrix[1][1] = 0;
-	channel->embedded_transform.matrix[1][2] = pixman_double_to_fixed(.5);
-
-	channel->embedded_transform.matrix[2][0] = 0;
-	channel->embedded_transform.matrix[2][1] = 0;
-	channel->embedded_transform.matrix[2][2] = pixman_fixed_1;
-
-	channel->transform = &channel->embedded_transform;
-	channel->is_affine = 1;
-
-	DBG(("%s: dx=%f, dy=%f, offset=%f\n",
-	     __FUNCTION__, dx, dy, -dx*(x0-x+dst_x) + -dy*(y0-y+dst_y)));
-
-	return channel->bo != NULL;
-}
-
-static int
-g4x_composite_picture(struct sna *sna,
-		      PicturePtr picture,
-		      struct sna_composite_channel *channel,
-		      int x, int y,
-		      int w, int h,
-		      int dst_x, int dst_y,
-		      bool precise)
-{
-	PixmapPtr pixmap;
-	uint32_t color;
-	int16_t dx, dy;
-
-	DBG(("%s: (%d, %d)x(%d, %d), dst=(%d, %d)\n",
-	     __FUNCTION__, x, y, w, h, dst_x, dst_y));
-
-	channel->is_solid = false;
-	channel->card_format = -1;
-
-	if (sna_picture_is_solid(picture, &color))
-		return g4x_composite_solid_init(sna, channel, color);
-
-	if (picture->pDrawable == NULL) {
-		int ret;
-
-		if (picture->pSourcePict->type == SourcePictTypeLinear)
-			return g4x_composite_linear_init(sna, picture, channel,
-							  x, y,
-							  w, h,
-							  dst_x, dst_y);
-
-		DBG(("%s -- fixup, gradient\n", __FUNCTION__));
-		ret = -1;
-		if (!precise)
-			ret = sna_render_picture_approximate_gradient(sna, picture, channel,
-								      x, y, w, h, dst_x, dst_y);
-		if (ret == -1)
-			ret = sna_render_picture_fixup(sna, picture, channel,
-						       x, y, w, h, dst_x, dst_y);
-		return ret;
-	}
-
-	if (picture->alphaMap) {
-		DBG(("%s -- fallback, alphamap\n", __FUNCTION__));
-		return sna_render_picture_fixup(sna, picture, channel,
-						x, y, w, h, dst_x, dst_y);
-	}
-
-	if (!g4x_check_repeat(picture)) {
-		DBG(("%s: unknown repeat mode fixup\n", __FUNCTION__));
-		return sna_render_picture_fixup(sna, picture, channel,
-						x, y, w, h, dst_x, dst_y);
-	}
-
-	if (!g4x_check_filter(picture)) {
-		DBG(("%s: unhandled filter fixup\n", __FUNCTION__));
-		return sna_render_picture_fixup(sna, picture, channel,
-						x, y, w, h, dst_x, dst_y);
-	}
-
-	channel->repeat = picture->repeat ? picture->repeatType : RepeatNone;
-	channel->filter = picture->filter;
-
-	pixmap = get_drawable_pixmap(picture->pDrawable);
-	get_drawable_deltas(picture->pDrawable, pixmap, &dx, &dy);
-
-	x += dx + picture->pDrawable->x;
-	y += dy + picture->pDrawable->y;
-
-	channel->is_affine = sna_transform_is_affine(picture->transform);
-	if (sna_transform_is_integer_translation(picture->transform, &dx, &dy)) {
-		DBG(("%s: integer translation (%d, %d), removing\n",
-		     __FUNCTION__, dx, dy));
-		x += dx;
-		y += dy;
-		channel->transform = NULL;
-		channel->filter = PictFilterNearest;
-	} else
-		channel->transform = picture->transform;
-
-	channel->pict_format = picture->format;
-	channel->card_format = g4x_get_card_format(picture->format);
-	if (channel->card_format == -1)
-		return sna_render_picture_convert(sna, picture, channel, pixmap,
-						  x, y, w, h, dst_x, dst_y,
-						  false);
-
-	if (too_large(pixmap->drawable.width, pixmap->drawable.height))
-		return sna_render_picture_extract(sna, picture, channel,
-						  x, y, w, h, dst_x, dst_y);
-
-	return sna_render_pixmap_bo(sna, channel, pixmap,
-				    x, y, w, h, dst_x, dst_y);
-}
-
-static void g4x_composite_channel_convert(struct sna_composite_channel *channel)
-{
-	DBG(("%s: repeat %d -> %d, filter %d -> %d\n",
-	     __FUNCTION__,
-	     channel->repeat, g4x_repeat(channel->repeat),
-	     channel->filter, g4x_repeat(channel->filter)));
-	channel->repeat = g4x_repeat(channel->repeat);
-	channel->filter = g4x_filter(channel->filter);
-	if (channel->card_format == (unsigned)-1)
-		channel->card_format = g4x_get_card_format(channel->pict_format);
-}
-
-static void
-g4x_render_composite_done(struct sna *sna,
-			  const struct sna_composite_op *op)
-{
-	DBG(("%s()\n", __FUNCTION__));
-
-	if (sna->render_state.gen4.vertex_offset) {
-		g4x_vertex_flush(sna);
-		g4x_magic_ca_pass(sna, op);
-	}
-
-	if (op->mask.bo)
-		kgem_bo_destroy(&sna->kgem, op->mask.bo);
-	if (op->src.bo)
-		kgem_bo_destroy(&sna->kgem, op->src.bo);
-
-	sna_render_composite_redirect_done(sna, op);
-}
-
-static bool
-g4x_composite_set_target(PicturePtr dst, struct sna_composite_op *op)
-{
-	struct sna_pixmap *priv;
-
-	if (!g4x_check_dst_format(dst->format)) {
-		DBG(("%s: incompatible render target format %08x\n",
-		     __FUNCTION__, dst->format));
-		return false;
-	}
-
-	op->dst.pixmap = get_drawable_pixmap(dst->pDrawable);
-	op->dst.width  = op->dst.pixmap->drawable.width;
-	op->dst.height = op->dst.pixmap->drawable.height;
-	op->dst.format = dst->format;
-	priv = sna_pixmap_force_to_gpu(op->dst.pixmap, MOVE_READ | MOVE_WRITE);
-	if (priv == NULL)
-		return false;
-
-	op->dst.bo = priv->gpu_bo;
-	op->damage = &priv->gpu_damage;
-	if (sna_damage_is_all(&priv->gpu_damage, op->dst.width, op->dst.height))
-		op->damage = NULL;
-	DBG(("%s: all-damaged=%d, damage=%p\n", __FUNCTION__,
-	     sna_damage_is_all(&priv->gpu_damage, op->dst.width, op->dst.height),
-	    op->damage));
-
-	get_drawable_deltas(dst->pDrawable, op->dst.pixmap,
-			    &op->dst.x, &op->dst.y);
-	return true;
-}
-
-static inline bool
-picture_is_cpu(PicturePtr picture)
-{
-	if (!picture->pDrawable)
-		return false;
-
-	return !is_gpu(picture->pDrawable);
-}
-
-static bool
-try_blt(struct sna *sna,
-	PicturePtr dst, PicturePtr src,
-	int width, int height)
-{
-	if (sna->kgem.mode != KGEM_RENDER) {
-		DBG(("%s: already performing BLT\n", __FUNCTION__));
-		return true;
-	}
-
-	if (too_large(width, height)) {
-		DBG(("%s: operation too large for 3D pipe (%d, %d)\n",
-		     __FUNCTION__, width, height));
-		return true;
-	}
-
-	if (too_large(dst->pDrawable->width, dst->pDrawable->height))
-		return true;
-
-	/* The blitter is much faster for solids */
-	if (sna_picture_is_solid(src, NULL))
-		return true;
-
-	/* is the source picture only in cpu memory e.g. a shm pixmap? */
-	return picture_is_cpu(src);
-}
-
-static bool
-check_gradient(PicturePtr picture)
-{
-	switch (picture->pSourcePict->type) {
-	case SourcePictTypeSolidFill:
-	case SourcePictTypeLinear:
-		return false;
-	default:
-		return true;
-	}
-}
-
-static bool
-has_alphamap(PicturePtr p)
-{
-	return p->alphaMap != NULL;
-}
-
-static bool
-untransformed(PicturePtr p)
-{
-	return !p->transform || pixman_transform_is_int_translate(p->transform);
-}
-
-static bool
-need_upload(PicturePtr p)
-{
-	return p->pDrawable && untransformed(p) && !is_gpu(p->pDrawable);
-}
-
-static bool
-source_is_busy(PixmapPtr pixmap)
-{
-	struct sna_pixmap *priv = sna_pixmap(pixmap);
-	if (priv == NULL)
-		return false;
-
-	if (priv->clear)
-		return false;
-
-	if (priv->gpu_bo && kgem_bo_is_busy(priv->gpu_bo))
-		return true;
-
-	return priv->gpu_damage && !priv->cpu_damage;
-}
-
-static bool
-source_fallback(PicturePtr p, PixmapPtr pixmap)
-{
-	if (sna_picture_is_solid(p, NULL))
-		return false;
-
-	if (p->pSourcePict)
-		return check_gradient(p);
-
-	if (!g4x_check_repeat(p) || !g4x_check_format(p->format))
-		return true;
-
-	/* soft errors: perfer to upload/compute rather than readback */
-	if (pixmap && source_is_busy(pixmap))
-		return false;
-
-	return has_alphamap(p) || !g4x_check_filter(p) || need_upload(p);
-}
-
-static bool
-g4x_composite_fallback(struct sna *sna,
-		       PicturePtr src,
-		       PicturePtr mask,
-		       PicturePtr dst)
-{
-	PixmapPtr src_pixmap;
-	PixmapPtr mask_pixmap;
-	PixmapPtr dst_pixmap;
-	bool src_fallback, mask_fallback;
-
-	if (!g4x_check_dst_format(dst->format)) {
-		DBG(("%s: unknown destination format: %d\n",
-		     __FUNCTION__, dst->format));
-		return true;
-	}
-
-	dst_pixmap = get_drawable_pixmap(dst->pDrawable);
-
-	src_pixmap = src->pDrawable ? get_drawable_pixmap(src->pDrawable) : NULL;
-	src_fallback = source_fallback(src, src_pixmap);
-
-	if (mask) {
-		mask_pixmap = mask->pDrawable ? get_drawable_pixmap(mask->pDrawable) : NULL;
-		mask_fallback = source_fallback(mask, mask_pixmap);
-	} else {
-		mask_pixmap = NULL;
-		mask_fallback = false;
-	}
-
-	/* If we are using the destination as a source and need to
-	 * readback in order to upload the source, do it all
-	 * on the cpu.
-	 */
-	if (src_pixmap == dst_pixmap && src_fallback) {
-		DBG(("%s: src is dst and will fallback\n",__FUNCTION__));
-		return true;
-	}
-	if (mask_pixmap == dst_pixmap && mask_fallback) {
-		DBG(("%s: mask is dst and will fallback\n",__FUNCTION__));
-		return true;
-	}
-
-	/* If anything is on the GPU, push everything out to the GPU */
-	if (dst_use_gpu(dst_pixmap)) {
-		DBG(("%s: dst is already on the GPU, try to use GPU\n",
-		     __FUNCTION__));
-		return false;
-	}
-
-	if (src_pixmap && !src_fallback) {
-		DBG(("%s: src is already on the GPU, try to use GPU\n",
-		     __FUNCTION__));
-		return false;
-	}
-	if (mask_pixmap && !mask_fallback) {
-		DBG(("%s: mask is already on the GPU, try to use GPU\n",
-		     __FUNCTION__));
-		return false;
-	}
-
-	/* However if the dst is not on the GPU and we need to
-	 * render one of the sources using the CPU, we may
-	 * as well do the entire operation in place onthe CPU.
-	 */
-	if (src_fallback) {
-		DBG(("%s: dst is on the CPU and src will fallback\n",
-		     __FUNCTION__));
-		return true;
-	}
-
-	if (mask_fallback) {
-		DBG(("%s: dst is on the CPU and mask will fallback\n",
-		     __FUNCTION__));
-		return true;
-	}
-
-	if (too_large(dst_pixmap->drawable.width,
-		      dst_pixmap->drawable.height) &&
-	    dst_is_cpu(dst_pixmap)) {
-		DBG(("%s: dst is on the CPU and too large\n", __FUNCTION__));
-		return true;
-	}
-
-	DBG(("%s: dst is not on the GPU and the operation should not fallback\n",
-	     __FUNCTION__));
-	return false;
-}
-
-static int
-reuse_source(struct sna *sna,
-	     PicturePtr src, struct sna_composite_channel *sc, int src_x, int src_y,
-	     PicturePtr mask, struct sna_composite_channel *mc, int msk_x, int msk_y)
-{
-	uint32_t color;
-
-	if (src_x != msk_x || src_y != msk_y)
-		return false;
-
-	if (src == mask) {
-		DBG(("%s: mask is source\n", __FUNCTION__));
-		*mc = *sc;
-		mc->bo = kgem_bo_reference(mc->bo);
-		return true;
-	}
-
-	if (sna_picture_is_solid(mask, &color))
-		return g4x_composite_solid_init(sna, mc, color);
-
-	if (sc->is_solid)
-		return false;
-
-	if (src->pDrawable == NULL || mask->pDrawable != src->pDrawable)
-		return false;
-
-	DBG(("%s: mask reuses source drawable\n", __FUNCTION__));
-
-	if (!sna_transform_equal(src->transform, mask->transform))
-		return false;
-
-	if (!sna_picture_alphamap_equal(src, mask))
-		return false;
-
-	if (!g4x_check_repeat(mask))
-		return false;
-
-	if (!g4x_check_filter(mask))
-		return false;
-
-	if (!g4x_check_format(mask->format))
-		return false;
-
-	DBG(("%s: reusing source channel for mask with a twist\n",
-	     __FUNCTION__));
-
-	*mc = *sc;
-	mc->repeat = g4x_repeat(mask->repeat ? mask->repeatType : RepeatNone);
-	mc->filter = g4x_filter(mask->filter);
-	mc->pict_format = mask->format;
-	mc->card_format = g4x_get_card_format(mask->format);
-	mc->bo = kgem_bo_reference(mc->bo);
-	return true;
-}
-
-static bool
-g4x_render_composite(struct sna *sna,
-		     uint8_t op,
-		     PicturePtr src,
-		     PicturePtr mask,
-		     PicturePtr dst,
-		     int16_t src_x, int16_t src_y,
-		     int16_t msk_x, int16_t msk_y,
-		     int16_t dst_x, int16_t dst_y,
-		     int16_t width, int16_t height,
-		     struct sna_composite_op *tmp)
-{
-	DBG(("%s: %dx%d, current mode=%d\n", __FUNCTION__,
-	     width, height, sna->kgem.mode));
-
-	if (op >= ARRAY_SIZE(g4x_blend_op))
-		return false;
-
-	if (mask == NULL &&
-	    try_blt(sna, dst, src, width, height) &&
-	    sna_blt_composite(sna, op,
-			      src, dst,
-			      src_x, src_y,
-			      dst_x, dst_y,
-			      width, height,
-			      tmp, false))
-		return true;
-
-	if (g4x_composite_fallback(sna, src, mask, dst))
-		return false;
-
-	if (need_tiling(sna, width, height))
-		return sna_tiling_composite(op, src, mask, dst,
-					    src_x, src_y,
-					    msk_x, msk_y,
-					    dst_x, dst_y,
-					    width, height,
-					    tmp);
-
-	if (!g4x_composite_set_target(dst, tmp))
-		return false;
-	sna_render_reduce_damage(tmp, dst_x, dst_y, width, height);
-
-	sna_render_composite_redirect_init(tmp);
-	if (too_large(tmp->dst.width, tmp->dst.height) &&
-	    !sna_render_composite_redirect(sna, tmp,
-					   dst_x, dst_y, width, height))
-		return false;
-
-	tmp->op = op;
-	switch (g4x_composite_picture(sna, src, &tmp->src,
-				       src_x, src_y,
-				       width, height,
-				       dst_x, dst_y,
-				       dst->polyMode == PolyModePrecise)) {
-	case -1:
-		DBG(("%s: failed to prepare source\n", __FUNCTION__));
-		goto cleanup_dst;
-	case 0:
-		if (!g4x_composite_solid_init(sna, &tmp->src, 0))
-			goto cleanup_dst;
-		/* fall through to fixup */
-	case 1:
-		if (mask == NULL &&
-		    sna_blt_composite__convert(sna,
-					       dst_x, dst_y, width, height,
-					       tmp))
-			return true;
-
-		g4x_composite_channel_convert(&tmp->src);
-		break;
-	}
-
-	tmp->is_affine = tmp->src.is_affine;
-	tmp->has_component_alpha = false;
-	tmp->need_magic_ca_pass = false;
-
-	tmp->prim_emit = g4x_emit_composite_primitive;
-	if (mask) {
-		if (mask->componentAlpha && PICT_FORMAT_RGB(mask->format)) {
-			tmp->has_component_alpha = true;
-
-			/* Check if it's component alpha that relies on a source alpha and on
-			 * the source value.  We can only get one of those into the single
-			 * source value that we get to blend with.
-			 */
-			if (g4x_blend_op[op].src_alpha &&
-			    (g4x_blend_op[op].src_blend != GEN4_BLENDFACTOR_ZERO)) {
-				if (op != PictOpOver) {
-					DBG(("%s -- fallback: unhandled component alpha blend\n",
-					     __FUNCTION__));
-
-					goto cleanup_src;
-				}
-
-				tmp->need_magic_ca_pass = true;
-				tmp->op = PictOpOutReverse;
-			}
-		}
-
-		if (!reuse_source(sna,
-				  src, &tmp->src, src_x, src_y,
-				  mask, &tmp->mask, msk_x, msk_y)) {
-			switch (g4x_composite_picture(sna, mask, &tmp->mask,
-						       msk_x, msk_y,
-						       width, height,
-						       dst_x, dst_y,
-						       dst->polyMode == PolyModePrecise)) {
-			case -1:
-				DBG(("%s: failed to prepare mask\n", __FUNCTION__));
-				goto cleanup_src;
-			case 0:
-				if (!g4x_composite_solid_init(sna, &tmp->mask, 0))
-					goto cleanup_src;
-				/* fall through to fixup */
-			case 1:
-				g4x_composite_channel_convert(&tmp->mask);
-				break;
-			}
-		}
-
-		tmp->is_affine &= tmp->mask.is_affine;
-
-		if (tmp->src.transform == NULL && tmp->mask.transform == NULL)
-			tmp->prim_emit = g4x_emit_composite_primitive_identity_source_mask;
-
-		tmp->floats_per_vertex = 5 + 2 * !tmp->is_affine;
-	} else {
-		if (tmp->src.is_solid)
-			tmp->prim_emit = g4x_emit_composite_primitive_solid;
-		else if (tmp->src.transform == NULL)
-			tmp->prim_emit = g4x_emit_composite_primitive_identity_source;
-		else if (tmp->src.is_affine)
-			tmp->prim_emit = g4x_emit_composite_primitive_affine_source;
-
-		tmp->floats_per_vertex = 3 + !tmp->is_affine;
-	}
-	tmp->floats_per_rect = 3*tmp->floats_per_vertex;
-
-	tmp->u.gen4.wm_kernel =
-		g4x_choose_composite_kernel(tmp->op,
-					    tmp->mask.bo != NULL,
-					    tmp->has_component_alpha,
-					    tmp->is_affine);
-	tmp->u.gen4.ve_id = (tmp->mask.bo != NULL) << 1 | tmp->is_affine;
-
-	tmp->blt   = g4x_render_composite_blt;
-	tmp->box   = g4x_render_composite_box;
-	tmp->boxes = g4x_render_composite_boxes;
-	tmp->done  = g4x_render_composite_done;
-
-	if (!kgem_check_bo(&sna->kgem,
-			   tmp->dst.bo, tmp->src.bo, tmp->mask.bo,
-			   NULL)) {
-		kgem_submit(&sna->kgem);
-		if (!kgem_check_bo(&sna->kgem,
-				     tmp->dst.bo, tmp->src.bo, tmp->mask.bo,
-				     NULL))
-			goto cleanup_mask;
-	}
-
-	g4x_bind_surfaces(sna, tmp);
-	g4x_align_vertex(sna, tmp);
-	return true;
-
-cleanup_mask:
-	if (tmp->mask.bo)
-		kgem_bo_destroy(&sna->kgem, tmp->mask.bo);
-cleanup_src:
-	if (tmp->src.bo)
-		kgem_bo_destroy(&sna->kgem, tmp->src.bo);
-cleanup_dst:
-	if (tmp->redirect.real_bo)
-		kgem_bo_destroy(&sna->kgem, tmp->dst.bo);
-	return false;
-}
-
-/* A poor man's span interface. But better than nothing? */
-#if !NO_COMPOSITE_SPANS
-inline static void
-g4x_emit_composite_texcoord(struct sna *sna,
-			    const struct sna_composite_channel *channel,
-			    int16_t x, int16_t y)
-{
-	float t[3];
-
-	if (channel->is_affine) {
-		sna_get_transformed_coordinates(x + channel->offset[0],
-						y + channel->offset[1],
-						channel->transform,
-						&t[0], &t[1]);
-		OUT_VERTEX_F(t[0] * channel->scale[0]);
-		OUT_VERTEX_F(t[1] * channel->scale[1]);
-	} else {
-		t[0] = t[1] = 0; t[2] = 1;
-		sna_get_transformed_coordinates_3d(x + channel->offset[0],
-						   y + channel->offset[1],
-						   channel->transform,
-						   &t[0], &t[1], &t[2]);
-		OUT_VERTEX_F(t[0] * channel->scale[0]);
-		OUT_VERTEX_F(t[1] * channel->scale[1]);
-		OUT_VERTEX_F(t[2]);
-	}
-}
-
-inline static void
-g4x_emit_composite_texcoord_affine(struct sna *sna,
-				   const struct sna_composite_channel *channel,
-				   int16_t x, int16_t y)
-{
-	float t[2];
-
-	sna_get_transformed_coordinates(x + channel->offset[0],
-					y + channel->offset[1],
-					channel->transform,
-					&t[0], &t[1]);
-	OUT_VERTEX_F(t[0] * channel->scale[0]);
-	OUT_VERTEX_F(t[1] * channel->scale[1]);
-}
-
-inline static void
-g4x_emit_composite_spans_vertex(struct sna *sna,
-				const struct sna_composite_spans_op *op,
-				int16_t x, int16_t y)
-{
-	OUT_VERTEX(x, y);
-	g4x_emit_composite_texcoord(sna, &op->base.src, x, y);
-}
-
-fastcall static void
-g4x_emit_composite_spans_primitive(struct sna *sna,
-				   const struct sna_composite_spans_op *op,
-				   const BoxRec *box,
-				   float opacity)
-{
-	g4x_emit_composite_spans_vertex(sna, op, box->x2, box->y2);
-	OUT_VERTEX_F(opacity);
-	OUT_VERTEX_F(1);
-	if (!op->base.is_affine)
-		OUT_VERTEX_F(1);
-
-	g4x_emit_composite_spans_vertex(sna, op, box->x1, box->y2);
-	OUT_VERTEX_F(opacity);
-	OUT_VERTEX_F(1);
-	if (!op->base.is_affine)
-		OUT_VERTEX_F(1);
-
-	g4x_emit_composite_spans_vertex(sna, op, box->x1, box->y1);
-	OUT_VERTEX_F(opacity);
-	OUT_VERTEX_F(0);
-	if (!op->base.is_affine)
-		OUT_VERTEX_F(1);
-}
-
-fastcall static void
-g4x_emit_composite_spans_solid(struct sna *sna,
-			       const struct sna_composite_spans_op *op,
-			       const BoxRec *box,
-			       float opacity)
-{
-	OUT_VERTEX(box->x2, box->y2);
-	OUT_VERTEX_F(1); OUT_VERTEX_F(1);
-	OUT_VERTEX_F(opacity); OUT_VERTEX_F(1);
-
-	OUT_VERTEX(box->x1, box->y2);
-	OUT_VERTEX_F(0); OUT_VERTEX_F(1);
-	OUT_VERTEX_F(opacity); OUT_VERTEX_F(1);
-
-	OUT_VERTEX(box->x1, box->y1);
-	OUT_VERTEX_F(0); OUT_VERTEX_F(0);
-	OUT_VERTEX_F(opacity); OUT_VERTEX_F(0);
-}
-
-fastcall static void
-g4x_emit_composite_spans_affine(struct sna *sna,
-				const struct sna_composite_spans_op *op,
-				const BoxRec *box,
-				float opacity)
-{
-	OUT_VERTEX(box->x2, box->y2);
-	g4x_emit_composite_texcoord_affine(sna, &op->base.src,
-					    box->x2, box->y2);
-	OUT_VERTEX_F(opacity); OUT_VERTEX_F(1);
-
-	OUT_VERTEX(box->x1, box->y2);
-	g4x_emit_composite_texcoord_affine(sna, &op->base.src,
-					    box->x1, box->y2);
-	OUT_VERTEX_F(opacity); OUT_VERTEX_F(1);
-
-	OUT_VERTEX(box->x1, box->y1);
-	g4x_emit_composite_texcoord_affine(sna, &op->base.src,
-					    box->x1, box->y1);
-	OUT_VERTEX_F(opacity); OUT_VERTEX_F(0);
-}
-
-fastcall static void
-g4x_render_composite_spans_box(struct sna *sna,
-			       const struct sna_composite_spans_op *op,
-			       const BoxRec *box, float opacity)
-{
-	DBG(("%s: src=+(%d, %d), opacity=%f, dst=+(%d, %d), box=(%d, %d) x (%d, %d)\n",
-	     __FUNCTION__,
-	     op->base.src.offset[0], op->base.src.offset[1],
-	     opacity,
-	     op->base.dst.x, op->base.dst.y,
-	     box->x1, box->y1,
-	     box->x2 - box->x1,
-	     box->y2 - box->y1));
-
-	g4x_get_rectangles(sna, &op->base, 1, g4x_bind_surfaces);
-	op->prim_emit(sna, op, box, opacity);
-}
-
-static void
-g4x_render_composite_spans_boxes(struct sna *sna,
-				 const struct sna_composite_spans_op *op,
-				 const BoxRec *box, int nbox,
-				 float opacity)
-{
-	DBG(("%s: nbox=%d, src=+(%d, %d), opacity=%f, dst=+(%d, %d)\n",
-	     __FUNCTION__, nbox,
-	     op->base.src.offset[0], op->base.src.offset[1],
-	     opacity,
-	     op->base.dst.x, op->base.dst.y));
-
-	do {
-		g4x_render_composite_spans_box(sna, op, box++, opacity);
-	} while (--nbox);
-}
-
-fastcall static void
-g4x_render_composite_spans_done(struct sna *sna,
-				const struct sna_composite_spans_op *op)
-{
-	g4x_vertex_flush(sna);
-
-	DBG(("%s()\n", __FUNCTION__));
-
-	if (op->base.src.bo)
-		kgem_bo_destroy(&sna->kgem, op->base.src.bo);
-
-	sna_render_composite_redirect_done(sna, &op->base);
-}
-
-static bool
-g4x_check_composite_spans(struct sna *sna,
-			  uint8_t op, PicturePtr src, PicturePtr dst,
-			  int16_t width, int16_t height,
-			  unsigned flags)
-{
-	DBG(("%s: op=%d, width=%d, height=%d, flags=%x\n",
-	     __FUNCTION__, op, width, height, flags));
-
-	if (op >= ARRAY_SIZE(g4x_blend_op))
-		return false;
-
-	if (g4x_composite_fallback(sna, src, NULL, dst)) {
-		DBG(("%s: operation would fallback\n", __FUNCTION__));
-		return false;
-	}
-
-	if (need_tiling(sna, width, height) && !is_gpu(dst->pDrawable)) {
-		DBG(("%s: fallback, tiled operation not on GPU\n",
-		     __FUNCTION__));
-		return false;
-	}
-
-	if (FORCE_SPANS)
-		return FORCE_SPANS > 0;
-
-	if ((flags & COMPOSITE_SPANS_RECTILINEAR) == 0) {
-		DBG(("%s: fallback, non-rectilinear spans\n",
-		     __FUNCTION__));
-		return false;
-	}
-
-	return true;
-}
-
-static bool
-g4x_render_composite_spans(struct sna *sna,
-			   uint8_t op,
-			   PicturePtr src,
-			   PicturePtr dst,
-			   int16_t src_x,  int16_t src_y,
-			   int16_t dst_x,  int16_t dst_y,
-			   int16_t width,  int16_t height,
-			   unsigned flags,
-			   struct sna_composite_spans_op *tmp)
-{
-	DBG(("%s: %dx%d with flags=%x, current mode=%d\n", __FUNCTION__,
-	     width, height, flags, sna->kgem.ring));
-
-	assert(g4x_check_composite_spans(sna, op, src, dst, width, height, flags));
-
-	if (need_tiling(sna, width, height)) {
-		DBG(("%s: tiling, operation (%dx%d) too wide for pipeline\n",
-		     __FUNCTION__, width, height));
-		return sna_tiling_composite_spans(op, src, dst,
-						  src_x, src_y, dst_x, dst_y,
-						  width, height, flags, tmp);
-	}
-
-	tmp->base.op = op;
-	if (!g4x_composite_set_target(dst, &tmp->base))
-		return false;
-	sna_render_reduce_damage(&tmp->base, dst_x, dst_y, width, height);
-
-	sna_render_composite_redirect_init(&tmp->base);
-	if (too_large(tmp->base.dst.width, tmp->base.dst.height)) {
-		if (!sna_render_composite_redirect(sna, &tmp->base,
-						   dst_x, dst_y, width, height))
-			return false;
-	}
-
-	switch (g4x_composite_picture(sna, src, &tmp->base.src,
-				       src_x, src_y,
-				       width, height,
-				       dst_x, dst_y,
-				       dst->polyMode == PolyModePrecise)) {
-	case -1:
-		goto cleanup_dst;
-	case 0:
-		if (!g4x_composite_solid_init(sna, &tmp->base.src, 0))
-			goto cleanup_dst;
-		/* fall through to fixup */
-	case 1:
-		g4x_composite_channel_convert(&tmp->base.src);
-		break;
-	}
-
-	tmp->base.mask.bo = NULL;
-
-	tmp->base.is_affine = tmp->base.src.is_affine;
-	tmp->base.has_component_alpha = false;
-	tmp->base.need_magic_ca_pass = false;
-
-	if (tmp->base.src.is_solid) {
-		DBG(("%s: using solid fast emitter\n", __FUNCTION__));
-		tmp->prim_emit = g4x_emit_composite_spans_solid;
-	} else if (tmp->base.is_affine) {
-		DBG(("%s: using affine fast emitter\n", __FUNCTION__));
-		tmp->prim_emit = g4x_emit_composite_spans_affine;
-	} else {
-		DBG(("%s: using general emitter\n", __FUNCTION__));
-		tmp->prim_emit = g4x_emit_composite_spans_primitive;
-	}
-	tmp->base.floats_per_vertex = 5 + 2*!tmp->base.is_affine;
-	tmp->base.floats_per_rect = 3 * tmp->base.floats_per_vertex;
-
-	tmp->base.u.gen4.wm_kernel = WM_KERNEL_OPACITY | !tmp->base.is_affine;
-	tmp->base.u.gen4.ve_id = 1 << 1 | tmp->base.is_affine;
-
-	tmp->box   = g4x_render_composite_spans_box;
-	tmp->boxes = g4x_render_composite_spans_boxes;
-	tmp->done  = g4x_render_composite_spans_done;
-
-	if (!kgem_check_bo(&sna->kgem,
-			   tmp->base.dst.bo, tmp->base.src.bo,
-			   NULL))  {
-		kgem_submit(&sna->kgem);
-		if (!kgem_check_bo(&sna->kgem,
-				   tmp->base.dst.bo, tmp->base.src.bo,
-				   NULL))
-			goto cleanup_src;
-	}
-
-	g4x_bind_surfaces(sna, &tmp->base);
-	g4x_align_vertex(sna, &tmp->base);
-	return true;
-
-cleanup_src:
-	if (tmp->base.src.bo)
-		kgem_bo_destroy(&sna->kgem, tmp->base.src.bo);
-cleanup_dst:
-	if (tmp->base.redirect.real_bo)
-		kgem_bo_destroy(&sna->kgem, tmp->base.dst.bo);
-	return false;
-}
-#endif
-
-static void
-g4x_copy_bind_surfaces(struct sna *sna, const struct sna_composite_op *op)
-{
-	bool dirty = kgem_bo_is_dirty(op->dst.bo);
-	uint32_t *binding_table;
-	uint16_t offset;
-
-	g4x_get_batch(sna);
-
-	binding_table = g4x_composite_get_binding_table(sna, &offset);
-
-	binding_table[0] =
-		g4x_bind_bo(sna,
-			     op->dst.bo, op->dst.width, op->dst.height,
-			     g4x_get_dest_format(op->dst.format),
-			     true);
-	binding_table[1] =
-		g4x_bind_bo(sna,
-			     op->src.bo, op->src.width, op->src.height,
-			     op->src.card_format,
-			     false);
-
-	if (sna->kgem.surface == offset &&
-	    *(uint64_t *)(sna->kgem.batch + sna->render_state.gen4.surface_table) == *(uint64_t*)binding_table) {
-		sna->kgem.surface += sizeof(struct gen4_surface_state_padded) / sizeof(uint32_t);
-		offset = sna->render_state.gen4.surface_table;
-	}
-
-	g4x_emit_state(sna, op, offset | dirty);
-}
-
-static void
-g4x_render_copy_one(struct sna *sna,
-		    const struct sna_composite_op *op,
-		    int sx, int sy,
-		    int w, int h,
-		    int dx, int dy)
-{
-	g4x_get_rectangles(sna, op, 1, g4x_copy_bind_surfaces);
-
-	OUT_VERTEX(dx+w, dy+h);
-	OUT_VERTEX_F((sx+w)*op->src.scale[0]);
-	OUT_VERTEX_F((sy+h)*op->src.scale[1]);
-
-	OUT_VERTEX(dx, dy+h);
-	OUT_VERTEX_F(sx*op->src.scale[0]);
-	OUT_VERTEX_F((sy+h)*op->src.scale[1]);
-
-	OUT_VERTEX(dx, dy);
-	OUT_VERTEX_F(sx*op->src.scale[0]);
-	OUT_VERTEX_F(sy*op->src.scale[1]);
-}
-
-static inline bool prefer_blt_copy(struct sna *sna, unsigned flags)
-{
-#if PREFER_BLT
-	return true;
-	(void)sna;
-#else
-	return sna->kgem.mode != KGEM_RENDER;
-#endif
-	(void)flags;
-}
-
-static bool
-g4x_render_copy_boxes(struct sna *sna, uint8_t alu,
-		      PixmapPtr src, struct kgem_bo *src_bo, int16_t src_dx, int16_t src_dy,
-		      PixmapPtr dst, struct kgem_bo *dst_bo, int16_t dst_dx, int16_t dst_dy,
-		      const BoxRec *box, int n, unsigned flags)
-{
-	struct sna_composite_op tmp;
-
-	DBG(("%s x %d\n", __FUNCTION__, n));
-
-	if (prefer_blt_copy(sna, flags) &&
-	    sna_blt_compare_depth(&src->drawable, &dst->drawable) &&
-	    sna_blt_copy_boxes(sna, alu,
-			       src_bo, src_dx, src_dy,
-			       dst_bo, dst_dx, dst_dy,
-			       dst->drawable.bitsPerPixel,
-			       box, n))
-		return true;
-
-	if (!(alu == GXcopy || alu == GXclear) || src_bo == dst_bo) {
-fallback_blt:
-		if (!sna_blt_compare_depth(&src->drawable, &dst->drawable))
-			return false;
-
-		return sna_blt_copy_boxes_fallback(sna, alu,
-						   src, src_bo, src_dx, src_dy,
-						   dst, dst_bo, dst_dx, dst_dy,
-						   box, n);
-	}
-
-	memset(&tmp, 0, sizeof(tmp));
-
-	DBG(("%s (%d, %d)->(%d, %d) x %d\n",
-	     __FUNCTION__, src_dx, src_dy, dst_dx, dst_dy, n));
-
-	if (dst->drawable.depth == src->drawable.depth) {
-		tmp.dst.format = sna_render_format_for_depth(dst->drawable.depth);
-		tmp.src.pict_format = tmp.dst.format;
-	} else {
-		tmp.dst.format = sna_format_for_depth(dst->drawable.depth);
-		tmp.src.pict_format = sna_format_for_depth(src->drawable.depth);
-	}
-	if (!g4x_check_format(tmp.src.pict_format))
-		goto fallback_blt;
-
-	tmp.op = alu == GXcopy ? PictOpSrc : PictOpClear;
-
-	tmp.dst.pixmap = dst;
-	tmp.dst.width  = dst->drawable.width;
-	tmp.dst.height = dst->drawable.height;
-	tmp.dst.x = tmp.dst.y = 0;
-	tmp.dst.bo = dst_bo;
-	tmp.damage = NULL;
-
-	sna_render_composite_redirect_init(&tmp);
-	if (too_large(tmp.dst.width, tmp.dst.height)) {
-		BoxRec extents = box[0];
-		int i;
-
-		for (i = 1; i < n; i++) {
-			if (box[i].x1 < extents.x1)
-				extents.x1 = box[i].x1;
-			if (box[i].y1 < extents.y1)
-				extents.y1 = box[i].y1;
-
-			if (box[i].x2 > extents.x2)
-				extents.x2 = box[i].x2;
-			if (box[i].y2 > extents.y2)
-				extents.y2 = box[i].y2;
-		}
-		if (!sna_render_composite_redirect(sna, &tmp,
-						   extents.x1 + dst_dx,
-						   extents.y1 + dst_dy,
-						   extents.x2 - extents.x1,
-						   extents.y2 - extents.y1))
-			goto fallback_tiled;
-	}
-
-	tmp.src.filter = SAMPLER_FILTER_NEAREST;
-	tmp.src.repeat = SAMPLER_EXTEND_NONE;
-	tmp.src.card_format = g4x_get_card_format(tmp.src.pict_format);
-	if (too_large(src->drawable.width, src->drawable.height)) {
-		BoxRec extents = box[0];
-		int i;
-
-		for (i = 1; i < n; i++) {
-			if (extents.x1 < box[i].x1)
-				extents.x1 = box[i].x1;
-			if (extents.y1 < box[i].y1)
-				extents.y1 = box[i].y1;
-
-			if (extents.x2 > box[i].x2)
-				extents.x2 = box[i].x2;
-			if (extents.y2 > box[i].y2)
-				extents.y2 = box[i].y2;
-		}
-
-		if (!sna_render_pixmap_partial(sna, src, src_bo, &tmp.src,
-					       extents.x1 + src_dx,
-					       extents.y1 + src_dy,
-					       extents.x2 - extents.x1,
-					       extents.y2 - extents.y1))
-			goto fallback_tiled_dst;
-	} else {
-		tmp.src.bo = kgem_bo_reference(src_bo);
-		tmp.src.width  = src->drawable.width;
-		tmp.src.height = src->drawable.height;
-		tmp.src.offset[0] = tmp.src.offset[1] = 0;
-		tmp.src.scale[0] = 1.f/src->drawable.width;
-		tmp.src.scale[1] = 1.f/src->drawable.height;
-	}
-
-	tmp.is_affine = true;
-	tmp.floats_per_vertex = 3;
-	tmp.floats_per_rect = 9;
-	tmp.u.gen4.wm_kernel = WM_KERNEL;
-	tmp.u.gen4.ve_id = 1;
-
-	if (!kgem_check_bo(&sna->kgem, dst_bo, src_bo, NULL)) {
-		kgem_submit(&sna->kgem);
-		if (!kgem_check_bo(&sna->kgem, dst_bo, src_bo, NULL))
-			goto fallback_tiled_src;
-	}
-
-	dst_dx += tmp.dst.x;
-	dst_dy += tmp.dst.y;
-	tmp.dst.x = tmp.dst.y = 0;
-
-	src_dx += tmp.src.offset[0];
-	src_dy += tmp.src.offset[1];
-
-	g4x_copy_bind_surfaces(sna, &tmp);
-	g4x_align_vertex(sna, &tmp);
-
-	do {
-		g4x_render_copy_one(sna, &tmp,
-				     box->x1 + src_dx, box->y1 + src_dy,
-				     box->x2 - box->x1, box->y2 - box->y1,
-				     box->x1 + dst_dx, box->y1 + dst_dy);
-		box++;
-	} while (--n);
-
-	g4x_vertex_flush(sna);
-	sna_render_composite_redirect_done(sna, &tmp);
-	kgem_bo_destroy(&sna->kgem, tmp.src.bo);
-	return true;
-
-fallback_tiled_src:
-	kgem_bo_destroy(&sna->kgem, tmp.src.bo);
-fallback_tiled_dst:
-	if (tmp.redirect.real_bo)
-		kgem_bo_destroy(&sna->kgem, tmp.dst.bo);
-fallback_tiled:
-	return sna_tiling_copy_boxes(sna, alu,
-				     src, src_bo, src_dx, src_dy,
-				     dst, dst_bo, dst_dx, dst_dy,
-				     box, n);
-}
-
-static void
-g4x_render_copy_blt(struct sna *sna,
-		    const struct sna_copy_op *op,
-		    int16_t sx, int16_t sy,
-		    int16_t w,  int16_t h,
-		    int16_t dx, int16_t dy)
-{
-	g4x_render_copy_one(sna, &op->base, sx, sy, w, h, dx, dy);
-}
-
-static void
-g4x_render_copy_done(struct sna *sna, const struct sna_copy_op *op)
-{
-	g4x_vertex_flush(sna);
-}
-
-static inline bool prefer_blt_fill(struct sna *sna)
-{
-#if PREFER_BLT
-	return true;
-	(void)sna;
-#else
-	return sna->kgem.mode != KGEM_RENDER;
-#endif
-}
-
-static bool
-g4x_render_copy(struct sna *sna, uint8_t alu,
-		PixmapPtr src, struct kgem_bo *src_bo,
-		PixmapPtr dst, struct kgem_bo *dst_bo,
-		struct sna_copy_op *op)
-{
-	DBG(("%s: src=%ld, dst=%ld, alu=%d\n",
-	     __FUNCTION__,
-	     src->drawable.serialNumber,
-	     dst->drawable.serialNumber,
-	     alu));
-
-	if (prefer_blt_fill(sna) &&
-	    sna_blt_compare_depth(&src->drawable, &dst->drawable) &&
-	    sna_blt_copy(sna, alu,
-			 src_bo, dst_bo,
-			 dst->drawable.bitsPerPixel,
-			 op))
-		return true;
-
-	if (!(alu == GXcopy || alu == GXclear) || src_bo == dst_bo ||
-	    too_large(src->drawable.width, src->drawable.height) ||
-	    too_large(dst->drawable.width, dst->drawable.height)) {
-fallback:
-		if (!sna_blt_compare_depth(&src->drawable, &dst->drawable))
-			return false;
-
-		return sna_blt_copy(sna, alu, src_bo, dst_bo,
-				    dst->drawable.bitsPerPixel,
-				    op);
-	}
-
-	if (dst->drawable.depth == src->drawable.depth) {
-		op->base.dst.format = sna_render_format_for_depth(dst->drawable.depth);
-		op->base.src.pict_format = op->base.dst.format;
-	} else {
-		op->base.dst.format = sna_format_for_depth(dst->drawable.depth);
-		op->base.src.pict_format = sna_format_for_depth(src->drawable.depth);
-	}
-	if (!g4x_check_format(op->base.src.pict_format))
-		goto fallback;
-
-	op->base.op = alu == GXcopy ? PictOpSrc : PictOpClear;
-
-	op->base.dst.pixmap = dst;
-	op->base.dst.width  = dst->drawable.width;
-	op->base.dst.height = dst->drawable.height;
-	op->base.dst.bo = dst_bo;
-
-	op->base.src.bo = src_bo;
-	op->base.src.card_format =
-		g4x_get_card_format(op->base.src.pict_format);
-	op->base.src.width  = src->drawable.width;
-	op->base.src.height = src->drawable.height;
-	op->base.src.scale[0] = 1.f/src->drawable.width;
-	op->base.src.scale[1] = 1.f/src->drawable.height;
-	op->base.src.filter = SAMPLER_FILTER_NEAREST;
-	op->base.src.repeat = SAMPLER_EXTEND_NONE;
-
-	op->base.is_affine = true;
-	op->base.floats_per_vertex = 3;
-	op->base.floats_per_rect = 9;
-	op->base.u.gen4.wm_kernel = WM_KERNEL;
-	op->base.u.gen4.ve_id = 1;
-
-	if (!kgem_check_bo(&sna->kgem, dst_bo, src_bo, NULL)) {
-		kgem_submit(&sna->kgem);
-		if (!kgem_check_bo(&sna->kgem, dst_bo, src_bo, NULL))
-			goto fallback;
-	}
-
-	if (kgem_bo_is_dirty(src_bo)) {
-		if (sna_blt_compare_depth(&src->drawable, &dst->drawable) &&
-		    sna_blt_copy(sna, alu,
-				 src_bo, dst_bo,
-				 dst->drawable.bitsPerPixel,
-				 op))
-			return true;
-	}
-
-	g4x_copy_bind_surfaces(sna, &op->base);
-	g4x_align_vertex(sna, &op->base);
-
-	op->blt  = g4x_render_copy_blt;
-	op->done = g4x_render_copy_done;
-	return true;
-}
-
-static void
-g4x_render_fill_rectangle(struct sna *sna,
-			  const struct sna_composite_op *op,
-			  int x, int y, int w, int h)
-{
-	g4x_get_rectangles(sna, op, 1, g4x_bind_surfaces);
-
-	OUT_VERTEX(x+w, y+h);
-	OUT_VERTEX_F(1);
-	OUT_VERTEX_F(1);
-
-	OUT_VERTEX(x, y+h);
-	OUT_VERTEX_F(0);
-	OUT_VERTEX_F(1);
-
-	OUT_VERTEX(x, y);
-	OUT_VERTEX_F(0);
-	OUT_VERTEX_F(0);
-}
-
-static bool
-g4x_render_fill_boxes(struct sna *sna,
-		      CARD8 op,
-		      PictFormat format,
-		      const xRenderColor *color,
-		      PixmapPtr dst, struct kgem_bo *dst_bo,
-		      const BoxRec *box, int n)
-{
-	struct sna_composite_op tmp;
-	uint32_t pixel;
-
-	if (op >= ARRAY_SIZE(g4x_blend_op)) {
-		DBG(("%s: fallback due to unhandled blend op: %d\n",
-		     __FUNCTION__, op));
-		return false;
-	}
-
-	if (op <= PictOpSrc &&
-	    (prefer_blt_fill(sna) ||
-	     too_large(dst->drawable.width, dst->drawable.height) ||
-	     !g4x_check_dst_format(format))) {
-		uint8_t alu = GXinvalid;
-
-		pixel = 0;
-		if (op == PictOpClear)
-			alu = GXclear;
-		else if (sna_get_pixel_from_rgba(&pixel,
-						 color->red,
-						 color->green,
-						 color->blue,
-						 color->alpha,
-						 format))
-			alu = GXcopy;
-
-		if (alu != GXinvalid &&
-		    sna_blt_fill_boxes(sna, alu,
-				       dst_bo, dst->drawable.bitsPerPixel,
-				       pixel, box, n))
-			return true;
-
-		if (!g4x_check_dst_format(format))
-			return false;
-
-		if (too_large(dst->drawable.width, dst->drawable.height))
-			return sna_tiling_fill_boxes(sna, op, format, color,
-						     dst, dst_bo, box, n);
-	}
-
-	if (op == PictOpClear) {
-		pixel = 0;
-		op = PictOpSrc;
-	} else if (!sna_get_pixel_from_rgba(&pixel,
-					    color->red,
-					    color->green,
-					    color->blue,
-					    color->alpha,
-					    PICT_a8r8g8b8))
-		return false;
-
-	DBG(("%s(%08x x %d)\n", __FUNCTION__, pixel, n));
-
-	memset(&tmp, 0, sizeof(tmp));
-
-	tmp.op = op;
-
-	tmp.dst.pixmap = dst;
-	tmp.dst.width  = dst->drawable.width;
-	tmp.dst.height = dst->drawable.height;
-	tmp.dst.format = format;
-	tmp.dst.bo = dst_bo;
-
-	g4x_composite_solid_init(sna, &tmp.src, pixel);
-
-	tmp.is_affine = true;
-	tmp.floats_per_vertex = 3;
-	tmp.floats_per_rect = 9;
-	tmp.u.gen4.wm_kernel = WM_KERNEL;
-	tmp.u.gen4.ve_id = 1;
-
-	if (!kgem_check_bo(&sna->kgem, dst_bo, NULL)) {
-		kgem_submit(&sna->kgem);
-		assert(kgem_check_bo(&sna->kgem, dst_bo, NULL));
-	}
-
-	g4x_bind_surfaces(sna, &tmp);
-	g4x_align_vertex(sna, &tmp);
-
-	do {
-		g4x_render_fill_rectangle(sna, &tmp,
-					   box->x1, box->y1,
-					   box->x2 - box->x1,
-					   box->y2 - box->y1);
-		box++;
-	} while (--n);
-
-	g4x_vertex_flush(sna);
-	kgem_bo_destroy(&sna->kgem, tmp.src.bo);
-	return true;
-}
-
-static void
-g4x_render_fill_op_blt(struct sna *sna, const struct sna_fill_op *op,
-		       int16_t x, int16_t y, int16_t w, int16_t h)
-{
-	g4x_render_fill_rectangle(sna, &op->base, x, y, w, h);
-}
-
-fastcall static void
-g4x_render_fill_op_box(struct sna *sna,
-		       const struct sna_fill_op *op,
-		       const BoxRec *box)
-{
-	g4x_render_fill_rectangle(sna, &op->base,
-				   box->x1, box->y1,
-				   box->x2-box->x1, box->y2-box->y1);
-}
-
-fastcall static void
-g4x_render_fill_op_boxes(struct sna *sna,
-			 const struct sna_fill_op *op,
-			 const BoxRec *box,
-			 int nbox)
-{
-	do {
-		g4x_render_fill_rectangle(sna, &op->base,
-					   box->x1, box->y1,
-					   box->x2-box->x1, box->y2-box->y1);
-		box++;
-	} while (--nbox);
-}
-
-static void
-g4x_render_fill_op_done(struct sna *sna, const struct sna_fill_op *op)
-{
-	g4x_vertex_flush(sna);
-	kgem_bo_destroy(&sna->kgem, op->base.src.bo);
-}
-
-static bool
-g4x_render_fill(struct sna *sna, uint8_t alu,
-		PixmapPtr dst, struct kgem_bo *dst_bo,
-		uint32_t color,
-		struct sna_fill_op *op)
-{
-	if (prefer_blt_fill(sna) &&
-	    sna_blt_fill(sna, alu,
-			 dst_bo, dst->drawable.bitsPerPixel,
-			 color,
-			 op))
-		return true;
-
-	if (!(alu == GXcopy || alu == GXclear) ||
-	    too_large(dst->drawable.width, dst->drawable.height))
-		return sna_blt_fill(sna, alu,
-				    dst_bo, dst->drawable.bitsPerPixel,
-				    color,
-				    op);
-
-	if (alu == GXclear)
-		color = 0;
-
-	op->base.op = color == 0 ? PictOpClear : PictOpSrc;
-
-	op->base.dst.pixmap = dst;
-	op->base.dst.width  = dst->drawable.width;
-	op->base.dst.height = dst->drawable.height;
-	op->base.dst.format = sna_format_for_depth(dst->drawable.depth);
-	op->base.dst.bo = dst_bo;
-	op->base.dst.x = op->base.dst.y = 0;
-
-	op->base.need_magic_ca_pass = 0;
-	op->base.has_component_alpha = 0;
-
-	g4x_composite_solid_init(sna, &op->base.src,
-				  sna_rgba_for_color(color,
-						     dst->drawable.depth));
-	op->base.mask.bo = NULL;
-
-	op->base.is_affine = true;
-	op->base.floats_per_vertex = 3;
-	op->base.floats_per_rect = 9;
-	op->base.u.gen4.wm_kernel = WM_KERNEL;
-	op->base.u.gen4.ve_id = 1;
-
-	if (!kgem_check_bo(&sna->kgem, dst_bo, NULL)) {
-		kgem_submit(&sna->kgem);
-		assert(kgem_check_bo(&sna->kgem, dst_bo, NULL));
-	}
-
-	g4x_bind_surfaces(sna, &op->base);
-	g4x_align_vertex(sna, &op->base);
-
-	op->blt   = g4x_render_fill_op_blt;
-	op->box   = g4x_render_fill_op_box;
-	op->boxes = g4x_render_fill_op_boxes;
-	op->done  = g4x_render_fill_op_done;
-	return true;
-}
-
-static bool
-g4x_render_fill_one_try_blt(struct sna *sna, PixmapPtr dst, struct kgem_bo *bo,
-			    uint32_t color,
-			    int16_t x1, int16_t y1, int16_t x2, int16_t y2,
-			    uint8_t alu)
-{
-	BoxRec box;
-
-	box.x1 = x1;
-	box.y1 = y1;
-	box.x2 = x2;
-	box.y2 = y2;
-
-	return sna_blt_fill_boxes(sna, alu,
-				  bo, dst->drawable.bitsPerPixel,
-				  color, &box, 1);
-}
-
-static bool
-g4x_render_fill_one(struct sna *sna, PixmapPtr dst, struct kgem_bo *bo,
-		    uint32_t color,
-		    int16_t x1, int16_t y1,
-		    int16_t x2, int16_t y2,
-		    uint8_t alu)
-{
-	struct sna_composite_op tmp;
-
-	DBG(("%s: color=%08x\n", __FUNCTION__, color));
-
-	if (g4x_render_fill_one_try_blt(sna, dst, bo, color,
-					 x1, y1, x2, y2, alu))
-		return true;
-
-	/* Must use the BLT if we can't RENDER... */
-	if (!(alu == GXcopy || alu == GXclear) ||
-	    too_large(dst->drawable.width, dst->drawable.height))
-		return false;
-
-	if (alu == GXclear)
-		color = 0;
-
-	tmp.op = color == 0 ? PictOpClear : PictOpSrc;
-
-	tmp.dst.pixmap = dst;
-	tmp.dst.width  = dst->drawable.width;
-	tmp.dst.height = dst->drawable.height;
-	tmp.dst.format = sna_format_for_depth(dst->drawable.depth);
-	tmp.dst.bo = bo;
-	tmp.dst.x = tmp.dst.y = 0;
-
-	g4x_composite_solid_init(sna, &tmp.src,
-				  sna_rgba_for_color(color,
-						     dst->drawable.depth));
-	tmp.mask.bo = NULL;
-
-	tmp.is_affine = true;
-	tmp.floats_per_vertex = 3;
-	tmp.floats_per_rect = 9;
-	tmp.has_component_alpha = false;
-	tmp.need_magic_ca_pass = false;
-
-	tmp.u.gen4.wm_kernel = WM_KERNEL;
-	tmp.u.gen4.ve_id = 1;
-
-	if (!kgem_check_bo(&sna->kgem, bo, NULL)) {
-		_kgem_submit(&sna->kgem);
-		assert(kgem_check_bo(&sna->kgem, bo, NULL));
-	}
-
-	g4x_bind_surfaces(sna, &tmp);
-	g4x_align_vertex(sna, &tmp);
-
-	g4x_render_fill_rectangle(sna, &tmp, x1, y1, x2 - x1, y2 - y1);
-
-	g4x_vertex_flush(sna);
-	kgem_bo_destroy(&sna->kgem, tmp.src.bo);
-
-	return true;
-}
-
-static void
-g4x_render_flush(struct sna *sna)
-{
-	g4x_vertex_close(sna);
-}
-
-static void
-discard_vbo(struct sna *sna)
-{
-	kgem_bo_destroy(&sna->kgem, sna->render.vbo);
-	sna->render.vbo = NULL;
-	sna->render.vertices = sna->render.vertex_data;
-	sna->render.vertex_size = ARRAY_SIZE(sna->render.vertex_data);
-	sna->render.vertex_used = 0;
-	sna->render.vertex_index = 0;
-}
-
-static void
-g4x_render_retire(struct kgem *kgem)
-{
-	struct sna *sna;
-
-	sna = container_of(kgem, struct sna, kgem);
-	if (kgem->nbatch == 0 && sna->render.vbo && !kgem_bo_is_busy(sna->render.vbo)) {
-		DBG(("%s: resetting idle vbo\n", __FUNCTION__));
-		sna->render.vertex_used = 0;
-		sna->render.vertex_index = 0;
-	}
-}
-
-static void
-g4x_render_expire(struct kgem *kgem)
-{
-	struct sna *sna;
-
-	sna = container_of(kgem, struct sna, kgem);
-	if (sna->render.vbo && !sna->render.vertex_used) {
-		DBG(("%s: discarding vbo\n", __FUNCTION__));
-		discard_vbo(sna);
-	}
-}
-
-static void g4x_render_reset(struct sna *sna)
-{
-	sna->render_state.gen4.needs_invariant = true;
-	sna->render_state.gen4.needs_urb = true;
-	sna->render_state.gen4.vb_id = 0;
-	sna->render_state.gen4.ve_id = -1;
-	sna->render_state.gen4.last_primitive = -1;
-	sna->render_state.gen4.last_pipelined_pointers = -1;
-
-	sna->render_state.gen4.drawrect_offset = -1;
-	sna->render_state.gen4.drawrect_limit = -1;
-	sna->render_state.gen4.surface_table = -1;
-
-	if (sna->render.vbo &&
-	    !kgem_bo_is_mappable(&sna->kgem, sna->render.vbo)) {
-		DBG(("%s: discarding unmappable vbo\n", __FUNCTION__));
-		discard_vbo(sna);
-	}
-}
-
-static void g4x_render_fini(struct sna *sna)
-{
-	kgem_bo_destroy(&sna->kgem, sna->render_state.gen4.general_bo);
-}
-
-static uint32_t g4x_create_vs_unit_state(struct sna_static_stream *stream)
-{
-	struct gen4_vs_unit_state *vs = sna_static_stream_map(stream, sizeof(*vs), 32);
-
-	/* Set up the vertex shader to be disabled (passthrough) */
-	vs->thread4.nr_urb_entries = URB_VS_ENTRIES;
-	vs->thread4.urb_entry_allocation_size = URB_VS_ENTRY_SIZE - 1;
-	vs->vs6.vs_enable = 0;
-	vs->vs6.vert_cache_disable = 1;
-
-	return sna_static_stream_offsetof(stream, vs);
-}
-
-static uint32_t g4x_create_sf_state(struct sna_static_stream *stream,
-				    uint32_t kernel)
-{
-	struct gen4_sf_unit_state *sf;
-
-	sf = sna_static_stream_map(stream, sizeof(*sf), 32);
-
-	sf->thread0.grf_reg_count = GEN4_GRF_BLOCKS(SF_KERNEL_NUM_GRF);
-	sf->thread0.kernel_start_pointer = kernel >> 6;
-	sf->thread3.const_urb_entry_read_length = 0;	/* no const URBs */
-	sf->thread3.const_urb_entry_read_offset = 0;	/* no const URBs */
-	sf->thread3.urb_entry_read_length = 1;	/* 1 URB per vertex */
-	/* don't smash vertex header, read start from dw8 */
-	sf->thread3.urb_entry_read_offset = 1;
-	sf->thread3.dispatch_grf_start_reg = 3;
-	sf->thread4.max_threads = G4X_MAX_SF_THREADS - 1;
-	sf->thread4.urb_entry_allocation_size = URB_SF_ENTRY_SIZE - 1;
-	sf->thread4.nr_urb_entries = URB_SF_ENTRIES;
-	sf->sf5.viewport_transform = false;	/* skip viewport */
-	sf->sf6.cull_mode = GEN4_CULLMODE_NONE;
-	sf->sf6.scissor = 0;
-	sf->sf7.trifan_pv = 2;
-	sf->sf6.dest_org_vbias = 0x8;
-	sf->sf6.dest_org_hbias = 0x8;
-
-	return sna_static_stream_offsetof(stream, sf);
-}
-
-static uint32_t g4x_create_sampler_state(struct sna_static_stream *stream,
-					 sampler_filter_t src_filter,
-					 sampler_extend_t src_extend,
-					 sampler_filter_t mask_filter,
-					 sampler_extend_t mask_extend)
-{
-	struct gen4_sampler_state *sampler_state;
-
-	sampler_state = sna_static_stream_map(stream,
-					      sizeof(struct gen4_sampler_state) * 2,
-					      32);
-	sampler_state_init(&sampler_state[0], src_filter, src_extend);
-	sampler_state_init(&sampler_state[1], mask_filter, mask_extend);
-
-	return sna_static_stream_offsetof(stream, sampler_state);
-}
-
-static void g4x_init_wm_state(struct gen4_wm_unit_state *wm,
-			      bool has_mask,
-			      uint32_t kernel,
-			      uint32_t sampler)
-{
-	assert((kernel & 63) == 0);
-	wm->thread0.kernel_start_pointer = kernel >> 6;
-	wm->thread0.grf_reg_count = GEN4_GRF_BLOCKS(PS_KERNEL_NUM_GRF);
-
-	wm->thread1.single_program_flow = 0;
-
-	wm->thread3.const_urb_entry_read_length = 0;
-	wm->thread3.const_urb_entry_read_offset = 0;
-
-	wm->thread3.urb_entry_read_offset = 0;
-	wm->thread3.dispatch_grf_start_reg = 3;
-
-	assert((sampler & 31) == 0);
-	wm->wm4.sampler_state_pointer = sampler >> 5;
-	wm->wm4.sampler_count = 1;
-
-	wm->wm5.max_threads = G4X_MAX_WM_THREADS - 1;
-	wm->wm5.transposed_urb_read = 0;
-	wm->wm5.thread_dispatch_enable = 1;
-	/* just use 16-pixel dispatch (4 subspans), don't need to change kernel
-	 * start point
-	 */
-	wm->wm5.enable_16_pix = 1;
-	wm->wm5.enable_8_pix = 0;
-	wm->wm5.early_depth_test = 1;
-
-	/* Each pair of attributes (src/mask coords) is two URB entries */
-	if (has_mask) {
-		wm->thread1.binding_table_entry_count = 3;
-		wm->thread3.urb_entry_read_length = 4;
-	} else {
-		wm->thread1.binding_table_entry_count = 2;
-		wm->thread3.urb_entry_read_length = 2;
-	}
-}
-
-static uint32_t g4x_create_cc_viewport(struct sna_static_stream *stream)
-{
-	struct gen4_cc_viewport vp;
-
-	vp.min_depth = -1.e35;
-	vp.max_depth = 1.e35;
-
-	return sna_static_stream_add(stream, &vp, sizeof(vp), 32);
-}
-
-static uint32_t g4x_create_cc_unit_state(struct sna_static_stream *stream)
-{
-	uint8_t *ptr, *base;
-	uint32_t vp;
-	int i, j;
-
-	vp = g4x_create_cc_viewport(stream);
-	base = ptr =
-		sna_static_stream_map(stream,
-				      GEN4_BLENDFACTOR_COUNT*GEN4_BLENDFACTOR_COUNT*64,
-				      64);
-
-	for (i = 0; i < GEN4_BLENDFACTOR_COUNT; i++) {
-		for (j = 0; j < GEN4_BLENDFACTOR_COUNT; j++) {
-			struct gen4_cc_unit_state *state =
-				(struct gen4_cc_unit_state *)ptr;
-
-			state->cc3.blend_enable =
-				!(j == GEN4_BLENDFACTOR_ZERO && i == GEN4_BLENDFACTOR_ONE);
-			state->cc4.cc_viewport_state_offset = vp >> 5;
-
-			state->cc5.logicop_func = 0xc;	/* COPY */
-			state->cc5.ia_blend_function = GEN4_BLENDFUNCTION_ADD;
-
-			/* Fill in alpha blend factors same as color, for the future. */
-			state->cc5.ia_src_blend_factor = i;
-			state->cc5.ia_dest_blend_factor = j;
-
-			state->cc6.blend_function = GEN4_BLENDFUNCTION_ADD;
-			state->cc6.clamp_post_alpha_blend = 1;
-			state->cc6.clamp_pre_alpha_blend = 1;
-			state->cc6.src_blend_factor = i;
-			state->cc6.dest_blend_factor = j;
-
-			ptr += 64;
-		}
-	}
-
-	return sna_static_stream_offsetof(stream, base);
-}
-
-static bool g4x_render_setup(struct sna *sna)
-{
-	struct gen4_render_state *state = &sna->render_state.gen4;
-	struct sna_static_stream general;
-	struct gen4_wm_unit_state_padded *wm_state;
-	uint32_t sf[2], wm[KERNEL_COUNT];
-	int i, j, k, l, m;
-
-	sna_static_stream_init(&general);
-
-	/* Zero pad the start. If you see an offset of 0x0 in the batchbuffer
-	 * dumps, you know it points to zero.
-	 */
-	null_create(&general);
-
-	sf[0] = sna_static_stream_compile_sf(sna, &general, brw_sf_kernel__nomask);
-	sf[1] = sna_static_stream_compile_sf(sna, &general, brw_sf_kernel__mask);
-	for (m = 0; m < KERNEL_COUNT; m++) {
-		if (wm_kernels[m].size) {
-			wm[m] = sna_static_stream_add(&general,
-						      wm_kernels[m].data,
-						      wm_kernels[m].size,
-						      64);
-		} else {
-			wm[m] = sna_static_stream_compile_wm(sna, &general,
-							     wm_kernels[m].data,
-							     16);
-		}
-	}
-
-	state->vs = g4x_create_vs_unit_state(&general);
-	state->sf[0] = g4x_create_sf_state(&general, sf[0]);
-	state->sf[1] = g4x_create_sf_state(&general, sf[1]);
-
-	wm_state = sna_static_stream_map(&general,
-					  sizeof(*wm_state) * KERNEL_COUNT *
-					  FILTER_COUNT * EXTEND_COUNT *
-					  FILTER_COUNT * EXTEND_COUNT,
-					  64);
-	state->wm = sna_static_stream_offsetof(&general, wm_state);
-	for (i = 0; i < FILTER_COUNT; i++) {
-		for (j = 0; j < EXTEND_COUNT; j++) {
-			for (k = 0; k < FILTER_COUNT; k++) {
-				for (l = 0; l < EXTEND_COUNT; l++) {
-					uint32_t sampler_state;
-
-					sampler_state =
-						g4x_create_sampler_state(&general,
-									  i, j,
-									  k, l);
-
-					for (m = 0; m < KERNEL_COUNT; m++) {
-						g4x_init_wm_state(&wm_state->state,
-								   wm_kernels[m].has_mask,
-								   wm[m], sampler_state);
-						wm_state++;
-					}
-				}
-			}
-		}
-	}
-
-	state->cc = g4x_create_cc_unit_state(&general);
-
-	state->general_bo = sna_static_stream_fini(sna, &general);
-	return state->general_bo != NULL;
-}
-
-bool g4x_render_init(struct sna *sna)
-{
-	if (!g4x_render_setup(sna))
-		return false;
-
-	sna->kgem.retire = g4x_render_retire;
-	sna->kgem.expire = g4x_render_expire;
-
-#if !NO_COMPOSITE
-	sna->render.composite = g4x_render_composite;
-#endif
-#if !NO_COMPOSITE_SPANS
-	sna->render.check_composite_spans = g4x_check_composite_spans;
-	sna->render.composite_spans = g4x_render_composite_spans;
-#endif
-
-#if !NO_VIDEO
-	sna->render.video = g4x_render_video;
-#endif
-
-#if !NO_COPY_BOXES
-	sna->render.copy_boxes = g4x_render_copy_boxes;
-#endif
-#if !NO_COPY
-	sna->render.copy = g4x_render_copy;
-#endif
-
-#if !NO_FILL_BOXES
-	sna->render.fill_boxes = g4x_render_fill_boxes;
-#endif
-#if !NO_FILL
-	sna->render.fill = g4x_render_fill;
-#endif
-#if !NO_FILL_ONE
-	sna->render.fill_one = g4x_render_fill_one;
-#endif
-
-	sna->render.flush = g4x_render_flush;
-	sna->render.reset = g4x_render_reset;
-	sna->render.fini = g4x_render_fini;
-
-	sna->render.max_3d_size = GEN4_MAX_3D_SIZE;
-	sna->render.max_3d_pitch = 1 << 18;
-	return true;
-}
diff --git a/src/sna/gen4_render.c b/src/sna/gen4_render.c
index 0484af8..e686cad 100644
--- a/src/sna/gen4_render.c
+++ b/src/sna/gen4_render.c
@@ -48,7 +48,6 @@
  * the BLT engine.
  */
 #define PREFER_BLT 1
-#define FLUSH_EVERY_VERTEX 1
 #define FORCE_SPANS 0
 
 #define NO_COMPOSITE 0
@@ -60,19 +59,6 @@
 #define NO_FILL_BOXES 0
 #define NO_VIDEO 0
 
-#if FLUSH_EVERY_VERTEX
-#define _FLUSH() do { \
-	gen4_vertex_flush(sna); \
-	OUT_BATCH(MI_FLUSH | MI_INHIBIT_RENDER_CACHE_FLUSH); \
-} while (0)
-#define FLUSH(OP) do { \
-	if ((OP)->mask.bo == NULL) _FLUSH(); \
-} while (0)
-#else
-#define _FLUSH()
-#define FLUSH(OP)
-#endif
-
 #define GEN4_GRF_BLOCKS(nreg)    ((nreg + 15) / 16 - 1)
 
 /* Set up a default static partitioning of the URB, which is supposed to
@@ -103,6 +89,7 @@
 
 #define GEN4_MAX_SF_THREADS 24
 #define GEN4_MAX_WM_THREADS 32
+#define G4X_MAX_WM_THREADS 50
 
 static const uint32_t ps_kernel_packed_static[][4] = {
 #include "exa_wm_xy.g4b"
@@ -184,7 +171,7 @@ static const struct blendinfo {
 #define SAMPLER_OFFSET(sf, se, mf, me, k) \
 	((((((sf) * EXTEND_COUNT + (se)) * FILTER_COUNT + (mf)) * EXTEND_COUNT + (me)) * KERNEL_COUNT + (k)) * 64)
 
-static bool
+static void
 gen4_emit_pipelined_pointers(struct sna *sna,
 			     const struct sna_composite_op *op,
 			     int blend, int kernel);
@@ -234,7 +221,6 @@ static void gen4_magic_ca_pass(struct sna *sna,
 	gen4_emit_pipelined_pointers(sna, op, PictOpAdd,
 				     gen4_choose_composite_kernel(PictOpAdd,
 								  true, true, op->is_affine));
-	OUT_BATCH(MI_FLUSH);
 
 	OUT_BATCH(GEN4_3DPRIMITIVE |
 		  GEN4_3DPRIMITIVE_VERTEX_SEQUENTIAL |
@@ -852,6 +838,7 @@ gen4_emit_composite_primitive(struct sna *sna,
 	bool is_affine = op->is_affine;
 	const float *src_sf = op->src.scale;
 	const float *mask_sf = op->mask.scale;
+	bool has_mask = op->u.gen4.ve_id & 2;
 
 	if (is_affine) {
 		sna_get_transformed_coordinates(r->src.x + op->src.offset[0],
@@ -892,7 +879,7 @@ gen4_emit_composite_primitive(struct sna *sna,
 						   &src_w[2]);
 	}
 
-	if (op->mask.bo) {
+	if (has_mask) {
 		if (is_affine) {
 			sna_get_transformed_coordinates(r->mask.x + op->mask.offset[0],
 							r->mask.y + op->mask.offset[1],
@@ -938,7 +925,7 @@ gen4_emit_composite_primitive(struct sna *sna,
 	OUT_VERTEX_F(src_y[2] * src_sf[1]);
 	if (!is_affine)
 		OUT_VERTEX_F(src_w[2]);
-	if (op->mask.bo) {
+	if (has_mask) {
 		OUT_VERTEX_F(mask_x[2] * mask_sf[0]);
 		OUT_VERTEX_F(mask_y[2] * mask_sf[1]);
 		if (!is_affine)
@@ -950,7 +937,7 @@ gen4_emit_composite_primitive(struct sna *sna,
 	OUT_VERTEX_F(src_y[1] * src_sf[1]);
 	if (!is_affine)
 		OUT_VERTEX_F(src_w[1]);
-	if (op->mask.bo) {
+	if (has_mask) {
 		OUT_VERTEX_F(mask_x[1] * mask_sf[0]);
 		OUT_VERTEX_F(mask_y[1] * mask_sf[1]);
 		if (!is_affine)
@@ -962,7 +949,7 @@ gen4_emit_composite_primitive(struct sna *sna,
 	OUT_VERTEX_F(src_y[0] * src_sf[1]);
 	if (!is_affine)
 		OUT_VERTEX_F(src_w[0]);
-	if (op->mask.bo) {
+	if (has_mask) {
 		OUT_VERTEX_F(mask_x[0] * mask_sf[0]);
 		OUT_VERTEX_F(mask_y[0] * mask_sf[1]);
 		if (!is_affine)
@@ -1017,8 +1004,6 @@ static bool gen4_rectangle_begin(struct sna *sna,
 
 	/* 7xpipelined pointers + 6xprimitive + 1xflush */
 	ndwords = op->need_magic_ca_pass? 20 : 6;
-	if (FLUSH_EVERY_VERTEX)
-		ndwords += 1;
 	if ((sna->render_state.gen4.vb_id & (1 << id)) == 0)
 		ndwords += 5;
 
@@ -1036,7 +1021,7 @@ static bool gen4_rectangle_begin(struct sna *sna,
 static int gen4_get_rectangles__flush(struct sna *sna,
 				      const struct sna_composite_op *op)
 {
-	if (!kgem_check_batch(&sna->kgem, (FLUSH_EVERY_VERTEX || op->need_magic_ca_pass) ? 25 : 6))
+	if (!kgem_check_batch(&sna->kgem, op->need_magic_ca_pass ? 25 : 6))
 		return 0;
 	if (!kgem_check_reloc_and_exec(&sna->kgem, 1))
 		return 0;
@@ -1085,8 +1070,7 @@ flush:
 }
 
 static uint32_t *
-gen4_composite_get_binding_table(struct sna *sna,
-				 uint16_t *offset)
+gen4_composite_get_binding_table(struct sna *sna, uint16_t *offset)
 {
 	sna->kgem.surface -=
 		sizeof(struct gen4_surface_state_padded) / sizeof(uint32_t);
@@ -1215,11 +1199,11 @@ gen4_align_vertex(struct sna *sna, const struct sna_composite_op *op)
 	}
 }
 
-static bool
+static void
 gen4_emit_binding_table(struct sna *sna, uint16_t offset)
 {
 	if (sna->render_state.gen4.surface_table == offset)
-		return false;
+		return;
 
 	sna->render_state.gen4.surface_table = offset;
 
@@ -1231,20 +1215,18 @@ gen4_emit_binding_table(struct sna *sna, uint16_t offset)
 	OUT_BATCH(0);		/* sf */
 	/* Only the PS uses the binding table */
 	OUT_BATCH(offset*4);
-
-	return true;
 }
 
-static bool
+static void
 gen4_emit_pipelined_pointers(struct sna *sna,
 			     const struct sna_composite_op *op,
 			     int blend, int kernel)
 {
-	uint32_t key;
 	uint16_t sp, bp;
+	uint32_t key;
 
 	DBG(("%s: has_mask=%d, src=(%d, %d), mask=(%d, %d),kernel=%d, blend=%d, ca=%d, format=%x\n",
-	     __FUNCTION__, op->mask.bo != NULL,
+	     __FUNCTION__, op->u.gen4.ve_id & 2,
 	     op->src.filter, op->src.repeat,
 	     op->mask.filter, op->mask.repeat,
 	     kernel, blend, op->has_component_alpha, (int)op->dst.format));
@@ -1255,25 +1237,23 @@ gen4_emit_pipelined_pointers(struct sna *sna,
 	bp = gen4_get_blend(blend, op->has_component_alpha, op->dst.format);
 
 	DBG(("%s: sp=%d, bp=%d\n", __FUNCTION__, sp, bp));
-
-	key = sp | bp << 16;
+	key = sp | (uint32_t)bp << 16;
 	if (key == sna->render_state.gen4.last_pipelined_pointers)
-		return false;
+		return;
 
 	OUT_BATCH(GEN4_3DSTATE_PIPELINED_POINTERS | 5);
 	OUT_BATCH(sna->render_state.gen4.vs);
 	OUT_BATCH(GEN4_GS_DISABLE); /* passthrough */
 	OUT_BATCH(GEN4_CLIP_DISABLE); /* passthrough */
-	OUT_BATCH(sna->render_state.gen4.sf[op->mask.bo != NULL]);
+	OUT_BATCH(sna->render_state.gen4.sf[1]);
 	OUT_BATCH(sna->render_state.gen4.wm + sp);
 	OUT_BATCH(sna->render_state.gen4.cc + bp);
 
 	sna->render_state.gen4.last_pipelined_pointers = key;
 	gen4_emit_urb(sna);
-	return true;
 }
 
-static void
+static bool
 gen4_emit_drawing_rectangle(struct sna *sna, const struct sna_composite_op *op)
 {
 	uint32_t limit = (op->dst.height - 1) << 16 | (op->dst.width - 1);
@@ -1284,7 +1264,8 @@ gen4_emit_drawing_rectangle(struct sna *sna, const struct sna_composite_op *op)
 
 	if (sna->render_state.gen4.drawrect_limit == limit &&
 	    sna->render_state.gen4.drawrect_offset == offset)
-		return;
+		return true;
+
 	sna->render_state.gen4.drawrect_offset = offset;
 	sna->render_state.gen4.drawrect_limit = limit;
 
@@ -1292,6 +1273,7 @@ gen4_emit_drawing_rectangle(struct sna *sna, const struct sna_composite_op *op)
 	OUT_BATCH(0);
 	OUT_BATCH(limit);
 	OUT_BATCH(offset);
+	return false;
 }
 
 static void
@@ -1305,19 +1287,17 @@ gen4_emit_vertex_elements(struct sna *sna,
 	 *    texture coordinate 1 if (has_mask is true): same as above
 	 */
 	struct gen4_render_state *render = &sna->render_state.gen4;
-	bool has_mask = op->mask.bo != NULL;
-	int nelem = has_mask ? 2 : 1;
-	int selem;
+	int id = op->u.gen4.ve_id;
 	uint32_t w_component;
 	uint32_t src_format;
-	int id = op->u.gen4.ve_id;
+	int selem;
 
 	if (render->ve_id == id)
 		return;
 
 	render->ve_id = id;
 
-	if (op->is_affine) {
+	if (id & 1) {
 		src_format = GEN4_SURFACEFORMAT_R32G32_FLOAT;
 		w_component = GEN4_VFCOMPONENT_STORE_1_FLT;
 		selem = 2;
@@ -1332,7 +1312,7 @@ gen4_emit_vertex_elements(struct sna *sna,
 	 *    dword 4-7: texture coordinate 0 (u0, v0, w0, 1.0)
 	 *    [optional] dword 8-11: texture coordinate 1 (u1, v1, w1, 1.0)
 	 */
-	OUT_BATCH(GEN4_3DSTATE_VERTEX_ELEMENTS | (2 * (1 + nelem) - 1));
+	OUT_BATCH(GEN4_3DSTATE_VERTEX_ELEMENTS | (2 * (1 + 2) - 1));
 
 	/* x,y */
 	OUT_BATCH(id << VE0_VERTEX_BUFFER_INDEX_SHIFT | VE0_VALID |
@@ -1355,15 +1335,21 @@ gen4_emit_vertex_elements(struct sna *sna,
 		  (2*4) << VE1_DESTINATION_ELEMENT_OFFSET_SHIFT);       /* VUE offset in dwords */
 
 	/* u1, v1, w1 */
-	if (has_mask) {
-		OUT_BATCH(id << VE0_VERTEX_BUFFER_INDEX_SHIFT | VE0_VALID |
-			  src_format << VE0_FORMAT_SHIFT |
-			  ((1 + selem) * 4) << VE0_OFFSET_SHIFT); /* vb offset in bytes */
+	OUT_BATCH(id << VE0_VERTEX_BUFFER_INDEX_SHIFT | VE0_VALID |
+		  src_format << VE0_FORMAT_SHIFT |
+		  ((1 + selem) * 4) << VE0_OFFSET_SHIFT); /* vb offset in bytes */
+	if (id & 2) {
 		OUT_BATCH(GEN4_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_0_SHIFT |
 			  GEN4_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_1_SHIFT |
 			  w_component << VE1_VFCOMPONENT_2_SHIFT |
 			  GEN4_VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_3_SHIFT |
 			  (3*4) << VE1_DESTINATION_ELEMENT_OFFSET_SHIFT);       /* VUE offset in dwords */
+	} else {
+		OUT_BATCH(GEN4_VFCOMPONENT_STORE_0 << VE1_VFCOMPONENT_0_SHIFT |
+			  GEN4_VFCOMPONENT_STORE_0 << VE1_VFCOMPONENT_1_SHIFT |
+			  GEN4_VFCOMPONENT_STORE_0 << VE1_VFCOMPONENT_2_SHIFT |
+			  GEN4_VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_3_SHIFT |
+			  (3*4) << VE1_DESTINATION_ELEMENT_OFFSET_SHIFT);       /* VUE offset in dwords */
 	}
 }
 
@@ -1372,14 +1358,10 @@ gen4_emit_state(struct sna *sna,
 		const struct sna_composite_op *op,
 		uint16_t wm_binding_table)
 {
-	bool flush = false;
+	bool flush;
 
-	gen4_emit_drawing_rectangle(sna, op);
-	flush |= gen4_emit_binding_table(sna, wm_binding_table);
-	flush |= gen4_emit_pipelined_pointers(sna, op, op->op, op->u.gen4.wm_kernel);
-	gen4_emit_vertex_elements(sna, op);
-
-	if (flush || kgem_bo_is_dirty(op->src.bo) || kgem_bo_is_dirty(op->mask.bo)) {
+	flush = wm_binding_table & 1;
+	if (kgem_bo_is_dirty(op->src.bo) || kgem_bo_is_dirty(op->mask.bo)) {
 		DBG(("%s: flushing dirty (%d, %d), forced? %d\n", __FUNCTION__,
 		     kgem_bo_is_dirty(op->src.bo),
 		     kgem_bo_is_dirty(op->mask.bo),
@@ -1387,13 +1369,22 @@ gen4_emit_state(struct sna *sna,
 		OUT_BATCH(MI_FLUSH);
 		kgem_clear_dirty(&sna->kgem);
 		kgem_bo_mark_dirty(op->dst.bo);
+		flush = false;
 	}
+	flush &= gen4_emit_drawing_rectangle(sna, op);
+	if (flush && op->op > PictOpSrc)
+		OUT_BATCH(MI_FLUSH | MI_INHIBIT_RENDER_CACHE_FLUSH);
+
+	gen4_emit_binding_table(sna, wm_binding_table & ~1);
+	gen4_emit_pipelined_pointers(sna, op, op->op, op->u.gen4.wm_kernel);
+	gen4_emit_vertex_elements(sna, op);
 }
 
 static void
 gen4_bind_surfaces(struct sna *sna,
 		   const struct sna_composite_op *op)
 {
+	bool dirty = kgem_bo_is_dirty(op->dst.bo);
 	uint32_t *binding_table;
 	uint16_t offset;
 
@@ -1411,7 +1402,8 @@ gen4_bind_surfaces(struct sna *sna,
 			     op->src.bo, op->src.width, op->src.height,
 			     op->src.card_format,
 			     false);
-	if (op->mask.bo)
+	if (op->mask.bo) {
+		assert(op->u.gen4.ve_id & 2);
 		binding_table[2] =
 			gen4_bind_bo(sna,
 				     op->mask.bo,
@@ -1419,6 +1411,7 @@ gen4_bind_surfaces(struct sna *sna,
 				     op->mask.height,
 				     op->mask.card_format,
 				     false);
+	}
 
 	if (sna->kgem.surface == offset &&
 	    *(uint64_t *)(sna->kgem.batch + sna->render_state.gen4.surface_table) == *(uint64_t*)binding_table &&
@@ -1428,7 +1421,7 @@ gen4_bind_surfaces(struct sna *sna,
 		offset = sna->render_state.gen4.surface_table;
 	}
 
-	gen4_emit_state(sna, op, offset);
+	gen4_emit_state(sna, op, offset | dirty);
 }
 
 fastcall static void
@@ -1445,9 +1438,6 @@ gen4_render_composite_blt(struct sna *sna,
 
 	gen4_get_rectangles(sna, op, 1, gen4_bind_surfaces);
 	op->prim_emit(sna, op, r);
-
-	/* XXX are the shaders fubar? */
-	FLUSH(op);
 }
 
 fastcall static void
@@ -1457,13 +1447,19 @@ gen4_render_composite_box(struct sna *sna,
 {
 	struct sna_composite_rectangles r;
 
+	DBG(("  %s: (%d, %d), (%d, %d)\n",
+	     __FUNCTION__,
+	     box->x1, box->y1, box->x2, box->y2));
+
+	gen4_get_rectangles(sna, op, 1, gen4_bind_surfaces);
+
 	r.dst.x = box->x1;
 	r.dst.y = box->y1;
 	r.width  = box->x2 - box->x1;
 	r.height = box->y2 - box->y1;
 	r.mask = r.src = r.dst;
 
-	gen4_render_composite_blt(sna, op, &r);
+	op->prim_emit(sna, op, &r);
 }
 
 static void
@@ -1479,16 +1475,28 @@ gen4_render_composite_boxes(struct sna *sna,
 	     op->mask.width, op->mask.height));
 
 	do {
-		struct sna_composite_rectangles r;
-
-		r.dst.x = box->x1;
-		r.dst.y = box->y1;
-		r.width  = box->x2 - box->x1;
-		r.height = box->y2 - box->y1;
-		r.mask = r.src = r.dst;
-		gen4_render_composite_blt(sna, op, &r);
-		box++;
-	} while (--nbox);
+		int nbox_this_time;
+
+		nbox_this_time = gen4_get_rectangles(sna, op, nbox,
+						     gen4_bind_surfaces);
+		nbox -= nbox_this_time;
+
+		do {
+			struct sna_composite_rectangles r;
+
+			DBG(("  %s: (%d, %d), (%d, %d)\n",
+			     __FUNCTION__,
+			     box->x1, box->y1, box->x2, box->y2));
+
+			r.dst.x = box->x1;
+			r.dst.y = box->y1;
+			r.width  = box->x2 - box->x1;
+			r.height = box->y2 - box->y1;
+			r.mask = r.src = r.dst;
+			op->prim_emit(sna, op, &r);
+			box++;
+		} while (--nbox_this_time);
+	} while (nbox);
 }
 
 #ifndef MAX
@@ -1529,6 +1537,7 @@ static uint32_t gen4_bind_video_source(struct sna *sna,
 static void gen4_video_bind_surfaces(struct sna *sna,
 				     const struct sna_composite_op *op)
 {
+	bool dirty = kgem_bo_is_dirty(op->dst.bo);
 	struct sna_video_frame *frame = op->priv;
 	uint32_t src_surf_format;
 	uint32_t src_surf_base[6];
@@ -1590,7 +1599,7 @@ static void gen4_video_bind_surfaces(struct sna *sna,
 					       src_surf_format);
 	}
 
-	gen4_emit_state(sna, op, offset);
+	gen4_emit_state(sna, op, offset | dirty);
 }
 
 static bool
@@ -1685,8 +1694,6 @@ gen4_render_video(struct sna *sna,
 		OUT_VERTEX_F((box->x1 - dxo) * src_scale_x);
 		OUT_VERTEX_F((box->y1 - dyo) * src_scale_y);
 
-		_FLUSH();
-
 		if (!DAMAGE_IS_ALL(priv->gpu_damage)) {
 			sna_damage_add_box(&priv->gpu_damage, &r);
 			sna_damage_subtract_box(&priv->cpu_damage, &r);
@@ -2001,22 +2008,12 @@ picture_is_cpu(PicturePtr picture)
 	return !is_gpu(picture->pDrawable);
 }
 
-static inline bool prefer_blt(struct sna *sna)
-{
-#if PREFER_BLT
-	return true;
-	(void)sna;
-#else
-	return sna->kgem.mode != KGEM_RENDER;
-#endif
-}
-
 static bool
 try_blt(struct sna *sna,
 	PicturePtr dst, PicturePtr src,
 	int width, int height)
 {
-	if (prefer_blt(sna)) {
+	if (sna->kgem.mode != KGEM_RENDER) {
 		DBG(("%s: already performing BLT\n", __FUNCTION__));
 		return true;
 	}
@@ -2296,6 +2293,7 @@ gen4_render_composite(struct sna *sna,
 					   dst_x, dst_y, width, height))
 		return false;
 
+	tmp->op = op;
 	switch (gen4_composite_picture(sna, src, &tmp->src,
 				       src_x, src_y,
 				       width, height,
@@ -2319,7 +2317,6 @@ gen4_render_composite(struct sna *sna,
 		break;
 	}
 
-	tmp->op = op;
 	tmp->is_affine = tmp->src.is_affine;
 	tmp->has_component_alpha = false;
 	tmp->need_magic_ca_pass = false;
@@ -2558,8 +2555,6 @@ gen4_render_composite_spans_box(struct sna *sna,
 
 	gen4_get_rectangles(sna, &op->base, 1, gen4_bind_surfaces);
 	op->prim_emit(sna, op, box, opacity);
-
-	_FLUSH();
 }
 
 static void
@@ -2587,7 +2582,6 @@ gen4_render_composite_spans_done(struct sna *sna,
 
 	DBG(("%s()\n", __FUNCTION__));
 
-	kgem_bo_destroy(&sna->kgem, op->base.mask.bo);
 	if (op->base.src.bo)
 		kgem_bo_destroy(&sna->kgem, op->base.src.bo);
 
@@ -2681,9 +2675,7 @@ gen4_render_composite_spans(struct sna *sna,
 		break;
 	}
 
-	tmp->base.mask.bo = sna_render_get_solid(sna, 0);
-	if (tmp->base.mask.bo == NULL)
-		goto cleanup_src;
+	tmp->base.mask.bo = NULL;
 
 	tmp->base.is_affine = tmp->base.src.is_affine;
 	tmp->base.has_component_alpha = false;
@@ -2736,6 +2728,7 @@ cleanup_dst:
 static void
 gen4_copy_bind_surfaces(struct sna *sna, const struct sna_composite_op *op)
 {
+	bool dirty = kgem_bo_is_dirty(op->dst.bo);
 	uint32_t *binding_table;
 	uint16_t offset;
 
@@ -2760,7 +2753,7 @@ gen4_copy_bind_surfaces(struct sna *sna, const struct sna_composite_op *op)
 		offset = sna->render_state.gen4.surface_table;
 	}
 
-	gen4_emit_state(sna, op, offset);
+	gen4_emit_state(sna, op, offset | dirty);
 }
 
 static void
@@ -2783,8 +2776,6 @@ gen4_render_copy_one(struct sna *sna,
 	OUT_VERTEX(dx, dy);
 	OUT_VERTEX_F(sx*op->src.scale[0]);
 	OUT_VERTEX_F(sy*op->src.scale[1]);
-
-	_FLUSH();
 }
 
 static inline bool prefer_blt_copy(struct sna *sna, unsigned flags)
@@ -2973,6 +2964,16 @@ gen4_render_copy_done(struct sna *sna, const struct sna_copy_op *op)
 	gen4_vertex_flush(sna);
 }
 
+static inline bool prefer_blt_fill(struct sna *sna)
+{
+#if PREFER_BLT
+	return true;
+	(void)sna;
+#else
+	return sna->kgem.mode != KGEM_RENDER;
+#endif
+}
+
 static bool
 gen4_render_copy(struct sna *sna, uint8_t alu,
 		 PixmapPtr src, struct kgem_bo *src_bo,
@@ -2985,7 +2986,7 @@ gen4_render_copy(struct sna *sna, uint8_t alu,
 	     dst->drawable.serialNumber,
 	     alu));
 
-	if (prefer_blt(sna) &&
+	if (prefer_blt_fill(sna) &&
 	    sna_blt_compare_depth(&src->drawable, &dst->drawable) &&
 	    sna_blt_copy(sna, alu,
 			 src_bo, dst_bo,
@@ -3062,42 +3063,11 @@ fallback:
 }
 
 static void
-gen4_fill_bind_surfaces(struct sna *sna, const struct sna_composite_op *op)
-{
-	uint32_t *binding_table;
-	uint16_t offset;
-
-	gen4_get_batch(sna);
-
-	binding_table = gen4_composite_get_binding_table(sna, &offset);
-
-	binding_table[0] =
-		gen4_bind_bo(sna,
-			     op->dst.bo, op->dst.width, op->dst.height,
-			     gen4_get_dest_format(op->dst.format),
-			     true);
-	binding_table[1] =
-		gen4_bind_bo(sna,
-			     op->src.bo, 1, 1,
-			     GEN4_SURFACEFORMAT_B8G8R8A8_UNORM,
-			     false);
-
-	if (sna->kgem.surface == offset &&
-	    *(uint64_t *)(sna->kgem.batch + sna->render_state.gen4.surface_table) == *(uint64_t*)binding_table) {
-		sna->kgem.surface +=
-			sizeof(struct gen4_surface_state_padded)/sizeof(uint32_t);
-		offset = sna->render_state.gen4.surface_table;
-	}
-
-	gen4_emit_state(sna, op, offset);
-}
-
-static void
 gen4_render_fill_rectangle(struct sna *sna,
 			   const struct sna_composite_op *op,
 			   int x, int y, int w, int h)
 {
-	gen4_get_rectangles(sna, op, 1, gen4_fill_bind_surfaces);
+	gen4_get_rectangles(sna, op, 1, gen4_bind_surfaces);
 
 	OUT_VERTEX(x+w, y+h);
 	OUT_VERTEX_F(1);
@@ -3110,8 +3080,6 @@ gen4_render_fill_rectangle(struct sna *sna,
 	OUT_VERTEX(x, y);
 	OUT_VERTEX_F(0);
 	OUT_VERTEX_F(0);
-
-	_FLUSH();
 }
 
 static bool
@@ -3132,7 +3100,7 @@ gen4_render_fill_boxes(struct sna *sna,
 	}
 
 	if (op <= PictOpSrc &&
-	    (prefer_blt(sna) ||
+	    (prefer_blt_fill(sna) ||
 	     too_large(dst->drawable.width, dst->drawable.height) ||
 	     !gen4_check_dst_format(format))) {
 		uint8_t alu = GXinvalid;
@@ -3185,9 +3153,7 @@ gen4_render_fill_boxes(struct sna *sna,
 	tmp.dst.format = format;
 	tmp.dst.bo = dst_bo;
 
-	tmp.src.bo = sna_render_get_solid(sna, pixel);
-	tmp.src.filter = SAMPLER_FILTER_NEAREST;
-	tmp.src.repeat = SAMPLER_EXTEND_REPEAT;
+	gen4_composite_solid_init(sna, &tmp.src, pixel);
 
 	tmp.is_affine = true;
 	tmp.floats_per_vertex = 3;
@@ -3200,7 +3166,7 @@ gen4_render_fill_boxes(struct sna *sna,
 		assert(kgem_check_bo(&sna->kgem, dst_bo, NULL));
 	}
 
-	gen4_fill_bind_surfaces(sna, &tmp);
+	gen4_bind_surfaces(sna, &tmp);
 	gen4_align_vertex(sna, &tmp);
 
 	do {
@@ -3260,7 +3226,7 @@ gen4_render_fill(struct sna *sna, uint8_t alu,
 		 uint32_t color,
 		 struct sna_fill_op *op)
 {
-	if (prefer_blt(sna) &&
+	if (prefer_blt_fill(sna) &&
 	    sna_blt_fill(sna, alu,
 			 dst_bo, dst->drawable.bitsPerPixel,
 			 color,
@@ -3289,16 +3255,10 @@ gen4_render_fill(struct sna *sna, uint8_t alu,
 	op->base.need_magic_ca_pass = 0;
 	op->base.has_component_alpha = 0;
 
-	op->base.src.bo =
-		sna_render_get_solid(sna,
-				     sna_rgba_for_color(color,
-							dst->drawable.depth));
-	op->base.src.filter = SAMPLER_FILTER_NEAREST;
-	op->base.src.repeat = SAMPLER_EXTEND_REPEAT;
-
+	gen4_composite_solid_init(sna, &op->base.src,
+				  sna_rgba_for_color(color,
+						     dst->drawable.depth));
 	op->base.mask.bo = NULL;
-	op->base.mask.filter = SAMPLER_FILTER_NEAREST;
-	op->base.mask.repeat = SAMPLER_EXTEND_NONE;
 
 	op->base.is_affine = true;
 	op->base.floats_per_vertex = 3;
@@ -3311,7 +3271,7 @@ gen4_render_fill(struct sna *sna, uint8_t alu,
 		assert(kgem_check_bo(&sna->kgem, dst_bo, NULL));
 	}
 
-	gen4_fill_bind_surfaces(sna, &op->base);
+	gen4_bind_surfaces(sna, &op->base);
 	gen4_align_vertex(sna, &op->base);
 
 	op->blt   = gen4_render_fill_op_blt;
@@ -3371,21 +3331,15 @@ gen4_render_fill_one(struct sna *sna, PixmapPtr dst, struct kgem_bo *bo,
 	tmp.dst.bo = bo;
 	tmp.dst.x = tmp.dst.y = 0;
 
-	tmp.src.bo =
-		sna_render_get_solid(sna,
-				     sna_rgba_for_color(color,
-							dst->drawable.depth));
-	tmp.src.filter = SAMPLER_FILTER_NEAREST;
-	tmp.src.repeat = SAMPLER_EXTEND_REPEAT;
-
+	gen4_composite_solid_init(sna, &tmp.src,
+				  sna_rgba_for_color(color,
+						     dst->drawable.depth));
 	tmp.mask.bo = NULL;
-	tmp.mask.filter = SAMPLER_FILTER_NEAREST;
-	tmp.mask.repeat = SAMPLER_EXTEND_NONE;
 
 	tmp.is_affine = true;
 	tmp.floats_per_vertex = 3;
 	tmp.floats_per_rect = 9;
-	tmp.has_component_alpha = 0;
+	tmp.has_component_alpha = false;
 	tmp.need_magic_ca_pass = false;
 
 	tmp.u.gen4.wm_kernel = WM_KERNEL;
@@ -3396,7 +3350,7 @@ gen4_render_fill_one(struct sna *sna, PixmapPtr dst, struct kgem_bo *bo,
 		assert(kgem_check_bo(&sna->kgem, bo, NULL));
 	}
 
-	gen4_fill_bind_surfaces(sna, &tmp);
+	gen4_bind_surfaces(sna, &tmp);
 	gen4_align_vertex(sna, &tmp);
 
 	gen4_render_fill_rectangle(sna, &tmp, x1, y1, x2 - x1, y2 - y1);
@@ -3488,7 +3442,7 @@ static uint32_t gen4_create_vs_unit_state(struct sna_static_stream *stream)
 }
 
 static uint32_t gen4_create_sf_state(struct sna_static_stream *stream,
-				     uint32_t kernel)
+				     int gen, uint32_t kernel)
 {
 	struct gen4_sf_unit_state *sf;
 
@@ -3533,6 +3487,7 @@ static uint32_t gen4_create_sampler_state(struct sna_static_stream *stream,
 }
 
 static void gen4_init_wm_state(struct gen4_wm_unit_state *wm,
+			       int gen,
 			       bool has_mask,
 			       uint32_t kernel,
 			       uint32_t sampler)
@@ -3553,7 +3508,7 @@ static void gen4_init_wm_state(struct gen4_wm_unit_state *wm,
 	wm->wm4.sampler_state_pointer = sampler >> 5;
 	wm->wm4.sampler_count = 1;
 
-	wm->wm5.max_threads = GEN4_MAX_WM_THREADS - 1;
+	wm->wm5.max_threads = gen >= 045 ? G4X_MAX_WM_THREADS - 1 : GEN4_MAX_WM_THREADS - 1;
 	wm->wm5.transposed_urb_read = 0;
 	wm->wm5.thread_dispatch_enable = 1;
 	/* just use 16-pixel dispatch (4 subspans), don't need to change kernel
@@ -3655,8 +3610,8 @@ static bool gen4_render_setup(struct sna *sna)
 	}
 
 	state->vs = gen4_create_vs_unit_state(&general);
-	state->sf[0] = gen4_create_sf_state(&general, sf[0]);
-	state->sf[1] = gen4_create_sf_state(&general, sf[1]);
+	state->sf[0] = gen4_create_sf_state(&general, sna->kgem.gen, sf[0]);
+	state->sf[1] = gen4_create_sf_state(&general, sna->kgem.gen, sf[1]);
 
 	wm_state = sna_static_stream_map(&general,
 					  sizeof(*wm_state) * KERNEL_COUNT *
@@ -3677,6 +3632,7 @@ static bool gen4_render_setup(struct sna *sna)
 
 					for (m = 0; m < KERNEL_COUNT; m++) {
 						gen4_init_wm_state(&wm_state->state,
+								   sna->kgem.gen,
 								   wm_kernels[m].has_mask,
 								   wm[m], sampler_state);
 						wm_state++;
diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c
index ca28b06..b7030cd 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -14285,9 +14285,6 @@ bool sna_accel_init(ScreenPtr screen, struct sna *sna)
 	} else if (sna->info->gen >= 050) {
 		if ((sna->have_render = gen5_render_init(sna)))
 			backend = "Ironlake";
-	} else if (sna->info->gen >= 045) {
-		if ((sna->have_render = g4x_render_init(sna)))
-			backend = "Eaglelake/Cantiga";
 	} else if (sna->info->gen >= 040) {
 		if ((sna->have_render = gen4_render_init(sna)))
 			backend = "Broadwater/Crestline";
diff --git a/src/sna/sna_glyphs.c b/src/sna/sna_glyphs.c
index f6c6816..f068f22 100644
--- a/src/sna/sna_glyphs.c
+++ b/src/sna/sna_glyphs.c
@@ -1091,7 +1091,7 @@ next_image:
 					     (int)this_atlas->format,
 					     (int)(format->depth << 24 | format->format)));
 					if (this_atlas->format == (format->depth << 24 | format->format) &&
-					    sna->kgem.gen != 045) { /* XXX cache corruption? how? */
+					    (sna->kgem.gen >> 3) != 4) { /* XXX cache corruption? how? */
 						ok = sna->render.composite(sna, PictOpAdd,
 									   this_atlas, NULL, mask,
 									   0, 0, 0, 0, 0, 0,
diff --git a/src/sna/sna_render.h b/src/sna/sna_render.h
index e9ec2ba..e056e3f 100644
--- a/src/sna/sna_render.h
+++ b/src/sna/sna_render.h
@@ -524,7 +524,6 @@ void no_render_init(struct sna *sna);
 bool gen2_render_init(struct sna *sna);
 bool gen3_render_init(struct sna *sna);
 bool gen4_render_init(struct sna *sna);
-bool g4x_render_init(struct sna *sna);
 bool gen5_render_init(struct sna *sna);
 bool gen6_render_init(struct sna *sna);
 bool gen7_render_init(struct sna *sna);
commit 5d6dd9c5a7eeb1f879525430ad89ab74d427e469
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Fri Nov 30 12:12:49 2012 +0000

    Convert generation counter to octal
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/i965_3d.c b/src/i965_3d.c
index a18db12..fe2d9aa 100644
--- a/src/i965_3d.c
+++ b/src/i965_3d.c
@@ -35,7 +35,7 @@
 void
 gen6_upload_invariant_states(intel_screen_private *intel)
 {
-	Bool ivb = INTEL_INFO(intel)->gen >= 70;
+	Bool ivb = INTEL_INFO(intel)->gen >= 070;
 
 	OUT_BATCH(BRW_PIPE_CONTROL | (4 - 2));
 	OUT_BATCH(BRW_PIPE_CONTROL_IS_FLUSH |
@@ -280,7 +280,7 @@ gen7_upload_bypass_states(intel_screen_private *intel)
 void
 gen6_upload_vs_state(intel_screen_private *intel)
 {
-	Bool ivb = INTEL_INFO(intel)->gen >= 70;
+	Bool ivb = INTEL_INFO(intel)->gen >= 070;
 	/* disable VS constant buffer */
 	OUT_BATCH(GEN6_3DSTATE_CONSTANT_VS | ((ivb ? 7 : 5) - 2));
 	OUT_BATCH(0);
diff --git a/src/i965_render.c b/src/i965_render.c
index 42b1959..39698b0 100644
--- a/src/i965_render.c
+++ b/src/i965_render.c
@@ -1054,7 +1054,7 @@ i965_create_sampler_state(intel_screen_private *intel,
 			  sampler_state_extend_t mask_extend,
 			  drm_intel_bo * border_color_bo)
 {
-	if (INTEL_INFO(intel)->gen < 70)
+	if (INTEL_INFO(intel)->gen < 070)
 		return gen4_create_sampler_state(intel, src_filter, src_extend,
 						 mask_filter, mask_extend,
 						 border_color_bo);
@@ -1417,7 +1417,7 @@ i965_set_picture_surface_state(intel_screen_private *intel,
 			       PicturePtr picture, PixmapPtr pixmap,
 			       Bool is_dst)
 {
-    if (INTEL_INFO(intel)->gen < 70)
+    if (INTEL_INFO(intel)->gen < 070)
         return gen4_set_picture_surface_state(intel, picture, pixmap, is_dst);
     return gen7_set_picture_surface_state(intel, picture, pixmap, is_dst);
 }
@@ -1571,7 +1571,7 @@ static void i965_emit_composite_state(struct intel_screen_private *intel)
 		}
 
 		/* Match Mesa driver setup */
-		if (INTEL_INFO(intel)->gen >= 45)
+		if (INTEL_INFO(intel)->gen >= 045)
 			OUT_BATCH(NEW_PIPELINE_SELECT | PIPELINE_SELECT_3D);
 		else
 			OUT_BATCH(BRW_PIPELINE_SELECT | PIPELINE_SELECT_3D);
@@ -1751,7 +1751,7 @@ static Bool i965_composite_check_aperture(intel_screen_private *intel)
 		render_state->gen6_depth_stencil_bo,
 	};
 
-	if (INTEL_INFO(intel)->gen >= 60)
+	if (INTEL_INFO(intel)->gen >= 060)
 		return drm_intel_bufmgr_check_aperture_space(gen6_bo_table,
 							ARRAY_SIZE(gen6_bo_table)) == 0;
 	else
@@ -2181,7 +2181,7 @@ static void i965_select_vertex_buffer(struct intel_screen_private *intel)
 	if (intel->vertex_id & (1 << id))
 		return;
 
-	if (INTEL_INFO(intel)->gen >= 70)
+	if (INTEL_INFO(intel)->gen >= 070)
 		modifyenable = GEN7_VB0_ADDRESS_MODIFYENABLE;
 
 	/* Set up the pointer to our (single) vertex buffer */
@@ -2190,7 +2190,7 @@ static void i965_select_vertex_buffer(struct intel_screen_private *intel)
 	/* XXX could use multiple vbo to reduce relocations if
 	 * frequently switching between vertex sizes, like rgb10text.
 	 */
-	if (INTEL_INFO(intel)->gen >= 60) {
+	if (INTEL_INFO(intel)->gen >= 060) {
 		OUT_BATCH((id << GEN6_VB0_BUFFER_INDEX_SHIFT) |
 			  GEN6_VB0_VERTEXDATA |
 			  modifyenable |
@@ -2201,7 +2201,7 @@ static void i965_select_vertex_buffer(struct intel_screen_private *intel)
 			  (4*intel->floats_per_vertex << VB0_BUFFER_PITCH_SHIFT));
 	}
 	OUT_RELOC(intel->vertex_bo, I915_GEM_DOMAIN_VERTEX, 0, 0);
-	if (INTEL_INFO(intel)->gen >= 50)
+	if (INTEL_INFO(intel)->gen >= 050)
 		OUT_RELOC(intel->vertex_bo,
 			  I915_GEM_DOMAIN_VERTEX, 0,
 			  sizeof(intel->vertex_ptr) - 1);
@@ -2252,7 +2252,7 @@ i965_composite(PixmapPtr dest, int srcX, int srcY, int maskX, int maskY,
 	if (intel->needs_render_state_emit) {
 		i965_bind_surfaces(intel);
 
-		if (INTEL_INFO(intel)->gen >= 60)
+		if (INTEL_INFO(intel)->gen >= 060)
 			gen6_emit_composite_state(intel);
 		else
 			i965_emit_composite_state(intel);
@@ -2271,7 +2271,7 @@ i965_composite(PixmapPtr dest, int srcX, int srcY, int maskX, int maskY,
 	i965_select_vertex_buffer(intel);
 
 	if (intel->vertex_offset == 0) {
-		if (INTEL_INFO(intel)->gen >= 70) {
+		if (INTEL_INFO(intel)->gen >= 070) {
 			OUT_BATCH(BRW_3DPRIMITIVE | (7 - 2));
 			OUT_BATCH(BRW_3DPRIMITIVE_VERTEX_SEQUENTIAL |
 				  _3DPRIM_RECTLIST);
@@ -2298,7 +2298,7 @@ i965_composite(PixmapPtr dest, int srcX, int srcY, int maskX, int maskY,
 			 w, h);
 	intel->vertex_index += 3;
 
-	if (INTEL_INFO(intel)->gen < 50) {
+	if (INTEL_INFO(intel)->gen < 050) {
 	    /* XXX OMG! */
 	    i965_vertex_flush(intel);
 	    OUT_BATCH(MI_FLUSH | MI_INHIBIT_RENDER_CACHE_FLUSH);
@@ -2355,7 +2355,7 @@ void gen4_render_state_init(ScrnInfoPtr scrn)
 		assert(intel->gen4_render_state != NULL);
 	}
 
-	if (INTEL_INFO(intel)->gen >= 60)
+	if (INTEL_INFO(intel)->gen >= 060)
 		return gen6_render_state_init(scrn);
 
 	render = intel->gen4_render_state;
@@ -2601,7 +2601,7 @@ gen6_composite_cc_state_pointers(intel_screen_private *intel,
 		cc_bo = render_state->cc_state_bo;
 		depth_stencil_bo = render_state->gen6_depth_stencil_bo;
 	}
-	if (INTEL_INFO(intel)->gen >= 70) {
+	if (INTEL_INFO(intel)->gen >= 070) {
 		gen7_upload_cc_state_pointers(intel, render_state->gen6_blend_bo, cc_bo, depth_stencil_bo, blend_offset);
 	} else {
 		gen6_upload_cc_state_pointers(intel, render_state->gen6_blend_bo, cc_bo, depth_stencil_bo, blend_offset);
@@ -2619,7 +2619,7 @@ gen6_composite_sampler_state_pointers(intel_screen_private *intel,
 
 	intel->gen6_render_state.samplers = bo;
 
-	if (INTEL_INFO(intel)->gen >= 70)
+	if (INTEL_INFO(intel)->gen >= 070)
 		gen7_upload_sampler_state_pointers(intel, bo);
 	else
 		gen6_upload_sampler_state_pointers(intel, bo);
@@ -2628,7 +2628,7 @@ gen6_composite_sampler_state_pointers(intel_screen_private *intel,
 static void
 gen6_composite_wm_constants(intel_screen_private *intel)
 {
-	Bool ivb = INTEL_INFO(intel)->gen >= 70;
+	Bool ivb = INTEL_INFO(intel)->gen >= 070;
 	/* disable WM constant buffer */
 	OUT_BATCH(GEN6_3DSTATE_CONSTANT_PS | ((ivb ? 7 : 5) - 2));
 	OUT_BATCH(0);
@@ -2652,7 +2652,7 @@ gen6_composite_sf_state(intel_screen_private *intel,
 
 	intel->gen6_render_state.num_sf_outputs = num_sf_outputs;
 
-	if (INTEL_INFO(intel)->gen >= 70)
+	if (INTEL_INFO(intel)->gen >= 070)
 		gen7_upload_sf_state(intel, num_sf_outputs, 1);
 	else
 		gen6_upload_sf_state(intel, num_sf_outputs, 1);
@@ -2839,7 +2839,7 @@ gen6_emit_composite_state(struct intel_screen_private *intel)
 	sampler_state_extend_t mask_extend = composite_op->mask_extend;
 	Bool is_affine = composite_op->is_affine;
 	Bool has_mask = intel->render_mask != NULL;
-	Bool ivb = INTEL_INFO(intel)->gen >= 70;
+	Bool ivb = INTEL_INFO(intel)->gen >= 070;
 	uint32_t src, dst;
 	drm_intel_bo *ps_sampler_state_bo = render->ps_sampler_state_bo[src_filter][src_extend][mask_filter][mask_extend];
 
diff --git a/src/i965_video.c b/src/i965_video.c
index 3276788..65f6061 100644
--- a/src/i965_video.c
+++ b/src/i965_video.c
@@ -897,7 +897,7 @@ i965_emit_video_setup(ScrnInfoPtr scrn, drm_intel_bo * surface_state_binding_tab
 
 	/* brw_debug (scrn, "before base address modify"); */
 	/* Match Mesa driver setup */
-	if (INTEL_INFO(intel)->gen >= 45)
+	if (INTEL_INFO(intel)->gen >= 045)
 		OUT_BATCH(NEW_PIPELINE_SELECT | PIPELINE_SELECT_3D);
 	else
 		OUT_BATCH(BRW_PIPELINE_SELECT | PIPELINE_SELECT_3D);
@@ -1428,7 +1428,7 @@ gen6_create_vidoe_objects(ScrnInfoPtr scrn)
 	const uint32_t *packed_ps_kernel, *planar_ps_kernel;
 	unsigned int packed_ps_size, planar_ps_size;
 	
-	if (INTEL_INFO(intel)->gen >= 70) {
+	if (INTEL_INFO(intel)->gen >= 070) {
 		create_sampler_state = gen7_create_sampler_state;
 		packed_ps_kernel = &ps_kernel_packed_static_gen7[0][0];
 		packed_ps_size = sizeof(ps_kernel_packed_static_gen7);
@@ -1787,7 +1787,7 @@ void Gen6DisplayVideoTextured(ScrnInfoPtr scrn,
 				PixmapPtr,
 				drm_intel_bo *, uint32_t);
 
-	if (INTEL_INFO(intel)->gen >= 70) {
+	if (INTEL_INFO(intel)->gen >= 070) {
 		create_dst_surface_state = gen7_create_dst_surface_state;
 		create_src_surface_state = gen7_create_src_surface_state;
 		emit_video_setup = gen7_emit_video_setup;
diff --git a/src/intel_batchbuffer.c b/src/intel_batchbuffer.c
index 46f22bc..334deb7 100644
--- a/src/intel_batchbuffer.c
+++ b/src/intel_batchbuffer.c
@@ -162,7 +162,7 @@ void intel_batch_emit_flush(ScrnInfoPtr scrn)
 	assert (!intel->in_batch_atomic);
 
 	/* Big hammer, look to the pipelined flushes in future. */
-	if ((INTEL_INFO(intel)->gen >= 60)) {
+	if ((INTEL_INFO(intel)->gen >= 060)) {
 		if (intel->current_batch == BLT_BATCH) {
 			BEGIN_BATCH_BLT(4);
 			OUT_BATCH(MI_FLUSH_DW | 2);
@@ -171,7 +171,7 @@ void intel_batch_emit_flush(ScrnInfoPtr scrn)
 			OUT_BATCH(0);
 			ADVANCE_BATCH();
 		} else  {
-			if ((INTEL_INFO(intel)->gen == 60)) {
+			if ((INTEL_INFO(intel)->gen == 060)) {
 				/* HW-Workaround for Sandybdrige */
 				intel_emit_post_sync_nonzero_flush(scrn);
 			} else {
@@ -187,7 +187,7 @@ void intel_batch_emit_flush(ScrnInfoPtr scrn)
 		}
 	} else {
 		flags = MI_WRITE_DIRTY_STATE | MI_INVALIDATE_MAP_CACHE;
-		if (INTEL_INFO(intel)->gen >= 40)
+		if (INTEL_INFO(intel)->gen >= 040)
 			flags = 0;
 
 		BEGIN_BATCH(1);
diff --git a/src/intel_dri.c b/src/intel_dri.c
index 4c0827d..25a7b9e 100644
--- a/src/intel_dri.c
+++ b/src/intel_dri.c
@@ -451,7 +451,7 @@ I830DRI2CopyRegion(DrawablePtr drawable, RegionPtr pRegion,
 	/* Wait for the scanline to be outside the region to be copied */
 	if (scrn->vtSema &&
 	    pixmap_is_scanout(get_drawable_pixmap(dst)) &&
-	    intel->swapbuffers_wait && INTEL_INFO(intel)->gen < 60) {
+	    intel->swapbuffers_wait && INTEL_INFO(intel)->gen < 060) {
 		BoxPtr box;
 		BoxRec crtcbox;
 		int y1, y2;
@@ -485,20 +485,20 @@ I830DRI2CopyRegion(DrawablePtr drawable, RegionPtr pRegion,
 			 * of extra time for the blitter to start up and
 			 * do its job for a full height blit
 			 */
-			if (full_height && INTEL_INFO(intel)->gen < 40)
+			if (full_height && INTEL_INFO(intel)->gen < 040)
 			    y2 -= 2;
 
 			if (pipe == 0) {
 				event = MI_WAIT_FOR_PIPEA_SCAN_LINE_WINDOW;
 				load_scan_lines_pipe =
 				    MI_LOAD_SCAN_LINES_DISPLAY_PIPEA;
-				if (full_height && INTEL_INFO(intel)->gen >= 40)
+				if (full_height && INTEL_INFO(intel)->gen >= 040)
 				    event = MI_WAIT_FOR_PIPEA_SVBLANK;
 			} else {
 				event = MI_WAIT_FOR_PIPEB_SCAN_LINE_WINDOW;
 				load_scan_lines_pipe =
 				    MI_LOAD_SCAN_LINES_DISPLAY_PIPEB;
-				if (full_height && INTEL_INFO(intel)->gen >= 40)
+				if (full_height && INTEL_INFO(intel)->gen >= 040)
 				    event = MI_WAIT_FOR_PIPEB_SVBLANK;
 			}
 
@@ -1513,7 +1513,7 @@ static const char *dri_driver_name(intel_screen_private *intel)
 	Bool dummy;
 
 	if (s == NULL || xf86getBoolValue(&dummy, s))
-		return INTEL_INFO(intel)->gen < 40 ? "i915" : "i965";
+		return INTEL_INFO(intel)->gen < 040 ? "i915" : "i965";
 
 	return s;
 }
diff --git a/src/intel_driver.c b/src/intel_driver.c
index 254aafa..5a176dc 100644
--- a/src/intel_driver.c
+++ b/src/intel_driver.c
@@ -325,7 +325,7 @@ static int intel_init_bufmgr(intel_screen_private *intel)
 
 	list_init(&intel->batch_pixmaps);
 
-	if ((INTEL_INFO(intel)->gen == 60)) {
+	if ((INTEL_INFO(intel)->gen == 060)) {
 		intel->wa_scratch_bo =
 			drm_intel_bo_alloc(intel->bufmgr, "wa scratch",
 					   4096, 4096);
@@ -411,7 +411,7 @@ static Bool can_accelerate_blt(struct intel_screen_private *intel)
 		return FALSE;
 	}
 
-	if (INTEL_INFO(intel)->gen == 60) {
+	if (INTEL_INFO(intel)->gen == 060) {
 		struct pci_device *const device = intel->PciInfo;
 
 		/* Sandybridge rev07 locks up easily, even with the
@@ -426,7 +426,7 @@ static Bool can_accelerate_blt(struct intel_screen_private *intel)
 		}
 	}
 
-	if (INTEL_INFO(intel)->gen >= 60) {
+	if (INTEL_INFO(intel)->gen >= 060) {
 		drm_i915_getparam_t gp;
 		int value;
 
@@ -587,7 +587,7 @@ static Bool I830PreInit(ScrnInfoPtr scrn, int flags)
 	intel->has_relaxed_fencing =
 		xf86ReturnOptValBool(intel->Options,
 				     OPTION_RELAXED_FENCING,
-				     INTEL_INFO(intel)->gen >= 33);
+				     INTEL_INFO(intel)->gen >= 033);
 	/* And override the user if there is no kernel support */
 	if (intel->has_relaxed_fencing)
 		intel->has_relaxed_fencing = has_relaxed_fencing(intel);
@@ -929,7 +929,7 @@ I830ScreenInit(SCREEN_INIT_ARGS_DECL)
 
 	intel_batch_init(scrn);
 
-	if (INTEL_INFO(intel)->gen >= 40)
+	if (INTEL_INFO(intel)->gen >= 040)
 		gen4_render_state_init(scrn);
 
 	miClearVisualTypes();
@@ -1022,7 +1022,7 @@ I830ScreenInit(SCREEN_INIT_ARGS_DECL)
 	xf86DPMSInit(screen, xf86DPMSSet, 0);
 
 #ifdef INTEL_XVMC
-	if (INTEL_INFO(intel)->gen >= 40)
+	if (INTEL_INFO(intel)->gen >= 040)
 		intel->XvMCEnabled = TRUE;
 	from = ((intel->directRenderingType == DRI_DRI2) &&
 		xf86GetOptValBool(intel->Options, OPTION_XVMC,
@@ -1184,7 +1184,7 @@ static Bool I830CloseScreen(CLOSE_SCREEN_ARGS_DECL)
 
 	intel_batch_teardown(scrn);
 
-	if (INTEL_INFO(intel)->gen >= 40)
+	if (INTEL_INFO(intel)->gen >= 040)
 		gen4_render_state_cleanup(scrn);
 
 	xf86_cursors_fini(screen);
diff --git a/src/intel_driver.h b/src/intel_driver.h
index b719062..b77b8d1 100644
--- a/src/intel_driver.h
+++ b/src/intel_driver.h
@@ -249,7 +249,7 @@
 #define CHIP_REVISION(p)  (p)->revision
 
 #define INTEL_INFO(intel) ((intel)->info)
-#define IS_GENx(intel, X) (INTEL_INFO(intel)->gen >= 10*(X) && INTEL_INFO(intel)->gen < 10*((X)+1))
+#define IS_GENx(intel, X) (INTEL_INFO(intel)->gen >= 8*(X) && INTEL_INFO(intel)->gen < 8*((X)+1))
 #define IS_GEN1(intel) IS_GENx(intel, 1)
 #define IS_GEN2(intel) IS_GENx(intel, 2)
 #define IS_GEN3(intel) IS_GENx(intel, 3)
@@ -257,7 +257,7 @@
 #define IS_GEN5(intel) IS_GENx(intel, 5)
 #define IS_GEN6(intel) IS_GENx(intel, 6)
 #define IS_GEN7(intel) IS_GENx(intel, 7)
-#define IS_HSW(intel) (INTEL_INFO(intel)->gen == 75)
+#define IS_HSW(intel) (INTEL_INFO(intel)->gen == 075)
 
 /* Some chips have specific errata (or limits) that we need to workaround. */
 #define IS_I830(intel) (DEVICE_ID((intel)->PciInfo) == PCI_CHIP_I830_M)
@@ -270,8 +270,8 @@
 #define IS_965_Q(pI810) (DEVICE_ID(pI810->PciInfo) == PCI_CHIP_I965_Q)
 
 /* supports Y tiled surfaces (pre-965 Mesa isn't ready yet) */
-#define SUPPORTS_YTILING(pI810) (INTEL_INFO(intel)->gen >= 40)
-#define HAS_BLT(pI810) (INTEL_INFO(intel)->gen >= 60)
+#define SUPPORTS_YTILING(pI810) (INTEL_INFO(intel)->gen >= 040)
+#define HAS_BLT(pI810) (INTEL_INFO(intel)->gen >= 060)
 
 struct intel_device_info {
 	int gen;
diff --git a/src/intel_hwmc.c b/src/intel_hwmc.c
index af8bd81..25978d2 100644
--- a/src/intel_hwmc.c
+++ b/src/intel_hwmc.c
@@ -75,11 +75,11 @@ static int create_context(ScrnInfoPtr scrn, XvMCContextPtr pContext,
 		contextRec->type = XVMC_I915_MPEG2_MC;
 		contextRec->i915.use_phys_addr = 0;
 	} else {
-		if (INTEL_INFO(intel)->gen >= 45)
+		if (INTEL_INFO(intel)->gen >= 045)
 			contextRec->type = XVMC_I965_MPEG2_VLD;
 		else
 			contextRec->type = XVMC_I965_MPEG2_MC;
-		contextRec->i965.is_g4x = INTEL_INFO(intel)->gen == 45;
+		contextRec->i965.is_g4x = INTEL_INFO(intel)->gen == 045;
 		contextRec->i965.is_965_q = IS_965_Q(intel);
 		contextRec->i965.is_igdng = IS_GEN5(intel);
 	}
@@ -227,7 +227,7 @@ Bool intel_xvmc_adaptor_init(ScreenPtr pScreen)
 		name = "i915_xvmc",
 		pAdapt->num_surfaces = ARRAY_SIZE(surface_info_i915);
 		pAdapt->surfaces = surface_info_i915;
-	} else if (INTEL_INFO(intel)->gen >= 45) {
+	} else if (INTEL_INFO(intel)->gen >= 045) {
 		name = "xvmc_vld",
 		pAdapt->num_surfaces = ARRAY_SIZE(surface_info_vld);
 		pAdapt->surfaces = surface_info_vld;
diff --git a/src/intel_memory.c b/src/intel_memory.c
index f08ebdd..e51fa33 100644
--- a/src/intel_memory.c
+++ b/src/intel_memory.c
@@ -94,7 +94,7 @@ unsigned long intel_get_fence_size(intel_screen_private *intel, unsigned long si
 	unsigned long i;
 	unsigned long start;
 
-	if (INTEL_INFO(intel)->gen >= 40 || intel->has_relaxed_fencing) {
+	if (INTEL_INFO(intel)->gen >= 040 || intel->has_relaxed_fencing) {
 		/* The 965 can have fences at any page boundary. */
 		return ALIGN(size, 4096);
 	} else {
@@ -127,7 +127,7 @@ intel_get_fence_pitch(intel_screen_private *intel, unsigned long pitch,
 		return pitch;
 
 	/* 965+ is flexible */
-	if (INTEL_INFO(intel)->gen >= 40)
+	if (INTEL_INFO(intel)->gen >= 040)
 		return ALIGN(pitch, tile_width);
 
 	/* Pre-965 needs power of two tile width */
@@ -173,7 +173,7 @@ static inline int intel_pad_drawable_width(int width)
 static size_t
 agp_aperture_size(struct pci_device *dev, int gen)
 {
-	return dev->regions[gen < 30 ? 0 : 2].size;
+	return dev->regions[gen < 030 ? 0 : 2].size;
 }
 
 static void intel_set_gem_max_sizes(ScrnInfoPtr scrn)
diff --git a/src/intel_module.c b/src/intel_module.c
index 08c9696..62076e1 100644
--- a/src/intel_module.c
+++ b/src/intel_module.c
@@ -56,59 +56,59 @@ static const struct intel_device_info intel_generic_info = {
 };
 
 static const struct intel_device_info intel_i81x_info = {
-	.gen = 10,
+	.gen = 010,
 };
 
 static const struct intel_device_info intel_i830_info = {
-	.gen = 20,
+	.gen = 020,
 };
 static const struct intel_device_info intel_i845_info = {
-	.gen = 20,
+	.gen = 020,
 };
 static const struct intel_device_info intel_i855_info = {
-	.gen = 21,
+	.gen = 021,
 };
 static const struct intel_device_info intel_i865_info = {
-	.gen = 22,
+	.gen = 022,
 };
 
 static const struct intel_device_info intel_i915_info = {
-	.gen = 30,
+	.gen = 030,
 };
 static const struct intel_device_info intel_i945_info = {
-	.gen = 31,
+	.gen = 031,
 };
 
 static const struct intel_device_info intel_g33_info = {
-	.gen = 33,
+	.gen = 033,
 };
 
 static const struct intel_device_info intel_i965_info = {
-	.gen = 40,
+	.gen = 040,
 };
 
 static const struct intel_device_info intel_g4x_info = {
-	.gen = 45,
+	.gen = 045,
 };
 
 static const struct intel_device_info intel_ironlake_info = {
-	.gen = 50,
+	.gen = 050,
 };
 
 static const struct intel_device_info intel_sandybridge_info = {
-	.gen = 60,
+	.gen = 060,
 };
 
 static const struct intel_device_info intel_ivybridge_info = {
-	.gen = 70,
+	.gen = 070,
 };
 
 static const struct intel_device_info intel_valleyview_info = {
-	.gen = 70,
+	.gen = 070,
 };
 
 static const struct intel_device_info intel_haswell_info = {
-	.gen = 75,
+	.gen = 075,
 };
 
 static const SymTabRec intel_chipsets[] = {
diff --git a/src/intel_uxa.c b/src/intel_uxa.c
index 6d202c7..76a3146 100644
--- a/src/intel_uxa.c
+++ b/src/intel_uxa.c
@@ -170,7 +170,7 @@ intel_uxa_pixmap_compute_size(PixmapPtr pixmap,
 		pitch = (w * pixmap->drawable.bitsPerPixel + 7) / 8;
 		pitch = ALIGN(pitch, 64);
 		size = pitch * ALIGN (h, 2);
-		if (INTEL_INFO(intel)->gen < 40) {
+		if (INTEL_INFO(intel)->gen < 040) {
 			/* Gen 2/3 has a maximum stride for tiling of
 			 * 8192 bytes.
 			 */
@@ -331,7 +331,7 @@ static void intel_uxa_solid(PixmapPtr pixmap, int x1, int y1, int x2, int y2)
 			cmd |=
 			    XY_COLOR_BLT_WRITE_ALPHA | XY_COLOR_BLT_WRITE_RGB;
 
-		if (INTEL_INFO(intel)->gen >= 40 && intel_pixmap_tiled(pixmap)) {
+		if (INTEL_INFO(intel)->gen >= 040 && intel_pixmap_tiled(pixmap)) {
 			assert((pitch % 512) == 0);
 			pitch >>= 2;
 			cmd |= XY_COLOR_BLT_TILED;
@@ -470,7 +470,7 @@ intel_uxa_copy(PixmapPtr dest, int src_x1, int src_y1, int dst_x1,
 			    XY_SRC_COPY_BLT_WRITE_ALPHA |
 			    XY_SRC_COPY_BLT_WRITE_RGB;
 
-		if (INTEL_INFO(intel)->gen >= 40) {
+		if (INTEL_INFO(intel)->gen >= 040) {
 			if (intel_pixmap_tiled(dest)) {
 				assert((dst_pitch % 512) == 0);
 				dst_pitch >>= 2;
@@ -1281,7 +1281,7 @@ intel_limits_init(intel_screen_private *intel)
 	 * the front, which will have an appropriate pitch/offset already set up,
 	 * so UXA doesn't need to worry.
 	 */
-	if (INTEL_INFO(intel)->gen >= 40) {
+	if (INTEL_INFO(intel)->gen >= 040) {
 		intel->accel_pixmap_offset_alignment = 4 * 2;
 		intel->accel_max_x = 8192;
 		intel->accel_max_y = 8192;
diff --git a/src/intel_video.c b/src/intel_video.c
index 09782aa..6cce182 100644
--- a/src/intel_video.c
+++ b/src/intel_video.c
@@ -353,7 +353,7 @@ void I830InitVideo(ScreenPtr screen)
 	 * supported hardware.
 	 */
 	if (scrn->bitsPerPixel >= 16 &&
-	    INTEL_INFO(intel)->gen >= 30) {
+	    INTEL_INFO(intel)->gen >= 030) {
 		texturedAdaptor = I830SetupImageVideoTextured(screen);
 		if (texturedAdaptor != NULL) {
 			xf86DrvMsg(scrn->scrnIndex, X_INFO,
@@ -436,7 +436,7 @@ static XF86VideoAdaptorPtr I830SetupImageVideoOverlay(ScreenPtr screen)
 
 	adapt->pPortPrivates[0].ptr = (pointer) (adaptor_priv);
 	adapt->nAttributes = NUM_ATTRIBUTES;
-	if (INTEL_INFO(intel)->gen >= 30)
+	if (INTEL_INFO(intel)->gen >= 030)
 		adapt->nAttributes += GAMMA_ATTRIBUTES;	/* has gamma */
 	adapt->pAttributes =
 	    xnfalloc(sizeof(XF86AttributeRec) * adapt->nAttributes);
@@ -445,7 +445,7 @@ static XF86VideoAdaptorPtr I830SetupImageVideoOverlay(ScreenPtr screen)
 	memcpy((char *)att, (char *)Attributes,
 	       sizeof(XF86AttributeRec) * NUM_ATTRIBUTES);
 	att += NUM_ATTRIBUTES;
-	if (INTEL_INFO(intel)->gen >= 30) {
+	if (INTEL_INFO(intel)->gen >= 030) {
 		memcpy((char *)att, (char *)GammaAttributes,
 		       sizeof(XF86AttributeRec) * GAMMA_ATTRIBUTES);
 	}
@@ -495,7 +495,7 @@ static XF86VideoAdaptorPtr I830SetupImageVideoOverlay(ScreenPtr screen)
 	/* Allow the pipe to be switched from pipe A to B when in clone mode */
 	xvPipe = MAKE_ATOM("XV_PIPE");
 
-	if (INTEL_INFO(intel)->gen >= 30) {
+	if (INTEL_INFO(intel)->gen >= 030) {
 		xvGamma0 = MAKE_ATOM("XV_GAMMA0");
 		xvGamma1 = MAKE_ATOM("XV_GAMMA1");
 		xvGamma2 = MAKE_ATOM("XV_GAMMA2");
@@ -681,17 +681,17 @@ I830SetPortAttributeOverlay(ScrnInfoPtr scrn,
 			adaptor_priv->desired_crtc = NULL;
 		else
 			adaptor_priv->desired_crtc = xf86_config->crtc[value];
-	} else if (attribute == xvGamma0 && (INTEL_INFO(intel)->gen >= 30)) {
+	} else if (attribute == xvGamma0 && (INTEL_INFO(intel)->gen >= 030)) {
 		adaptor_priv->gamma0 = value;
-	} else if (attribute == xvGamma1 && (INTEL_INFO(intel)->gen >= 30)) {
+	} else if (attribute == xvGamma1 && (INTEL_INFO(intel)->gen >= 030)) {
 		adaptor_priv->gamma1 = value;
-	} else if (attribute == xvGamma2 && (INTEL_INFO(intel)->gen >= 30)) {
+	} else if (attribute == xvGamma2 && (INTEL_INFO(intel)->gen >= 030)) {
 		adaptor_priv->gamma2 = value;
-	} else if (attribute == xvGamma3 && (INTEL_INFO(intel)->gen >= 30)) {
+	} else if (attribute == xvGamma3 && (INTEL_INFO(intel)->gen >= 030)) {
 		adaptor_priv->gamma3 = value;
-	} else if (attribute == xvGamma4 && (INTEL_INFO(intel)->gen >= 30)) {
+	} else if (attribute == xvGamma4 && (INTEL_INFO(intel)->gen >= 030)) {
 		adaptor_priv->gamma4 = value;
-	} else if (attribute == xvGamma5 && (INTEL_INFO(intel)->gen >= 30)) {
+	} else if (attribute == xvGamma5 && (INTEL_INFO(intel)->gen >= 030)) {
 		adaptor_priv->gamma5 = value;
 	} else if (attribute == xvColorKey) {
 		adaptor_priv->colorKey = value;
@@ -704,7 +704,7 @@ I830SetPortAttributeOverlay(ScrnInfoPtr scrn,
 	     attribute == xvGamma2 ||
 	     attribute == xvGamma3 ||
 	     attribute == xvGamma4 ||
-	     attribute == xvGamma5) && (INTEL_INFO(intel)->gen >= 30)) {
+	     attribute == xvGamma5) && (INTEL_INFO(intel)->gen >= 030)) {
 		OVERLAY_DEBUG("GAMMA\n");
 	}
 
@@ -739,17 +739,17 @@ I830GetPortAttribute(ScrnInfoPtr scrn,
 		if (c == xf86_config->num_crtc)
 			c = -1;
 		*value = c;
-	} else if (attribute == xvGamma0 && (INTEL_INFO(intel)->gen >= 30)) {
+	} else if (attribute == xvGamma0 && (INTEL_INFO(intel)->gen >= 030)) {
 		*value = adaptor_priv->gamma0;
-	} else if (attribute == xvGamma1 && (INTEL_INFO(intel)->gen >= 30)) {
+	} else if (attribute == xvGamma1 && (INTEL_INFO(intel)->gen >= 030)) {
 		*value = adaptor_priv->gamma1;
-	} else if (attribute == xvGamma2 && (INTEL_INFO(intel)->gen >= 30)) {
+	} else if (attribute == xvGamma2 && (INTEL_INFO(intel)->gen >= 030)) {
 		*value = adaptor_priv->gamma2;
-	} else if (attribute == xvGamma3 && (INTEL_INFO(intel)->gen >= 30)) {
+	} else if (attribute == xvGamma3 && (INTEL_INFO(intel)->gen >= 030)) {
 		*value = adaptor_priv->gamma3;
-	} else if (attribute == xvGamma4 && (INTEL_INFO(intel)->gen >= 30)) {
+	} else if (attribute == xvGamma4 && (INTEL_INFO(intel)->gen >= 030)) {
 		*value = adaptor_priv->gamma4;
-	} else if (attribute == xvGamma5 && (INTEL_INFO(intel)->gen >= 30)) {
+	} else if (attribute == xvGamma5 && (INTEL_INFO(intel)->gen >= 030)) {
 		*value = adaptor_priv->gamma5;
 	} else if (attribute == xvColorKey) {
 		*value = adaptor_priv->colorKey;
@@ -1313,18 +1313,18 @@ intel_wait_for_scanline(ScrnInfoPtr scrn, PixmapPtr pixmap,
 	 * of extra time for the blitter to start up and
 	 * do its job for a full height blit
 	 */
-	if (full_height && INTEL_INFO(intel)->gen < 40)
+	if (full_height && INTEL_INFO(intel)->gen < 040)
 		y2 -= 2;
 
 	if (pipe == 0) {
 		pipe = MI_LOAD_SCAN_LINES_DISPLAY_PIPEA;
 		event = MI_WAIT_FOR_PIPEA_SCAN_LINE_WINDOW;
-		if (full_height && INTEL_INFO(intel)->gen >= 40)
+		if (full_height && INTEL_INFO(intel)->gen >= 040)
 			event = MI_WAIT_FOR_PIPEA_SVBLANK;
 	} else {
 		pipe = MI_LOAD_SCAN_LINES_DISPLAY_PIPEB;
 		event = MI_WAIT_FOR_PIPEB_SCAN_LINE_WINDOW;
-		if (full_height && INTEL_INFO(intel)->gen >= 40)
+		if (full_height && INTEL_INFO(intel)->gen >= 040)
 			event = MI_WAIT_FOR_PIPEB_SVBLANK;
 	}
 
@@ -1381,7 +1381,7 @@ intel_setup_dst_params(ScrnInfoPtr scrn, intel_adaptor_private *adaptor_priv, sh
 	if (adaptor_priv->textured) {
 		pitchAlign = 4;
 	} else {
-		if (INTEL_INFO(intel)->gen >= 40)
+		if (INTEL_INFO(intel)->gen >= 040)
 			/* Actually the alignment is 64 bytes, too. But the
 			 * stride must be at least 512 bytes. Take the easy fix
 			 * and align on 512 bytes unconditionally. */
@@ -1561,16 +1561,16 @@ I830PutImageTextured(ScrnInfoPtr scrn,
 			return BadAlloc;
 	}
 
-	if (crtc && adaptor_priv->SyncToVblank != 0 && INTEL_INFO(intel)->gen < 60) {
+	if (crtc && adaptor_priv->SyncToVblank != 0 && INTEL_INFO(intel)->gen < 060) {
 		intel_wait_for_scanline(scrn, pixmap, crtc, clipBoxes);
 	}
 
-	if (INTEL_INFO(intel)->gen >= 60) {
+	if (INTEL_INFO(intel)->gen >= 060) {
 		Gen6DisplayVideoTextured(scrn, adaptor_priv, id, clipBoxes,
 					 width, height, dstPitch, dstPitch2,
 					 src_w, src_h,
 					 drw_w, drw_h, pixmap);
-	} else if (INTEL_INFO(intel)->gen >= 40) {
+	} else if (INTEL_INFO(intel)->gen >= 040) {
 		I965DisplayVideoTextured(scrn, adaptor_priv, id, clipBoxes,
 					 width, height, dstPitch, dstPitch2,
 					 src_w, src_h,
diff --git a/src/sna/brw/brw_disasm.c b/src/sna/brw/brw_disasm.c
index e6da174..ea6155c 100644
--- a/src/sna/brw/brw_disasm.c
+++ b/src/sna/brw/brw_disasm.c
@@ -875,16 +875,17 @@ void brw_disasm(FILE *file, const struct brw_instruction *inst, int gen)
 		string(file, ")");
 	}
 
-	if (inst->header.opcode == BRW_OPCODE_SEND && gen < 60)
+	if (inst->header.opcode == BRW_OPCODE_SEND && gen < 060)
 		format(file, " %d", inst->header.destreg__conditionalmod);
 
 	if (opcode[inst->header.opcode].ndst > 0) {
 		pad(file, 16);
 		dest(file, inst);
-	} else if (gen >= 60 && (inst->header.opcode == BRW_OPCODE_IF ||
-				 inst->header.opcode == BRW_OPCODE_ELSE ||
-				 inst->header.opcode == BRW_OPCODE_ENDIF ||
-				 inst->header.opcode == BRW_OPCODE_WHILE)) {
+	} else if (gen >= 060 &&
+		   (inst->header.opcode == BRW_OPCODE_IF ||
+		    inst->header.opcode == BRW_OPCODE_ELSE ||
+		    inst->header.opcode == BRW_OPCODE_ENDIF ||
+		    inst->header.opcode == BRW_OPCODE_WHILE)) {
 		format(file, " %d", inst->bits1.branch_gen6.jump_count);
 	}
 
@@ -901,9 +902,9 @@ void brw_disasm(FILE *file, const struct brw_instruction *inst, int gen)
 	    inst->header.opcode == BRW_OPCODE_SENDC) {
 		enum brw_message_target target;
 
-		if (gen >= 60)
+		if (gen >= 060)
 			target = inst->header.destreg__conditionalmod;
-		else if (gen >= 50)
+		else if (gen >= 050)
 			target = inst->bits2.send_gen5.sfid;
 		else
 			target = inst->bits3.generic.msg_target;
@@ -912,7 +913,7 @@ void brw_disasm(FILE *file, const struct brw_instruction *inst, int gen)
 		pad (file, 16);
 		space = 0;
 
-		if (gen >= 60) {
+		if (gen >= 060) {
 			control (file, "target function", target_function_gen6,
 				 target, &space);
 		} else {
@@ -934,19 +935,19 @@ void brw_disasm(FILE *file, const struct brw_instruction *inst, int gen)
 				 inst->bits3.math.precision, &space);
 			break;
 		case BRW_SFID_SAMPLER:
-			if (gen >= 70) {
+			if (gen >= 070) {
 				format (file, " (%d, %d, %d, %d)",
 					inst->bits3.sampler_gen7.binding_table_index,
 					inst->bits3.sampler_gen7.sampler,
 					inst->bits3.sampler_gen7.msg_type,
 					inst->bits3.sampler_gen7.simd_mode);
-			} else if (gen >= 50) {
+			} else if (gen >= 050) {
 				format (file, " (%d, %d, %d, %d)",
 					inst->bits3.sampler_gen5.binding_table_index,
 					inst->bits3.sampler_gen5.sampler,
 					inst->bits3.sampler_gen5.msg_type,
 					inst->bits3.sampler_gen5.simd_mode);
-			} else if (gen >= 45) {
+			} else if (gen >= 045) {
 				format (file, " (%d, %d)",
 					inst->bits3.sampler_g4x.binding_table_index,
 					inst->bits3.sampler_g4x.sampler);
@@ -961,13 +962,13 @@ void brw_disasm(FILE *file, const struct brw_instruction *inst, int gen)
 			}
 			break;
 		case BRW_SFID_DATAPORT_READ:
-			if (gen >= 60) {
+			if (gen >= 060) {
 				format (file, " (%d, %d, %d, %d)",
 					inst->bits3.gen6_dp.binding_table_index,
 					inst->bits3.gen6_dp.msg_control,
 					inst->bits3.gen6_dp.msg_type,
 					inst->bits3.gen6_dp.send_commit_msg);
-			} else if (gen >= 45) {
+			} else if (gen >= 045) {
 				format (file, " (%d, %d, %d)",
 					inst->bits3.dp_read_gen5.binding_table_index,
 					inst->bits3.dp_read_gen5.msg_control,
@@ -981,7 +982,7 @@ void brw_disasm(FILE *file, const struct brw_instruction *inst, int gen)
 			break;
 
 		case BRW_SFID_DATAPORT_WRITE:
-			if (gen >= 70) {
+			if (gen >= 070) {
 				format (file, " (");
 
 				control (file, "DP rc message type",
@@ -992,7 +993,7 @@ void brw_disasm(FILE *file, const struct brw_instruction *inst, int gen)
 					inst->bits3.gen7_dp.binding_table_index,
 					inst->bits3.gen7_dp.msg_control,
 					inst->bits3.gen7_dp.msg_type);
-			} else if (gen >= 60) {
+			} else if (gen >= 060) {
 				format (file, " (");
 
 				control (file, "DP rc message type",
@@ -1015,14 +1016,14 @@ void brw_disasm(FILE *file, const struct brw_instruction *inst, int gen)
 			break;
 
 		case BRW_SFID_URB:
-			if (gen >= 50) {
+			if (gen >= 050) {
 				format (file, " %d", inst->bits3.urb_gen5.offset);
 			} else {
 				format (file, " %d", inst->bits3.urb.offset);
 			}
 
 			space = 1;
-			if (gen >= 50) {
+			if (gen >= 050) {
 				control (file, "urb opcode", urb_opcode,
 					 inst->bits3.urb_gen5.opcode, &space);
 			}
@@ -1051,7 +1052,7 @@ void brw_disasm(FILE *file, const struct brw_instruction *inst, int gen)
 		}
 		if (space)
 			string (file, " ");
-		if (gen >= 50) {
+		if (gen >= 050) {
 			format (file, "mlen %d",
 				inst->bits3.generic_gen5.msg_length);
 			format (file, " rlen %d",
@@ -1068,13 +1069,13 @@ void brw_disasm(FILE *file, const struct brw_instruction *inst, int gen)
 		string(file, "{");
 		space = 1;
 		control(file, "access mode", access_mode, inst->header.access_mode, &space);
-		if (gen >= 60)
+		if (gen >= 060)
 			control(file, "write enable control", wectrl, inst->header.mask_control, &space);
 		else
 			control(file, "mask control", mask_ctrl, inst->header.mask_control, &space);
 		control(file, "dependency control", dep_ctrl, inst->header.dependency_control, &space);
 
-		if (gen >= 60)
+		if (gen >= 060)
 			qtr_ctrl(file, inst);
 		else {
 			if (inst->header.compression_control == BRW_COMPRESSION_COMPRESSED &&
@@ -1089,7 +1090,7 @@ void brw_disasm(FILE *file, const struct brw_instruction *inst, int gen)
 		}
 
 		control(file, "thread control", thread_ctrl, inst->header.thread_control, &space);
-		if (gen >= 60)
+		if (gen >= 060)
 			control(file, "acc write control", accwr, inst->header.acc_wr_control, &space);
 		if (inst->header.opcode == BRW_OPCODE_SEND ||
 		    inst->header.opcode == BRW_OPCODE_SENDC)
diff --git a/src/sna/brw/brw_eu.c b/src/sna/brw/brw_eu.c
index 7c32ea1..9bd8ba5 100644
--- a/src/sna/brw/brw_eu.c
+++ b/src/sna/brw/brw_eu.c
@@ -79,7 +79,7 @@ void brw_set_compression_control(struct brw_compile *p,
 {
 	p->compressed = (compression_control == BRW_COMPRESSION_COMPRESSED);
 
-	if (p->gen >= 60) {
+	if (p->gen >= 060) {
 		/* Since we don't use the 32-wide support in gen6, we translate
 		 * the pre-gen6 compression control here.
 		 */
diff --git a/src/sna/brw/brw_eu.h b/src/sna/brw/brw_eu.h
index 65e66d5..24ab599 100644
--- a/src/sna/brw/brw_eu.h
+++ b/src/sna/brw/brw_eu.h
@@ -1862,7 +1862,7 @@ static inline void brw_set_saturate(struct brw_compile *p, unsigned value)
 
 static inline void brw_set_acc_write_control(struct brw_compile *p, unsigned value)
 {
-	if (p->gen >= 60)
+	if (p->gen >= 060)
 		p->current->header.acc_wr_control = value;
 }
 
@@ -1938,7 +1938,7 @@ static inline void brw_##OP(struct brw_compile *p,			\
 	rnd = brw_next_insn(p, BRW_OPCODE_##OP);			\
 	brw_set_dest(p, rnd, dest);					\
 	brw_set_src0(p, rnd, src);					\
-	if (p->gen < 60) {						\
+	if (p->gen < 060) {						\
 		/* turn on round-increments */				\
 		rnd->header.destreg__conditionalmod = BRW_CONDITIONAL_R; \
 		add = brw_ADD(p, dest, dest, brw_imm_f(1.0f));		\
diff --git a/src/sna/brw/brw_eu_emit.c b/src/sna/brw/brw_eu_emit.c
index 3f01ae7..5c0b306 100644
--- a/src/sna/brw/brw_eu_emit.c
+++ b/src/sna/brw/brw_eu_emit.c
@@ -61,7 +61,7 @@ gen6_resolve_implied_move(struct brw_compile *p,
 			  struct brw_reg *src,
 			  unsigned msg_reg_nr)
 {
-	if (p->gen < 60)
+	if (p->gen < 060)
 		return;
 
 	if (src->file == BRW_MESSAGE_REGISTER_FILE)
@@ -88,7 +88,7 @@ gen7_convert_mrf_to_grf(struct brw_compile *p, struct brw_reg *reg)
 	 * Since we're pretending to have 16 MRFs anyway, we may as well use the
 	 * registers required for messages with EOT.
 	 */
-	if (p->gen >= 70 && reg->file == BRW_MESSAGE_REGISTER_FILE) {
+	if (p->gen >= 070 && reg->file == BRW_MESSAGE_REGISTER_FILE) {
 		reg->file = BRW_GENERAL_REGISTER_FILE;
 		reg->nr += 111;
 	}
@@ -378,13 +378,13 @@ brw_set_message_descriptor(struct brw_compile *p,
 {
 	brw_set_src1(p, inst, brw_imm_d(0));
 
-	if (p->gen >= 50) {
+	if (p->gen >= 050) {
 		inst->bits3.generic_gen5.header_present = header_present;
 		inst->bits3.generic_gen5.response_length = response_length;
 		inst->bits3.generic_gen5.msg_length = msg_length;
 		inst->bits3.generic_gen5.end_of_thread = end_of_thread;
 
-		if (p->gen >= 60) {
+		if (p->gen >= 060) {
 			/* On Gen6+ Message target/SFID goes in bits 27:24 of the header */
 			inst->header.destreg__conditionalmod = sfid;
 		} else {
@@ -439,7 +439,7 @@ static void brw_set_math_message(struct brw_compile *p,
 	brw_set_message_descriptor(p, insn, BRW_SFID_MATH,
 				   msg_length, response_length,
 				   false, false);
-	if (p->gen == 50) {
+	if (p->gen == 050) {
 		insn->bits3.math_gen5.function = function;
 		insn->bits3.math_gen5.int_type = integer_type;
 		insn->bits3.math_gen5.precision = low_precision;
@@ -485,7 +485,7 @@ static void brw_set_urb_message(struct brw_compile *p,
 {
 	brw_set_message_descriptor(p, insn, BRW_SFID_URB,
 				   msg_length, response_length, true, end_of_thread);
-	if (p->gen >= 70) {
+	if (p->gen >= 070) {
 		insn->bits3.urb_gen7.opcode = 0;	/* URB_WRITE_HWORD */
 		insn->bits3.urb_gen7.offset = offset;
 		assert(swizzle_control != BRW_URB_SWIZZLE_TRANSPOSE);
@@ -493,7 +493,7 @@ static void brw_set_urb_message(struct brw_compile *p,
 		/* per_slot_offset = 0 makes it ignore offsets in message header */
 		insn->bits3.urb_gen7.per_slot_offset = 0;
 		insn->bits3.urb_gen7.complete = complete;
-	} else if (p->gen >= 50) {
+	} else if (p->gen >= 050) {
 		insn->bits3.urb_gen5.opcode = 0;	/* URB_WRITE */
 		insn->bits3.urb_gen5.offset = offset;
 		insn->bits3.urb_gen5.swizzle_control = swizzle_control;
@@ -525,13 +525,13 @@ brw_set_dp_write_message(struct brw_compile *p,
 {
 	unsigned sfid;
 
-	if (p->gen >= 70) {
+	if (p->gen >= 070) {
 		/* Use the Render Cache for RT writes; otherwise use the Data Cache */
 		if (msg_type == GEN6_DATAPORT_WRITE_MESSAGE_RENDER_TARGET_WRITE)
 			sfid = GEN6_SFID_DATAPORT_RENDER_CACHE;
 		else
 			sfid = GEN7_SFID_DATAPORT_DATA_CACHE;
-	} else if (p->gen >= 60) {
+	} else if (p->gen >= 060) {
 		/* Use the render cache for all write messages. */
 		sfid = GEN6_SFID_DATAPORT_RENDER_CACHE;
 	} else {
@@ -542,18 +542,18 @@ brw_set_dp_write_message(struct brw_compile *p,
 				   msg_length, response_length,
 				   header_present, end_of_thread);
 
-	if (p->gen >= 70) {
+	if (p->gen >= 070) {
 		insn->bits3.gen7_dp.binding_table_index = binding_table_index;
 		insn->bits3.gen7_dp.msg_control = msg_control;
 		insn->bits3.gen7_dp.last_render_target = last_render_target;
 		insn->bits3.gen7_dp.msg_type = msg_type;
-	} else if (p->gen >= 60) {
+	} else if (p->gen >= 060) {
 		insn->bits3.gen6_dp.binding_table_index = binding_table_index;
 		insn->bits3.gen6_dp.msg_control = msg_control;
 		insn->bits3.gen6_dp.last_render_target = last_render_target;
 		insn->bits3.gen6_dp.msg_type = msg_type;
 		insn->bits3.gen6_dp.send_commit_msg = send_commit_msg;
-	} else if (p->gen >= 50) {
+	} else if (p->gen >= 050) {
 		insn->bits3.dp_write_gen5.binding_table_index = binding_table_index;
 		insn->bits3.dp_write_gen5.msg_control = msg_control;
 		insn->bits3.dp_write_gen5.last_render_target = last_render_target;
@@ -580,9 +580,9 @@ brw_set_dp_read_message(struct brw_compile *p,
 {
 	unsigned sfid;
 
-	if (p->gen >= 70) {
+	if (p->gen >= 070) {
 		sfid = GEN7_SFID_DATAPORT_DATA_CACHE;
-	} else if (p->gen >= 60) {
+	} else if (p->gen >= 060) {
 		if (target_cache == BRW_DATAPORT_READ_TARGET_RENDER_CACHE)
 			sfid = GEN6_SFID_DATAPORT_RENDER_CACHE;
 		else
@@ -595,23 +595,23 @@ brw_set_dp_read_message(struct brw_compile *p,
 				   msg_length, response_length,
 				   true, false);
 
-	if (p->gen >= 70) {
+	if (p->gen >= 070) {
 		insn->bits3.gen7_dp.binding_table_index = binding_table_index;
 		insn->bits3.gen7_dp.msg_control = msg_control;
 		insn->bits3.gen7_dp.last_render_target = 0;
 		insn->bits3.gen7_dp.msg_type = msg_type;
-	} else if (p->gen >= 60) {
+	} else if (p->gen >= 060) {
 		insn->bits3.gen6_dp.binding_table_index = binding_table_index;
 		insn->bits3.gen6_dp.msg_control = msg_control;
 		insn->bits3.gen6_dp.last_render_target = 0;
 		insn->bits3.gen6_dp.msg_type = msg_type;
 		insn->bits3.gen6_dp.send_commit_msg = 0;
-	} else if (p->gen >= 50) {
+	} else if (p->gen >= 050) {
 		insn->bits3.dp_read_gen5.binding_table_index = binding_table_index;
 		insn->bits3.dp_read_gen5.msg_control = msg_control;
 		insn->bits3.dp_read_gen5.msg_type = msg_type;
 		insn->bits3.dp_read_gen5.target_cache = target_cache;
-	} else if (p->gen >= 45) {
+	} else if (p->gen >= 045) {
 		insn->bits3.dp_read_g4x.binding_table_index = binding_table_index; /*0:7*/
 		insn->bits3.dp_read_g4x.msg_control = msg_control;  /*8:10*/
 		insn->bits3.dp_read_g4x.msg_type = msg_type;  /*11:13*/
@@ -638,17 +638,17 @@ static void brw_set_sampler_message(struct brw_compile *p,
 				   msg_length, response_length,
 				   header_present, false);
 
-	if (p->gen >= 70) {
+	if (p->gen >= 070) {
 		insn->bits3.sampler_gen7.binding_table_index = binding_table_index;
 		insn->bits3.sampler_gen7.sampler = sampler;
 		insn->bits3.sampler_gen7.msg_type = msg_type;
 		insn->bits3.sampler_gen7.simd_mode = simd_mode;
-	} else if (p->gen >= 50) {
+	} else if (p->gen >= 050) {
 		insn->bits3.sampler_gen5.binding_table_index = binding_table_index;
 		insn->bits3.sampler_gen5.sampler = sampler;
 		insn->bits3.sampler_gen5.msg_type = msg_type;
 		insn->bits3.sampler_gen5.simd_mode = simd_mode;
-	} else if (p->gen >= 45) {
+	} else if (p->gen >= 045) {
 		insn->bits3.sampler_g4x.binding_table_index = binding_table_index;
 		insn->bits3.sampler_g4x.sampler = sampler;
 		insn->bits3.sampler_g4x.msg_type = msg_type;
@@ -706,11 +706,11 @@ brw_IF(struct brw_compile *p, unsigned execute_size)
 	insn = brw_next_insn(p, BRW_OPCODE_IF);
 
 	/* Override the defaults for this instruction: */
-	if (p->gen < 60) {
+	if (p->gen < 060) {
 		brw_set_dest(p, insn, brw_ip_reg());
 		brw_set_src0(p, insn, brw_ip_reg());
 		brw_set_src1(p, insn, brw_imm_d(0x0));
-	} else if (p->gen < 70) {
+	} else if (p->gen < 070) {
 		brw_set_dest(p, insn, brw_imm_w(0));
 		insn->bits1.branch_gen6.jump_count = 0;
 		brw_set_src0(p, insn, __retype_d(brw_null_reg()));
@@ -827,7 +827,7 @@ patch_IF_ELSE(struct brw_compile *p,
 	/* Jump count is for 64bit data chunk each, so one 128bit instruction
 	 * requires 2 chunks.
 	 */
-	if (p->gen >= 50)
+	if (p->gen >= 050)
 		br = 2;
 
 	assert(endif_inst->header.opcode == BRW_OPCODE_ENDIF);
@@ -835,7 +835,7 @@ patch_IF_ELSE(struct brw_compile *p,
 
 	if (else_inst == NULL) {
 		/* Patch IF -> ENDIF */
-		if (p->gen < 60) {
+		if (p->gen < 060) {
 			/* Turn it into an IFF, which means no mask stack operations for
 			 * all-false and jumping past the ENDIF.
 			 */
@@ -843,7 +843,7 @@ patch_IF_ELSE(struct brw_compile *p,
 			if_inst->bits3.if_else.jump_count = br * (endif_inst - if_inst + 1);
 			if_inst->bits3.if_else.pop_count = 0;
 			if_inst->bits3.if_else.pad0 = 0;
-		} else if (p->gen < 70) {
+		} else if (p->gen < 070) {
 			/* As of gen6, there is no IFF and IF must point to the ENDIF. */
 			if_inst->bits1.branch_gen6.jump_count = br * (endif_inst - if_inst);
 		} else {
@@ -854,23 +854,23 @@ patch_IF_ELSE(struct brw_compile *p,
 		else_inst->header.execution_size = if_inst->header.execution_size;
 
 		/* Patch IF -> ELSE */
-		if (p->gen < 60) {
+		if (p->gen < 060) {
 			if_inst->bits3.if_else.jump_count = br * (else_inst - if_inst);
 			if_inst->bits3.if_else.pop_count = 0;
 			if_inst->bits3.if_else.pad0 = 0;
-		} else if (p->gen <= 70) {
+		} else if (p->gen <= 070) {
 			if_inst->bits1.branch_gen6.jump_count = br * (else_inst - if_inst + 1);
 		}
 
 		/* Patch ELSE -> ENDIF */
-		if (p->gen < 60) {
+		if (p->gen < 060) {
 			/* BRW_OPCODE_ELSE pre-gen6 should point just past the
 			 * matching ENDIF.
 			 */
 			else_inst->bits3.if_else.jump_count = br*(endif_inst - else_inst + 1);
 			else_inst->bits3.if_else.pop_count = 1;
 			else_inst->bits3.if_else.pad0 = 0;
-		} else if (p->gen < 70) {
+		} else if (p->gen < 070) {
 			/* BRW_OPCODE_ELSE on gen6 should point to the matching ENDIF. */
 			else_inst->bits1.branch_gen6.jump_count = br*(endif_inst - else_inst);
 		} else {
@@ -890,11 +890,11 @@ brw_ELSE(struct brw_compile *p)
 
 	insn = brw_next_insn(p, BRW_OPCODE_ELSE);
 
-	if (p->gen < 60) {
+	if (p->gen < 060) {
 		brw_set_dest(p, insn, brw_ip_reg());
 		brw_set_src0(p, insn, brw_ip_reg());
 		brw_set_src1(p, insn, brw_imm_d(0x0));
-	} else if (p->gen < 70) {
+	} else if (p->gen < 070) {
 		brw_set_dest(p, insn, brw_imm_w(0));
 		insn->bits1.branch_gen6.jump_count = 0;
 		brw_set_src0(p, insn, __retype_d(brw_null_reg()));
@@ -938,11 +938,11 @@ brw_ENDIF(struct brw_compile *p)
 
 	insn = brw_next_insn(p, BRW_OPCODE_ENDIF);
 
-	if (p->gen < 60) {
+	if (p->gen < 060) {
 		brw_set_dest(p, insn, __retype_ud(brw_vec4_grf(0,0)));
 		brw_set_src0(p, insn, __retype_ud(brw_vec4_grf(0,0)));
 		brw_set_src1(p, insn, brw_imm_d(0x0));
-	} else if (p->gen < 70) {
+	} else if (p->gen < 070) {
 		brw_set_dest(p, insn, brw_imm_w(0));
 		brw_set_src0(p, insn, __retype_d(brw_null_reg()));
 		brw_set_src1(p, insn, __retype_d(brw_null_reg()));
@@ -957,11 +957,11 @@ brw_ENDIF(struct brw_compile *p)
 	insn->header.thread_control = BRW_THREAD_SWITCH;
 
 	/* Also pop item off the stack in the endif instruction: */
-	if (p->gen < 60) {
+	if (p->gen < 060) {
 		insn->bits3.if_else.jump_count = 0;
 		insn->bits3.if_else.pop_count = 1;
 		insn->bits3.if_else.pad0 = 0;
-	} else if (p->gen < 70) {
+	} else if (p->gen < 070) {
 		insn->bits1.branch_gen6.jump_count = 2;
 	} else {
 		insn->bits3.break_cont.jip = 2;
@@ -974,7 +974,7 @@ struct brw_instruction *brw_BREAK(struct brw_compile *p, int pop_count)
 	struct brw_instruction *insn;
 
 	insn = brw_next_insn(p, BRW_OPCODE_BREAK);
-	if (p->gen >= 60) {
+	if (p->gen >= 060) {
 		brw_set_dest(p, insn, __retype_d(brw_null_reg()));
 		brw_set_src0(p, insn, __retype_d(brw_null_reg()));
 		brw_set_src1(p, insn, brw_imm_d(0x0));
@@ -1041,7 +1041,7 @@ struct brw_instruction *brw_CONT(struct brw_compile *p, int pop_count)
  */
 struct brw_instruction *brw_DO(struct brw_compile *p, unsigned execute_size)
 {
-	if (p->gen >= 60 || p->single_program_flow) {
+	if (p->gen >= 060 || p->single_program_flow) {
 		return &p->store[p->nr_insn];
 	} else {
 		struct brw_instruction *insn = brw_next_insn(p, BRW_OPCODE_DO);
@@ -1068,10 +1068,10 @@ struct brw_instruction *brw_WHILE(struct brw_compile *p,
 	struct brw_instruction *insn;
 	unsigned br = 1;
 
-	if (p->gen >= 50)
+	if (p->gen >= 050)
 		br = 2;
 
-	if (p->gen >= 70) {
+	if (p->gen >= 070) {
 		insn = brw_next_insn(p, BRW_OPCODE_WHILE);
 
 		brw_set_dest(p, insn, __retype_d(brw_null_reg()));
@@ -1080,7 +1080,7 @@ struct brw_instruction *brw_WHILE(struct brw_compile *p,
 		insn->bits3.break_cont.jip = br * (do_insn - insn);
 
 		insn->header.execution_size = BRW_EXECUTE_8;
-	} else if (p->gen >= 60) {
+	} else if (p->gen >= 060) {
 		insn = brw_next_insn(p, BRW_OPCODE_WHILE);
 
 		brw_set_dest(p, insn, brw_imm_w(0));
@@ -1126,7 +1126,7 @@ void brw_land_fwd_jump(struct brw_compile *p,
 	struct brw_instruction *landing = &p->store[p->nr_insn];
 	unsigned jmpi = 1;
 
-	if (p->gen >= 50)
+	if (p->gen >= 050)
 		jmpi = 2;
 
 	assert(jmp_insn->header.opcode == BRW_OPCODE_JMPI);
@@ -1195,7 +1195,7 @@ void brw_math(struct brw_compile *p,
 	      unsigned data_type,
 	      unsigned precision)
 {
-	if (p->gen >= 60) {
+	if (p->gen >= 060) {
 		struct brw_instruction *insn = brw_next_insn(p, BRW_OPCODE_MATH);
 
 		assert(dest.file == BRW_GENERAL_REGISTER_FILE);
@@ -1294,7 +1294,7 @@ void brw_math_16(struct brw_compile *p,
 {
 	struct brw_instruction *insn;
 
-	if (p->gen >= 60) {
+	if (p->gen >= 060) {
 		insn = brw_next_insn(p, BRW_OPCODE_MATH);
 
 		/* Math is the same ISA format as other opcodes, except that CondModifier
@@ -1362,7 +1362,7 @@ void brw_oword_block_write_scratch(struct brw_compile *p,
 	uint32_t msg_control, msg_type;
 	int mlen;
 
-	if (p->gen >= 60)
+	if (p->gen >= 060)
 		offset /= 16;
 
 	mrf = __retype_ud(mrf);
@@ -1418,7 +1418,7 @@ void brw_oword_block_write_scratch(struct brw_compile *p,
 		 * protection.  Our use of DP writes is all about register
 		 * spilling within a thread.
 		 */
-		if (p->gen >= 60) {
+		if (p->gen >= 060) {
 			dest = __retype_uw(vec16(brw_null_reg()));
 			send_commit_msg = 0;
 		} else {
@@ -1427,13 +1427,13 @@ void brw_oword_block_write_scratch(struct brw_compile *p,
 		}
 
 		brw_set_dest(p, insn, dest);
-		if (p->gen >= 60) {
+		if (p->gen >= 060) {
 			brw_set_src0(p, insn, mrf);
 		} else {
 			brw_set_src0(p, insn, brw_null_reg());
 		}
 
-		if (p->gen >= 60)
+		if (p->gen >= 060)
 			msg_type = GEN6_DATAPORT_WRITE_MESSAGE_OWORD_BLOCK_WRITE;
 		else
 			msg_type = BRW_DATAPORT_WRITE_MESSAGE_OWORD_BLOCK_WRITE;
@@ -1470,7 +1470,7 @@ brw_oword_block_read_scratch(struct brw_compile *p,
 	uint32_t msg_control;
 	int rlen;
 
-	if (p->gen >= 60)
+	if (p->gen >= 060)
 		offset /= 16;
 
 	mrf = __retype_ud(mrf);
@@ -1507,7 +1507,7 @@ brw_oword_block_read_scratch(struct brw_compile *p,
 		insn->header.destreg__conditionalmod = mrf.nr;
 
 		brw_set_dest(p, insn, dest); /* UW? */
-		if (p->gen >= 60) {
+		if (p->gen >= 060) {
 			brw_set_src0(p, insn, mrf);
 		} else {
 			brw_set_src0(p, insn, brw_null_reg());
@@ -1538,7 +1538,7 @@ void brw_oword_block_read(struct brw_compile *p,
 	struct brw_instruction *insn;
 
 	/* On newer hardware, offset is in units of owords. */
-	if (p->gen >= 60)
+	if (p->gen >= 060)
 		offset /= 16;
 
 	mrf = __retype_ud(mrf);
@@ -1562,7 +1562,7 @@ void brw_oword_block_read(struct brw_compile *p,
 	dest = __retype_uw(vec8(dest));
 
 	brw_set_dest(p, insn, dest);
-	if (p->gen >= 60) {
+	if (p->gen >= 060) {
 		brw_set_src0(p, insn, mrf);
 	} else {
 		brw_set_src0(p, insn, brw_null_reg());
@@ -1634,7 +1634,7 @@ void brw_dp_READ_4_vs(struct brw_compile *p,
 	struct brw_instruction *insn;
 	unsigned msg_reg_nr = 1;
 
-	if (p->gen >= 60)
+	if (p->gen >= 060)
 		location /= 16;
 
 	/* Setup MRF[1] with location/offset into const buffer */
@@ -1655,7 +1655,7 @@ void brw_dp_READ_4_vs(struct brw_compile *p,
 	insn->header.mask_control = BRW_MASK_DISABLE;
 
 	brw_set_dest(p, insn, dest);
-	if (p->gen >= 60) {
+	if (p->gen >= 060) {
 		brw_set_src0(p, insn, brw_message_reg(msg_reg_nr));
 	} else {
 		brw_set_src0(p, insn, brw_null_reg());
@@ -1710,9 +1710,9 @@ void brw_dp_READ_4_vs_relative(struct brw_compile *p,
 	brw_set_dest(p, insn, dest);
 	brw_set_src0(p, insn, src);
 
-	if (p->gen >= 60)
+	if (p->gen >= 060)
 		msg_type = GEN6_DATAPORT_READ_MESSAGE_OWORD_DUAL_BLOCK_READ;
-	else if (p->gen >= 45)
+	else if (p->gen >= 045)
 		msg_type = G45_DATAPORT_READ_MESSAGE_OWORD_DUAL_BLOCK_READ;
 	else
 		msg_type = BRW_DATAPORT_READ_MESSAGE_OWORD_DUAL_BLOCK_READ;
@@ -1747,7 +1747,7 @@ void brw_fb_WRITE(struct brw_compile *p,
 	else
 		dest = __retype_uw(vec8(brw_null_reg()));
 
-	if (p->gen >= 60 && binding_table_index == 0) {
+	if (p->gen >= 060 && binding_table_index == 0) {
 		insn = brw_next_insn(p, BRW_OPCODE_SENDC);
 	} else {
 		insn = brw_next_insn(p, BRW_OPCODE_SEND);
@@ -1756,7 +1756,7 @@ void brw_fb_WRITE(struct brw_compile *p,
 	insn->header.predicate_control = 0;
 	insn->header.compression_control = BRW_COMPRESSION_NONE;
 
-	if (p->gen >= 60) {
+	if (p->gen >= 060) {
 		/* headerless version, just submit color payload */
 		src0 = brw_message_reg(msg_reg_nr);
 
@@ -1802,7 +1802,7 @@ void brw_SAMPLE(struct brw_compile *p,
 {
 	assert(writemask);
 
-	if (p->gen < 50 || writemask != WRITEMASK_XYZW) {
+	if (p->gen < 050 || writemask != WRITEMASK_XYZW) {
 		struct brw_reg m1 = brw_message_reg(msg_reg_nr);
 
 		writemask = ~writemask & WRITEMASK_XYZW;
@@ -1828,7 +1828,7 @@ void brw_SAMPLE(struct brw_compile *p,
 		insn = brw_next_insn(p, BRW_OPCODE_SEND);
 		insn->header.predicate_control = 0; /* XXX */
 		insn->header.compression_control = BRW_COMPRESSION_NONE;
-		if (p->gen < 60)
+		if (p->gen < 060)
 			insn->header.destreg__conditionalmod = msg_reg_nr;
 
 		brw_set_dest(p, insn, dest);
@@ -1865,7 +1865,7 @@ void brw_urb_WRITE(struct brw_compile *p,
 
 	gen6_resolve_implied_move(p, &src0, msg_reg_nr);
 
-	if (p->gen >= 70) {
+	if (p->gen >= 070) {
 		/* Enable Channel Masks in the URB_WRITE_HWORD message header */
 		brw_push_insn_state(p);
 		brw_set_access_mode(p, BRW_ALIGN_1);
@@ -1883,7 +1883,7 @@ void brw_urb_WRITE(struct brw_compile *p,
 	brw_set_src0(p, insn, src0);
 	brw_set_src1(p, insn, brw_imm_d(0));
 
-	if (p->gen <= 60)
+	if (p->gen <= 060)
 		insn->header.destreg__conditionalmod = msg_reg_nr;
 
 	brw_set_urb_message(p,
@@ -1931,7 +1931,7 @@ brw_find_loop_end(struct brw_compile *p, int start)
 		struct brw_instruction *insn = &p->store[ip];
 
 		if (insn->header.opcode == BRW_OPCODE_WHILE) {
-			int jip = p->gen <= 70 ? insn->bits1.branch_gen6.jump_count
+			int jip = p->gen <= 070 ? insn->bits1.branch_gen6.jump_count
 				: insn->bits3.break_cont.jip;
 			if (ip + jip / br <= start)
 				return ip;
@@ -1950,7 +1950,7 @@ brw_set_uip_jip(struct brw_compile *p)
 	int ip;
 	int br = 2;
 
-	if (p->gen <= 60)
+	if (p->gen <= 060)
 		return;
 
 	for (ip = 0; ip < p->nr_insn; ip++) {
@@ -1961,7 +1961,7 @@ brw_set_uip_jip(struct brw_compile *p)
 			insn->bits3.break_cont.jip = br * (brw_find_next_block_end(p, ip) - ip);
 			/* Gen7 UIP points to WHILE; Gen6 points just after it */
 			insn->bits3.break_cont.uip =
-				br * (brw_find_loop_end(p, ip) - ip + (p->gen <= 70 ? 1 : 0));
+				br * (brw_find_loop_end(p, ip) - ip + (p->gen <= 070 ? 1 : 0));
 			break;
 		case BRW_OPCODE_CONTINUE:
 			insn->bits3.break_cont.jip = br * (brw_find_next_block_end(p, ip) - ip);
@@ -1991,7 +1991,7 @@ void brw_ff_sync(struct brw_compile *p,
 	brw_set_src0(p, insn, src0);
 	brw_set_src1(p, insn, brw_imm_d(0));
 
-	if (p->gen < 60)
+	if (p->gen < 060)
 		insn->header.destreg__conditionalmod = msg_reg_nr;
 
 	brw_set_ff_sync_message(p,
diff --git a/src/sna/brw/brw_wm.c b/src/sna/brw/brw_wm.c
index af047a2..e8dc6ac 100644
--- a/src/sna/brw/brw_wm.c
+++ b/src/sna/brw/brw_wm.c
@@ -41,15 +41,15 @@ static void brw_wm_affine_st(struct brw_compile *p, int dw,
 
 	if (dw == 16) {
 		brw_set_compression_control(p, BRW_COMPRESSION_COMPRESSED);
-		uv = p->gen >= 60 ? 6 : 3;
+		uv = p->gen >= 060 ? 6 : 3;
 	} else {
 		brw_set_compression_control(p, BRW_COMPRESSION_NONE);
-		uv = p->gen >= 60 ? 4 : 3;
+		uv = p->gen >= 060 ? 4 : 3;
 	}
 	uv += 2*channel;
 
 	msg++;
-	if (p->gen >= 60) {
+	if (p->gen >= 060) {
 		brw_PLN(p,
 			brw_message_reg(msg),
 			brw_vec1_grf(uv, 0),
@@ -96,7 +96,7 @@ static int brw_wm_sample(struct brw_compile *p, int dw,
 	int len;
 
 	len = dw == 16 ? 4 : 2;
-	if (p->gen >= 60) {
+	if (p->gen >= 060) {
 		header = false;
 		src0 = brw_message_reg(++msg);
 	} else {
@@ -125,7 +125,7 @@ static int brw_wm_sample__alpha(struct brw_compile *p, int dw,
 		rlen = 2;
 	}
 
-	if (p->gen >= 60)
+	if (p->gen >= 060)
 		src0 = brw_message_reg(msg);
 	else
 		src0 = brw_vec8_grf(0, 0);
@@ -182,7 +182,7 @@ static void brw_fb_write(struct brw_compile *p, int dw)
 		msg_len = 4;
 	}
 
-	if (p->gen < 60) {
+	if (p->gen < 060) {
 		brw_push_insn_state(p);
 		brw_set_compression_control(p, BRW_COMPRESSION_NONE);
 		brw_set_mask_control(p, BRW_MASK_DISABLE);
@@ -197,7 +197,7 @@ static void brw_fb_write(struct brw_compile *p, int dw)
 	insn->header.predicate_control = 0;
 	insn->header.compression_control = BRW_COMPRESSION_NONE;
 
-	if (p->gen >= 60) {
+	if (p->gen >= 060) {
 		msg_type = GEN6_DATAPORT_WRITE_MESSAGE_RENDER_TARGET_WRITE;
 		src0 = brw_message_reg(2);
 		header = false;
@@ -219,7 +219,7 @@ static void brw_wm_write(struct brw_compile *p, int dw, int src)
 {
 	int n;
 
-	if (dw == 8 && p->gen >= 60) {
+	if (dw == 8 && p->gen >= 060) {
 		/* XXX pixel execution mask? */
 		brw_set_compression_control(p, BRW_COMPRESSION_NONE);
 
@@ -233,11 +233,11 @@ static void brw_wm_write(struct brw_compile *p, int dw, int src)
 	brw_set_compression_control(p, BRW_COMPRESSION_COMPRESSED);
 
 	for (n = 0; n < 4; n++) {
-		if (p->gen >= 60) {
+		if (p->gen >= 060) {
 			brw_MOV(p,
 				brw_message_reg(2 + 2*n),
 				brw_vec8_grf(src + 2*n, 0));
-		} else if (p->gen >= 45 && dw == 16) {
+		} else if (p->gen >= 045 && dw == 16) {
 			brw_MOV(p,
 				brw_message_reg(2 + n + BRW_MRF_COMPR4),
 				brw_vec8_grf(src + 2*n, 0));
@@ -265,7 +265,7 @@ static void brw_wm_write__mask(struct brw_compile *p, int dw,
 {
 	int n;
 
-	if (dw == 8 && p->gen >= 60) {
+	if (dw == 8 && p->gen >= 060) {
 		brw_set_compression_control(p, BRW_COMPRESSION_NONE);
 
 		brw_MUL(p,
@@ -291,12 +291,12 @@ static void brw_wm_write__mask(struct brw_compile *p, int dw,
 	brw_set_compression_control(p, BRW_COMPRESSION_COMPRESSED);
 
 	for (n = 0; n < 4; n++) {
-		if (p->gen >= 60) {
+		if (p->gen >= 060) {
 			brw_MUL(p,
 				brw_message_reg(2 + 2*n),
 				brw_vec8_grf(src + 2*n, 0),
 				brw_vec8_grf(mask, 0));
-		} else if (p->gen >= 45 && dw == 16) {
+		} else if (p->gen >= 045 && dw == 16) {
 			brw_MUL(p,
 				brw_message_reg(2 + n + BRW_MRF_COMPR4),
 				brw_vec8_grf(src + 2*n, 0),
@@ -327,7 +327,7 @@ static void brw_wm_write__opacity(struct brw_compile *p, int dw,
 {
 	int n;
 
-	if (dw == 8 && p->gen >= 60) {
+	if (dw == 8 && p->gen >= 060) {
 		brw_set_compression_control(p, BRW_COMPRESSION_NONE);
 
 		brw_MUL(p,
@@ -353,12 +353,12 @@ static void brw_wm_write__opacity(struct brw_compile *p, int dw,
 	brw_set_compression_control(p, BRW_COMPRESSION_COMPRESSED);
 
 	for (n = 0; n < 4; n++) {
-		if (p->gen >= 60) {
+		if (p->gen >= 060) {
 			brw_MUL(p,
 				brw_message_reg(2 + 2*n),
 				brw_vec8_grf(src + 2*n, 0),
 				brw_vec1_grf(mask, 3));
-		} else if (p->gen >= 45 && dw == 16) {
+		} else if (p->gen >= 045 && dw == 16) {
 			brw_MUL(p,
 				brw_message_reg(2 + n + BRW_MRF_COMPR4),
 				brw_vec8_grf(src + 2*n, 0),
@@ -389,7 +389,7 @@ static void brw_wm_write__mask_ca(struct brw_compile *p, int dw,
 {
 	int n;
 
-	if (dw == 8 && p->gen >= 60) {
+	if (dw == 8 && p->gen >= 060) {
 		brw_set_compression_control(p, BRW_COMPRESSION_NONE);
 
 		brw_MUL(p,
@@ -415,12 +415,12 @@ static void brw_wm_write__mask_ca(struct brw_compile *p, int dw,
 	brw_set_compression_control(p, BRW_COMPRESSION_COMPRESSED);
 
 	for (n = 0; n < 4; n++) {
-		if (p->gen >= 60) {
+		if (p->gen >= 060) {
 			brw_MUL(p,
 				brw_message_reg(2 + 2*n),
 				brw_vec8_grf(src + 2*n, 0),
 				brw_vec8_grf(mask + 2*n, 0));
-		} else if (p->gen >= 45 && dw == 16) {
+		} else if (p->gen >= 045 && dw == 16) {
 			brw_MUL(p,
 				brw_message_reg(2 + n + BRW_MRF_COMPR4),
 				brw_vec8_grf(src + 2*n, 0),
@@ -449,7 +449,7 @@ done:
 bool
 brw_wm_kernel__affine(struct brw_compile *p, int dispatch)
 {
-	if (p->gen < 60)
+	if (p->gen < 060)
 		brw_wm_xy(p, dispatch);
 	brw_wm_write(p, dispatch, brw_wm_affine(p, dispatch, 0, 1, 12));
 
@@ -461,7 +461,7 @@ brw_wm_kernel__affine_mask(struct brw_compile *p, int dispatch)
 {
 	int src, mask;
 
-	if (p->gen < 60)
+	if (p->gen < 060)
 		brw_wm_xy(p, dispatch);
 
 	src = brw_wm_affine(p, dispatch, 0, 1, 12);
@@ -476,7 +476,7 @@ brw_wm_kernel__affine_mask_ca(struct brw_compile *p, int dispatch)
 {
 	int src, mask;
 
-	if (p->gen < 60)
+	if (p->gen < 060)
 		brw_wm_xy(p, dispatch);
 
 	src = brw_wm_affine(p, dispatch, 0, 1, 12);
@@ -491,7 +491,7 @@ brw_wm_kernel__affine_mask_sa(struct brw_compile *p, int dispatch)
 {
 	int src, mask;
 
-	if (p->gen < 60)
+	if (p->gen < 060)
 		brw_wm_xy(p, dispatch);
 
 	src = brw_wm_affine__alpha(p, dispatch, 0, 1, 12);
@@ -510,15 +510,15 @@ static void brw_wm_projective_st(struct brw_compile *p, int dw,
 
 	if (dw == 16) {
 		brw_set_compression_control(p, BRW_COMPRESSION_COMPRESSED);
-		uv = p->gen >= 60 ? 6 : 3;
+		uv = p->gen >= 060 ? 6 : 3;
 	} else {
 		brw_set_compression_control(p, BRW_COMPRESSION_NONE);
-		uv = p->gen >= 60 ? 4 : 3;
+		uv = p->gen >= 060 ? 4 : 3;
 	}
 	uv += 2*channel;
 
 	msg++;
-	if (p->gen >= 60) {
+	if (p->gen >= 060) {
 		/* First compute 1/z */
 		brw_PLN(p,
 			brw_message_reg(msg),
@@ -594,7 +594,7 @@ static int brw_wm_projective__alpha(struct brw_compile *p, int dw,
 bool
 brw_wm_kernel__projective(struct brw_compile *p, int dispatch)
 {
-	if (p->gen < 60)
+	if (p->gen < 060)
 		brw_wm_xy(p, dispatch);
 	brw_wm_write(p, dispatch, brw_wm_projective(p, dispatch, 0, 1, 12));
 
@@ -606,7 +606,7 @@ brw_wm_kernel__projective_mask(struct brw_compile *p, int dispatch)
 {
 	int src, mask;
 
-	if (p->gen < 60)
+	if (p->gen < 060)
 		brw_wm_xy(p, dispatch);
 
 	src = brw_wm_projective(p, dispatch, 0, 1, 12);
@@ -621,7 +621,7 @@ brw_wm_kernel__projective_mask_ca(struct brw_compile *p, int dispatch)
 {
 	int src, mask;
 
-	if (p->gen < 60)
+	if (p->gen < 060)
 		brw_wm_xy(p, dispatch);
 
 	src = brw_wm_projective(p, dispatch, 0, 1, 12);
@@ -636,7 +636,7 @@ brw_wm_kernel__projective_mask_sa(struct brw_compile *p, int dispatch)
 {
 	int src, mask;
 
-	if (p->gen < 60)
+	if (p->gen < 060)
 		brw_wm_xy(p, dispatch);
 
 	src = brw_wm_projective__alpha(p, dispatch, 0, 1, 12);
@@ -651,7 +651,7 @@ brw_wm_kernel__affine_opacity(struct brw_compile *p, int dispatch)
 {
 	int src, mask;
 
-	if (p->gen < 60) {
+	if (p->gen < 060) {
 		brw_wm_xy(p, dispatch);
 		mask = 5;
 	} else
@@ -668,7 +668,7 @@ brw_wm_kernel__projective_opacity(struct brw_compile *p, int dispatch)
 {
 	int src, mask;
 
-	if (p->gen < 60) {
+	if (p->gen < 060) {
 		brw_wm_xy(p, dispatch);
 		mask = 5;
 	} else
diff --git a/src/sna/g4x_render.c b/src/sna/g4x_render.c
index 49eb178..70faab7 100644
--- a/src/sna/g4x_render.c
+++ b/src/sna/g4x_render.c
@@ -629,7 +629,7 @@ g4x_bind_bo(struct sna *sna,
 	uint32_t domains;
 	uint16_t offset;
 
-	assert(sna->kgem.gen != 40 || !kgem_bo_is_snoop(bo));
+	assert(sna->kgem.gen != 040 || !kgem_bo_is_snoop(bo));
 
 	/* After the first bind, we manage the cache domains within the batch */
 	offset = kgem_bo_get_binding(bo, format);
@@ -1153,7 +1153,7 @@ g4x_emit_invariant(struct sna *sna)
 {
 	assert(sna->kgem.surface == sna->kgem.batch_size);
 
-	if (sna->kgem.gen >= 45)
+	if (sna->kgem.gen >= 045)
 		OUT_BATCH(NEW_PIPELINE_SELECT | PIPELINE_SELECT_3D);
 	else
 		OUT_BATCH(GEN4_PIPELINE_SELECT | PIPELINE_SELECT_3D);
diff --git a/src/sna/gen2_render.c b/src/sna/gen2_render.c
index 31074af..b37af9b 100644
--- a/src/sna/gen2_render.c
+++ b/src/sna/gen2_render.c
@@ -175,7 +175,7 @@ gen2_get_card_format(struct sna *sna, uint32_t format)
 		if (i8xx_tex_formats[i].fmt == format)
 			return i8xx_tex_formats[i].card_fmt;
 
-	if (sna->kgem.gen < 21) {
+	if (sna->kgem.gen < 021) {
 		/* Whilst these are not directly supported on 830/845,
 		 * we only enable them when we can implicitly convert
 		 * them to a supported variant through the texture
@@ -203,7 +203,7 @@ gen2_check_format(struct sna *sna, PicturePtr p)
 		if (i8xx_tex_formats[i].fmt == p->format)
 			return true;
 
-	if (sna->kgem.gen > 21) {
+	if (sna->kgem.gen > 021) {
 		for (i = 0; i < ARRAY_SIZE(i85x_tex_formats); i++)
 			if (i85x_tex_formats[i].fmt == p->format)
 				return true;
@@ -1317,7 +1317,7 @@ gen2_check_card_format(struct sna *sna,
 
 	for (i = 0; i < ARRAY_SIZE(i85x_tex_formats); i++) {
 		if (i85x_tex_formats[i].fmt == format) {
-			if (sna->kgem.gen >= 21)
+			if (sna->kgem.gen >= 021)
 				return true;
 
 			if (source_is_covered(picture, x, y, w,h)) {
diff --git a/src/sna/gen4_render.c b/src/sna/gen4_render.c
index 5134bb9..0484af8 100644
--- a/src/sna/gen4_render.c
+++ b/src/sna/gen4_render.c
@@ -644,7 +644,7 @@ gen4_bind_bo(struct sna *sna,
 	uint32_t domains;
 	uint16_t offset;
 
-	assert(sna->kgem.gen != 40 || !kgem_bo_is_snoop(bo));
+	assert(sna->kgem.gen != 040 || !kgem_bo_is_snoop(bo));
 
 	/* After the first bind, we manage the cache domains within the batch */
 	offset = kgem_bo_get_binding(bo, format);
@@ -1169,7 +1169,7 @@ gen4_emit_invariant(struct sna *sna)
 {
 	assert(sna->kgem.surface == sna->kgem.batch_size);
 
-	if (sna->kgem.gen >= 45)
+	if (sna->kgem.gen >= 045)
 		OUT_BATCH(NEW_PIPELINE_SELECT | PIPELINE_SELECT_3D);
 	else
 		OUT_BATCH(GEN4_PIPELINE_SELECT | PIPELINE_SELECT_3D);
diff --git a/src/sna/gen7_render.c b/src/sna/gen7_render.c
index 50d1b30..9d4e1a2 100644
--- a/src/sna/gen7_render.c
+++ b/src/sna/gen7_render.c
@@ -1373,7 +1373,7 @@ gen7_bind_bo(struct sna *sna,
 	ss[5] = is_dst && bo->scanout ? 0 : 3 << 16;
 	ss[6] = 0;
 	ss[7] = 0;
-	if (sna->kgem.gen == 75)
+	if (sna->kgem.gen == 075)
 		ss[7] |= HSW_SURFACE_SWIZZLE(RED, GREEN, BLUE, ALPHA);
 
 	kgem_bo_set_binding(bo, format, offset);
@@ -4258,14 +4258,14 @@ static bool gen7_render_setup(struct sna *sna)
 	struct gen7_sampler_state *ss;
 	int i, j, k, l, m;
 
-	if (sna->kgem.gen == 70) {
+	if (sna->kgem.gen == 070) {
 		state->info = &ivb_gt_info;
 		if (DEVICE_ID(sna->PciInfo) & 0xf) {
 			state->info = &ivb_gt1_info;
 			if (DEVICE_ID(sna->PciInfo) & 0x20)
 				state->info = &ivb_gt2_info; /* XXX requires GT_MODE WiZ disabled */
 		}
-	} else if (sna->kgem.gen == 75) {
+	} else if (sna->kgem.gen == 075) {
 		state->info = &hsw_gt_info;
 	} else
 		return false;
diff --git a/src/sna/kgem.c b/src/sna/kgem.c
index 32187b1..59b5d24 100644
--- a/src/sna/kgem.c
+++ b/src/sna/kgem.c
@@ -601,7 +601,7 @@ agp_aperture_size(struct pci_device *dev, unsigned gen)
 	/* XXX assume that only future chipsets are unknown and follow
 	 * the post gen2 PCI layout.
 	 */
-	return dev->regions[gen < 30 ? 0 : 2].size;
+	return dev->regions[gen < 030 ? 0 : 2].size;
 }
 
 static size_t
@@ -734,12 +734,12 @@ static bool is_hw_supported(struct kgem *kgem,
 	 * hw acceleration.
 	 */
 
-	if (kgem->gen == 60 && dev->revision < 8) {
+	if (kgem->gen == 060 && dev->revision < 8) {
 		/* pre-production SNB with dysfunctional BLT */
 		return false;
 	}
 
-	if (kgem->gen >= 60) /* Only if the kernel supports the BLT ring */
+	if (kgem->gen >= 060) /* Only if the kernel supports the BLT ring */
 		return kgem->has_blt;
 
 	return true;
@@ -747,7 +747,7 @@ static bool is_hw_supported(struct kgem *kgem,
 
 static bool test_has_relaxed_fencing(struct kgem *kgem)
 {
-	if (kgem->gen < 40) {
+	if (kgem->gen < 040) {
 		if (DBG_NO_RELAXED_FENCING)
 			return false;
 
@@ -768,7 +768,7 @@ static bool test_has_llc(struct kgem *kgem)
 #endif
 	if (has_llc == -1) {
 		DBG(("%s: no kernel/drm support for HAS_LLC, assuming support for LLC based on GPU generation\n", __FUNCTION__));
-		has_llc = kgem->gen >= 60;
+		has_llc = kgem->gen >= 060;
 	}
 
 	return has_llc;
@@ -783,7 +783,7 @@ static bool test_has_cacheing(struct kgem *kgem)
 		return false;
 
 	/* Incoherent blt and sampler hangs the GPU */
-	if (kgem->gen == 40)
+	if (kgem->gen == 040)
 		return false;
 
 	handle = gem_create(kgem->fd, 1);
@@ -805,7 +805,7 @@ static bool test_has_userptr(struct kgem *kgem)
 		return false;
 
 	/* Incoherent blt and sampler hangs the GPU */
-	if (kgem->gen == 40)
+	if (kgem->gen == 040)
 		return false;
 
 	ptr = malloc(PAGE_SIZE);
@@ -886,7 +886,7 @@ void kgem_init(struct kgem *kgem, int fd, struct pci_device *dev, int gen)
 	DBG(("%s: semaphores enabled? %d\n", __FUNCTION__,
 	     kgem->has_semaphores));
 
-	kgem->can_blt_cpu = gen >= 30;
+	kgem->can_blt_cpu = gen >= 030;
 	DBG(("%s: can blt to cpu? %d\n", __FUNCTION__,
 	     kgem->can_blt_cpu));
 
@@ -905,10 +905,10 @@ void kgem_init(struct kgem *kgem, int fd, struct pci_device *dev, int gen)
 	}
 
 	kgem->batch_size = ARRAY_SIZE(kgem->batch);
-	if (gen == 22)
+	if (gen == 022)
 		/* 865g cannot handle a batch spanning multiple pages */
 		kgem->batch_size = PAGE_SIZE / sizeof(uint32_t);
-	if (gen >= 70 && gen < 80)
+	if ((gen >> 3) == 7)
 		kgem->batch_size = 16*1024;
 	if (!kgem->has_relaxed_delta && kgem->batch_size > 4*1024)
 		kgem->batch_size = 4*1024;
@@ -917,7 +917,7 @@ void kgem_init(struct kgem *kgem, int fd, struct pci_device *dev, int gen)
 	     kgem->batch_size));
 
 	kgem->min_alignment = 4;
-	if (gen < 40)
+	if (gen < 040)
 		kgem->min_alignment = 64;
 
 	kgem->half_cpu_cache_pages = cpu_cache_size() >> 13;
@@ -960,7 +960,7 @@ void kgem_init(struct kgem *kgem, int fd, struct pci_device *dev, int gen)
 	kgem->aperture_total = aperture.aper_size;
 	kgem->aperture_high = aperture.aper_size * 3/4;
 	kgem->aperture_low = aperture.aper_size * 1/3;
-	if (gen < 33) {
+	if (gen < 033) {
 		/* Severe alignment penalties */
 		kgem->aperture_high /= 2;
 		kgem->aperture_low /= 2;
@@ -986,7 +986,7 @@ void kgem_init(struct kgem *kgem, int fd, struct pci_device *dev, int gen)
 	kgem->max_gpu_size = kgem->max_object_size;
 	if (!kgem->has_llc)
 		kgem->max_gpu_size = MAX_CACHE_SIZE;
-	if (gen < 40) {
+	if (gen < 040) {
 		/* If we have to use fences for blitting, we have to make
 		 * sure we can fit them into the aperture.
 		 */
@@ -1008,7 +1008,7 @@ void kgem_init(struct kgem *kgem, int fd, struct pci_device *dev, int gen)
 		kgem->max_gpu_size = totalram / 4;
 
 	half_gpu_max = kgem->max_gpu_size / 2;
-	if (kgem->gen >= 40)
+	if (kgem->gen >= 040)
 		kgem->max_cpu_size = half_gpu_max;
 	else
 		kgem->max_cpu_size = kgem->max_object_size;
@@ -1085,9 +1085,9 @@ static uint32_t kgem_untiled_pitch(struct kgem *kgem,
 void kgem_get_tile_size(struct kgem *kgem, int tiling,
 			int *tile_width, int *tile_height, int *tile_size)
 {
-	if (kgem->gen <= 30) {
+	if (kgem->gen <= 030) {
 		if (tiling) {
-			if (kgem->gen < 30) {
+			if (kgem->gen < 030) {
 				*tile_width = 128;
 				*tile_height = 16;
 				*tile_size = 2048;
@@ -1136,9 +1136,9 @@ static uint32_t kgem_surface_size(struct kgem *kgem,
 	assert(width <= MAXSHORT);
 	assert(height <= MAXSHORT);
 
-	if (kgem->gen <= 30) {
+	if (kgem->gen <= 030) {
 		if (tiling) {
-			if (kgem->gen < 30) {
+			if (kgem->gen < 030) {
 				tile_width = 128;
 				tile_height = 16;
 			} else {
@@ -1173,7 +1173,7 @@ static uint32_t kgem_surface_size(struct kgem *kgem,
 
 	*pitch = ALIGN(width * bpp / 8, tile_width);
 	height = ALIGN(height, tile_height);
-	if (kgem->gen >= 40)
+	if (kgem->gen >= 040)
 		return PAGE_ALIGN(*pitch * height);
 
 	/* If it is too wide for the blitter, don't even bother.  */
@@ -1194,7 +1194,7 @@ static uint32_t kgem_surface_size(struct kgem *kgem,
 		return PAGE_ALIGN(size);
 
 	/*  We need to allocate a pot fence region for a tiled buffer. */
-	if (kgem->gen < 30)
+	if (kgem->gen < 030)
 		tile_width = 512 * 1024;
 	else
 		tile_width = 1024 * 1024;
@@ -1208,8 +1208,8 @@ static uint32_t kgem_aligned_height(struct kgem *kgem,
 {
 	uint32_t tile_height;
 
-	if (kgem->gen <= 30) {
-		tile_height = tiling ? kgem->gen < 30 ? 16 : 8 : 1;
+	if (kgem->gen <= 030) {
+		tile_height = tiling ? kgem->gen < 030 ? 16 : 8 : 1;
 	} else switch (tiling) {
 		/* XXX align to an even tile row */
 	default:
@@ -2770,7 +2770,7 @@ search_linear_cache(struct kgem *kgem, unsigned int num_pages, unsigned flags)
 			continue;
 
 		if (use_active &&
-		    kgem->gen <= 40 &&
+		    kgem->gen <= 040 &&
 		    bo->tiling != I915_TILING_NONE)
 			continue;
 
@@ -2985,7 +2985,7 @@ int kgem_choose_tiling(struct kgem *kgem, int tiling, int width, int height, int
 	if (DBG_NO_TILING)
 		return tiling < 0 ? tiling : I915_TILING_NONE;
 
-	if (kgem->gen < 40) {
+	if (kgem->gen < 040) {
 		if (tiling && width * bpp > 8192 * 8) {
 			DBG(("%s: pitch too large for tliing [%d]\n",
 			     __FUNCTION__, width*bpp/8));
@@ -2994,7 +2994,7 @@ int kgem_choose_tiling(struct kgem *kgem, int tiling, int width, int height, int
 		}
 	} else {
 		/* XXX rendering to I915_TILING_Y seems broken? */
-		if (kgem->gen < 50 && tiling == I915_TILING_Y)
+		if (kgem->gen < 050 && tiling == I915_TILING_Y)
 			tiling = I915_TILING_X;
 
 		if (width*bpp > (MAXSHORT-512) * 8) {
@@ -3147,9 +3147,9 @@ inline int kgem_bo_fenced_size(struct kgem *kgem, struct kgem_bo *bo)
 	unsigned int size;
 
 	assert(bo->tiling);
-	assert(kgem->gen < 40);
+	assert(kgem->gen < 040);
 
-	if (kgem->gen < 30)
+	if (kgem->gen < 030)
 		size = 512 * 1024;
 	else
 		size = 1024 * 1024;
@@ -3206,7 +3206,7 @@ struct kgem_bo *kgem_create_2d(struct kgem *kgem,
 			assert(bo->refcnt == 0);
 			assert(bo->reusable);
 
-			if (kgem->gen < 40) {
+			if (kgem->gen < 040) {
 				if (bo->pitch < pitch) {
 					DBG(("tiled and pitch too small: tiling=%d, (want %d), pitch=%d, need %d\n",
 					     bo->tiling, tiling,
@@ -3348,7 +3348,7 @@ search_again:
 			assert(bo->reusable);
 			assert(bo->tiling == tiling);
 
-			if (kgem->gen < 40) {
+			if (kgem->gen < 040) {
 				if (bo->pitch < pitch) {
 					DBG(("tiled and pitch too small: tiling=%d, (want %d), pitch=%d, need %d\n",
 					     bo->tiling, tiling,
@@ -3406,7 +3406,7 @@ search_again:
 	}
 
 	if (--retry && flags & CREATE_EXACT) {
-		if (kgem->gen >= 40) {
+		if (kgem->gen >= 040) {
 			for (i = I915_TILING_NONE; i <= I915_TILING_Y; i++) {
 				if (i == tiling)
 					continue;
@@ -3772,7 +3772,7 @@ bool kgem_check_bo_fenced(struct kgem *kgem, struct kgem_bo *bo)
 	while (bo->proxy)
 		bo = bo->proxy;
 	if (bo->exec) {
-		if (kgem->gen < 40 &&
+		if (kgem->gen < 040 &&
 		    bo->tiling != I915_TILING_NONE &&
 		    (bo->exec->flags & EXEC_OBJECT_NEEDS_FENCE) == 0) {
 			if (kgem->nfence >= kgem->fence_max)
@@ -3796,7 +3796,7 @@ bool kgem_check_bo_fenced(struct kgem *kgem, struct kgem_bo *bo)
 	if (kgem->aperture + num_pages(bo) > kgem->aperture_high)
 		return false;
 
-	if (kgem->gen < 40 && bo->tiling != I915_TILING_NONE) {
+	if (kgem->gen < 040 && bo->tiling != I915_TILING_NONE) {
 		if (kgem->nfence >= kgem->fence_max)
 			return false;
 
@@ -3829,7 +3829,7 @@ bool kgem_check_many_bo_fenced(struct kgem *kgem, ...)
 		while (bo->proxy)
 			bo = bo->proxy;
 		if (bo->exec) {
-			if (kgem->gen >= 40 || bo->tiling == I915_TILING_NONE)
+			if (kgem->gen >= 040 || bo->tiling == I915_TILING_NONE)
 				continue;
 
 			if ((bo->exec->flags & EXEC_OBJECT_NEEDS_FENCE) == 0) {
@@ -3842,7 +3842,7 @@ bool kgem_check_many_bo_fenced(struct kgem *kgem, ...)
 
 		num_pages += num_pages(bo);
 		num_exec++;
-		if (kgem->gen < 40 && bo->tiling) {
+		if (kgem->gen < 040 && bo->tiling) {
 			fenced_size += kgem_bo_fenced_size(kgem, bo);
 			num_fence++;
 		}
@@ -3916,7 +3916,7 @@ uint32_t kgem_add_reloc(struct kgem *kgem,
 			kgem_add_bo(kgem, bo);
 		assert(bo->rq == kgem->next_request);
 
-		if (kgem->gen < 40 && read_write_domain & KGEM_RELOC_FENCED) {
+		if (kgem->gen < 040 && read_write_domain & KGEM_RELOC_FENCED) {
 			if (bo->tiling &&
 			    (bo->exec->flags & EXEC_OBJECT_NEEDS_FENCE) == 0) {
 				assert(kgem->nfence < kgem->fence_max);
@@ -4072,7 +4072,7 @@ void *kgem_bo_map(struct kgem *kgem, struct kgem_bo *bo)
 	ptr = bo->map;
 	if (ptr == NULL) {
 		assert(kgem_bo_size(bo) <= kgem->aperture_mappable / 2);
-		assert(kgem->gen != 21 || bo->tiling != I915_TILING_Y);
+		assert(kgem->gen != 021 || bo->tiling != I915_TILING_Y);
 
 		kgem_trim_vma_cache(kgem, MAP_GTT, bucket(bo));
 
@@ -4439,7 +4439,7 @@ static inline bool
 use_snoopable_buffer(struct kgem *kgem, uint32_t flags)
 {
 	if ((flags & KGEM_BUFFER_WRITE) == 0)
-		return kgem->gen >= 30;
+		return kgem->gen >= 030;
 
 	return true;
 }
@@ -5202,7 +5202,7 @@ kgem_replace_bo(struct kgem *kgem,
 	br00 = XY_SRC_COPY_BLT_CMD;
 	br13 = pitch;
 	pitch = src->pitch;
-	if (kgem->gen >= 40 && src->tiling) {
+	if (kgem->gen >= 040 && src->tiling) {
 		br00 |= BLT_SRC_TILED;
 		pitch >>= 2;
 	}
diff --git a/src/sna/kgem.h b/src/sna/kgem.h
index c20b4f3..63b3857 100644
--- a/src/sna/kgem.h
+++ b/src/sna/kgem.h
@@ -460,7 +460,7 @@ static inline bool kgem_bo_blt_pitch_is_ok(struct kgem *kgem,
 					   struct kgem_bo *bo)
 {
 	int pitch = bo->pitch;
-	if (kgem->gen >= 40 && bo->tiling)
+	if (kgem->gen >= 040 && bo->tiling)
 		pitch /= 4;
 	if (pitch > MAXSHORT) {
 		DBG(("%s: can not blt to handle=%d, adjusted pitch=%d\n",
@@ -489,7 +489,7 @@ static inline bool __kgem_bo_is_mappable(struct kgem *kgem,
 	if (bo->domain == DOMAIN_GTT)
 		return true;
 
-	if (kgem->gen < 40 && bo->tiling &&
+	if (kgem->gen < 040 && bo->tiling &&
 	    bo->presumed_offset & (kgem_bo_fenced_size(kgem, bo) - 1))
 		return false;
 
@@ -528,7 +528,7 @@ static inline bool kgem_bo_can_map(struct kgem *kgem, struct kgem_bo *bo)
 	if (!bo->tiling && kgem->has_llc)
 		return true;
 
-	if (kgem->gen == 21 && bo->tiling == I915_TILING_Y)
+	if (kgem->gen == 021 && bo->tiling == I915_TILING_Y)
 		return false;
 
 	return kgem_bo_size(bo) <= kgem->aperture_mappable / 4;
diff --git a/src/sna/kgem_debug.c b/src/sna/kgem_debug.c
index 2dc1b45..595c20f 100644
--- a/src/sna/kgem_debug.c
+++ b/src/sna/kgem_debug.c
@@ -273,7 +273,7 @@ decode_2d(struct kgem *kgem, uint32_t offset)
 				 kgem_debug_handle_is_fenced(kgem, reloc->target_handle),
 				 kgem_debug_handle_tiling(kgem, reloc->target_handle));
 		kgem_debug_print(data, offset, 5, "color\n");
-		assert(kgem->gen >= 40 ||
+		assert(kgem->gen >= 040 ||
 		       kgem_debug_handle_is_fenced(kgem, reloc->target_handle));
 		return len;
 
@@ -321,7 +321,7 @@ decode_2d(struct kgem *kgem, uint32_t offset)
 				 reloc->read_domains, reloc->write_domain,
 				 kgem_debug_handle_is_fenced(kgem, reloc->target_handle),
 				 kgem_debug_handle_tiling(kgem, reloc->target_handle));
-		assert(kgem->gen >= 40 ||
+		assert(kgem->gen >= 040 ||
 		       kgem_debug_handle_is_fenced(kgem, reloc->target_handle));
 
 		kgem_debug_print(data, offset, 5, "src (%d,%d)\n",
@@ -336,7 +336,7 @@ decode_2d(struct kgem *kgem, uint32_t offset)
 				 reloc->read_domains, reloc->write_domain,
 				 kgem_debug_handle_is_fenced(kgem, reloc->target_handle),
 				 kgem_debug_handle_tiling(kgem, reloc->target_handle));
-		assert(kgem->gen >= 40 ||
+		assert(kgem->gen >= 040 ||
 		       kgem_debug_handle_is_fenced(kgem, reloc->target_handle));
 
 		return len;
@@ -368,18 +368,18 @@ decode_2d(struct kgem *kgem, uint32_t offset)
 
 static int (*decode_3d(int gen))(struct kgem*, uint32_t)
 {
-	if (gen >= 80) {
-	} else if (gen >= 70) {
+	if (gen >= 0100) {
+	} else if (gen >= 070) {
 		return kgem_gen7_decode_3d;
-	} else if (gen >= 60) {
+	} else if (gen >= 060) {
 		return kgem_gen6_decode_3d;
-	} else if (gen >= 50) {
+	} else if (gen >= 050) {
 		return kgem_gen5_decode_3d;
-	} else if (gen >= 40) {
+	} else if (gen >= 040) {
 		return kgem_gen4_decode_3d;
-	} else if (gen >= 30) {
+	} else if (gen >= 030) {
 		return kgem_gen3_decode_3d;
-	} else if (gen >= 20) {
+	} else if (gen >= 020) {
 		return kgem_gen2_decode_3d;
 	}
 	assert(0);
@@ -387,18 +387,18 @@ static int (*decode_3d(int gen))(struct kgem*, uint32_t)
 
 static void (*finish_state(int gen))(struct kgem*)
 {
-	if (gen >= 80) {
-	} else if (gen >= 70) {
+	if (gen >= 0100) {
+	} else if (gen >= 070) {
 		return kgem_gen7_finish_state;
-	} else if (gen >= 60) {
+	} else if (gen >= 060) {
 		return kgem_gen6_finish_state;
-	} else if (gen >= 50) {
+	} else if (gen >= 050) {
 		return kgem_gen5_finish_state;
-	} else if (gen >= 40) {
+	} else if (gen >= 040) {
 		return kgem_gen4_finish_state;
-	} else if (gen >= 30) {
+	} else if (gen >= 030) {
 		return kgem_gen3_finish_state;
-	} else if (gen >= 20) {
+	} else if (gen >= 020) {
 		return kgem_gen2_finish_state;
 	}
 	assert(0);
diff --git a/src/sna/kgem_debug_gen6.c b/src/sna/kgem_debug_gen6.c
index e0b09d5..fd3f789 100644
--- a/src/sna/kgem_debug_gen6.c
+++ b/src/sna/kgem_debug_gen6.c
@@ -643,7 +643,7 @@ int kgem_gen6_decode_3d(struct kgem *kgem, uint32_t offset)
 	case 0x6101:
 		i = 0;
 		kgem_debug_print(data, offset, i++, "STATE_BASE_ADDRESS\n");
-		if (kgem->gen >= 60) {
+		if (kgem->gen >= 060) {
 			assert(len == 10);
 
 			state_base_out(data, offset, i++, "general");
@@ -658,7 +658,7 @@ int kgem_gen6_decode_3d(struct kgem *kgem, uint32_t offset)
 			state_max_out(data, offset, i++, "instruction");
 
 			gen6_update_dynamic_buffer(kgem, offset + 3);
-		} else if (kgem->gen >= 50) {
+		} else if (kgem->gen >= 050) {
 			assert(len == 8);
 
 			state_base_out(data, offset, i++, "general");
@@ -674,7 +674,7 @@ int kgem_gen6_decode_3d(struct kgem *kgem, uint32_t offset)
 		return len;
 
 	case 0x7801:
-		if (kgem->gen >= 60) {
+		if (kgem->gen >= 060) {
 			assert(len == 4);
 
 			kgem_debug_print(data, offset, 0,
@@ -686,7 +686,7 @@ int kgem_gen6_decode_3d(struct kgem *kgem, uint32_t offset)
 			kgem_debug_print(data, offset, 1, "VS binding table\n");
 			kgem_debug_print(data, offset, 2, "GS binding table\n");
 			kgem_debug_print(data, offset, 3, "WM binding table\n");
-		} else if (kgem->gen >= 40) {
+		} else if (kgem->gen >= 040) {
 			assert(len == 6);
 
 			kgem_debug_print(data, offset, 0,
diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c
index 79514c5..ca28b06 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -496,14 +496,14 @@ static inline uint32_t default_tiling(PixmapPtr pixmap,
 	struct sna *sna = to_sna_from_pixmap(pixmap);
 
 	/* Try to avoid hitting the Y-tiling GTT mapping bug on 855GM */
-	if (sna->kgem.gen == 21)
+	if (sna->kgem.gen == 021)
 		return I915_TILING_X;
 
 	/* Only on later generations was the render pipeline
 	 * more flexible than the BLT. So on gen2/3, prefer to
 	 * keep large objects accessible through the BLT.
 	 */
-	if (sna->kgem.gen < 40 &&
+	if (sna->kgem.gen < 040 &&
 	    (pixmap->drawable.width  > sna->render.max_3d_size ||
 	     pixmap->drawable.height > sna->render.max_3d_size))
 		return I915_TILING_X;
@@ -3848,7 +3848,7 @@ sna_put_xybitmap_blt(DrawablePtr drawable, GCPtr gc, RegionPtr region,
 		b[0] = XY_MONO_SRC_COPY | 3 << 20;
 		b[0] |= ((box->x1 - x) & 7) << 17;
 		b[1] = bo->pitch;
-		if (sna->kgem.gen >= 40 && bo->tiling) {
+		if (sna->kgem.gen >= 040 && bo->tiling) {
 			b[0] |= BLT_DST_TILED;
 			b[1] >>= 2;
 		}
@@ -3976,7 +3976,7 @@ sna_put_xypixmap_blt(DrawablePtr drawable, GCPtr gc, RegionPtr region,
 			b[0] = XY_FULL_MONO_PATTERN_MONO_SRC_BLT | 3 << 20;
 			b[0] |= ((box->x1 - x) & 7) << 17;
 			b[1] = bo->pitch;
-			if (sna->kgem.gen >= 40 && bo->tiling) {
+			if (sna->kgem.gen >= 040 && bo->tiling) {
 				b[0] |= BLT_DST_TILED;
 				b[1] >>= 2;
 			}
@@ -6128,7 +6128,7 @@ sna_copy_bitmap_blt(DrawablePtr _bitmap, DrawablePtr drawable, GCPtr gc,
 
 	br00 = 3 << 20;
 	br13 = arg->bo->pitch;
-	if (sna->kgem.gen >= 40 && arg->bo->tiling) {
+	if (sna->kgem.gen >= 040 && arg->bo->tiling) {
 		br00 |= BLT_DST_TILED;
 		br13 >>= 2;
 	}
@@ -6292,7 +6292,7 @@ sna_copy_plane_blt(DrawablePtr source, DrawablePtr drawable, GCPtr gc,
 
 	br00 = XY_MONO_SRC_COPY | 3 << 20;
 	br13 = arg->bo->pitch;
-	if (sna->kgem.gen >= 40 && arg->bo->tiling) {
+	if (sna->kgem.gen >= 040 && arg->bo->tiling) {
 		br00 |= BLT_DST_TILED;
 		br13 >>= 2;
 	}
@@ -9900,7 +9900,7 @@ sna_poly_fill_rect_tiled_8x8_blt(DrawablePtr drawable,
 
 	br00 = XY_SCANLINE_BLT;
 	br13 = bo->pitch;
-	if (sna->kgem.gen >= 40 && bo->tiling) {
+	if (sna->kgem.gen >= 040 && bo->tiling) {
 		br00 |= BLT_DST_TILED;
 		br13 >>= 2;
 	}
@@ -10504,7 +10504,7 @@ sna_poly_fill_rect_stippled_8x8_blt(DrawablePtr drawable,
 		DBG(("%s: pat offset (%d, %d)\n", __FUNCTION__ ,px, py));
 		br00 = XY_SCANLINE_BLT | px << 12 | py << 8 | 3 << 20;
 		br13 = bo->pitch;
-		if (sna->kgem.gen >= 40 && bo->tiling) {
+		if (sna->kgem.gen >= 040 && bo->tiling) {
 			br00 |= BLT_DST_TILED;
 			br13 >>= 2;
 		}
@@ -10804,7 +10804,7 @@ sna_poly_fill_rect_stippled_1_blt(DrawablePtr drawable,
 
 	br00 = 3 << 20;
 	br13 = bo->pitch;
-	if (sna->kgem.gen >= 40 && bo->tiling) {
+	if (sna->kgem.gen >= 040 && bo->tiling) {
 		br00 |= BLT_DST_TILED;
 		br13 >>= 2;
 	}
@@ -11500,7 +11500,7 @@ sna_poly_fill_rect_stippled_n_blt__imm(DrawablePtr drawable,
 
 	br00 = XY_MONO_SRC_COPY_IMM | 3 << 20;
 	br13 = bo->pitch;
-	if (sna->kgem.gen >= 40 && bo->tiling) {
+	if (sna->kgem.gen >= 040 && bo->tiling) {
 		br00 |= BLT_DST_TILED;
 		br13 >>= 2;
 	}
@@ -11645,7 +11645,7 @@ sna_poly_fill_rect_stippled_n_blt(DrawablePtr drawable,
 
 	br00 = XY_MONO_SRC_COPY | 3 << 20;
 	br13 = bo->pitch;
-	if (sna->kgem.gen >= 40 && bo->tiling) {
+	if (sna->kgem.gen >= 040 && bo->tiling) {
 		br00 |= BLT_DST_TILED;
 		br13 >>= 2;
 	}
@@ -12298,7 +12298,7 @@ sna_glyph_blt(DrawablePtr drawable, GCPtr gc,
 	b = sna->kgem.batch + sna->kgem.nbatch;
 	b[0] = XY_SETUP_BLT | 3 << 20;
 	b[1] = bo->pitch;
-	if (sna->kgem.gen >= 40 && bo->tiling) {
+	if (sna->kgem.gen >= 040 && bo->tiling) {
 		b[0] |= BLT_DST_TILED;
 		b[1] >>= 2;
 	}
@@ -12316,7 +12316,7 @@ sna_glyph_blt(DrawablePtr drawable, GCPtr gc,
 	sna->kgem.nbatch += 8;
 
 	br00 = XY_TEXT_IMMEDIATE_BLT;
-	if (bo->tiling && sna->kgem.gen >= 40)
+	if (bo->tiling && sna->kgem.gen >= 040)
 		br00 |= BLT_DST_TILED;
 
 	do {
@@ -12361,7 +12361,7 @@ sna_glyph_blt(DrawablePtr drawable, GCPtr gc,
 				b = sna->kgem.batch + sna->kgem.nbatch;
 				b[0] = XY_SETUP_BLT | 3 << 20;
 				b[1] = bo->pitch;
-				if (sna->kgem.gen >= 40 && bo->tiling) {
+				if (sna->kgem.gen >= 040 && bo->tiling) {
 					b[0] |= BLT_DST_TILED;
 					b[1] >>= 2;
 				}
@@ -12942,7 +12942,7 @@ sna_reversed_glyph_blt(DrawablePtr drawable, GCPtr gc,
 	b = sna->kgem.batch + sna->kgem.nbatch;
 	b[0] = XY_SETUP_BLT | 1 << 20;
 	b[1] = bo->pitch;
-	if (sna->kgem.gen >= 40 && bo->tiling) {
+	if (sna->kgem.gen >= 040 && bo->tiling) {
 		b[0] |= BLT_DST_TILED;
 		b[1] >>= 2;
 	}
@@ -13023,7 +13023,7 @@ sna_reversed_glyph_blt(DrawablePtr drawable, GCPtr gc,
 				b = sna->kgem.batch + sna->kgem.nbatch;
 				b[0] = XY_SETUP_BLT | 1 << 20;
 				b[1] = bo->pitch;
-				if (sna->kgem.gen >= 40 && bo->tiling) {
+				if (sna->kgem.gen >= 040 && bo->tiling) {
 					b[0] |= BLT_DST_TILED;
 					b[1] >>= 2;
 				}
@@ -13046,7 +13046,7 @@ sna_reversed_glyph_blt(DrawablePtr drawable, GCPtr gc,
 			sna->kgem.nbatch += 3 + len;
 
 			b[0] = XY_TEXT_IMMEDIATE_BLT | (1 + len);
-			if (bo->tiling && sna->kgem.gen >= 40)
+			if (bo->tiling && sna->kgem.gen >= 040)
 				b[0] |= BLT_DST_TILED;
 			b[1] = (uint16_t)y1 << 16 | (uint16_t)x1;
 			b[2] = (uint16_t)(y1+h) << 16 | (uint16_t)(x1+w);
@@ -13358,7 +13358,7 @@ sna_push_pixels_solid_blt(GCPtr gc,
 		b[0] = XY_MONO_SRC_COPY | 3 << 20;
 		b[0] |= ((box->x1 - region->extents.x1) & 7) << 17;
 		b[1] = bo->pitch;
-		if (sna->kgem.gen >= 40 && bo->tiling) {
+		if (sna->kgem.gen >= 040 && bo->tiling) {
 			b[0] |= BLT_DST_TILED;
 			b[1] >>= 2;
 		}
@@ -14275,26 +14275,26 @@ bool sna_accel_init(ScreenPtr screen, struct sna *sna)
 	no_render_init(sna);
 
 #if !DEBUG_NO_RENDER
-	if (sna->info->gen >= 80) {
-	} else if (sna->info->gen >= 70) {
+	if (sna->info->gen >= 0100) {
+	} else if (sna->info->gen >= 070) {
 		if ((sna->have_render = gen7_render_init(sna)))
 			backend = "IvyBridge";
-	} else if (sna->info->gen >= 60) {
+	} else if (sna->info->gen >= 060) {
 		if ((sna->have_render = gen6_render_init(sna)))
 			backend = "SandyBridge";
-	} else if (sna->info->gen >= 50) {
+	} else if (sna->info->gen >= 050) {
 		if ((sna->have_render = gen5_render_init(sna)))
 			backend = "Ironlake";
-	} else if (sna->info->gen >= 45) {
+	} else if (sna->info->gen >= 045) {
 		if ((sna->have_render = g4x_render_init(sna)))
 			backend = "Eaglelake/Cantiga";
-	} else if (sna->info->gen >= 40) {
+	} else if (sna->info->gen >= 040) {
 		if ((sna->have_render = gen4_render_init(sna)))
 			backend = "Broadwater/Crestline";
-	} else if (sna->info->gen >= 30) {
+	} else if (sna->info->gen >= 030) {
 		if ((sna->have_render = gen3_render_init(sna)))
 			backend = "gen3";
-	} else if (sna->info->gen >= 20) {
+	} else if (sna->info->gen >= 020) {
 		if ((sna->have_render = gen2_render_init(sna)))
 			backend = "gen2";
 	}
diff --git a/src/sna/sna_blt.c b/src/sna/sna_blt.c
index a260423..ef8b4f1 100644
--- a/src/sna/sna_blt.c
+++ b/src/sna/sna_blt.c
@@ -119,7 +119,7 @@ static bool sna_blt_fill_init(struct sna *sna,
 
 	blt->br13 = bo->pitch;
 	blt->cmd = XY_SCANLINE_BLT;
-	if (kgem->gen >= 40 && bo->tiling) {
+	if (kgem->gen >= 040 && bo->tiling) {
 		blt->cmd |= BLT_DST_TILED;
 		blt->br13 >>= 2;
 	}
@@ -267,14 +267,14 @@ static bool sna_blt_copy_init(struct sna *sna,
 		blt->cmd |= BLT_WRITE_ALPHA | BLT_WRITE_RGB;
 
 	blt->pitch[0] = src->pitch;
-	if (kgem->gen >= 40 && src->tiling) {
+	if (kgem->gen >= 040 && src->tiling) {
 		blt->cmd |= BLT_SRC_TILED;
 		blt->pitch[0] >>= 2;
 	}
 	assert(blt->pitch[0] <= MAXSHORT);
 
 	blt->pitch[1] = dst->pitch;
-	if (kgem->gen >= 40 && dst->tiling) {
+	if (kgem->gen >= 040 && dst->tiling) {
 		blt->cmd |= BLT_DST_TILED;
 		blt->pitch[1] >>= 2;
 	}
@@ -317,14 +317,14 @@ static bool sna_blt_alpha_fixup_init(struct sna *sna,
 
 	blt->cmd = XY_FULL_MONO_PATTERN_BLT;
 	blt->pitch[0] = src->pitch;
-	if (kgem->gen >= 40 && src->tiling) {
+	if (kgem->gen >= 040 && src->tiling) {
 		blt->cmd |= BLT_SRC_TILED;
 		blt->pitch[0] >>= 2;
 	}
 	assert(blt->pitch[0] <= MAXSHORT);
 
 	blt->pitch[1] = dst->pitch;
-	if (kgem->gen >= 40 && dst->tiling) {
+	if (kgem->gen >= 040 && dst->tiling) {
 		blt->cmd |= BLT_DST_TILED;
 		blt->pitch[1] >>= 2;
 	}
@@ -1256,7 +1256,7 @@ prepare_blt_copy(struct sna *sna,
 
 	DBG(("%s\n", __FUNCTION__));
 
-	if (sna->kgem.gen >= 60)
+	if (sna->kgem.gen >= 060)
 		op->done = gen6_blt_copy_done;
 	else
 		op->done = nop_done;
@@ -1942,7 +1942,7 @@ static void convert_done(struct sna *sna, const struct sna_composite_op *op)
 {
 	struct kgem *kgem = &sna->kgem;
 
-	if (kgem->gen >= 60 && kgem_check_batch(kgem, 3)) {
+	if (kgem->gen >= 060 && kgem_check_batch(kgem, 3)) {
 		uint32_t *b = kgem->batch + kgem->nbatch;
 		b[0] = XY_SETUP_CLIP;
 		b[1] = b[2] = 0;
@@ -2185,7 +2185,7 @@ bool sna_blt_copy(struct sna *sna, uint8_t alu,
 		return false;
 
 	op->blt  = sna_blt_copy_op_blt;
-	if (sna->kgem.gen >= 60)
+	if (sna->kgem.gen >= 060)
 		op->done = gen6_blt_copy_op_done;
 	else
 		op->done = sna_blt_copy_op_done;
@@ -2211,7 +2211,7 @@ static bool sna_blt_fill_box(struct sna *sna, uint8_t alu,
 
 	cmd = XY_COLOR_BLT;
 	br13 = bo->pitch;
-	if (kgem->gen >= 40 && bo->tiling) {
+	if (kgem->gen >= 040 && bo->tiling) {
 		cmd |= BLT_DST_TILED;
 		br13 >>= 2;
 	}
@@ -2325,7 +2325,7 @@ bool sna_blt_fill_boxes(struct sna *sna, uint8_t alu,
 
 	br13 = bo->pitch;
 	cmd = XY_SCANLINE_BLT;
-	if (kgem->gen >= 40 && bo->tiling) {
+	if (kgem->gen >= 040 && bo->tiling) {
 		cmd |= 1 << 11;
 		br13 >>= 2;
 	}
@@ -2479,14 +2479,14 @@ bool sna_blt_copy_boxes(struct sna *sna, uint8_t alu,
 		cmd |= BLT_WRITE_ALPHA | BLT_WRITE_RGB;
 
 	src_pitch = src_bo->pitch;
-	if (kgem->gen >= 40 && src_bo->tiling) {
+	if (kgem->gen >= 040 && src_bo->tiling) {
 		cmd |= BLT_SRC_TILED;
 		src_pitch >>= 2;
 	}
 	assert(src_pitch <= MAXSHORT);
 
 	br13 = dst_bo->pitch;
-	if (kgem->gen >= 40 && dst_bo->tiling) {
+	if (kgem->gen >= 040 && dst_bo->tiling) {
 		cmd |= BLT_DST_TILED;
 		br13 >>= 2;
 	}
@@ -2632,7 +2632,7 @@ bool sna_blt_copy_boxes(struct sna *sna, uint8_t alu,
 		} while (1);
 	}
 
-	if (kgem->gen >= 60 && kgem_check_batch(kgem, 3)) {
+	if (kgem->gen >= 060 && kgem_check_batch(kgem, 3)) {
 		uint32_t *b = kgem->batch + kgem->nbatch;
 		b[0] = XY_SETUP_CLIP;
 		b[1] = b[2] = 0;
diff --git a/src/sna/sna_display.c b/src/sna/sna_display.c
index cec2af3..8dc1058 100644
--- a/src/sna/sna_display.c
+++ b/src/sna/sna_display.c
@@ -2919,13 +2919,13 @@ sna_wait_for_scanline(struct sna *sna,
 	DBG(("%s: pipe=%d, y1=%d, y2=%d, full_height?=%d\n",
 	     __FUNCTION__, pipe, y1, y2, full_height));
 
-	if (sna->kgem.gen >= 80)
+	if (sna->kgem.gen >= 0100)
 		ret = false;
-	else if (sna->kgem.gen >= 70)
+	else if (sna->kgem.gen >= 070)
 		ret = sna_emit_wait_for_scanline_gen7(sna, pipe, y1, y2, full_height);
-	else if (sna->kgem.gen >= 60)
+	else if (sna->kgem.gen >= 060)
 		ret =sna_emit_wait_for_scanline_gen6(sna, pipe, y1, y2, full_height);
-	else if (sna->kgem.gen >= 40)
+	else if (sna->kgem.gen >= 040)
 		ret = sna_emit_wait_for_scanline_gen4(sna, pipe, y1, y2, full_height);
 	else
 		ret = sna_emit_wait_for_scanline_gen2(sna, pipe, y1, y2, full_height);
diff --git a/src/sna/sna_dri.c b/src/sna/sna_dri.c
index 82d9485..2568c6b 100644
--- a/src/sna/sna_dri.c
+++ b/src/sna/sna_dri.c
@@ -497,7 +497,7 @@ static void sna_dri_select_mode(struct sna *sna, struct kgem_bo *src, bool sync)
 	struct drm_i915_gem_busy busy;
 	int mode;
 
-	if (sna->kgem.gen < 60) {
+	if (sna->kgem.gen < 060) {
 		kgem_set_mode(&sna->kgem, KGEM_BLT);
 		return;
 	}
@@ -2419,7 +2419,7 @@ static const char *dri_driver_name(struct sna *sna)
 	Bool dummy;
 
 	if (s == NULL || xf86getBoolValue(&dummy, s))
-		return (sna->kgem.gen && sna->kgem.gen < 40) ? "i915" : "i965";
+		return (sna->kgem.gen && sna->kgem.gen < 040) ? "i915" : "i965";
 
 	return s;
 }
diff --git a/src/sna/sna_driver.c b/src/sna/sna_driver.c
index 086be6a..7ac44d2 100644
--- a/src/sna/sna_driver.c
+++ b/src/sna/sna_driver.c
@@ -813,7 +813,7 @@ sna_register_all_privates(void)
 static size_t
 agp_aperture_size(struct pci_device *dev, int gen)
 {
-	return dev->regions[gen < 30 ? 0 : 2].size;
+	return dev->regions[gen < 030 ? 0 : 2].size;
 }
 
 static Bool
diff --git a/src/sna/sna_glyphs.c b/src/sna/sna_glyphs.c
index be1ce83..f6c6816 100644
--- a/src/sna/sna_glyphs.c
+++ b/src/sna/sna_glyphs.c
@@ -1091,7 +1091,7 @@ next_image:
 					     (int)this_atlas->format,
 					     (int)(format->depth << 24 | format->format)));
 					if (this_atlas->format == (format->depth << 24 | format->format) &&
-					    sna->kgem.gen != 45) { /* XXX cache corruption? how? */
+					    sna->kgem.gen != 045) { /* XXX cache corruption? how? */
 						ok = sna->render.composite(sna, PictOpAdd,
 									   this_atlas, NULL, mask,
 									   0, 0, 0, 0, 0, 0,
diff --git a/src/sna/sna_io.c b/src/sna/sna_io.c
index 2038e5d..bb7f9f9 100644
--- a/src/sna/sna_io.c
+++ b/src/sna/sna_io.c
@@ -364,7 +364,7 @@ fallback:
 
 	cmd = XY_SRC_COPY_BLT_CMD;
 	src_pitch = src_bo->pitch;
-	if (kgem->gen >= 40 && src_bo->tiling) {
+	if (kgem->gen >= 040 && src_bo->tiling) {
 		cmd |= BLT_SRC_TILED;
 		src_pitch >>= 2;
 	}
@@ -483,7 +483,7 @@ fallback:
 
 static bool upload_inplace__tiled(struct kgem *kgem, struct kgem_bo *bo)
 {
-	if (kgem->gen < 50) /* bit17 swizzling :( */
+	if (kgem->gen < 050) /* bit17 swizzling :( */
 		return false;
 
 	if (bo->tiling != I915_TILING_X)
@@ -811,7 +811,7 @@ tile:
 
 	cmd = XY_SRC_COPY_BLT_CMD;
 	br13 = dst_bo->pitch;
-	if (kgem->gen >= 40 && dst_bo->tiling) {
+	if (kgem->gen >= 040 && dst_bo->tiling) {
 		cmd |= BLT_DST_TILED;
 		br13 >>= 2;
 	}
@@ -1180,7 +1180,7 @@ tile:
 
 	cmd = XY_SRC_COPY_BLT_CMD;
 	br13 = dst_bo->pitch;
-	if (kgem->gen >= 40 && dst_bo->tiling) {
+	if (kgem->gen >= 040 && dst_bo->tiling) {
 		cmd |= BLT_DST_TILED;
 		br13 >>= 2;
 	}
diff --git a/src/sna/sna_render.c b/src/sna/sna_render.c
index 0a2856e..27168ac 100644
--- a/src/sna/sna_render.c
+++ b/src/sna/sna_render.c
@@ -1865,7 +1865,7 @@ sna_render_composite_redirect(struct sna *sna,
 
 			offset = box.x1 * op->dst.pixmap->drawable.bitsPerPixel / 8 / tile_width * tile_size;
 		} else {
-			if (sna->kgem.gen < 40) {
+			if (sna->kgem.gen < 040) {
 				box.y1 = box.y1 & ~3;
 				box.y2 = ALIGN(box.y2, 4);
 
diff --git a/src/sna/sna_video.c b/src/sna/sna_video.c
index 7bf20e9..4345454 100644
--- a/src/sna/sna_video.c
+++ b/src/sna/sna_video.c
@@ -197,12 +197,12 @@ sna_video_frame_init(struct sna *sna,
 	if (video->textured) {
 		align = 4;
 	} else {
-		if (sna->kgem.gen >= 40)
+		if (sna->kgem.gen >= 040)
 			/* Actually the alignment is 64 bytes, too. But the
 			 * stride must be at least 512 bytes. Take the easy fix
 			 * and align on 512 bytes unconditionally. */
 			align = 512;
-		else if (sna->kgem.gen < 21)
+		else if (sna->kgem.gen < 021)
 			/* Harsh, errata on these chipsets limit the stride
 			 * to be a multiple of 256 bytes.
 			 */
@@ -213,7 +213,7 @@ sna_video_frame_init(struct sna *sna,
 
 #if SNA_XVMC
 	/* for i915 xvmc, hw requires 1kb aligned surfaces */
-	if (id == FOURCC_XVMC && sna->kgem.gen < 40)
+	if (id == FOURCC_XVMC && sna->kgem.gen < 040)
 		align = 1024;
 #endif
 
diff --git a/src/sna/sna_video_hwmc.c b/src/sna/sna_video_hwmc.c
index b0e8d25..0eaf051 100644
--- a/src/sna/sna_video_hwmc.c
+++ b/src/sna/sna_video_hwmc.c
@@ -71,14 +71,14 @@ static int create_context(ScrnInfoPtr scrn, XvMCContextPtr pContext,
 
 	*num_priv = sizeof(struct sna_xvmc_hw_context) >> 2;
 
-	if (sna->kgem.gen >= 40) {
-		if (sna->kgem.gen >= 45)
+	if (sna->kgem.gen >= 040) {
+		if (sna->kgem.gen >= 045)
 			contextRec->type = XVMC_I965_MPEG2_VLD;
 		else
 			contextRec->type = XVMC_I965_MPEG2_MC;
-		contextRec->i965.is_g4x = sna->kgem.gen == 45;
+		contextRec->i965.is_g4x = sna->kgem.gen == 045;
 		contextRec->i965.is_965_q = IS_965_Q(sna);
-		contextRec->i965.is_igdng = sna->kgem.gen == 50;
+		contextRec->i965.is_igdng = sna->kgem.gen == 050;
 	} else {
 		contextRec->type = XVMC_I915_MPEG2_MC;
 		contextRec->i915.use_phys_addr = 0;
@@ -196,11 +196,11 @@ Bool sna_video_xvmc_setup(struct sna *sna,
 	char buf[64];
 
 	/* Needs KMS support. */
-	if (sna->kgem.gen < 31)
+	if (sna->kgem.gen < 031)
 		return FALSE;
 
 	/* Not implemented */
-	if (sna->kgem.gen >= 60)
+	if (sna->kgem.gen >= 060)
 		return FALSE;
 
 	pAdapt = calloc(1, sizeof(XF86MCAdaptorRec));
@@ -217,11 +217,11 @@ Bool sna_video_xvmc_setup(struct sna *sna,
 	pAdapt->CreateSubpicture =  create_subpicture;
 	pAdapt->DestroySubpicture = destroy_subpicture;
 
-	if (sna->kgem.gen >= 45) {
+	if (sna->kgem.gen >= 045) {
 		name = "xvmc_vld",
 		pAdapt->num_surfaces = ARRAY_SIZE(surface_info_vld);
 		pAdapt->surfaces = surface_info_vld;
-	} else if (sna->kgem.gen >= 40) {
+	} else if (sna->kgem.gen >= 040) {
 		name = "i965_xvmc",
 		pAdapt->num_surfaces = ARRAY_SIZE(surface_info_i965);
 		pAdapt->surfaces = surface_info_i965;
diff --git a/src/sna/sna_video_overlay.c b/src/sna/sna_video_overlay.c
index a1cc4b9..a1a905a 100644
--- a/src/sna/sna_video_overlay.c
+++ b/src/sna/sna_video_overlay.c
@@ -41,7 +41,7 @@
 
 #define MAKE_ATOM(a) MakeAtom(a, sizeof(a) - 1, TRUE)
 
-#define HAS_GAMMA(sna) ((sna)->kgem.gen >= 30)
+#define HAS_GAMMA(sna) ((sna)->kgem.gen >= 030)
 
 static Atom xvBrightness, xvContrast, xvSaturation, xvColorKey, xvPipe;
 static Atom xvGamma0, xvGamma1, xvGamma2, xvGamma3, xvGamma4, xvGamma5;
@@ -296,7 +296,7 @@ sna_video_overlay_query_best_size(ScrnInfoPtr scrn,
 		drw_h = vid_h >> 1;
 	}
 
-	if (sna->kgem.gen < 21) {
+	if (sna->kgem.gen < 021) {
 		max_w = IMAGE_MAX_WIDTH_LEGACY;
 		max_h = IMAGE_MAX_HEIGHT_LEGACY;
 	} else {
@@ -555,7 +555,7 @@ sna_video_overlay_query_video_attributes(ScrnInfoPtr scrn,
 
 	DBG(("%s: w is %d, h is %d\n", __FUNCTION__, *w, *h));
 
-	if (sna->kgem.gen < 21) {
+	if (sna->kgem.gen < 021) {
 		if (*w > IMAGE_MAX_WIDTH_LEGACY)
 			*w = IMAGE_MAX_WIDTH_LEGACY;
 		if (*h > IMAGE_MAX_HEIGHT_LEGACY)
@@ -665,7 +665,7 @@ XF86VideoAdaptorPtr sna_video_overlay_setup(struct sna *sna,
 	adaptor->nEncodings = 1;
 	adaptor->pEncodings = xnfalloc(sizeof(DummyEncoding));
 	memcpy(adaptor->pEncodings, DummyEncoding, sizeof(DummyEncoding));
-	if (sna->kgem.gen < 21) {
+	if (sna->kgem.gen < 021) {
 		adaptor->pEncodings->width = IMAGE_MAX_WIDTH_LEGACY;
 		adaptor->pEncodings->height = IMAGE_MAX_HEIGHT_LEGACY;
 	}
diff --git a/src/sna/sna_video_sprite.c b/src/sna/sna_video_sprite.c
index d4eae91..b51bf16 100644
--- a/src/sna/sna_video_sprite.c
+++ b/src/sna/sna_video_sprite.c
@@ -118,7 +118,7 @@ static void sna_video_sprite_best_size(ScrnInfoPtr scrn, Bool motion,
 {
 	struct sna *sna = to_sna(scrn);
 
-	if (sna->kgem.gen == 75) {
+	if (sna->kgem.gen == 075) {
 		*p_w = vid_w;
 		*p_h = vid_h;
 	} else {
diff --git a/src/sna/sna_video_textured.c b/src/sna/sna_video_textured.c
index 01977ba..f420769 100644
--- a/src/sna/sna_video_textured.c
+++ b/src/sna/sna_video_textured.c
@@ -254,7 +254,7 @@ sna_video_textured_put_image(ScrnInfoPtr scrn,
 		DBG(("%s: using passthough, name=%d\n",
 		     __FUNCTION__, *(uint32_t *)buf));
 
-		if (sna->kgem.gen < 31) {
+		if (sna->kgem.gen < 031) {
 			/* XXX: i915 is not support and needs some
 			 * serious care.  grep for KMS in i915_hwmc.c */
 			return BadAlloc;
commit 131600020638ef15166361214cd5e1a0c08c2ea6
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Fri Nov 30 11:43:56 2012 +0000

    sna: Prevent gen4 from rendering to I915_TILING_Y
    
    It always seems to end up in a hang...
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/kgem.c b/src/sna/kgem.c
index b479817..32187b1 100644
--- a/src/sna/kgem.c
+++ b/src/sna/kgem.c
@@ -2993,6 +2993,10 @@ int kgem_choose_tiling(struct kgem *kgem, int tiling, int width, int height, int
 			goto done;
 		}
 	} else {
+		/* XXX rendering to I915_TILING_Y seems broken? */
+		if (kgem->gen < 50 && tiling == I915_TILING_Y)
+			tiling = I915_TILING_X;
+
 		if (width*bpp > (MAXSHORT-512) * 8) {
 			DBG(("%s: large pitch [%d], forcing TILING_X\n",
 			     __FUNCTION__, width*bpp/8));
diff --git a/src/sna/sna.h b/src/sna/sna.h
index 6028c4f..9b93ed9 100644
--- a/src/sna/sna.h
+++ b/src/sna/sna.h
@@ -804,6 +804,7 @@ memcpy_xor(const void *src, void *dst, int bpp,
 
 #define SNA_CREATE_FB 0x10
 #define SNA_CREATE_SCRATCH 0x11
+#define SNA_CREATE_GLYPHS 0x12
 
 inline static bool is_power_of_two(unsigned x)
 {
diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c
index 2f49f12..79514c5 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -1170,6 +1170,14 @@ static PixmapPtr sna_create_pixmap(ScreenPtr screen,
 			goto fallback;
 	}
 
+	if (usage == SNA_CREATE_GLYPHS) {
+		if (flags & KGEM_CAN_CREATE_GPU)
+			return sna_pixmap_create_scratch(screen,
+							 width, height, depth,
+							 -I915_TILING_Y);
+		else
+			goto fallback;
+	}
 	if (usage == SNA_CREATE_SCRATCH) {
 		if (flags & KGEM_CAN_CREATE_GPU)
 			return sna_pixmap_create_scratch(screen,
diff --git a/src/sna/sna_glyphs.c b/src/sna/sna_glyphs.c
index a58ddcf..be1ce83 100644
--- a/src/sna/sna_glyphs.c
+++ b/src/sna/sna_glyphs.c
@@ -215,7 +215,7 @@ bool sna_glyphs_create(struct sna *sna)
 					      CACHE_PICTURE_SIZE,
 					      CACHE_PICTURE_SIZE,
 					      depth,
-					      SNA_CREATE_SCRATCH);
+					      SNA_CREATE_GLYPHS);
 		if (!pixmap)
 			goto bail;
 


More information about the xorg-commit mailing list