Mesa (master): r600g: depth buffer likely needs decompression when used as texture

Jerome Glisse glisse at kemper.freedesktop.org
Sun Aug 22 18:26:30 UTC 2010


Module: Mesa
Branch: master
Commit: ed99c28d12579bb8ee79eb9cfa55452785be7b6e
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=ed99c28d12579bb8ee79eb9cfa55452785be7b6e

Author: Jerome Glisse <jglisse at redhat.com>
Date:   Sun Aug 22 14:22:00 2010 -0400

r600g: depth buffer likely needs decompression when used as texture

Before using depth buffer as texture, it needs to be decompressed
(tile pattern of db are different from one used for colorbuffer
like texture)

Signed-off-by: Jerome Glisse <jglisse at redhat.com>

---

 src/gallium/drivers/r600/r600_blit.c     |  665 +++++++++++++++++++++++++++++-
 src/gallium/drivers/r600/r600_context.h  |    2 +-
 src/gallium/drivers/r600/r600_draw.c     |    2 +-
 src/gallium/drivers/r600/r600_resource.h |    8 +
 src/gallium/drivers/r600/r600_screen.h   |    9 +-
 src/gallium/drivers/r600/r600_shader.c   |    1 +
 src/gallium/drivers/r600/r600_state.c    |   38 ++-
 src/gallium/drivers/r600/r600_texture.c  |  228 ++++++++++
 8 files changed, 919 insertions(+), 34 deletions(-)

diff --git a/src/gallium/drivers/r600/r600_blit.c b/src/gallium/drivers/r600/r600_blit.c
index dc57b33..8cb2795 100644
--- a/src/gallium/drivers/r600/r600_blit.c
+++ b/src/gallium/drivers/r600/r600_blit.c
@@ -24,6 +24,7 @@
  *      Jerome Glisse
  *      Marek Olšák
  */
+#include <errno.h>
 #include <pipe/p_screen.h>
 #include <util/u_blitter.h>
 #include <util/u_inlines.h>
@@ -31,6 +32,7 @@
 #include "util/u_surface.h"
 #include "r600_screen.h"
 #include "r600_context.h"
+#include "r600d.h"
 
 static void r600_blitter_save_states(struct pipe_context *ctx)
 {
@@ -130,28 +132,8 @@ static void r600_resource_copy_region(struct pipe_context *ctx,
 				      unsigned srcx, unsigned srcy, unsigned srcz,
 				      unsigned width, unsigned height)
 {
-	struct r600_context *rctx = r600_context(ctx);
-	struct pipe_framebuffer_state *fb = &rctx->framebuffer->state.framebuffer;
-	struct pipe_sampler_state *samplers[PIPE_MAX_ATTRIBS];
-	struct pipe_sampler_view_state *sampler_views[PIPE_MAX_ATTRIBS];
-	unsigned i;
-
-	for (i = 0; i < rctx->ps_nsampler_view; i++) {
-		sampler_views[i] = &rctx->ps_sampler_view[i]->state.sampler_view;
-	}
-	for (i = 0; i < rctx->ps_nsampler; i++) {
-		samplers[i] = &rctx->ps_sampler[i]->state.sampler;
-	}
-	r600_blitter_save_states(ctx);
-	util_blitter_save_framebuffer(rctx->blitter, fb);
-	util_blitter_save_fragment_sampler_states(rctx->blitter, rctx->ps_nsampler, samplers);
-	util_blitter_save_fragment_sampler_views(rctx->blitter, rctx->ps_nsampler_view, sampler_views);
-
-	util_blitter_copy_region(rctx->blitter, dst, subdst, dstx, dsty, dstz,
-			src, subsrc, srcx, srcy, srcz, width, height,
-			TRUE);
-	/* resume queries */
-	r600_queries_resume(ctx);
+	util_resource_copy_region(pipe, dst, subdst, dstx, dsty, dstz,
+				  src, subsrc, srcx, srcy, srcz, width, height);
 }
 
 void r600_init_blit_functions(struct r600_context *rctx)
@@ -161,3 +143,642 @@ void r600_init_blit_functions(struct r600_context *rctx)
 	rctx->context.clear_depth_stencil = r600_clear_depth_stencil;
 	rctx->context.resource_copy_region = r600_resource_copy_region;
 }
