From ed99c28d12579bb8ee79eb9cfa55452785be7b6e Mon Sep 17 00:00:00 2001 From: Jerome Glisse Date: Sun, 22 Aug 2010 14:22:00 -0400 Subject: [PATCH] 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 --- 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 dc57b333a03..8cb2795d2bd 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 #include #include #include @@ -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 900aa9fd0c2..d96d5b513fe 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 f0584551620..1eb868c4c77 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 5ebda027e91..5b3a7027a79 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 147be3c4ac0..4b2aac73ace 100644 --- a/src/gallium/drivers/r600/r600_screen.h +++ b/src/gallium/drivers/r600/r600_screen.h @@ -30,6 +30,7 @@ #include #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 79fc04a9fe3..5cdbe2bfe80 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 e9b03f571ad..58df32818ee 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 92b4f430c57..c79dd34f09e 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 #include #include #include @@ -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; +} -- 2.30.2