[PATCH] r600g: add support for common surface allocator for tiling v2

Jerome Glisse jglisse at redhat.com
Tue Dec 13 08:11:34 PST 2011


Tiled surface have all kind of alignment constraint that needs to
be met. Instead of having all this code duplicated btw ddx and
mesa use common code in libdrm_radeon this also ensure that both
ddx and mesa compute those alignment in the same way.

v2 fix evergreen

Signed-off-by: Jerome Glisse <jglisse at redhat.com>
---
 src/gallium/drivers/r600/evergreen_state.c        |  266 ++++++++++++++++++---
 src/gallium/drivers/r600/evergreend.h             |   15 ++
 src/gallium/drivers/r600/r600_hw_context.c        |    3 +
 src/gallium/drivers/r600/r600_pipe.h              |    1 +
 src/gallium/drivers/r600/r600_resource.h          |    1 +
 src/gallium/drivers/r600/r600_state.c             |  205 ++++++++++++-----
 src/gallium/drivers/r600/r600_texture.c           |  107 ++++++++-
 src/gallium/targets/dri-r600/Makefile             |    2 +-
 src/gallium/winsys/radeon/drm/radeon_drm_winsys.c |   17 ++
 src/gallium/winsys/radeon/drm/radeon_drm_winsys.h |    1 +
 src/gallium/winsys/radeon/drm/radeon_winsys.h     |   10 +
 11 files changed, 531 insertions(+), 97 deletions(-)

diff --git a/src/gallium/drivers/r600/evergreen_state.c b/src/gallium/drivers/r600/evergreen_state.c
index aca6136..7d87b77 100644
--- a/src/gallium/drivers/r600/evergreen_state.c
+++ b/src/gallium/drivers/r600/evergreen_state.c
@@ -48,6 +48,61 @@
 #include "r600_pipe.h"
 #include "r600_formats.h"
 