+
+
+struct r600_blit_states {
+	struct radeon_state	*rasterizer;
+	struct radeon_state	*dsa;
+	struct radeon_state	*blend;
+	struct radeon_state	*viewport;
+	struct radeon_state	*cb_cntl;
+	struct radeon_state	*config;
+	struct radeon_state	*vgt;
+	struct radeon_state	*draw;
+	struct radeon_state	*vs_constant0;
+	struct radeon_state	*vs_constant1;
+	struct radeon_state	*vs_constant2;
+	struct radeon_state	*vs_constant3;
+	struct radeon_state	*ps_shader;
+	struct radeon_state	*vs_shader;
+	struct radeon_state	*vs_resource0;
+	struct radeon_state	*vs_resource1;
+};
+
+static int r600_blit_state_vs_resources(struct r600_screen *rscreen, struct r600_blit_states *bstates)
+{
+	struct radeon_state *rstate;
+	struct radeon_bo *bo;
+	u32 vbo[] = {
+		0xBF800000, 0xBF800000, 0x3F800000, 0x3F800000,
+		0x3F000000, 0x3F000000, 0x3F000000, 0x00000000,
+		0x3F800000, 0xBF800000, 0x3F800000, 0x3F800000,
+		0x3F000000, 0x3F000000, 0x3F000000, 0x00000000,
+		0x3F800000, 0x3F800000, 0x3F800000, 0x3F800000,
+		0x3F000000, 0x3F000000, 0x3F000000, 0x00000000,
+		0xBF800000, 0x3F800000, 0x3F800000, 0x3F800000,
+		0x3F000000, 0x3F000000, 0x3F000000, 0x00000000
+	};
+
+	/* simple shader */
+	bo = radeon_bo(rscreen->rw, 0, 128, 4096, NULL);
+	if (bo == NULL) {
+		return -ENOMEM;
+	}
+	if (radeon_bo_map(rscreen->rw, bo)) {
+		radeon_bo_decref(rscreen->rw, bo);
+		return -ENOMEM;
+	}
+	memcpy(bo->data, vbo, 128);
+	radeon_bo_unmap(rscreen->rw, bo);
+
+	rstate = radeon_state(rscreen->rw, R600_VS_RESOURCE_TYPE, R600_VS_RESOURCE + 0);
+	if (rstate == NULL) {
+		radeon_bo_decref(rscreen->rw, bo);
+		return -ENOMEM;
+	}
+
+	/* set states (most default value are 0 and struct already
+	 * initialized to 0, thus avoid resetting them)
+	 */
+	rstate->states[R600_VS_RESOURCE__RESOURCE160_WORD0] = 0x00000000;
+	rstate->states[R600_VS_RESOURCE__RESOURCE160_WORD1] = 0x00000080;
+	rstate->states[R600_VS_RESOURCE__RESOURCE160_WORD2] = 0x02302000;
+	rstate->states[R600_VS_RESOURCE__RESOURCE160_WORD3] = 0x00000000;
+	rstate->states[R600_VS_RESOURCE__RESOURCE160_WORD4] = 0x00000000;
+	rstate->states[R600_VS_RESOURCE__RESOURCE160_WORD5] = 0x00000000;
+	rstate->states[R600_VS_RESOURCE__RESOURCE160_WORD6] = 0xC0000000;
+	rstate->bo[0] = bo;
+	rstate->nbo = 1;
+	rstate->placement[0] = RADEON_GEM_DOMAIN_GTT;
+	if (radeon_state_pm4(rstate)) {
+		radeon_state_decref(rstate);
+		return -ENOMEM;
+	}
+	bstates->vs_resource0 = rstate;
+
+	rstate = radeon_state(rscreen->rw, R600_VS_RESOURCE_TYPE, R600_VS_RESOURCE + 1);
+	if (rstate == NULL) {
+		return -ENOMEM;
+	}
+	rstate->states[R600_VS_RESOURCE__RESOURCE160_WORD0] = 0x00000010;
+	rstate->states[R600_VS_RESOURCE__RESOURCE160_WORD1] = 0x00000070;
+	rstate->states[R600_VS_RESOURCE__RESOURCE160_WORD2] = 0x02302000;
+	rstate->states[R600_VS_RESOURCE__RESOURCE160_WORD3] = 0x00000000;
+	rstate->states[R600_VS_RESOURCE__RESOURCE160_WORD4] = 0x00000000;
+	rstate->states[R600_VS_RESOURCE__RESOURCE160_WORD5] = 0x00000000;
+	rstate->states[R600_VS_RESOURCE__RESOURCE160_WORD6] = 0xC0000000;
+	rstate->bo[0] = radeon_bo_incref(rscreen->rw, bo);
+	rstate->nbo = 1;
+	rstate->placement[0] = RADEON_GEM_DOMAIN_GTT;
+	if (radeon_state_pm4(rstate)) {
+		radeon_state_decref(rstate);
+		return -ENOMEM;
+	}
+	bstates->vs_resource1 = rstate;
+
+	return 0;
+}
+
+static struct radeon_state *r600_blit_state_vs_shader(struct r600_screen *rscreen)
+{
+	struct radeon_state *rstate;
+	struct radeon_bo *bo;
+	u32 shader_bc[] = {
+		0x00000004, 0x81000400,
+		0x00000008, 0xA01C0000,
+		0xC001A03C, 0x94000688,
+		0xC0024000, 0x94200688,
+		0x7C000000, 0x002D1001,
+		0x00080000, 0x00000000,
+		0x7C000100, 0x002D1002,
+		0x00080000, 0x00000000,
+		0x00000001, 0x00601910,
+		0x00000401, 0x20601910,
+		0x00000801, 0x40601910,
+		0x80000C01, 0x60601910,
+		0x00000002, 0x00801910,
+		0x00000402, 0x20801910,
+		0x00000802, 0x40801910,
+		0x80000C02, 0x60801910
+	};
+
+	/* simple shader */
+	bo = radeon_bo(rscreen->rw, 0, 128, 4096, NULL);
+	if (bo == NULL) {
+		return NULL;
+	}
+	if (radeon_bo_map(rscreen->rw, bo)) {
+		radeon_bo_decref(rscreen->rw, bo);
+		return NULL;
+	}
+	memcpy(bo->data, shader_bc, 128);
+	radeon_bo_unmap(rscreen->rw, bo);
+
+	rstate = radeon_state(rscreen->rw, R600_VS_SHADER_TYPE, R600_VS_SHADER);
+	if (rstate == NULL) {
+		radeon_bo_decref(rscreen->rw, bo);
+		return NULL;
+	}
+
+	/* set states (most default value are 0 and struct already
+	 * initialized to 0, thus avoid resetting them)
+	 */
+	rstate->states[R600_VS_SHADER__SPI_VS_OUT_ID_0] = 0x03020100;
+	rstate->states[R600_VS_SHADER__SPI_VS_OUT_ID_1] = 0x07060504;
+	rstate->states[R600_VS_SHADER__SQ_PGM_RESOURCES_VS] = 0x00000005;
+
+	rstate->bo[0] = bo;
+	rstate->bo[1] = radeon_bo_incref(rscreen->rw, bo);
+	rstate->nbo = 2;
+	rstate->placement[0] = RADEON_GEM_DOMAIN_GTT;
+	rstate->placement[2] = RADEON_GEM_DOMAIN_GTT;
+
+	if (radeon_state_pm4(rstate)) {
+		radeon_state_decref(rstate);
+		return NULL;
+	}
+	return rstate;
+}
+
+static struct radeon_state *r600_blit_state_ps_shader(struct r600_screen *rscreen)
+{
+	struct radeon_state *rstate;
+	struct radeon_bo *bo;
+	u32 shader_bc[] = {
+		0x00000002, 0xA00C0000,
+		0xC0008000, 0x94200688,
+		0x00000000, 0x00201910,
+		0x00000400, 0x20201910,
+		0x00000800, 0x40201910,
+		0x80000C00, 0x60201910
+	};
+
+	/* simple shader */
+	bo = radeon_bo(rscreen->rw, 0, 128, 4096, NULL);
+	if (bo == NULL) {
+		radeon_bo_decref(rscreen->rw, bo);
+		return NULL;
+	}
+	if (radeon_bo_map(rscreen->rw, bo)) {
+		return NULL;
+	}
+	memcpy(bo->data, shader_bc, 48);
+	radeon_bo_unmap(rscreen->rw, bo);
+
+	rstate = radeon_state(rscreen->rw, R600_PS_SHADER_TYPE, R600_PS_SHADER);
+	if (rstate == NULL) {
+		radeon_bo_decref(rscreen->rw, bo);
+		return NULL;
+	}
+
+	/* set states (most default value are 0 and struct already
+	 * initialized to 0, thus avoid resetting them)
+	 */
+	rstate->states[R600_PS_SHADER__SPI_PS_INPUT_CNTL_0] = 0x00000C00;
+	rstate->states[R600_PS_SHADER__SPI_PS_IN_CONTROL_0] = 0x10000001;
+	rstate->states[R600_PS_SHADER__SQ_PGM_EXPORTS_PS] = 0x00000002;
+	rstate->states[R600_PS_SHADER__SQ_PGM_RESOURCES_PS] = 0x00000002;
+
+	rstate->bo[0] = bo;
+	rstate->nbo = 1;
+	rstate->placement[0] = RADEON_GEM_DOMAIN_GTT;
+
+	if (radeon_state_pm4(rstate)) {
+		radeon_state_decref(rstate);
+		return NULL;
+	}
+	return rstate;
+}
+
+static struct radeon_state *r600_blit_state_vgt(struct r600_screen *rscreen)
+{
+	struct radeon_state *rstate;
+
+	rstate = radeon_state(rscreen->rw, R600_VGT_TYPE, R600_VGT);
+	if (rstate == NULL)
+		return NULL;
+
+	/* set states (most default value are 0 and struct already
+	 * initialized to 0, thus avoid resetting them)
+	 */
+	rstate->states[R600_VGT__VGT_DMA_NUM_INSTANCES] = 0x00000001;
+	rstate->states[R600_VGT__VGT_MAX_VTX_INDX] = 0x00FFFFFF;
+	rstate->states[R600_VGT__VGT_PRIMITIVE_TYPE] = 0x00000005;
+
+	if (radeon_state_pm4(rstate)) {
+		radeon_state_decref(rstate);
+		return NULL;
+	}
+	return rstate;
+}
+
+static struct radeon_state *r600_blit_state_draw(struct r600_screen *rscreen)
+{
+	struct radeon_state *rstate;
+
+	rstate = radeon_state(rscreen->rw, R600_DRAW_TYPE, R600_DRAW);
+	if (rstate == NULL)
+		return NULL;
+
+	/* set states (most default value are 0 and struct already
+	 * initialized to 0, thus avoid resetting them)
+	 */
+	rstate->states[R600_DRAW__VGT_DRAW_INITIATOR] = 0x00000002;
+	rstate->states[R600_DRAW__VGT_NUM_INDICES] = 0x00000004;
+
+	if (radeon_state_pm4(rstate)) {
+		radeon_state_decref(rstate);
+		return NULL;
+	}
+	return rstate;
+}
+
+static struct radeon_state *r600_blit_state_vs_constant(struct r600_screen *rscreen,
+					unsigned id, float c0, float c1,
+					float c2, float c3)
+{
+	struct radeon_state *rstate;
+
+	rstate = radeon_state(rscreen->rw, R600_VS_CONSTANT_TYPE, R600_VS_CONSTANT + id);
+	if (rstate == NULL)
+		return NULL;
+
+	/* set states (most default value are 0 and struct already
+	 * initialized to 0, thus avoid resetting them)
+	 */
+	rstate->states[R600_VS_CONSTANT__SQ_ALU_CONSTANT0_256] = fui(c0);
+	rstate->states[R600_VS_CONSTANT__SQ_ALU_CONSTANT1_256] = fui(c1);
+	rstate->states[R600_VS_CONSTANT__SQ_ALU_CONSTANT2_256] = fui(c2);
+	rstate->states[R600_VS_CONSTANT__SQ_ALU_CONSTANT3_256] = fui(c3);
+
+	if (radeon_state_pm4(rstate)) {
+		radeon_state_decref(rstate);
+		return NULL;
+	}
+	return rstate;
+}
+
+static struct radeon_state *r600_blit_state_rasterizer(struct r600_screen *rscreen)
+{
+	struct radeon_state *rstate;
+
+	rstate = radeon_state(rscreen->rw, R600_RASTERIZER_TYPE, R600_RASTERIZER);
+	if (rstate == NULL)
+		return NULL;
+
+	/* set states (most default value are 0 and struct already
+	 * initialized to 0, thus avoid resetting them)
+	 */
+	rstate->states[R600_RASTERIZER__PA_CL_GB_HORZ_CLIP_ADJ] = 0x3F800000;
+	rstate->states[R600_RASTERIZER__PA_CL_GB_HORZ_DISC_ADJ] = 0x3F800000;
+	rstate->states[R600_RASTERIZER__PA_CL_GB_VERT_CLIP_ADJ] = 0x3F800000;
+	rstate->states[R600_RASTERIZER__PA_CL_GB_VERT_DISC_ADJ] = 0x3F800000;
+	rstate->states[R600_RASTERIZER__PA_SC_LINE_CNTL] = 0x00000400;
+	rstate->states[R600_RASTERIZER__PA_SC_LINE_STIPPLE] = 0x00000005;
+	rstate->states[R600_RASTERIZER__PA_SU_LINE_CNTL] = 0x00000008;
+	rstate->states[R600_RASTERIZER__PA_SU_POINT_MINMAX] = 0x80000000;
+	rstate->states[R600_RASTERIZER__PA_SU_SC_MODE_CNTL] = 0x00080004;
+	rstate->states[R600_RASTERIZER__SPI_INTERP_CONTROL_0] = 0x00000001;
+
+	if (radeon_state_pm4(rstate)) {
+		radeon_state_decref(rstate);
+		return NULL;
+	}
+	return rstate;
+}
+
+static struct radeon_state *r600_blit_state_dsa(struct r600_screen *rscreen)
+{
+	struct radeon_state *rstate;
+
+	rstate = radeon_state(rscreen->rw, R600_DSA_TYPE, R600_DSA);
+	if (rstate == NULL)
+		return NULL;
+
+	/* set states (most default value are 0 and struct already
+	 * initialized to 0, thus avoid resetting them)
+	 */
+	rstate->states[R600_DSA__DB_ALPHA_TO_MASK] = 0x0000AA00;
+	rstate->states[R600_DSA__DB_DEPTH_CLEAR] = 0x3F800000;
+	rstate->states[R600_DSA__DB_RENDER_CONTROL] = 0x00000060;
+	rstate->states[R600_DSA__DB_RENDER_OVERRIDE] = 0x0000002A;
+	rstate->states[R600_DSA__DB_SHADER_CONTROL] = 0x00000210;
+
+	if (radeon_state_pm4(rstate)) {
+		radeon_state_decref(rstate);
+		return NULL;
+	}
+	return rstate;
+}
+
+static struct radeon_state *r600_blit_state_blend(struct r600_screen *rscreen)
+{
+	struct radeon_state *rstate;
+
+	rstate = radeon_state(rscreen->rw, R600_BLEND_TYPE, R600_BLEND);
+	if (rstate == NULL)
+		return NULL;
+
+	/* set states (most default value are 0 and struct already
+	 * initialized to 0, thus avoid resetting them)
+	 */
+
+	if (radeon_state_pm4(rstate)) {
+		radeon_state_decref(rstate);
+		return NULL;
+	}
+	return rstate;
+}
+
+static struct radeon_state *r600_blit_state_viewport(struct r600_screen *rscreen)
+{
+	struct radeon_state *rstate;
+
+	rstate = radeon_state(rscreen->rw, R600_VIEWPORT_TYPE, R600_VIEWPORT);
+	if (rstate == NULL)
+		return NULL;
+
+	/* set states (most default value are 0 and struct already
+	 * initialized to 0, thus avoid resetting them)
+	 */
+	rstate->states[R600_VIEWPORT__PA_CL_VPORT_XOFFSET_0] = 0x42FA0000;
+	rstate->states[R600_VIEWPORT__PA_CL_VPORT_XSCALE_0] = 0x42FA0000;
+	rstate->states[R600_VIEWPORT__PA_CL_VPORT_YOFFSET_0] = 0x42FA0000;
+	rstate->states[R600_VIEWPORT__PA_CL_VPORT_YSCALE_0] = 0xC2FA0000;
+	rstate->states[R600_VIEWPORT__PA_CL_VPORT_ZOFFSET_0] = 0x3F000000;
+	rstate->states[R600_VIEWPORT__PA_CL_VPORT_ZSCALE_0] = 0x3F000000;
+	rstate->states[R600_VIEWPORT__PA_CL_VTE_CNTL] = 0x0000043F;
+	rstate->states[R600_VIEWPORT__PA_SC_VPORT_ZMAX_0] = 0x3F800000;
+
+	if (radeon_state_pm4(rstate)) {
+		radeon_state_decref(rstate);
+		return NULL;
+	}
+	return rstate;
+}
+
+static struct radeon_state *r600_blit_state_cb_cntl(struct r600_screen *rscreen)
+{
+	struct radeon_state *rstate;
+
+	rstate = radeon_state(rscreen->rw, R600_CB_CNTL_TYPE, R600_CB_CNTL);
+	if (rstate == NULL)
+		return NULL;
+
+	/* set states (most default value are 0 and struct already
+	 * initialized to 0, thus avoid resetting them)
+	 */
+	rstate->states[R600_CB_CNTL__CB_CLRCMP_CONTROL] = 0x01000000;
+	rstate->states[R600_CB_CNTL__CB_CLRCMP_DST] = 0x000000FF;
+	rstate->states[R600_CB_CNTL__CB_CLRCMP_MSK] = 0xFFFFFFFF;
+	rstate->states[R600_CB_CNTL__CB_COLOR_CONTROL] = 0x00CC0080;
+	rstate->states[R600_CB_CNTL__CB_SHADER_MASK] = 0x0000000F;
+	rstate->states[R600_CB_CNTL__CB_TARGET_MASK] = 0x0000000F;
+	rstate->states[R600_CB_CNTL__PA_SC_AA_MASK] = 0xFFFFFFFF;
+
+	if (radeon_state_pm4(rstate)) {
+		radeon_state_decref(rstate);
+		return NULL;
+	}
+	return rstate;
+}
+
+static int r600_blit_states_init(struct pipe_context *ctx, struct r600_blit_states *bstates)
+{
+	struct r600_screen *rscreen = r600_screen(ctx->screen);
+	struct r600_context *rctx = r600_context(ctx);
+	int r;
+
+	bstates->ps_shader = r600_blit_state_ps_shader(rscreen);
+	if (bstates->ps_shader == NULL) {
+		R600_ERR("failed creating ps_shader state\n");
+		return -ENOMEM;
+	}
+	bstates->vs_shader = r600_blit_state_vs_shader(rscreen);
+	if (bstates->vs_shader == NULL) {
+		R600_ERR("failed creating vs_shader state\n");
+		return -ENOMEM;
+	}
+	bstates->vgt = r600_blit_state_vgt(rscreen);
+	if (bstates->vgt == NULL) {
+		R600_ERR("failed creating vgt state\n");
+		return -ENOMEM;
+	}
+	bstates->draw = r600_blit_state_draw(rscreen);
+	if (bstates->draw == NULL) {
+		R600_ERR("failed creating draw state\n");
+		return -ENOMEM;
+	}
+	bstates->vs_constant0 = r600_blit_state_vs_constant(rscreen, 0, 1.0, 0.0, 0.0, 0.0);
+	if (bstates->vs_constant0 == NULL) {
+		R600_ERR("failed creating vs_constant0 state\n");
+		return -ENOMEM;
+	}
+	bstates->vs_constant1 = r600_blit_state_vs_constant(rscreen, 1, 0.0, 1.0, 0.0, 0.0);
+	if (bstates->vs_constant1 == NULL) {
+		R600_ERR("failed creating vs_constant1 state\n");
+		return -ENOMEM;
+	}
+	bstates->vs_constant2 = r600_blit_state_vs_constant(rscreen, 2, 0.0, 0.0, -0.00199900055, 0.0);
+	if (bstates->vs_constant2 == NULL) {
+		R600_ERR("failed creating vs_constant2 state\n");
+		return -ENOMEM;
+	}
+	bstates->vs_constant3 = r600_blit_state_vs_constant(rscreen, 3, 0.0, 0.0, -0.99900049, 1.0);
+	if (bstates->vs_constant3 == NULL) {
+		R600_ERR("failed creating vs_constant3 state\n");
+		return -ENOMEM;
+	}
+	bstates->rasterizer = r600_blit_state_rasterizer(rscreen);
+	if (bstates->rasterizer == NULL) {
+		R600_ERR("failed creating rasterizer state\n");
+		return -ENOMEM;
+	}
+	bstates->dsa = r600_blit_state_dsa(rscreen);
+	if (bstates->dsa == NULL) {
+		R600_ERR("failed creating dsa state\n");
+		return -ENOMEM;
+	}
+	bstates->blend = r600_blit_state_blend(rscreen);
+	if (bstates->blend == NULL) {
+		R600_ERR("failed creating blend state\n");
+		return -ENOMEM;
+	}
+	bstates->viewport = r600_blit_state_viewport(rscreen);
+	if (bstates->viewport == NULL) {
+		R600_ERR("failed creating viewport state\n");
+		return -ENOMEM;
+	}
+	bstates->cb_cntl = r600_blit_state_cb_cntl(rscreen);
+	if (bstates->cb_cntl == NULL) {
+		R600_ERR("failed creating cb_cntl state\n");
+		return -ENOMEM;
+	}
+	r = r600_blit_state_vs_resources(rscreen, bstates);
+	if (r) {
+		R600_ERR("failed creating vs_resource state\n");
+		return r;
+	}
+	bstates->config = radeon_state_incref(rctx->hw_states.config);
+	return 0;
+}
+
+static void r600_blit_states_destroy(struct pipe_context *ctx, struct r600_blit_states *bstates)
+{
+	radeon_state_decref(bstates->rasterizer);
+	radeon_state_decref(bstates->dsa);
+	radeon_state_decref(bstates->blend);
+	radeon_state_decref(bstates->viewport);
+	radeon_state_decref(bstates->cb_cntl);
+	radeon_state_decref(bstates->config);
+	radeon_state_decref(bstates->vgt);
+	radeon_state_decref(bstates->draw);
+	radeon_state_decref(bstates->vs_constant0);
+	radeon_state_decref(bstates->vs_constant1);
+	radeon_state_decref(bstates->vs_constant2);
+	radeon_state_decref(bstates->vs_constant3);
+	radeon_state_decref(bstates->ps_shader);
+	radeon_state_decref(bstates->vs_shader);
+	radeon_state_decref(bstates->vs_resource0);
+	radeon_state_decref(bstates->vs_resource1);
+}
+
+int r600_blit_uncompress_depth(struct pipe_context *ctx, struct r600_resource_texture *rtexture, unsigned level)
+{
+	struct r600_screen *rscreen = r600_screen(ctx->screen);
+	struct r600_context *rctx = r600_context(ctx);
+	struct radeon_draw *draw = NULL;
+	struct r600_blit_states bstates;
+	int r;
+
+	r = r600_texture_scissor(ctx, rtexture, level);
+	if (r) {
+		return r;
+	}
+	r = r600_texture_cb0(ctx, rtexture, level);
+	if (r) {
+		return r;
+	}
+	r = r600_texture_db(ctx, rtexture, level);
+	if (r) {
+		return r;
+	}
+
+	r = r600_blit_states_init(ctx, &bstates);
+	if (r) {
+		return r;
+	}
+	bstates.dsa->states[R600_DSA__DB_RENDER_CONTROL] = 0x000000EC;
+	bstates.cb_cntl->states[R600_CB_CNTL__CB_TARGET_MASK] = 0x00000001;
+	/* force rebuild */
+	bstates.dsa->cpm4 = bstates.cb_cntl->cpm4 = 0;
+	if (radeon_state_pm4(bstates.dsa)) {
+		goto out;
+	}
+	if (radeon_state_pm4(bstates.cb_cntl)) {
+		goto out;
+	}
+
+	draw = radeon_draw(rscreen->rw);
+	if (draw == NULL) {
+		R600_ERR("failed creating draw for uncompressing textures\n");
+		goto out;
+	}
+
+	r = radeon_draw_set(draw, bstates.vs_shader);
+	if (r) {
+		goto out;
+	}
+	r = radeon_draw_set(draw, bstates.ps_shader);
+	if (r) {
+		goto out;
+	}
+	r = radeon_draw_set(draw, bstates.rasterizer);
+	if (r) {
+		goto out;
+	}
+	r = radeon_draw_set(draw, bstates.dsa);
+	if (r) {
+		goto out;
+	}
+	r = radeon_draw_set(draw, bstates.blend);
+	if (r) {
+		goto out;
+	}
+	r = radeon_draw_set(draw, bstates.viewport);
+	if (r) {
+		goto out;
+	}
+	r = radeon_draw_set(draw, bstates.cb_cntl);
+	if (r) {
+		goto out;
+	}
+	r = radeon_draw_set(draw, bstates.config);
+	if (r) {
+		goto out;
+	}
+	r = radeon_draw_set(draw, bstates.vgt);
+	if (r) {
+		goto out;
+	}
+	r = radeon_draw_set(draw, bstates.draw);
+	if (r) {
+		goto out;
+	}
+	r = radeon_draw_set(draw, bstates.vs_resource0);
+	if (r) {
+		goto out;
+	}
+	r = radeon_draw_set(draw, bstates.vs_resource1);
+	if (r) {
+		goto out;
+	}
+	r = radeon_draw_set(draw, bstates.vs_constant0);
+	if (r) {
+		goto out;
+	}
+	r = radeon_draw_set(draw, bstates.vs_constant1);
+	if (r) {
+		goto out;
+	}
+	r = radeon_draw_set(draw, bstates.vs_constant2);
+	if (r) {
+		goto out;
+	}
+	r = radeon_draw_set(draw, bstates.vs_constant3);
+	if (r) {
+		goto out;
+	}
+	r = radeon_draw_set(draw, rtexture->scissor[level]);
+	if (r) {
+		goto out;
+	}
+	r = radeon_draw_set(draw, rtexture->cb0[level]);
+	if (r) {
+		goto out;
+	}
+	r = radeon_draw_set(draw, rtexture->db[level]);
+	if (r) {
+		goto out;
+	}
+
+	/* suspend queries */
+	r600_queries_suspend(ctx);
+
+	/* schedule draw*/
+	r = radeon_ctx_set_draw_new(rctx->ctx, draw);
+	if (r == -EBUSY) {
+		r600_flush(ctx, 0, NULL);
+		r = radeon_ctx_set_draw_new(rctx->ctx, draw);
+	}
+	if (r) {
+		goto out;
+	}
+
+	/* resume queries */
+	r600_queries_resume(ctx);
+
+out:
+	r600_blit_states_destroy(ctx, &bstates);
+	return r;
+}
diff --git a/src/gallium/drivers/r600/r600_context.h b/src/gallium/drivers/r600/r600_context.h
index 900aa9f..d96d5b5 100644
--- a/src/gallium/drivers/r600/r600_context.h
+++ b/src/gallium/drivers/r600/r600_context.h
@@ -186,7 +186,7 @@ struct r600_context_state *r600_context_state_decref(struct r600_context_state *
 void r600_flush(struct pipe_context *ctx, unsigned flags,
 			struct pipe_fence_handle **fence);
 
-int r600_context_hw_states(struct r600_context *rctx);
+int r600_context_hw_states(struct pipe_context *ctx);
 
 void r600_draw_vbo(struct pipe_context *ctx,
                    const struct pipe_draw_info *info);
diff --git a/src/gallium/drivers/r600/r600_draw.c b/src/gallium/drivers/r600/r600_draw.c
index f058455..1eb868c 100644
--- a/src/gallium/drivers/r600/r600_draw.c
+++ b/src/gallium/drivers/r600/r600_draw.c
@@ -58,7 +58,7 @@ static int r600_draw_common(struct r600_draw *draw)
 	struct pipe_vertex_buffer *vertex_buffer;
 	int r;
 
-	r = r600_context_hw_states(rctx);
+	r = r600_context_hw_states(draw->ctx);
 	if (r)
 		return r;
 	switch (draw->index_size) {
diff --git a/src/gallium/drivers/r600/r600_resource.h b/src/gallium/drivers/r600/r600_resource.h
index 5ebda02..5b3a702 100644
--- a/src/gallium/drivers/r600/r600_resource.h
+++ b/src/gallium/drivers/r600/r600_resource.h
@@ -44,6 +44,8 @@ struct r600_resource_texture {
 	struct r600_resource		resource;
 	unsigned long			offset[PIPE_MAX_TEXTURE_LEVELS];
 	unsigned long			pitch[PIPE_MAX_TEXTURE_LEVELS];
+	unsigned long			width[PIPE_MAX_TEXTURE_LEVELS];
+	unsigned long			height[PIPE_MAX_TEXTURE_LEVELS];
 	unsigned long			layer_size[PIPE_MAX_TEXTURE_LEVELS];
 	unsigned long			pitch_override;
 	unsigned long			bpt;
@@ -51,6 +53,12 @@ struct r600_resource_texture {
 	unsigned			tilled;
 	unsigned			array_mode;
 	unsigned			tile_type;
+	unsigned			depth;
+	unsigned			dirty;
+	struct radeon_bo		*uncompressed;
+	struct radeon_state		*scissor[PIPE_MAX_TEXTURE_LEVELS];
+	struct radeon_state		*cb0[PIPE_MAX_TEXTURE_LEVELS];
+	struct radeon_state		*db[PIPE_MAX_TEXTURE_LEVELS];
 };
 
 void r600_init_context_resource_functions(struct r600_context *r600);
diff --git a/src/gallium/drivers/r600/r600_screen.h b/src/gallium/drivers/r600/r600_screen.h
index 147be3c..4b2aac7 100644
--- a/src/gallium/drivers/r600/r600_screen.h
+++ b/src/gallium/drivers/r600/r600_screen.h
@@ -30,6 +30,7 @@
 #include <radeon_drm.h>
 #include "radeon.h"
 #include "util/u_transfer.h"
+#include "r600_resource.h"
 
 /* Texture transfer. */
 struct r600_transfer {
@@ -63,7 +64,7 @@ unsigned r600_buffer_is_referenced_by_cs(struct pipe_context *context,
 struct pipe_resource *r600_buffer_from_handle(struct pipe_screen *screen,
 					      struct winsys_handle *whandle);
 
-/* Texture transfer functions. */
+/* r600_texture.c texture transfer functions. */
 struct pipe_transfer* r600_texture_get_transfer(struct pipe_context *ctx,
 						struct pipe_resource *texture,
 						struct pipe_subresource sr,
@@ -75,7 +76,13 @@ void* r600_texture_transfer_map(struct pipe_context *ctx,
 				struct pipe_transfer* transfer);
 void r600_texture_transfer_unmap(struct pipe_context *ctx,
 				 struct pipe_transfer* transfer);
+int r600_texture_scissor(struct pipe_context *ctx, struct r600_resource_texture *rtexture, unsigned level);
+int r600_texture_cb0(struct pipe_context *ctx, struct r600_resource_texture *rtexture, unsigned level);
+int r600_texture_db(struct pipe_context *ctx, struct r600_resource_texture *rtexture, unsigned level);
+int r600_texture_from_depth(struct pipe_context *ctx, struct r600_resource_texture *rtexture, unsigned level);
 
+/* r600_blit.c */
+int r600_blit_uncompress_depth(struct pipe_context *ctx, struct r600_resource_texture *rtexture, unsigned level);
 
 /* helpers */
 int r600_conv_pipe_format(unsigned pformat, unsigned *format);
diff --git a/src/gallium/drivers/r600/r600_shader.c b/src/gallium/drivers/r600/r600_shader.c
index 79fc04a..5cdbe2b 100644
--- a/src/gallium/drivers/r600/r600_shader.c
+++ b/src/gallium/drivers/r600/r600_shader.c
@@ -150,6 +150,7 @@ static int r600_pipe_shader_vs(struct pipe_context *ctx, struct r600_context_sta
 	rpshader->rstate->bo[1] = radeon_bo_incref(rscreen->rw, rpshader->bo);
 	rpshader->rstate->nbo = 2;
 	rpshader->rstate->placement[0] = RADEON_GEM_DOMAIN_GTT;
+	rpshader->rstate->placement[2] = RADEON_GEM_DOMAIN_GTT;
 	return radeon_state_pm4(state);
 }
 
diff --git a/src/gallium/drivers/r600/r600_state.c b/src/gallium/drivers/r600/r600_state.c
index e9b03f5..58df328 100644
--- a/src/gallium/drivers/r600/r600_state.c
+++ b/src/gallium/drivers/r600/r600_state.c
@@ -776,7 +776,9 @@ static struct radeon_state *r600_db(struct r600_context *rctx)
 	rtex->tilled = 1;
 	rtex->array_mode = 2;
 	rtex->tile_type = 1;
+	rtex->depth = 1;
 	rbuffer = &rtex->resource;
+R600_ERR("DB handle %d   %p  %d\n", rbuffer->bo->handle, rtex, state->zsbuf->texture->format);
 	rstate->bo[0] = radeon_bo_incref(rscreen->rw, rbuffer->bo);
 	rstate->nbo = 1;
 	rstate->placement[0] = RADEON_GEM_DOMAIN_VRAM;
@@ -785,7 +787,7 @@ static struct radeon_state *r600_db(struct r600_context *rctx)
 	slice = (rtex->pitch[level] / rtex->bpt) * state->zsbuf->height / 64 - 1;
 	format = r600_translate_dbformat(state->zsbuf->texture->format);
 	rstate->states[R600_DB__DB_DEPTH_BASE] = rtex->offset[level] >> 8;
-	rstate->states[R600_DB__DB_DEPTH_INFO] = 0x00010000 |
+	rstate->states[R600_DB__DB_DEPTH_INFO] = S_028010_ARRAY_MODE(rtex->array_mode) |
 					S_028010_FORMAT(format);
 	rstate->states[R600_DB__DB_DEPTH_VIEW] = 0x00000000;
 	rstate->states[R600_DB__DB_PREFETCH_LIMIT] = (state->zsbuf->height / 8) -1;
@@ -1214,10 +1216,11 @@ static inline unsigned r600_tex_dim(unsigned dim)
 	}
 }
 
-static struct radeon_state *r600_resource(struct r600_context *rctx,
+static struct radeon_state *r600_resource(struct pipe_context *ctx,
 					const struct pipe_sampler_view *view,
 					unsigned id)
 {
+	struct r600_context *rctx = r600_context(ctx);
 	struct r600_screen *rscreen = rctx->screen;
 	const struct util_format_description *desc;
 	struct r600_resource_texture *tmp;
@@ -1225,7 +1228,8 @@ static struct radeon_state *r600_resource(struct r600_context *rctx,
 	struct radeon_state *rstate;
 	unsigned format;
 	uint32_t word4 = 0, yuv_format = 0, pitch = 0;
-	unsigned char swizzle[4];
+	unsigned char swizzle[4], array_mode = 0, tile_type = 0;
+	int r;
 
 	swizzle[0] = view->swizzle_r;
 	swizzle[1] = view->swizzle_g;
@@ -1247,8 +1251,23 @@ static struct radeon_state *r600_resource(struct r600_context *rctx,
 	}
 	tmp = (struct r600_resource_texture*)view->texture;
 	rbuffer = &tmp->resource;
-	rstate->bo[0] = radeon_bo_incref(rscreen->rw, rbuffer->bo);
-	rstate->bo[1] = radeon_bo_incref(rscreen->rw, rbuffer->bo);
+	if (tmp->depth) {
+		r = r600_texture_from_depth(ctx, tmp, view->first_level);
+		if (r) {
+			return NULL;
+		}
+format = r600_translate_colorformat(view->texture->format);
+R600_ERR("DEPTH TEXTURE %d rtex %p %d 0x%02X\n", tmp->uncompressed->handle, tmp, view->texture->format, format);
+format = 17;
+		rstate->bo[0] = radeon_bo_incref(rscreen->rw, tmp->uncompressed);
+		rstate->bo[1] = radeon_bo_incref(rscreen->rw, tmp->uncompressed);
+//		array_mode = tmp->array_mode;
+//		tile_type = tmp->tile_type;
+	} else {
+R600_ERR("NOT DEPTH TEXTURE\n");
+		rstate->bo[0] = radeon_bo_incref(rscreen->rw, rbuffer->bo);
+		rstate->bo[1] = radeon_bo_incref(rscreen->rw, rbuffer->bo);
+	}
 	rstate->nbo = 2;
 	rstate->placement[0] = RADEON_GEM_DOMAIN_GTT;
 	rstate->placement[1] = RADEON_GEM_DOMAIN_GTT;
@@ -1261,8 +1280,8 @@ static struct radeon_state *r600_resource(struct r600_context *rctx,
 	/* FIXME properly handle first level != 0 */
 	rstate->states[R600_PS_RESOURCE__RESOURCE0_WORD0] =
 			S_038000_DIM(r600_tex_dim(view->texture->target)) |
-			S_038000_TILE_MODE(tmp->array_mode) |
-			S_038000_TILE_TYPE(tmp->tile_type) |
+			S_038000_TILE_MODE(array_mode) |
+			S_038000_TILE_TYPE(tile_type) |
 			S_038000_PITCH((pitch / 8) - 1) |
 			S_038000_TEX_WIDTH(view->texture->width0 - 1);
 	rstate->states[R600_PS_RESOURCE__RESOURCE0_WORD1] =
@@ -1347,8 +1366,9 @@ static struct radeon_state *r600_cb_cntl(struct r600_context *rctx)
 	return rstate;
 }
 
-int r600_context_hw_states(struct r600_context *rctx)
+int r600_context_hw_states(struct pipe_context *ctx)
 {
+	struct r600_context *rctx = r600_context(ctx);
 	unsigned i;
 	int r;
 	int nr_cbufs = rctx->framebuffer->state.framebuffer.nr_cbufs;
@@ -1410,7 +1430,7 @@ int r600_context_hw_states(struct r600_context *rctx)
 	rctx->hw_states.ps_nsampler = rctx->ps_nsampler;
 	for (i = 0; i < rctx->ps_nsampler_view; i++) {
 		if (rctx->ps_sampler_view[i]) {
-			rctx->hw_states.ps_resource[i] = r600_resource(rctx,
+			rctx->hw_states.ps_resource[i] = r600_resource(ctx,
 							&rctx->ps_sampler_view[i]->state.sampler_view,
 							R600_PS_RESOURCE + i);
 		}
diff --git a/src/gallium/drivers/r600/r600_texture.c b/src/gallium/drivers/r600/r600_texture.c
index 92b4f43..c79dd34 100644
--- a/src/gallium/drivers/r600/r600_texture.c
+++ b/src/gallium/drivers/r600/r600_texture.c
@@ -24,6 +24,7 @@
  *      Jerome Glisse
  *      Corbin Simpson
  */
+#include <errno.h>
 #include <pipe/p_screen.h>
 #include <util/u_format.h>
 #include <util/u_math.h>
@@ -33,6 +34,7 @@
 #include "r600_screen.h"
 #include "r600_context.h"
 #include "r600_resource.h"
+#include "r600_state_inlines.h"
 #include "r600d.h"
 
 extern struct u_resource_vtbl r600_texture_vtbl;
@@ -91,6 +93,8 @@ static void r600_setup_miptree(struct r600_screen *rscreen, struct r600_resource
 		rtex->offset[i] = offset;
 		rtex->layer_size[i] = layer_size;
 		rtex->pitch[i] = pitch;
+		rtex->width[i] = w;
+		rtex->height[i] = h;
 		offset += size;
 	}
 	rtex->size = offset;
@@ -130,10 +134,19 @@ static void r600_texture_destroy(struct pipe_screen *screen,
 	struct r600_resource_texture *rtex = (struct r600_resource_texture*)ptex;
 	struct r600_resource *resource = &rtex->resource;
 	struct r600_screen *rscreen = r600_screen(screen);
+	unsigned i;
 
 	if (resource->bo) {
 		radeon_bo_decref(rscreen->rw, resource->bo);
 	}
+	if (rtex->uncompressed) {
+		radeon_bo_decref(rscreen->rw, rtex->uncompressed);
+	}
+	for (i = 0; i < PIPE_MAX_TEXTURE_LEVELS; i++) {
+		radeon_state_decref(rtex->scissor[i]);
+		radeon_state_decref(rtex->cb0[i]);
+		radeon_state_decref(rtex->db[i]);
+	}
 	FREE(rtex);
 }
 
@@ -595,3 +608,218 @@ out_unknown:
 	R600_ERR("Unable to handle texformat %d %s\n", format, util_format_name(format));
 	return ~0;
 }
+
+int r600_texture_from_depth(struct pipe_context *ctx, struct r600_resource_texture *rtexture, unsigned level)
+{
+	struct r600_screen *rscreen = r600_screen(ctx->screen);
+	int r;
+
+	if (!rtexture->depth) {
+		/* This shouldn't happen maybe print a warning */
+		return 0;
+	}
+	if (rtexture->uncompressed && !rtexture->dirty) {
+		/* Uncompressed bo already in good state */
+		return 0;
+	}
+
+	/* allocate uncompressed texture */
+	if (rtexture->uncompressed == NULL) {
+		rtexture->uncompressed = radeon_bo(rscreen->rw, 0, rtexture->size, 4096, NULL);
+		if (rtexture->uncompressed == NULL) {
+			return -ENOMEM;
+		}
+	}
+
+	/* render a rectangle covering whole buffer to uncompress depth */
+	r = r600_blit_uncompress_depth(ctx, rtexture, level);
+R600_ERR("---step0 %d\n", r);
+	if (r) {
+		return r;
+	}
+
+	rtexture->dirty = 0;
+	return 0;
+}
+
+static struct radeon_state *r600_texture_state_scissor(struct r600_screen *rscreen,
+					struct r600_resource_texture *rtexture,
+					unsigned level)
+{
+	struct radeon_state *rstate;
+
+	rstate = radeon_state(rscreen->rw, R600_SCISSOR_TYPE, R600_SCISSOR);
+	if (rstate == NULL)
+		return NULL;
+
+	/* set states (most default value are 0 and struct already
+	 * initialized to 0, thus avoid resetting them)
+	 */
+	rstate->states[R600_SCISSOR__PA_SC_CLIPRECT_0_BR] = S_028244_BR_X(rtexture->width[level]) | S_028244_BR_Y(rtexture->height[level]);
+	rstate->states[R600_SCISSOR__PA_SC_CLIPRECT_0_TL] = 0x80000000;
+	rstate->states[R600_SCISSOR__PA_SC_CLIPRECT_1_BR] = S_028244_BR_X(rtexture->width[level]) | S_028244_BR_Y(rtexture->height[level]);
+	rstate->states[R600_SCISSOR__PA_SC_CLIPRECT_1_TL] = 0x80000000;
+	rstate->states[R600_SCISSOR__PA_SC_CLIPRECT_2_BR] = S_028244_BR_X(rtexture->width[level]) | S_028244_BR_Y(rtexture->height[level]);
+	rstate->states[R600_SCISSOR__PA_SC_CLIPRECT_2_TL] = 0x80000000;
+	rstate->states[R600_SCISSOR__PA_SC_CLIPRECT_3_BR] = S_028244_BR_X(rtexture->width[level]) | S_028244_BR_Y(rtexture->height[level]);
+	rstate->states[R600_SCISSOR__PA_SC_CLIPRECT_3_TL] = 0x80000000;
+	rstate->states[R600_SCISSOR__PA_SC_CLIPRECT_RULE] = 0x0000FFFF;
+	rstate->states[R600_SCISSOR__PA_SC_EDGERULE] = 0xAAAAAAAA;
+	rstate->states[R600_SCISSOR__PA_SC_GENERIC_SCISSOR_BR] = S_028244_BR_X(rtexture->width[level]) | S_028244_BR_Y(rtexture->height[level]);
+	rstate->states[R600_SCISSOR__PA_SC_GENERIC_SCISSOR_TL] = 0x80000000;
+	rstate->states[R600_SCISSOR__PA_SC_SCREEN_SCISSOR_BR] = S_028244_BR_X(rtexture->width[level]) | S_028244_BR_Y(rtexture->height[level]);
+	rstate->states[R600_SCISSOR__PA_SC_SCREEN_SCISSOR_TL] = 0x80000000;
+	rstate->states[R600_SCISSOR__PA_SC_VPORT_SCISSOR_0_BR] = S_028244_BR_X(rtexture->width[level]) | S_028244_BR_Y(rtexture->height[level]);
+	rstate->states[R600_SCISSOR__PA_SC_VPORT_SCISSOR_0_TL] = 0x80000000;
+	rstate->states[R600_SCISSOR__PA_SC_WINDOW_SCISSOR_BR] = S_028244_BR_X(rtexture->width[level]) | S_028244_BR_Y(rtexture->height[level]);
+	rstate->states[R600_SCISSOR__PA_SC_WINDOW_SCISSOR_TL] = 0x80000000;
+
+	if (radeon_state_pm4(rstate)) {
+		radeon_state_decref(rstate);
+		return NULL;
+	}
+	return rstate;
+}
+
+static struct radeon_state *r600_texture_state_cb0(struct r600_screen *rscreen,
+				struct r600_resource_texture *rtexture,
+				unsigned level)
+{
+	struct radeon_state *rstate;
+	struct r600_resource *rbuffer;
+	unsigned pitch, slice;
+	unsigned color_info;
+	unsigned format, swap, ntype;
+	const struct util_format_description *desc;
+
+	rstate = radeon_state(rscreen->rw, R600_CB0_TYPE, R600_CB0);
+	if (rstate == NULL)
+		return NULL;
+	rbuffer = &rtexture->resource;
+
+	/* set states (most default value are 0 and struct already
+	 * initialized to 0, thus avoid resetting them)
+	 */
+	pitch = (rtexture->pitch[level] / rtexture->bpt) / 8 - 1;
+	slice = (rtexture->pitch[level] / rtexture->bpt) * rtexture->height[level] / 64 - 1;
+	ntype = 0;
+	desc = util_format_description(rbuffer->base.b.format);
+	if (desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB)
+		ntype = V_0280A0_NUMBER_SRGB;
+	format = r600_translate_colorformat(rtexture->resource.base.b.format);
+	swap = r600_translate_colorswap(rtexture->resource.base.b.format);
+	color_info = S_0280A0_FORMAT(format) |
+		S_0280A0_COMP_SWAP(swap) |
+		S_0280A0_BLEND_CLAMP(1) |
+		S_0280A0_NUMBER_TYPE(ntype);
+	if (desc->colorspace == UTIL_FORMAT_COLORSPACE_ZS) {
+R600_ERR("CB0 uncompressed texture %p (handle)%d %d 0x%02X\n", rtexture, rtexture->uncompressed->handle, rtexture->resource.base.b.format, format);
+format = 17;
+		rstate->bo[0] = radeon_bo_incref(rscreen->rw, rtexture->uncompressed);
+		rstate->bo[1] = radeon_bo_incref(rscreen->rw, rtexture->uncompressed);
+		rstate->bo[2] = radeon_bo_incref(rscreen->rw, rtexture->uncompressed);
+		rstate->placement[0] = RADEON_GEM_DOMAIN_GTT;
+		rstate->placement[2] = RADEON_GEM_DOMAIN_GTT;
+		rstate->placement[4] = RADEON_GEM_DOMAIN_GTT;
+		rstate->nbo = 3;
+	} else {
+		rstate->bo[0] = radeon_bo_incref(rscreen->rw, rbuffer->bo);
+		rstate->bo[1] = radeon_bo_incref(rscreen->rw, rbuffer->bo);
+		rstate->bo[2] = radeon_bo_incref(rscreen->rw, rbuffer->bo);
+		rstate->placement[0] = RADEON_GEM_DOMAIN_GTT;
+		rstate->placement[2] = RADEON_GEM_DOMAIN_GTT;
+		rstate->placement[4] = RADEON_GEM_DOMAIN_GTT;
+		rstate->nbo = 3;
+		color_info |= S_0280A0_SOURCE_FORMAT(1);
+	}
+	rstate->states[R600_CB0__CB_COLOR0_BASE] = rtexture->offset[level] >> 8;
+	rstate->states[R600_CB0__CB_COLOR0_INFO] = color_info;
+	rstate->states[R600_CB0__CB_COLOR0_SIZE] = S_028060_PITCH_TILE_MAX(pitch) |
+						S_028060_SLICE_TILE_MAX(slice);
+
+	if (radeon_state_pm4(rstate)) {
+		radeon_state_decref(rstate);
+		return NULL;
+	}
+	return rstate;
+}
+
+static struct radeon_state *r600_texture_state_db(struct r600_screen *rscreen,
+				struct r600_resource_texture *rtexture,
+				unsigned level)
+{
+	struct radeon_state *rstate;
+	struct r600_resource *rbuffer;
+	unsigned pitch, slice, format;
+
+	rstate = radeon_state(rscreen->rw, R600_DB_TYPE, R600_DB);
+	if (rstate == NULL)
+		return NULL;
+	rbuffer = &rtexture->resource;
+
+	/* set states (most default value are 0 and struct already
+	 * initialized to 0, thus avoid resetting them)
+	 */
+	pitch = (rtexture->pitch[level] / rtexture->bpt) / 8 - 1;
+	slice = (rtexture->pitch[level] / rtexture->bpt) * rtexture->height[level] / 64 - 1;
+	format = r600_translate_dbformat(rbuffer->base.b.format);
+	rstate->states[R600_DB__DB_DEPTH_BASE] = rtexture->offset[level] >> 8;
+	rstate->states[R600_DB__DB_DEPTH_INFO] = S_028010_ARRAY_MODE(rtexture->array_mode) |
+					S_028010_FORMAT(format);
+	rstate->states[R600_DB__DB_DEPTH_VIEW] = 0x00000000;
+	rstate->states[R600_DB__DB_PREFETCH_LIMIT] = (rtexture->height[level] / 8) -1;
+	rstate->states[R600_DB__DB_DEPTH_SIZE] = S_028000_PITCH_TILE_MAX(pitch) |
+						S_028000_SLICE_TILE_MAX(slice);
+R600_ERR("DB handle %d  %p %d\n", rbuffer->bo->handle, rtexture, rbuffer->base.b.format);
+	rstate->bo[0] = radeon_bo_incref(rscreen->rw, rbuffer->bo);
+	rstate->placement[0] = RADEON_GEM_DOMAIN_GTT;
+	rstate->nbo = 1;
+
+	if (radeon_state_pm4(rstate)) {
+		radeon_state_decref(rstate);
+		return NULL;
+	}
+	return rstate;
+}
+
+int r600_texture_scissor(struct pipe_context *ctx, struct r600_resource_texture *rtexture, unsigned level)
+{
+	struct r600_screen *rscreen = r600_screen(ctx->screen);
+
+	if (rtexture->scissor[level] == NULL) {
+		rtexture->scissor[level] = r600_texture_state_scissor(rscreen, rtexture, level);
+		if (rtexture->scissor[level] == NULL) {
+			R600_ERR("failed to create scissor for uncompressing depth\n");
+			return -ENOMEM;
+		}
+	}
+	return 0;
+}
+
+int r600_texture_cb0(struct pipe_context *ctx, struct r600_resource_texture *rtexture, unsigned level)
+{
+	struct r600_screen *rscreen = r600_screen(ctx->screen);
+
+	if (rtexture->cb0[level] == NULL) {
+		rtexture->cb0[level] = r600_texture_state_cb0(rscreen, rtexture, level);
+		if (rtexture->cb0[level] == NULL) {
+			R600_ERR("failed to create cb0 state for texture\n");
+			return -ENOMEM;
+		}
+	}
+	return 0;
+}
+
+int r600_texture_db(struct pipe_context *ctx, struct r600_resource_texture *rtexture, unsigned level)
+{
+	struct r600_screen *rscreen = r600_screen(ctx->screen);
+
+	if (rtexture->db[level] == NULL) {
+		rtexture->db[level] = r600_texture_state_db(rscreen, rtexture, level);
+		if (rtexture->db[level] == NULL) {
+			R600_ERR("failed to create db state for texture\n");
+			return -ENOMEM;
+		}
+	}
+	return 0;
+}




More information about the mesa-commit mailing list