X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fgallium%2Fdrivers%2Fr600%2Fr600_blit.c;h=151f48a8bf8b1f70e4403ac62b26645104251581;hb=213b9004a6ee033a16af3dcd187aa68b56c39858;hp=d3b722c82f7b25d094fb7f14c313383a24f61da2;hpb=bd25e23bf3740f59ce8859848c715daeb9e9821f;p=mesa.git diff --git a/src/gallium/drivers/r600/r600_blit.c b/src/gallium/drivers/r600/r600_blit.c index d3b722c82f7..151f48a8bf8 100644 --- a/src/gallium/drivers/r600/r600_blit.c +++ b/src/gallium/drivers/r600/r600_blit.c @@ -1,5 +1,5 @@ /* - * Copyright 2009 Marek Olšák + * Copyright 2010 Jerome Glisse * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -19,69 +19,155 @@ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE * USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: - * Jerome Glisse - * Marek Olšák */ -#include -#include +#include #include -#include -#include -#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) +#include +#include "r600_pipe.h" + +enum r600_blitter_op /* bitmask */ +{ + R600_CLEAR = 1, + R600_CLEAR_SURFACE = 2, + R600_COPY = 4 +}; + +static void r600_blitter_begin(struct pipe_context *ctx, enum r600_blitter_op op) { - struct r600_context *rctx = r600_context(ctx); + struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx; - util_blitter_save_blend(rctx->blitter, rctx->blend); - util_blitter_save_depth_stencil_alpha(rctx->blitter, rctx->dsa); - if (rctx->stencil_ref) { - util_blitter_save_stencil_ref(rctx->blitter, - &rctx->stencil_ref->state.stencil_ref); + rctx->blit = true; + r600_context_queries_suspend(&rctx->ctx); + + util_blitter_save_blend(rctx->blitter, rctx->states[R600_PIPE_STATE_BLEND]); + util_blitter_save_depth_stencil_alpha(rctx->blitter, rctx->states[R600_PIPE_STATE_DSA]); + if (rctx->states[R600_PIPE_STATE_STENCIL_REF]) { + util_blitter_save_stencil_ref(rctx->blitter, &rctx->stencil_ref); } - util_blitter_save_rasterizer(rctx->blitter, rctx->rasterizer); + util_blitter_save_rasterizer(rctx->blitter, rctx->states[R600_PIPE_STATE_RASTERIZER]); util_blitter_save_fragment_shader(rctx->blitter, rctx->ps_shader); util_blitter_save_vertex_shader(rctx->blitter, rctx->vs_shader); util_blitter_save_vertex_elements(rctx->blitter, rctx->vertex_elements); - if (rctx->viewport) { - util_blitter_save_viewport(rctx->blitter, &rctx->viewport->state.viewport); + if (rctx->states[R600_PIPE_STATE_VIEWPORT]) { + util_blitter_save_viewport(rctx->blitter, &rctx->viewport); + } + if (rctx->states[R600_PIPE_STATE_CLIP]) { + util_blitter_save_clip(rctx->blitter, &rctx->clip); } - if (rctx->clip) { - util_blitter_save_clip(rctx->blitter, &rctx->clip->state.clip); + util_blitter_save_vertex_buffers(rctx->blitter, + rctx->vbuf_mgr->nr_vertex_buffers, + rctx->vbuf_mgr->vertex_buffer); + + if (op & (R600_CLEAR_SURFACE | R600_COPY)) + util_blitter_save_framebuffer(rctx->blitter, &rctx->framebuffer); + + if (op & R600_COPY) { + util_blitter_save_fragment_sampler_states( + rctx->blitter, rctx->ps_samplers.n_samplers, + (void**)rctx->ps_samplers.samplers); + + util_blitter_save_fragment_sampler_views( + rctx->blitter, rctx->ps_samplers.n_views, + (struct pipe_sampler_view**)rctx->ps_samplers.views); + } + +} + +static void r600_blitter_end(struct pipe_context *ctx) +{ + struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx; + r600_context_queries_resume(&rctx->ctx); + rctx->blit = false; +} + +void r600_blit_uncompress_depth(struct pipe_context *ctx, struct r600_resource_texture *texture) +{ + struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx; + struct pipe_surface *zsurf, *cbsurf, surf_tmpl; + int level = 0; + float depth = 1.0f; + + if (!texture->dirty_db) + return; + + surf_tmpl.format = texture->resource.b.b.b.format; + surf_tmpl.u.tex.level = level; + surf_tmpl.u.tex.first_layer = 0; + surf_tmpl.u.tex.last_layer = 0; + surf_tmpl.usage = PIPE_BIND_DEPTH_STENCIL; + + zsurf = ctx->create_surface(ctx, &texture->resource.b.b.b, &surf_tmpl); + + surf_tmpl.format = ((struct pipe_resource*)texture->flushed_depth_texture)->format; + surf_tmpl.usage = PIPE_BIND_RENDER_TARGET; + cbsurf = ctx->create_surface(ctx, + (struct pipe_resource*)texture->flushed_depth_texture, &surf_tmpl); + + if (rctx->family == CHIP_RV610 || rctx->family == CHIP_RV630 || + rctx->family == CHIP_RV620 || rctx->family == CHIP_RV635) + depth = 0.0f; + + r600_blitter_begin(ctx, R600_CLEAR_SURFACE); + util_blitter_custom_depth_stencil(rctx->blitter, zsurf, cbsurf, rctx->custom_dsa_flush, depth); + r600_blitter_end(ctx); + + pipe_surface_reference(&zsurf, NULL); + pipe_surface_reference(&cbsurf, NULL); + + texture->dirty_db = FALSE; +} + +void r600_flush_depth_textures(struct r600_pipe_context *rctx) +{ + unsigned int i; + + if (rctx->blit) return; + + /* FIXME: This handles fragment shader textures only. */ + + for (i = 0; i < rctx->ps_samplers.n_views; ++i) { + struct r600_pipe_sampler_view *view; + struct r600_resource_texture *tex; + + view = rctx->ps_samplers.views[i]; + if (!view) continue; + + tex = (struct r600_resource_texture *)view->base.texture; + if (!tex->depth) + continue; + + if (tex->is_flushing_texture) + continue; + + r600_blit_uncompress_depth(&rctx->context, tex); + } + + /* also check CB here */ + for (i = 0; i < rctx->framebuffer.nr_cbufs; i++) { + struct r600_resource_texture *tex; + tex = (struct r600_resource_texture *)rctx->framebuffer.cbufs[i]->texture; + + if (!tex->depth) + continue; + + if (tex->is_flushing_texture) + continue; + + r600_blit_uncompress_depth(&rctx->context, tex); } - util_blitter_save_vertex_buffers(rctx->blitter, rctx->nvertex_buffer, - rctx->vertex_buffer); - - /* remove ptr so they don't get deleted */ - rctx->blend = NULL; - rctx->clip = NULL; - rctx->vs_shader = NULL; - rctx->ps_shader = NULL; - rctx->rasterizer = NULL; - rctx->dsa = NULL; - rctx->vertex_elements = NULL; - - /* suspend queries */ - r600_queries_suspend(ctx); } static void r600_clear(struct pipe_context *ctx, unsigned buffers, const float *rgba, double depth, unsigned stencil) { - struct r600_context *rctx = r600_context(ctx); - struct pipe_framebuffer_state *fb = &rctx->framebuffer->state.framebuffer; + struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx; + struct pipe_framebuffer_state *fb = &rctx->framebuffer; - r600_blitter_save_states(ctx); + r600_blitter_begin(ctx, R600_CLEAR); util_blitter_clear(rctx->blitter, fb->width, fb->height, fb->nr_cbufs, buffers, rgba, depth, stencil); - /* resume queries */ - r600_queries_resume(ctx); + r600_blitter_end(ctx); } static void r600_clear_render_target(struct pipe_context *ctx, @@ -90,16 +176,12 @@ static void r600_clear_render_target(struct pipe_context *ctx, unsigned dstx, unsigned dsty, unsigned width, unsigned height) { - struct r600_context *rctx = r600_context(ctx); - struct pipe_framebuffer_state *fb = &rctx->framebuffer->state.framebuffer; - - r600_blitter_save_states(ctx); - util_blitter_save_framebuffer(rctx->blitter, fb); + struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx; + r600_blitter_begin(ctx, R600_CLEAR_SURFACE); util_blitter_clear_render_target(rctx->blitter, dst, rgba, dstx, dsty, width, height); - /* resume queries */ - r600_queries_resume(ctx); + r600_blitter_end(ctx); } static void r600_clear_depth_stencil(struct pipe_context *ctx, @@ -110,700 +192,146 @@ static void r600_clear_depth_stencil(struct pipe_context *ctx, unsigned dstx, unsigned dsty, unsigned width, unsigned height) { - struct r600_context *rctx = r600_context(ctx); - struct pipe_framebuffer_state *fb = &rctx->framebuffer->state.framebuffer; - - r600_blitter_save_states(ctx); - util_blitter_save_framebuffer(rctx->blitter, fb); + struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx; + r600_blitter_begin(ctx, R600_CLEAR_SURFACE); util_blitter_clear_depth_stencil(rctx->blitter, dst, clear_flags, depth, stencil, dstx, dsty, width, height); - /* resume queries */ - r600_queries_resume(ctx); + r600_blitter_end(ctx); } -static void r600_resource_copy_region(struct pipe_context *ctx, - struct pipe_resource *dst, - struct pipe_subresource subdst, - unsigned dstx, unsigned dsty, unsigned dstz, - struct pipe_resource *src, - struct pipe_subresource subsrc, - unsigned srcx, unsigned srcy, unsigned srcz, - unsigned width, unsigned height) -{ - util_resource_copy_region(ctx, dst, subdst, dstx, dsty, dstz, - src, subsrc, srcx, srcy, srcz, width, height); -} -void r600_init_blit_functions(struct r600_context *rctx) +/* Copy a block of pixels from one surface to another using HW. */ +static void r600_hw_copy_region(struct pipe_context *ctx, + struct pipe_resource *dst, + unsigned dst_level, + unsigned dstx, unsigned dsty, unsigned dstz, + struct pipe_resource *src, + unsigned src_level, + const struct pipe_box *src_box) { - rctx->context.clear = r600_clear; - rctx->context.clear_render_target = r600_clear_render_target; - rctx->context.clear_depth_stencil = r600_clear_depth_stencil; - rctx->context.resource_copy_region = r600_resource_copy_region; -} + struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx; + r600_blitter_begin(ctx, R600_COPY); + util_blitter_copy_region(rctx->blitter, dst, dst_level, dstx, dsty, dstz, + src, src_level, src_box, TRUE); + r600_blitter_end(ctx); +} -struct r600_blit_states { - struct radeon_state *rasterizer; - struct radeon_state *dsa; - struct radeon_state *blend; - 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; +struct texture_orig_info { + unsigned format; + unsigned width0; + unsigned height0; }; -static int r600_blit_state_vs_resources(struct r600_screen *rscreen, struct r600_blit_states *bstates) +static void r600_compressed_to_blittable(struct pipe_resource *tex, + unsigned level, + struct texture_orig_info *orig) { - 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); + struct r600_resource_texture *rtex = (struct r600_resource_texture*)tex; + unsigned pixsize = util_format_get_blocksize(tex->format); + int new_format; + int new_height, new_width; - rstate = radeon_state(rscreen->rw, R600_VS_RESOURCE0 + 0); - if (rstate == NULL) { - radeon_bo_decref(rscreen->rw, bo); - return -ENOMEM; - } + orig->format = tex->format; + orig->width0 = tex->width0; + orig->height0 = tex->height0; - /* set states (most default value are 0 and struct already - * initialized to 0, thus avoid resetting them) - */ - rstate->states[R600_RESOURCE__RESOURCE_WORD0] = 0x00000000; - rstate->states[R600_RESOURCE__RESOURCE_WORD1] = 0x00000080; - rstate->states[R600_RESOURCE__RESOURCE_WORD2] = 0x02302000; - rstate->states[R600_RESOURCE__RESOURCE_WORD3] = 0x00000000; - rstate->states[R600_RESOURCE__RESOURCE_WORD4] = 0x00000000; - rstate->states[R600_RESOURCE__RESOURCE_WORD5] = 0x00000000; - rstate->states[R600_RESOURCE__RESOURCE_WORD6] = 0xC0000000; - rstate->bo[0] = bo; - rstate->nbo = 1; - rstate->placement[0] = RADEON_GEM_DOMAIN_GTT; - rstate->reloc_pm4_id[0] = R600_RESOURCE__RESOURCE_BO0_ID; - rstate->reloc_pm4_id[1] = R600_RESOURCE__RESOURCE_BO1_ID; - if (radeon_state_pm4(rstate)) { - radeon_state_decref(rstate); - return -ENOMEM; - } - bstates->vs_resource0 = rstate; + if (pixsize == 8) + new_format = PIPE_FORMAT_R16G16B16A16_UNORM; /* 64-bit block */ + else + new_format = PIPE_FORMAT_R32G32B32A32_UNORM; /* 128-bit block */ - rstate = radeon_state(rscreen->rw, R600_VS_RESOURCE0 + 1); - if (rstate == NULL) { - return -ENOMEM; - } - rstate->states[R600_RESOURCE__RESOURCE_WORD0] = 0x00000010; - rstate->states[R600_RESOURCE__RESOURCE_WORD1] = 0x00000070; - rstate->states[R600_RESOURCE__RESOURCE_WORD2] = 0x02302000; - rstate->states[R600_RESOURCE__RESOURCE_WORD3] = 0x00000000; - rstate->states[R600_RESOURCE__RESOURCE_WORD4] = 0x00000000; - rstate->states[R600_RESOURCE__RESOURCE_WORD5] = 0x00000000; - rstate->states[R600_RESOURCE__RESOURCE_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_r600[] = { - 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 - }; - u32 shader_bc_r700[] = { - 0x00000004, 0x81000400, - 0x00000008, 0xA01C0000, - 0xC001A03C, 0x94000688, - 0xC0024000, 0x94200688, - 0x7C000000, 0x002D1001, - 0x00080000, 0x00000000, - 0x7C000100, 0x002D1002, - 0x00080000, 0x00000000, - 0x00000001, 0x00600C90, - 0x00000401, 0x20600C90, - 0x00000801, 0x40600C90, - 0x80000C01, 0x60600C90, - 0x00000002, 0x00800C90, - 0x00000402, 0x20800C90, - 0x00000802, 0x40800C90, - 0x80000C02, 0x60800C90 - }; - - /* 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; - } - switch (rscreen->chip_class) { - case R600: - memcpy(bo->data, shader_bc_r600, 128); - break; - case R700: - memcpy(bo->data, shader_bc_r700, 128); - break; - default: - R600_ERR("unsupported chip family\n"); - radeon_bo_unmap(rscreen->rw, bo); - radeon_bo_decref(rscreen->rw, bo); - return NULL; - } - radeon_bo_unmap(rscreen->rw, bo); + new_width = util_format_get_nblocksx(tex->format, orig->width0); + new_height = util_format_get_nblocksy(tex->format, orig->height0); - rstate = radeon_state(rscreen->rw, R600_VS_SHADER); - if (rstate == NULL) { - radeon_bo_decref(rscreen->rw, bo); - return NULL; - } + rtex->force_int_type = true; + tex->width0 = new_width; + tex->height0 = new_height; + tex->format = new_format; - /* 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; - rstate->reloc_pm4_id[0] = R600_VS_SHADER__SQ_PGM_START_VS_BO_ID; - rstate->reloc_pm4_id[1] = R600_VS_SHADER__SQ_PGM_START_FS_BO_ID; - - 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) +static void r600_reset_blittable_to_compressed(struct pipe_resource *tex, + unsigned level, + struct texture_orig_info *orig) { - struct radeon_state *rstate; - struct radeon_bo *bo; - u32 shader_bc_r600[] = { - 0x00000002, 0xA00C0000, - 0xC0008000, 0x94200688, - 0x00000000, 0x00201910, - 0x00000400, 0x20201910, - 0x00000800, 0x40201910, - 0x80000C00, 0x60201910 - }; - u32 shader_bc_r700[] = { - 0x00000002, 0xA00C0000, - 0xC0008000, 0x94200688, - 0x00000000, 0x00200C90, - 0x00000400, 0x20200C90, - 0x00000800, 0x40200C90, - 0x80000C00, 0x60200C90 - }; - - /* 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; - } - switch (rscreen->chip_class) { - case R600: - memcpy(bo->data, shader_bc_r600, 48); - break; - case R700: - memcpy(bo->data, shader_bc_r700, 48); - break; - default: - R600_ERR("unsupported chip family\n"); - radeon_bo_unmap(rscreen->rw, bo); - radeon_bo_decref(rscreen->rw, bo); - return NULL; - } - radeon_bo_unmap(rscreen->rw, bo); - - rstate = radeon_state(rscreen->rw, R600_PS_SHADER); - if (rstate == NULL) { - radeon_bo_decref(rscreen->rw, bo); - return NULL; - } + struct r600_resource_texture *rtex = (struct r600_resource_texture*)tex; + rtex->force_int_type = false; - /* 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; - rstate->reloc_pm4_id[0] = R600_PS_SHADER__SQ_PGM_START_PS_BO_ID; - - 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); - 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; + tex->format = orig->format; + tex->width0 = orig->width0; + tex->height0 = orig->height0; } -static struct radeon_state *r600_blit_state_draw(struct r600_screen *rscreen) +static void r600_resource_copy_region(struct pipe_context *ctx, + struct pipe_resource *dst, + unsigned dst_level, + unsigned dstx, unsigned dsty, unsigned dstz, + struct pipe_resource *src, + unsigned src_level, + const struct pipe_box *src_box) { - struct radeon_state *rstate; + struct r600_resource_texture *rsrc = (struct r600_resource_texture*)src; + struct texture_orig_info orig_info[2]; + boolean restore_orig[2]; - rstate = radeon_state(rscreen->rw, 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; + /* Fallback for buffers. */ + if (dst->target == PIPE_BUFFER && src->target == PIPE_BUFFER) { + util_resource_copy_region(ctx, dst, dst_level, dstx, dsty, dstz, + src, src_level, src_box); + return; } - 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_CONSTANT0 + 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; -} + if (rsrc->depth && !rsrc->is_flushing_texture) + r600_texture_depth_flush(ctx, src, FALSE); -static struct radeon_state *r600_blit_state_rasterizer(struct r600_screen *rscreen) -{ - struct radeon_state *rstate; - - rstate = radeon_state(rscreen->rw, 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; -} + restore_orig[0] = restore_orig[1] = FALSE; -static struct radeon_state *r600_blit_state_dsa(struct r600_screen *rscreen) -{ - struct radeon_state *rstate; - - rstate = radeon_state(rscreen->rw, 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; + if (util_format_is_compressed(src->format)) { + r600_compressed_to_blittable(src, src_level, &orig_info[0]); + restore_orig[0] = TRUE; } - 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); - 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; + if (util_format_is_compressed(dst->format)) { + r600_compressed_to_blittable(dst, dst_level, &orig_info[1]); + restore_orig[1] = TRUE; + /* translate the dst box as well */ + dstx = util_format_get_nblocksx(orig_info[1].format, dstx); + dsty = util_format_get_nblocksy(orig_info[1].format, dsty); } - 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); - 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; -} + r600_hw_copy_region(ctx, dst, dst_level, dstx, dsty, dstz, + src, src_level, src_box); -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->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; + if (restore_orig[0]) + r600_reset_blittable_to_compressed(src, src_level, &orig_info[0]); + + if (restore_orig[1]) + r600_reset_blittable_to_compressed(dst, dst_level, &orig_info[1]); } -static void r600_blit_states_destroy(struct pipe_context *ctx, struct r600_blit_states *bstates) +void r600_init_blit_functions(struct r600_pipe_context *rctx) { - radeon_state_decref(bstates->rasterizer); - radeon_state_decref(bstates->dsa); - radeon_state_decref(bstates->blend); - 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); + rctx->context.clear = r600_clear; + rctx->context.clear_render_target = r600_clear_render_target; + rctx->context.clear_depth_stencil = r600_clear_depth_stencil; + rctx->context.resource_copy_region = r600_resource_copy_region; } -int r600_blit_uncompress_depth(struct pipe_context *ctx, struct r600_resource_texture *rtexture, unsigned level) +void r600_blit_push_depth(struct pipe_context *ctx, struct r600_resource_texture *texture) { - 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_texture_viewport(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] = 0x0000008C; - 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.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->viewport[level]); - 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(rctx->ctx, draw); - if (r == -EBUSY) { - r600_flush(ctx, 0, NULL); - r = radeon_ctx_set_draw(rctx->ctx, draw); - } - if (r) { - goto out; - } - - /* resume queries */ - r600_queries_resume(ctx); - -out: - r600_blit_states_destroy(ctx, &bstates); - return r; + struct pipe_box sbox; + + sbox.x = sbox.y = sbox.z = 0; + sbox.width = texture->resource.b.b.b.width0; + sbox.height = texture->resource.b.b.b.height0; + /* XXX that might be wrong */ + sbox.depth = 1; + + r600_hw_copy_region(ctx, (struct pipe_resource *)texture, 0, + 0, 0, 0, + (struct pipe_resource *)texture->flushed_depth_texture, 0, + &sbox); }