+static u32 eg_num_banks(u32 nbanks)
+{
+	switch (nbanks) {
+	case 2:
+		return 0;
+	case 4:
+		return 1;
+	case 8:
+	default:
+		return 2;
+	case 16:
+		return 3;
+	}
+}
+
+
+static unsigned eg_tile_split(unsigned tile_split)
+{
+	switch (tile_split) {
+	case 64:	tile_split = 0;	break;
+	case 128:	tile_split = 1;	break;
+	case 256:	tile_split = 2;	break;
+	case 512:	tile_split = 3;	break;
+	default:
+	case 1024:	tile_split = 4;	break;
+	case 2048:	tile_split = 5;	break;
+	case 4096:	tile_split = 6;	break;
+	}
+	return tile_split;
+}
+
+static unsigned eg_macro_tile_aspect(unsigned macro_tile_aspect)
+{
+	switch (macro_tile_aspect) {
+	default:
+	case 1:	macro_tile_aspect = 0;	break;
+	case 2:	macro_tile_aspect = 1;	break;
+	case 4:	macro_tile_aspect = 2;	break;
+	case 8:	macro_tile_aspect = 3;	break;
+	}
+	return macro_tile_aspect;
+}
+
+static unsigned eg_bank_wh(unsigned bankwh)
+{
+	switch (bankwh) {
+	default:
+	case 1:	bankwh = 0;	break;
+	case 2:	bankwh = 1;	break;
+	case 4:	bankwh = 2;	break;
+	case 8:	bankwh = 3;	break;
+	}
+	return bankwh;
+}
+
 static uint32_t r600_translate_blend_function(int blend_func)
 {
 	switch (blend_func) {
@@ -1035,13 +1090,15 @@ static struct pipe_sampler_view *evergreen_create_sampler_view(struct pipe_conte
 							struct pipe_resource *texture,
 							const struct pipe_sampler_view *state)
 {
+	struct r600_screen *rscreen = (struct r600_screen*)ctx->screen;
 	struct r600_pipe_sampler_view *view = CALLOC_STRUCT(r600_pipe_sampler_view);
 	struct r600_pipe_resource_state *rstate;
 	struct r600_resource_texture *tmp = (struct r600_resource_texture*)texture;
 	unsigned format, endian;
 	uint32_t word4 = 0, yuv_format = 0, pitch = 0;
 	unsigned char swizzle[4], array_mode = 0, tile_type = 0;
-	unsigned height, depth;
+	unsigned height, depth, width;
+	unsigned macro_aspect, tile_split, bankh, bankw, nbanks;
 
 	if (view == NULL)
 		return NULL;
@@ -1074,13 +1131,50 @@ static struct pipe_sampler_view *evergreen_create_sampler_view(struct pipe_conte
 
 	endian = r600_colorformat_endian_swap(format);
 
-	height = texture->height0;
-	depth = texture->depth0;
-
-	pitch = align(tmp->pitch_in_blocks[0] *
-		      util_format_get_blockwidth(state->format), 8);
-	array_mode = tmp->array_mode[0];
-	tile_type = tmp->tile_type;
+	if (!rscreen->use_surface) {
+		height = texture->height0;
+		depth = texture->depth0;
+		width = texture->width0;
+		pitch = align(tmp->pitch_in_blocks[0] *
+				util_format_get_blockwidth(state->format), 8);
+		array_mode = tmp->array_mode[0];
+		tile_type = tmp->tile_type;
+		tile_split = 0;
+		macro_aspect = 0;
+		bankw = 0;
+		bankh = 0;
+	} else {
+		width = tmp->surface.level[0].width;
+		height = tmp->surface.level[0].height;
+		depth = tmp->surface.level[0].depth;
+		pitch = align(tmp->surface.level[0].pitch, 8);
+		tile_type = tmp->tile_type;
+
+		switch (tmp->surface.level[0].mode) {
+		case RADEON_SURF_MODE_LINEAR_ALIGNED:
+			array_mode = V_028C70_ARRAY_LINEAR_ALIGNED;
+			break;
+		case RADEON_SURF_MODE_2D:
+			array_mode = V_028C70_ARRAY_2D_TILED_THIN1;
+			break;
+		case RADEON_SURF_MODE_1D:
+			array_mode = V_028C70_ARRAY_1D_TILED_THIN1;
+			break;
+		case RADEON_SURF_MODE_LINEAR:
+		default:
+			array_mode = V_028C70_ARRAY_LINEAR_GENERAL;
+			break;
+		}
+		tile_split = tmp->surface.tile_split;
+		macro_aspect = tmp->surface.macro_tile_aspect;
+		bankw = tmp->surface.bank_width;
+		bankh = tmp->surface.bank_height;
+		tile_split = eg_tile_split(tile_split);
+		macro_aspect = eg_macro_tile_aspect(macro_aspect);
+		bankw = eg_bank_wh(bankw);
+		bankh = eg_bank_wh(bankh);
+	}
+	nbanks = eg_num_banks(rscreen->tiling_info.num_banks);
 
 	if (texture->target == PIPE_TEXTURE_1D_ARRAY) {
 	        height = 1;
@@ -1097,7 +1191,7 @@ static struct pipe_sampler_view *evergreen_create_sampler_view(struct pipe_conte
 	rstate->val[0] = (S_030000_DIM(r600_tex_dim(texture->target)) |
 			  S_030000_PITCH((pitch / 8) - 1) |
 			  S_030000_NON_DISP_TILING_ORDER(tile_type) |
-			  S_030000_TEX_WIDTH(texture->width0 - 1));
+			  S_030000_TEX_WIDTH(width - 1));
 	rstate->val[1] = (S_030004_TEX_HEIGHT(height - 1) |
 			  S_030004_TEX_DEPTH(depth - 1) |
 			  S_030004_ARRAY_MODE(array_mode));
@@ -1110,9 +1204,15 @@ static struct pipe_sampler_view *evergreen_create_sampler_view(struct pipe_conte
 	rstate->val[5] = (S_030014_LAST_LEVEL(state->u.tex.last_level) |
 			  S_030014_BASE_ARRAY(state->u.tex.first_layer) |
 			  S_030014_LAST_ARRAY(state->u.tex.last_layer));
-	rstate->val[6] = (S_030018_MAX_ANISO(4 /* max 16 samples */));
-	rstate->val[7] = (S_03001C_DATA_FORMAT(format) |
-			  S_03001C_TYPE(V_03001C_SQ_TEX_VTX_VALID_TEXTURE));
+	/* aniso max 16 samples */
+	rstate->val[6] = (S_030018_MAX_ANISO(4)) |
+			 (S_030018_TILE_SPLIT(tile_split));
+	rstate->val[7] = S_03001C_DATA_FORMAT(format) |
+			 S_03001C_TYPE(V_03001C_SQ_TEX_VTX_VALID_TEXTURE) |
+			 S_03001C_BANK_WIDTH(bankw) |
+			 S_03001C_BANK_HEIGHT(bankh) |
+			 S_03001C_MACRO_TILE_ASPECT(macro_aspect) |
+			 S_03001C_NUM_BANKS(nbanks);
 
 	return &view->base;
 }
@@ -1337,14 +1437,15 @@ static void evergreen_set_viewport_state(struct pipe_context *ctx,
 static void evergreen_cb(struct r600_pipe_context *rctx, struct r600_pipe_state *rstate,
 			const struct pipe_framebuffer_state *state, int cb)
 {
+	struct r600_screen *rscreen = rctx->screen;
 	struct r600_resource_texture *rtex;
 	struct r600_surface *surf;
 	unsigned level = state->cbufs[cb]->u.tex.level;
 	unsigned pitch, slice;
-	unsigned color_info;
+	unsigned color_info, color_attrib;
 	unsigned format, swap, ntype, endian;
 	uint64_t offset;
-	unsigned tile_type;
+	unsigned tile_type, macro_aspect, tile_split, bankh, bankw, nbanks;
 	const struct util_format_description *desc;
 	int i;
 	unsigned blend_clamp = 0, blend_bypass = 0;
@@ -1361,10 +1462,58 @@ static void evergreen_cb(struct r600_pipe_context *rctx, struct r600_pipe_state
 	}
 
 	/* XXX quite sure for dx10+ hw don't need any offset hacks */
-	offset = r600_texture_get_offset(rtex,
-					 level, state->cbufs[cb]->u.tex.first_layer);
-	pitch = rtex->pitch_in_blocks[level] / 8 - 1;
-	slice = rtex->pitch_in_blocks[level] * surf->aligned_height / 64 - 1;
+	if (!rscreen->use_surface) {
+		offset = r600_texture_get_offset(rtex,
+				level, state->cbufs[cb]->u.tex.first_layer);
+		pitch = rtex->pitch_in_blocks[level] / 8 - 1;
+		slice = rtex->pitch_in_blocks[level] * surf->aligned_height / 64 - 1;
+		color_info = S_028C70_ARRAY_MODE(rtex->array_mode[level]);
+		tile_split = 0;
+		macro_aspect = 0;
+		bankw = 0;
+		bankh = 0;
+		if (rtex->array_mode[level] > V_028C70_ARRAY_LINEAR_ALIGNED) {
+			tile_type = rtex->tile_type;
+		} else {
+			/* workaround for linear buffers */
+			tile_type = 1;
+		}
+	} else {
+		offset = rtex->surface.level[level].offset +
+			 state->cbufs[cb]->u.tex.first_layer *
+			 rtex->surface.level[level].layer_size;
+		pitch = rtex->surface.level[level].pitch / 8 - 1;
+		slice = (rtex->surface.level[level].pitch * rtex->surface.level[level].height_aligned) / 64 - 1;
+		color_info = 0;
+		switch (rtex->surface.level[level].mode) {
+		case RADEON_SURF_MODE_LINEAR_ALIGNED:
+			color_info = S_028C70_ARRAY_MODE(V_028C70_ARRAY_LINEAR_ALIGNED);
+			tile_type = 1;
+			break;
+		case RADEON_SURF_MODE_1D:
+			color_info = S_028C70_ARRAY_MODE(V_028C70_ARRAY_1D_TILED_THIN1);
+			tile_type = rtex->tile_type;
+			break;
+		case RADEON_SURF_MODE_2D:
+			color_info = S_028C70_ARRAY_MODE(V_028C70_ARRAY_2D_TILED_THIN1);
+			tile_type = rtex->tile_type;
+			break;
+		case RADEON_SURF_MODE_LINEAR:
+		default:
+			color_info = S_028C70_ARRAY_MODE(V_028C70_ARRAY_LINEAR_GENERAL);
+			tile_type = 1;
+			break;
+		}
+		tile_split = rtex->surface.tile_split;
+		macro_aspect = rtex->surface.macro_tile_aspect;
+		bankw = rtex->surface.bank_width;
+		bankh = rtex->surface.bank_height;
+		tile_split = eg_tile_split(tile_split);
+		macro_aspect = eg_macro_tile_aspect(macro_aspect);
+		bankw = eg_bank_wh(bankw);
+		bankh = eg_bank_wh(bankh);
+	}
+	nbanks = eg_num_banks(rscreen->tiling_info.num_banks);
 	desc = util_format_description(surf->base.format);
 	for (i = 0; i < 4; i++) {
 		if (desc->channel[i].type != UTIL_FORMAT_TYPE_VOID) {
@@ -1372,6 +1521,13 @@ static void evergreen_cb(struct r600_pipe_context *rctx, struct r600_pipe_state
 		}
 	}
 
+	color_attrib = S_028C74_TILE_SPLIT(tile_split)|
+			S_028C74_NUM_BANKS(nbanks) |
+			S_028C74_BANK_WIDTH(bankw) |
+			S_028C74_BANK_HEIGHT(bankh) |
+			S_028C74_MACRO_TILE_ASPECT(macro_aspect) |
+			S_028C74_NON_DISP_TILING_ORDER(tile_type);
+
 	ntype = V_028C70_NUMBER_UNORM;
 	if (desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB)
 		ntype = V_028C70_NUMBER_SRGB;
@@ -1409,9 +1565,8 @@ static void evergreen_cb(struct r600_pipe_context *rctx, struct r600_pipe_state
 		blend_bypass = 1;
 	}
 
-	color_info = S_028C70_FORMAT(format) |
+	color_info |= S_028C70_FORMAT(format) |
 		S_028C70_COMP_SWAP(swap) |
-		S_028C70_ARRAY_MODE(rtex->array_mode[level]) |
 		S_028C70_BLEND_CLAMP(blend_clamp) |
 		S_028C70_BLEND_BYPASS(blend_bypass) |
 		S_028C70_NUMBER_TYPE(ntype) |
@@ -1438,10 +1593,6 @@ static void evergreen_cb(struct r600_pipe_context *rctx, struct r600_pipe_state
 	}
 	rctx->alpha_ref_dirty = true;
 
-	if (rtex->array_mode[level] > V_028C70_ARRAY_LINEAR_ALIGNED) {
-		tile_type = rtex->tile_type;
-	} else /* workaround for linear buffers */
-		tile_type = 1;
 
 	offset += r600_resource_va(rctx->context.screen, state->cbufs[cb]->texture);
 	offset >>= 8;
@@ -1469,17 +1620,19 @@ static void evergreen_cb(struct r600_pipe_context *rctx, struct r600_pipe_state
 				0x00000000, 0xFFFFFFFF, NULL, 0);
 	r600_pipe_state_add_reg(rstate,
 				R_028C74_CB_COLOR0_ATTRIB + cb * 0x3C,
-				S_028C74_NON_DISP_TILING_ORDER(tile_type),
+				color_attrib,
 				0xFFFFFFFF, &rtex->resource, RADEON_USAGE_READWRITE);
 }
 
 static void evergreen_db(struct r600_pipe_context *rctx, struct r600_pipe_state *rstate,
 			 const struct pipe_framebuffer_state *state)
 {
+	struct r600_screen *rscreen = rctx->screen;
 	struct r600_resource_texture *rtex;
 	struct r600_surface *surf;
-	unsigned level, first_layer, pitch, slice, format, array_mode;
 	uint64_t offset;
+	unsigned level, first_layer, pitch, slice, format, array_mode;
+	unsigned macro_aspect, tile_split, bankh, bankw, z_info, nbanks;
 
 	if (state->zsbuf == NULL)
 		return;
@@ -1487,20 +1640,60 @@ static void evergreen_db(struct r600_pipe_context *rctx, struct r600_pipe_state
 	surf = (struct r600_surface *)state->zsbuf;
 	level = surf->base.u.tex.level;
 	rtex = (struct r600_resource_texture*)surf->base.texture;
-
-	/* XXX remove this once tiling is properly supported */
-	array_mode = rtex->array_mode[level] ? rtex->array_mode[level] :
-					       V_028C70_ARRAY_1D_TILED_THIN1;
-
 	first_layer = surf->base.u.tex.first_layer;
-	offset = r600_texture_get_offset(rtex, level, first_layer);
-	pitch = rtex->pitch_in_blocks[level] / 8 - 1;
-	slice = rtex->pitch_in_blocks[level] * surf->aligned_height / 64 - 1;
 	format = r600_translate_dbformat(rtex->real_format);
 
-	offset += r600_resource_va(rctx->context.screen, surf->base.texture);
+	offset = r600_resource_va(rctx->context.screen, surf->base.texture);
+	/* XXX remove this once tiling is properly supported */
+	if (!rscreen->use_surface) {
+		/* XXX remove this once tiling is properly supported */
+		array_mode = rtex->array_mode[level] ? rtex->array_mode[level] :
+				V_028C70_ARRAY_1D_TILED_THIN1;
+
+		offset += r600_texture_get_offset(rtex, level, first_layer);
+		pitch = rtex->pitch_in_blocks[level] / 8 - 1;
+		slice = rtex->pitch_in_blocks[level] * surf->aligned_height / 64 - 1;
+		tile_split = 0;
+		macro_aspect = 0;
+		bankw = 0;
+		bankh = 0;
+	} else {
+		offset += rtex->surface.level[level].offset +
+			 state->zsbuf->u.tex.first_layer *
+			 rtex->surface.level[level].layer_size;
+		pitch = rtex->surface.level[level].pitch / 8 - 1;
+		slice = (rtex->surface.level[level].pitch * rtex->surface.level[level].height_aligned) / 64 - 1;
+		switch (rtex->surface.level[level].mode) {
+		case RADEON_SURF_MODE_2D:
+			array_mode = V_028C70_ARRAY_2D_TILED_THIN1;
+			break;
+		case RADEON_SURF_MODE_1D:
+		case RADEON_SURF_MODE_LINEAR_ALIGNED:
+		case RADEON_SURF_MODE_LINEAR:
+		default:
+			array_mode = V_028C70_ARRAY_1D_TILED_THIN1;
+			break;
+		}
+		tile_split = rtex->surface.tile_split;
+		macro_aspect = rtex->surface.macro_tile_aspect;
+		bankw = rtex->surface.bank_width;
+		bankh = rtex->surface.bank_height;
+		tile_split = eg_tile_split(tile_split);
+		macro_aspect = eg_macro_tile_aspect(macro_aspect);
+		bankw = eg_bank_wh(bankw);
+		bankh = eg_bank_wh(bankh);
+	}
+	nbanks = eg_num_banks(rscreen->tiling_info.num_banks);
 	offset >>= 8;
 
+	z_info = S_028040_ARRAY_MODE(array_mode) |
+		 S_028040_FORMAT(format) |
+		 S_028040_TILE_SPLIT(tile_split)|
+		 S_028040_NUM_BANKS(nbanks) |
+		 S_028040_BANK_WIDTH(bankw) |
+		 S_028040_BANK_HEIGHT(bankh) |
+		 S_028040_MACRO_TILE_ASPECT(macro_aspect);
+
 	r600_pipe_state_add_reg(rstate, R_028048_DB_Z_READ_BASE,
 				offset, 0xFFFFFFFF, &rtex->resource, RADEON_USAGE_READWRITE);
 	r600_pipe_state_add_reg(rstate, R_028050_DB_Z_WRITE_BASE,
@@ -1525,8 +1718,7 @@ static void evergreen_db(struct r600_pipe_context *rctx, struct r600_pipe_state
 					0, 0xFFFFFFFF, NULL, RADEON_USAGE_READWRITE);
 	}
 
-	r600_pipe_state_add_reg(rstate, R_028040_DB_Z_INFO,
-				S_028040_ARRAY_MODE(array_mode) | S_028040_FORMAT(format),
+	r600_pipe_state_add_reg(rstate, R_028040_DB_Z_INFO, z_info,
 				0xFFFFFFFF, &rtex->resource, RADEON_USAGE_READWRITE);
 	r600_pipe_state_add_reg(rstate, R_028058_DB_DEPTH_SIZE,
 				S_028058_PITCH_TILE_MAX(pitch),
diff --git a/src/gallium/drivers/r600/evergreend.h b/src/gallium/drivers/r600/evergreend.h
index 68b77b4..3c9506e 100644
--- a/src/gallium/drivers/r600/evergreend.h
+++ b/src/gallium/drivers/r600/evergreend.h
@@ -367,6 +367,11 @@
 #define   S_028C74_NON_DISP_TILING_ORDER(x)            (((x) & 0x1) << 4)
 #define   G_028C74_NON_DISP_TILING_ORDER(x)            (((x) >> 4) & 0x1)
 #define   C_028C74_NON_DISP_TILING_ORDER               0xFFFFFFEF
+#define   S_028C74_TILE_SPLIT(x)                       (((x) & 0xf) << 5)
+#define   S_028C74_NUM_BANKS(x)                        (((x) & 0x3) << 10)
+#define   S_028C74_BANK_WIDTH(x)                       (((x) & 0x3) << 13)
+#define   S_028C74_BANK_HEIGHT(x)                      (((x) & 0x3) << 16)
+#define   S_028C74_MACRO_TILE_ASPECT(x)                (((x) & 0x3) << 19)
 
 #define R_028C78_CB_COLOR0_DIM                         0x028C78
 #define   S_028C78_WIDTH_MAX(x)                        (((x) & 0xFFFF) << 0)
@@ -541,6 +546,11 @@
 #define   S_028040_ZRANGE_PRECISION(x)                 (((x) & 0x1) << 31)
 #define   G_028040_ZRANGE_PRECISION(x)                 (((x) >> 31) & 0x1)
 #define   C_028040_ZRANGE_PRECISION                    0x7FFFFFFF
+#define   S_028040_TILE_SPLIT(x)                       (((x) & 0x7) << 8)
+#define   S_028040_NUM_BANKS(x)                        (((x) & 0x3) << 12)
+#define   S_028040_BANK_WIDTH(x)                       (((x) & 0x3) << 16)
+#define   S_028040_BANK_HEIGHT(x)                      (((x) & 0x3) << 20)
+#define   S_028040_MACRO_TILE_ASPECT(x)                (((x) & 0x3) << 24)
 
 #define R_028044_DB_STENCIL_INFO                     0x028044
 #define   S_028044_FORMAT(x)                           (((x) & 0x1) << 0)
@@ -1075,7 +1085,12 @@
 #define   S_030018_INTERLACED(x)                       (((x) & 0x1) << 6)
 #define   G_030018_INTERLACED(x)                       (((x) >> 6) & 0x1)
 #define   C_030018_INTERLACED                          0xFFFFFFBF
+#define   S_030018_TILE_SPLIT(x)                       (((x) & 0x7) << 29)
 #define R_03001C_SQ_TEX_RESOURCE_WORD7_0             0x03001C
+#define   S_03001C_MACRO_TILE_ASPECT(x)                (((x) & 0x3) << 6)
+#define   S_03001C_BANK_WIDTH(x)                       (((x) & 0x3) << 8)
+#define   S_03001C_BANK_HEIGHT(x)                      (((x) & 0x3) << 10)
+#define   S_03001C_NUM_BANKS(x)                        (((x) & 0x3) << 16)
 #define   S_03001C_TYPE(x)                             (((x) & 0x3) << 30)
 #define   G_03001C_TYPE(x)                             (((x) >> 30) & 0x3)
 #define   C_03001C_TYPE                                0x3FFFFFFF
diff --git a/src/gallium/drivers/r600/r600_hw_context.c b/src/gallium/drivers/r600/r600_hw_context.c
index b0a28d9..823a166 100644
--- a/src/gallium/drivers/r600/r600_hw_context.c
+++ b/src/gallium/drivers/r600/r600_hw_context.c
@@ -1540,6 +1540,9 @@ void r600_context_flush(struct r600_context *ctx, unsigned flags)
 	ctx->pm4[ctx->pm4_cdwords++] = PKT3(PKT3_EVENT_WRITE, 0, 0);
 	ctx->pm4[ctx->pm4_cdwords++] = EVENT_TYPE(EVENT_TYPE_PS_PARTIAL_FLUSH) | EVENT_INDEX(4);
 
+	/* force to keep tiling flags */
+	flags |= RADEON_FLUSH_KEEP_TILING_FLAGS;
+
 	/* Flush the CS. */
 	ctx->cs->cdw = ctx->pm4_cdwords;
 	ctx->ws->cs_flush(ctx->cs, flags);
diff --git a/src/gallium/drivers/r600/r600_pipe.h b/src/gallium/drivers/r600/r600_pipe.h
index bd78243..7b73900 100644
--- a/src/gallium/drivers/r600/r600_pipe.h
+++ b/src/gallium/drivers/r600/r600_pipe.h
@@ -93,6 +93,7 @@ struct r600_screen {
 	struct r600_pipe_fences		fences;
 
 	unsigned			num_contexts;
+	unsigned			use_surface;
 
 	/* for thread-safe write accessing to num_contexts */
 	pipe_mutex			mutex_num_contexts;
diff --git a/src/gallium/drivers/r600/r600_resource.h b/src/gallium/drivers/r600/r600_resource.h
index f39ac55..9802133 100644
--- a/src/gallium/drivers/r600/r600_resource.h
+++ b/src/gallium/drivers/r600/r600_resource.h
@@ -60,6 +60,7 @@ struct r600_resource_texture {
 	struct r600_resource_texture    *stencil; /* Stencil is in a separate buffer on Evergreen. */
 	struct r600_resource_texture	*flushed_depth_texture;
 	boolean				is_flushing_texture;
+	struct radeon_surface		surface;
 };
 
 #define R600_TEX_IS_TILED(tex, level) ((tex)->array_mode[level] != V_038000_ARRAY_LINEAR_GENERAL && (tex)->array_mode[level] != V_038000_ARRAY_LINEAR_ALIGNED)
diff --git a/src/gallium/drivers/r600/r600_state.c b/src/gallium/drivers/r600/r600_state.c
index 12157ff..30eafc8 100644
--- a/src/gallium/drivers/r600/r600_state.c
+++ b/src/gallium/drivers/r600/r600_state.c
@@ -1077,6 +1077,7 @@ static struct pipe_sampler_view *r600_create_sampler_view(struct pipe_context *c
 							struct pipe_resource *texture,
 							const struct pipe_sampler_view *state)
 {
+	struct r600_screen *rscreen = (struct r600_screen*)ctx->screen;
 	struct r600_pipe_sampler_view *view = CALLOC_STRUCT(r600_pipe_sampler_view);
 	struct r600_pipe_resource_state *rstate;
 	struct r600_resource_texture *tmp = (struct r600_resource_texture*)texture;
@@ -1118,48 +1119,97 @@ static struct pipe_sampler_view *r600_create_sampler_view(struct pipe_context *c
 
 	offset_level = state->u.tex.first_level;
 	last_level = state->u.tex.last_level - offset_level;
-	width = u_minify(texture->width0, offset_level);
-	height = u_minify(texture->height0, offset_level);
-	depth = u_minify(texture->depth0, offset_level);
-
-	pitch = align(tmp->pitch_in_blocks[offset_level] *
-		      util_format_get_blockwidth(state->format), 8);
-	array_mode = tmp->array_mode[offset_level];
-	tile_type = tmp->tile_type;
-
-	if (texture->target == PIPE_TEXTURE_1D_ARRAY) {
-	        height = 1;
-		depth = texture->array_size;
-	} else if (texture->target == PIPE_TEXTURE_2D_ARRAY) {
-		depth = texture->array_size;
-	}
-
-	rstate->bo[0] = &tmp->resource;
-	rstate->bo[1] = &tmp->resource;
-	rstate->bo_usage[0] = RADEON_USAGE_READ;
-	rstate->bo_usage[1] = RADEON_USAGE_READ;
-
-	rstate->val[0] = (S_038000_DIM(r600_tex_dim(texture->target)) |
-			  S_038000_TILE_MODE(array_mode) |
-			  S_038000_TILE_TYPE(tile_type) |
-			  S_038000_PITCH((pitch / 8) - 1) |
-			  S_038000_TEX_WIDTH(width - 1));
-	rstate->val[1] = (S_038004_TEX_HEIGHT(height - 1) |
-			  S_038004_TEX_DEPTH(depth - 1) |
-			  S_038004_DATA_FORMAT(format));
-	rstate->val[2] = tmp->offset[offset_level] >> 8;
-	rstate->val[3] = tmp->offset[offset_level+1] >> 8;
-	rstate->val[4] = (word4 |
-			  S_038010_SRF_MODE_ALL(V_038010_SRF_MODE_ZERO_CLAMP_MINUS_ONE) |
-			  S_038010_REQUEST_SIZE(1) |
-			  S_038010_ENDIAN_SWAP(endian) |
-			  S_038010_BASE_LEVEL(0));
-	rstate->val[5] = (S_038014_LAST_LEVEL(last_level) |
-			  S_038014_BASE_ARRAY(state->u.tex.first_layer) |
-			  S_038014_LAST_ARRAY(state->u.tex.last_layer));
-	rstate->val[6] = (S_038018_TYPE(V_038010_SQ_TEX_VTX_VALID_TEXTURE) |
-			  S_038018_MAX_ANISO(4 /* max 16 samples */));
+	if (!rscreen->use_surface) {
+		width = u_minify(texture->width0, offset_level);
+		height = u_minify(texture->height0, offset_level);
+		depth = u_minify(texture->depth0, offset_level);
+
+		pitch = align(tmp->pitch_in_blocks[offset_level] *
+				util_format_get_blockwidth(state->format), 8);
+		array_mode = tmp->array_mode[offset_level];
+		tile_type = tmp->tile_type;
+
+		if (texture->target == PIPE_TEXTURE_1D_ARRAY) {
+			height = 1;
+			depth = texture->array_size;
+		} else if (texture->target == PIPE_TEXTURE_2D_ARRAY) {
+			depth = texture->array_size;
+		}
 
+		rstate->bo[0] = &tmp->resource;
+		rstate->bo[1] = &tmp->resource;
+		rstate->bo_usage[0] = RADEON_USAGE_READ;
+		rstate->bo_usage[1] = RADEON_USAGE_READ;
+
+		rstate->val[0] = (S_038000_DIM(r600_tex_dim(texture->target)) |
+				S_038000_TILE_MODE(array_mode) |
+				S_038000_TILE_TYPE(tile_type) |
+				S_038000_PITCH((pitch / 8) - 1) |
+				S_038000_TEX_WIDTH(width - 1));
+		rstate->val[1] = (S_038004_TEX_HEIGHT(height - 1) |
+				S_038004_TEX_DEPTH(depth - 1) |
+				S_038004_DATA_FORMAT(format));
+		rstate->val[2] = tmp->offset[offset_level] >> 8;
+		rstate->val[3] = tmp->offset[offset_level+1] >> 8;
+		rstate->val[4] = (word4 |
+				S_038010_SRF_MODE_ALL(V_038010_SRF_MODE_ZERO_CLAMP_MINUS_ONE) |
+				S_038010_REQUEST_SIZE(1) |
+				S_038010_ENDIAN_SWAP(endian) |
+				S_038010_BASE_LEVEL(0));
+		rstate->val[5] = (S_038014_LAST_LEVEL(last_level) |
+				S_038014_BASE_ARRAY(state->u.tex.first_layer) |
+				S_038014_LAST_ARRAY(state->u.tex.last_layer));
+		rstate->val[6] = (S_038018_TYPE(V_038010_SQ_TEX_VTX_VALID_TEXTURE) |
+				S_038018_MAX_ANISO(4 /* max 16 samples */));
+	} else {
+		width = tmp->surface.level[offset_level].width;
+		height = tmp->surface.level[offset_level].height;
+		depth = tmp->surface.level[offset_level].depth;
+		pitch = align(tmp->surface.level[offset_level].pitch, 8);
+		tile_type = tmp->tile_type;
+
+		switch (tmp->surface.level[offset_level].mode) {
+		case RADEON_SURF_MODE_LINEAR_ALIGNED:
+			array_mode = V_038000_ARRAY_LINEAR_ALIGNED;
+			break;
+		case RADEON_SURF_MODE_1D:
+			array_mode = V_038000_ARRAY_1D_TILED_THIN1;
+			break;
+		case RADEON_SURF_MODE_2D:
+			array_mode = V_038000_ARRAY_2D_TILED_THIN1;
+			break;
+		case RADEON_SURF_MODE_LINEAR:
+		default:
+			array_mode = V_038000_ARRAY_LINEAR_GENERAL;
+			break;
+		}
+
+		rstate->bo[0] = &tmp->resource;
+		rstate->bo[1] = &tmp->resource;
+		rstate->bo_usage[0] = RADEON_USAGE_READ;
+		rstate->bo_usage[1] = RADEON_USAGE_READ;
+
+		rstate->val[0] = (S_038000_DIM(r600_tex_dim(texture->target)) |
+				S_038000_TILE_MODE(array_mode) |
+				S_038000_TILE_TYPE(tile_type) |
+				S_038000_PITCH((pitch / 8) - 1) |
+				S_038000_TEX_WIDTH(width - 1));
+		rstate->val[1] = (S_038004_TEX_HEIGHT(height - 1) |
+				S_038004_TEX_DEPTH(depth - 1) |
+				S_038004_DATA_FORMAT(format));
+		rstate->val[2] = tmp->surface.level[offset_level].offset >> 8;
+		rstate->val[3] = tmp->surface.level[offset_level + 1].offset >> 8;
+		rstate->val[4] = (word4 |
+				S_038010_SRF_MODE_ALL(V_038010_SRF_MODE_ZERO_CLAMP_MINUS_ONE) |
+				S_038010_REQUEST_SIZE(1) |
+				S_038010_ENDIAN_SWAP(endian) |
+				S_038010_BASE_LEVEL(0));
+		rstate->val[5] = (S_038014_LAST_LEVEL(last_level) |
+				S_038014_BASE_ARRAY(state->u.tex.first_layer) |
+				S_038014_LAST_ARRAY(state->u.tex.last_layer));
+		rstate->val[6] = (S_038018_TYPE(V_038010_SQ_TEX_VTX_VALID_TEXTURE) |
+				S_038018_MAX_ANISO(4 /* max 16 samples */));
+	}
 	return &view->base;
 }
 
@@ -1444,6 +1494,7 @@ static void r600_set_viewport_state(struct pipe_context *ctx,
 static void r600_cb(struct r600_pipe_context *rctx, struct r600_pipe_state *rstate,
 			const struct pipe_framebuffer_state *state, int cb)
 {
+	struct r600_screen *rscreen = rctx->screen;
 	struct r600_resource_texture *rtex;
 	struct r600_surface *surf;
 	unsigned level = state->cbufs[cb]->u.tex.level;
@@ -1461,15 +1512,39 @@ static void r600_cb(struct r600_pipe_context *rctx, struct r600_pipe_state *rsta
 		rctx->have_depth_fb = TRUE;
 
 	if (rtex->depth && !rtex->is_flushing_texture) {
-	        r600_texture_depth_flush(&rctx->context, state->cbufs[cb]->texture, TRUE);
 		rtex = rtex->flushed_depth_texture;
 	}
 
 	/* XXX quite sure for dx10+ hw don't need any offset hacks */
-	offset = r600_texture_get_offset(rtex,
-					 level, state->cbufs[cb]->u.tex.first_layer);
-	pitch = rtex->pitch_in_blocks[level] / 8 - 1;
-	slice = rtex->pitch_in_blocks[level] * surf->aligned_height / 64 - 1;
+	if (!rscreen->use_surface) {
+		offset = r600_texture_get_offset(rtex,
+						 level, state->cbufs[cb]->u.tex.first_layer);
+		pitch = rtex->pitch_in_blocks[level] / 8 - 1;
+		slice = rtex->pitch_in_blocks[level] * surf->aligned_height / 64 - 1;
+		color_info = S_0280A0_ARRAY_MODE(rtex->array_mode[level]);
+	} else {
+		offset = rtex->surface.level[level].offset +
+			 state->cbufs[cb]->u.tex.first_layer *
+			 rtex->surface.level[level].layer_size;
+		pitch = rtex->surface.level[level].pitch / 8 - 1;
+		slice = (rtex->surface.level[level].pitch * rtex->surface.level[level].height_aligned) / 64 - 1;
+		color_info = 0;
+		switch (rtex->surface.level[level].mode) {
+		case RADEON_SURF_MODE_LINEAR_ALIGNED:
+			color_info = S_0280A0_ARRAY_MODE(V_038000_ARRAY_LINEAR_ALIGNED);
+			break;
+		case RADEON_SURF_MODE_1D:
+			color_info = S_0280A0_ARRAY_MODE(V_038000_ARRAY_1D_TILED_THIN1);
+			break;
+		case RADEON_SURF_MODE_2D:
+			color_info = S_0280A0_ARRAY_MODE(V_038000_ARRAY_2D_TILED_THIN1);
+			break;
+		case RADEON_SURF_MODE_LINEAR:
+		default:
+			color_info = S_0280A0_ARRAY_MODE(V_038000_ARRAY_LINEAR_GENERAL);
+			break;
+		}
+	}
 	desc = util_format_description(surf->base.format);
 
 	for (i = 0; i < 4; i++) {
@@ -1501,9 +1576,8 @@ static void r600_cb(struct r600_pipe_context *rctx, struct r600_pipe_state *rsta
 		endian = r600_colorformat_endian_swap(format);
 	}
 
-	color_info = S_0280A0_FORMAT(format) |
+	color_info |= S_0280A0_FORMAT(format) |
 		S_0280A0_COMP_SWAP(swap) |
-		S_0280A0_ARRAY_MODE(rtex->array_mode[level]) |
 		S_0280A0_BLEND_CLAMP(1) |
 		S_0280A0_NUMBER_TYPE(ntype) |
 		S_0280A0_ENDIAN(endian);
@@ -1567,6 +1641,7 @@ static void r600_cb(struct r600_pipe_context *rctx, struct r600_pipe_state *rsta
 static void r600_db(struct r600_pipe_context *rctx, struct r600_pipe_state *rstate,
 			const struct pipe_framebuffer_state *state)
 {
+	struct r600_screen *rscreen = rctx->screen;
 	struct r600_resource_texture *rtex;
 	struct r600_surface *surf;
 	unsigned level, pitch, slice, format, offset, array_mode;
@@ -1579,15 +1654,35 @@ static void r600_db(struct r600_pipe_context *rctx, struct r600_pipe_state *rsta
 	surf = (struct r600_surface *)state->zsbuf;
 	rtex = (struct r600_resource_texture*)state->zsbuf->texture;
 
-	/* XXX remove this once tiling is properly supported */
-	array_mode = rtex->array_mode[level] ? rtex->array_mode[level] :
-					       V_0280A0_ARRAY_1D_TILED_THIN1;
+	if (!rscreen->use_surface) {
+		/* XXX remove this once tiling is properly supported */
+		array_mode = rtex->array_mode[level] ? rtex->array_mode[level] :
+			V_0280A0_ARRAY_1D_TILED_THIN1;
+
+		/* XXX quite sure for dx10+ hw don't need any offset hacks */
+		offset = r600_texture_get_offset((struct r600_resource_texture *)state->zsbuf->texture,
+				level, state->zsbuf->u.tex.first_layer);
+		pitch = rtex->pitch_in_blocks[level] / 8 - 1;
+		slice = rtex->pitch_in_blocks[level] * surf->aligned_height / 64 - 1;
+	} else {
+		offset = rtex->surface.level[level].offset +
+			 state->zsbuf->u.tex.first_layer *
+			 rtex->surface.level[level].layer_size;
+		pitch = rtex->surface.level[level].pitch / 8 - 1;
+		slice = (rtex->surface.level[level].pitch * rtex->surface.level[level].height_aligned) / 64 - 1;
+		switch (rtex->surface.level[level].mode) {
+		case RADEON_SURF_MODE_2D:
+			array_mode = V_0280A0_ARRAY_2D_TILED_THIN1;
+			break;
+		case RADEON_SURF_MODE_1D:
+		case RADEON_SURF_MODE_LINEAR_ALIGNED:
+		case RADEON_SURF_MODE_LINEAR:
+		default:
+			array_mode = V_0280A0_ARRAY_1D_TILED_THIN1;
+			break;
+		}
+	}
 
-	/* XXX quite sure for dx10+ hw don't need any offset hacks */
-	offset = r600_texture_get_offset((struct r600_resource_texture *)state->zsbuf->texture,
-					 level, state->zsbuf->u.tex.first_layer);
-	pitch = rtex->pitch_in_blocks[level] / 8 - 1;
-	slice = rtex->pitch_in_blocks[level] * surf->aligned_height / 64 - 1;
 	format = r600_translate_dbformat(state->zsbuf->texture->format);
 
 	r600_pipe_state_add_reg(rstate, R_02800C_DB_DEPTH_BASE,
diff --git a/src/gallium/drivers/r600/r600_texture.c b/src/gallium/drivers/r600/r600_texture.c
index decd941..ae033ec 100644
--- a/src/gallium/drivers/r600/r600_texture.c
+++ b/src/gallium/drivers/r600/r600_texture.c
@@ -241,6 +241,89 @@ static void r600_texture_set_array_mode(struct pipe_screen *screen,
 	}
 }
 
+static int r600_setup_surface(struct pipe_screen *screen,
+			      struct r600_resource_texture *rtex,
+			      unsigned array_mode)
+{
+	struct pipe_resource *ptex = &rtex->resource.b.b.b;
+	struct r600_screen *rscreen = (struct r600_screen*)screen;
+	unsigned i;
+	int r;
+
+	rtex->surface.width = util_format_get_nblocksx(rtex->real_format, ptex->width0);
+	rtex->surface.height = util_format_get_nblocksy(rtex->real_format, ptex->height0);
+	rtex->surface.depth = ptex->depth0;
+	rtex->surface.last_level = ptex->last_level;
+	rtex->surface.element_bytes = util_format_get_blocksize(rtex->real_format);
+	rtex->surface.nsamples = 1;
+	rtex->surface.flags = 0;
+	switch (array_mode) {
+	case V_038000_ARRAY_1D_TILED_THIN1:
+		rtex->surface.flags |= RADEON_SURF_SET(RADEON_SURF_MODE_1D, MODE);
+		break;
+	case V_038000_ARRAY_2D_TILED_THIN1:
+		rtex->surface.flags |= RADEON_SURF_SET(RADEON_SURF_MODE_2D, MODE);
+		break;
+	case V_038000_ARRAY_LINEAR_ALIGNED:
+		rtex->surface.flags |= RADEON_SURF_SET(RADEON_SURF_MODE_LINEAR_ALIGNED, MODE);
+		break;
+	case V_038000_ARRAY_LINEAR_GENERAL:
+	default:
+		rtex->surface.flags |= RADEON_SURF_SET(RADEON_SURF_MODE_LINEAR, MODE);
+		break;
+	}
+	switch (ptex->target) {
+	case PIPE_TEXTURE_1D:
+		rtex->surface.flags |= RADEON_SURF_SET(RADEON_SURF_TYPE_1D, TYPE);
+		break;
+	case PIPE_TEXTURE_RECT:
+	case PIPE_TEXTURE_2D:
+		rtex->surface.flags |= RADEON_SURF_SET(RADEON_SURF_TYPE_2D, TYPE);
+		break;
+	case PIPE_TEXTURE_3D:
+		rtex->surface.flags |= RADEON_SURF_SET(RADEON_SURF_TYPE_3D, TYPE);
+		break;
+	case PIPE_TEXTURE_1D_ARRAY:
+		rtex->surface.flags |= RADEON_SURF_SET(RADEON_SURF_TYPE_1D_ARRAY, TYPE);
+		rtex->surface.depth = ptex->array_size;
+		break;
+	case PIPE_TEXTURE_2D_ARRAY:
+		rtex->surface.flags |= RADEON_SURF_SET(RADEON_SURF_TYPE_2D_ARRAY, TYPE);
+		rtex->surface.depth = ptex->array_size;
+		break;
+	case PIPE_TEXTURE_CUBE:
+		rtex->surface.flags |= RADEON_SURF_SET(RADEON_SURF_TYPE_CUBEMAP, TYPE);
+		break;
+	case PIPE_BUFFER:
+	default:
+		return -EINVAL;
+	}
+	if (ptex->bind & PIPE_BIND_SCANOUT) {
+		rtex->surface.flags |= RADEON_SURF_SCANOUT;
+	}
+	if (util_format_is_depth_and_stencil(ptex->format)) {
+		rtex->surface.flags |= RADEON_SURF_ZBUFFER;
+		rtex->surface.flags |= RADEON_SURF_SBUFFER;
+	}
+	rtex->surface.tile_thickness = 1;
+	rtex->surface.thin_factor = 1;
+	rtex->surface.bank_width = 0;
+	rtex->surface.bank_height = 0;
+	rtex->surface.macro_tile_aspect = 0;
+	rtex->surface.tile_split = 0;
+
+	r = rscreen->ws->surface_init(rscreen->ws, &rtex->surface);
+	if (r) {
+		return r;
+	}
+	rtex->size = rtex->surface.bo_size;
+	for (i = 0; i <= ptex->last_level; i++) {
+		rtex->offset[i] = rtex->surface.level[i].offset;
+		rtex->layer_size[i] = rtex->surface.level[i].layer_size;
+	}
+	return 0;
+}
+
 static void r600_setup_miptree(struct pipe_screen *screen,
 			       struct r600_resource_texture *rtex,
 			       unsigned array_mode)
@@ -369,6 +452,8 @@ static const struct u_resource_vtbl r600_texture_vtbl =
 	u_default_transfer_inline_write	/* transfer_inline_write */
 };
 
+DEBUG_GET_ONCE_BOOL_OPTION(use_surface, "R600_SURF", FALSE);
+
 static struct r600_resource_texture *
 r600_texture_create_object(struct pipe_screen *screen,
 			   const struct pipe_resource *base,
@@ -381,6 +466,14 @@ r600_texture_create_object(struct pipe_screen *screen,
 	struct r600_resource_texture *rtex;
 	struct r600_resource *resource;
 	struct r600_screen *rscreen = (struct r600_screen*)screen;
+	int r;
+
+	/* FIXME ugly temporary hack to allow to switch btw current code
+	 * and common surface allocator code
+	 */
+	if (debug_get_option_use_surface()) {
+		rscreen->use_surface = 1;
+	}
 
 	rtex = CALLOC_STRUCT(r600_resource_texture);
 	if (rtex == NULL)
@@ -442,6 +535,13 @@ r600_texture_create_object(struct pipe_screen *screen,
 		rtex->depth = 1;
 
 	r600_setup_miptree(screen, rtex, array_mode);
+	if (rscreen->use_surface) {
+		r = r600_setup_surface(screen, rtex, array_mode);
+		if (r) {
+			FREE(rtex);
+			return NULL;
+		}
+	}
 
 	/* If we initialized separate stencil for Evergreen. place it after depth. */
 	if (rtex->stencil) {
@@ -492,10 +592,9 @@ struct pipe_resource *r600_texture_create(struct pipe_screen *screen,
 	    !(templ->bind & PIPE_BIND_SCANOUT)) {
 		if (util_format_is_compressed(templ->format)) {
 			array_mode = V_038000_ARRAY_1D_TILED_THIN1;
-		}
-		else if (debug_get_option_tiling_enabled() &&
-			 rscreen->info.drm_minor >= 9 &&
-			 permit_hardware_blit(screen, templ)) {
+		} else if (debug_get_option_tiling_enabled() &&
+			   rscreen->info.drm_minor >= 9 &&
+			   permit_hardware_blit(screen, templ)) {
 			array_mode = V_038000_ARRAY_2D_TILED_THIN1;
 		}
 	}
diff --git a/src/gallium/targets/dri-r600/Makefile b/src/gallium/targets/dri-r600/Makefile
index 2995b58..8f05103 100644
--- a/src/gallium/targets/dri-r600/Makefile
+++ b/src/gallium/targets/dri-r600/Makefile
@@ -21,6 +21,6 @@ DRIVER_DEFINES = \
 
 include ../Makefile.dri
 
-DRI_LIB_DEPS +=
+DRI_LIB_DEPS += $(shell $(PKG_CONFIG) libdrm_radeon --libs)
 
 symlinks:
diff --git a/src/gallium/winsys/radeon/drm/radeon_drm_winsys.c b/src/gallium/winsys/radeon/drm/radeon_drm_winsys.c
index 5bc25d6..49af513 100644
--- a/src/gallium/winsys/radeon/drm/radeon_drm_winsys.c
+++ b/src/gallium/winsys/radeon/drm/radeon_drm_winsys.c
@@ -289,6 +289,7 @@ static void radeon_winsys_destroy(struct radeon_winsys *rws)
 
     ws->cman->destroy(ws->cman);
     ws->kman->destroy(ws->kman);
+    radeon_surface_manager_free(ws->surf_man);
     FREE(rws);
 }
 
@@ -326,6 +327,14 @@ static boolean radeon_cs_request_feature(struct radeon_winsys_cs *rcs,
     return FALSE;
 }
 
+static int radeon_drm_winsys_surface_init(struct radeon_winsys *rws,
+                                          struct radeon_surface *surf)
+{
+    struct radeon_drm_winsys *ws = (struct radeon_drm_winsys*)rws;
+
+    return radeon_surface_init(ws->surf_man, surf);
+}
+
 struct radeon_winsys *radeon_drm_winsys_create(int fd)
 {
     struct radeon_drm_winsys *ws = CALLOC_STRUCT(radeon_drm_winsys);
@@ -346,10 +355,16 @@ struct radeon_winsys *radeon_drm_winsys_create(int fd)
     if (!ws->cman)
         goto fail;
 
+    /* FIXME check for libdrm version ?? */
+    ws->surf_man = radeon_surface_manager_new(fd);
+    if (!ws->surf_man)
+        goto fail;
+
     /* Set functions. */
     ws->base.destroy = radeon_winsys_destroy;
     ws->base.query_info = radeon_query_info;
     ws->base.cs_request_feature = radeon_cs_request_feature;
+    ws->base.surface_init = radeon_drm_winsys_surface_init;
 
     radeon_bomgr_init_functions(ws);
     radeon_drm_cs_init_functions(ws);
@@ -364,6 +379,8 @@ fail:
         ws->cman->destroy(ws->cman);
     if (ws->kman)
         ws->kman->destroy(ws->kman);
+    if (ws->surf_man)
+        radeon_surface_manager_free(ws->surf_man);
     FREE(ws);
     return NULL;
 }
diff --git a/src/gallium/winsys/radeon/drm/radeon_drm_winsys.h b/src/gallium/winsys/radeon/drm/radeon_drm_winsys.h
index 6921644..6ac86bc 100644
--- a/src/gallium/winsys/radeon/drm/radeon_drm_winsys.h
+++ b/src/gallium/winsys/radeon/drm/radeon_drm_winsys.h
@@ -49,6 +49,7 @@ struct radeon_drm_winsys {
 
     struct pb_manager *kman;
     struct pb_manager *cman;
+    struct radeon_surface_manager *surf_man;
 
     uint32_t num_cpus;      /* Number of CPUs. */
 
diff --git a/src/gallium/winsys/radeon/drm/radeon_winsys.h b/src/gallium/winsys/radeon/drm/radeon_winsys.h
index d33eaa7..88f4fc5 100644
--- a/src/gallium/winsys/radeon/drm/radeon_winsys.h
+++ b/src/gallium/winsys/radeon/drm/radeon_winsys.h
@@ -43,6 +43,7 @@
 #include "pipebuffer/pb_bufmgr.h"
 #include "pipe/p_defines.h"
 #include "pipe/p_state.h"
+#include "libdrm/radeon_surface.h"
 
 #define RADEON_MAX_CMDBUF_DWORDS (16 * 1024)
 
@@ -355,6 +356,15 @@ struct radeon_winsys {
     boolean (*cs_request_feature)(struct radeon_winsys_cs *cs,
                                   enum radeon_feature_id fid,
                                   boolean enable);
+
+    /**
+     * Initialize surface
+     *
+     * \param ws        The winsys this function is called from.
+     * \param surf      Surface structure ptr
+     */
+    int (*surface_init)(struct radeon_winsys *ws,
+                        struct radeon_surface *surf);
 };
 
 #endif
-- 
1.7.7.1


--IJpNTDwzlM2Ie8A6
Content-Type: text/plain; charset=iso-8859-1
Content-Disposition: attachment; filename="0001-radeon-add-surface-allocator-helper.patch"
Content-Transfer-Encoding: 8bit



More information about the mesa-dev mailing list