summaryrefslogtreecommitdiff
path: root/src/gallium/drivers/r600/r600_blit.c
diff options
context:
space:
mode:
authorJerome Glisse <jglisse@redhat.com>2010-08-22 14:22:00 -0400
committerJerome Glisse <jglisse@redhat.com>2010-08-22 14:26:05 -0400
commited99c28d12579bb8ee79eb9cfa55452785be7b6e (patch)
tree777c2bc49f31715eb5e56c0addd3fb5d4363898e /src/gallium/drivers/r600/r600_blit.c
parent42719df0b866a00ea4a7739e82e1639c9943fcfd (diff)
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@redhat.com>
Diffstat (limited to 'src/gallium/drivers/r600/r600_blit.c')
-rw-r--r--src/gallium/drivers/r600/r600_blit.c665
1 files changed, 643 insertions, 22 deletions
diff --git a/src/gallium/drivers/r600/r600_blit.c b/src/gallium/drivers/r600/r600_blit.c
index dc57b333a0..8cb2795d2b 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;
+}