X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fgallium%2Fdrivers%2Fr300%2Fr300_blit.c;h=faaf9523cb22c57719476feea95344e1eca7ea56;hb=ebe12d50064370e4ddec21a1e087b24295940319;hp=6bcfbc0d7916f9f6e5ae208f6820c8b45dddcd08;hpb=74288078eab1971cc6ce3ae00fa55eb917b5826a;p=mesa.git diff --git a/src/gallium/drivers/r300/r300_blit.c b/src/gallium/drivers/r300/r300_blit.c index 6bcfbc0d791..faaf9523cb2 100644 --- a/src/gallium/drivers/r300/r300_blit.c +++ b/src/gallium/drivers/r300/r300_blit.c @@ -1,5 +1,5 @@ /* - * Copyright 2008 Corbin Simpson + * Copyright 2009 Marek Olšák * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -21,76 +21,111 @@ * USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "r300_blit.h" +#include "r300_context.h" -/* Does a "paint" into the specified rectangle. - * Returns 1 on success, 0 on error. */ -int r300_fill_blit(struct r300_context* r300, - unsigned cpp, - short dst_pitch, - struct pipe_buffer* dst_buffer, - unsigned dst_offset, - short x, short y, - short w, short h, - unsigned color) +static void r300_blitter_save_states(struct r300_context* r300) { - CS_LOCALS(r300); - uint32_t dest_type; -#if 0 - /* Check for fallbacks. */ - /* XXX we can do YUV surfaces, too, but only in 3D mode. Hmm... */ - switch(cpp) { - case 2: - case 6: - dest_type = ATI_DATATYPE_CI8; - break; - case 4: - dest_type = ATI_DATATYPE_RGB565; - break; - case 8: - dest_type = ATI_DATATYPE_ARGB8888; - break; - default: - /* Whatever this is, we can't fill it. (Yet.) */ - return 0; - } + util_blitter_save_blend(r300->blitter, r300->blend_state.state); + util_blitter_save_depth_stencil_alpha(r300->blitter, r300->dsa_state.state); + util_blitter_save_stencil_ref(r300->blitter, &(r300->stencil_ref)); + util_blitter_save_rasterizer(r300->blitter, r300->rs_state.state); + util_blitter_save_fragment_shader(r300->blitter, r300->fs); + util_blitter_save_vertex_shader(r300->blitter, r300->vs); +} + +/* Clear currently bound buffers. */ +void r300_clear(struct pipe_context* pipe, + unsigned buffers, + const float* rgba, + double depth, + unsigned stencil) +{ + /* XXX Implement fastfill. + * + * If fastfill is enabled, a few facts should be considered: + * + * 1) Zbuffer must be micro-tiled and whole microtiles must be + * written. + * + * 2) ZB_DEPTHCLEARVALUE is used to clear a zbuffer and Z Mask must be + * equal to 0. + * + * 3) RB3D_COLOR_CLEAR_VALUE is used to clear a colorbuffer and + * RB3D_COLOR_CHANNEL_MASK must be equal to 0. + * + * 4) ZB_CB_CLEAR can be used to make the ZB units help in clearing + * the colorbuffer. The color clear value is supplied through both + * RB3D_COLOR_CLEAR_VALUE and ZB_DEPTHCLEARVALUE, and the colorbuffer + * must be set in ZB_DEPTHOFFSET and ZB_DEPTHPITCH in addition to + * RB3D_COLOROFFSET and RB3D_COLORPITCH. It's obvious that the zbuffer + * will not be cleared and multiple render targets cannot be cleared + * this way either. + * + * 5) For 16-bit integer buffering, compression causes a hung with one or + * two samples and should not be used. + * + * 6) Fastfill must not be used if reading of compressed Z data is disabled + * and writing of compressed Z data is enabled (RD/WR_COMP_ENABLE), + * i.e. it cannot be used to compress the zbuffer. + * (what the hell does that mean and how does it fit in clearing + * the buffers?) + * + * - Marek + */ + + struct r300_context* r300 = r300_context(pipe); + struct pipe_framebuffer_state* fb = + (struct pipe_framebuffer_state*)r300->fb_state.state; + + r300_blitter_save_states(r300); + + util_blitter_clear(r300->blitter, + fb->width, + fb->height, + fb->nr_cbufs, + buffers, rgba, depth, stencil); +} + +/* Copy a block of pixels from one surface to another. */ +void r300_surface_copy(struct pipe_context* pipe, + struct pipe_surface* dst, + unsigned dstx, unsigned dsty, + struct pipe_surface* src, + unsigned srcx, unsigned srcy, + unsigned width, unsigned height) +{ + struct r300_context* r300 = r300_context(pipe); - /* XXX odds are *incredibly* good that we were in 3D just a bit ago, - * so flush here first. */ + /* Yeah we have to save all those states to ensure this blitter operation + * is really transparent. The states will be restored by the blitter once + * copying is done. */ + r300_blitter_save_states(r300); + util_blitter_save_framebuffer(r300->blitter, r300->fb_state.state); - BEGIN_CS(10 + 2 + 2); + util_blitter_save_fragment_sampler_states( + r300->blitter, r300->sampler_count, (void**)r300->sampler_states); - /* Set up the 2D engine. */ - OUT_CS_REG(RADEON_DEFAULT_SC_BOTTOM_RIGHT, - RADEON_DEFAULT_SC_RIGHT_MAX | RADEON_DEFAULT_SC_BOTTOM_MAX); - OUT_CS_REG(RADEON_DP_GUI_MASTER_CNTL, - RADEON_GMC_DST_PITCH_OFFSET_CNTL | - RADEON_GMC_BRUSH_SOLID_COLOR | - (dest_type << 8) | - RADEON_GMC_SRC_DATATYPE_COLOR | - RADEON_ROP3_P | - RADEON_GMC_CLR_CMP_CNTL_DIS); - /* XXX pack this? */ - OUT_CS_REG(RADEON_DP_BRUSH_FRGD_CLR, color); - OUT_CS_REG(RADEON_DP_BRUSH_BKGD_CLR, 0x00000000); - OUT_CS_REG(RADEON_DP_SRC_FRGD_CLR, 0xffffffff); - OUT_CS_REG(RADEON_DP_SRC_BKGD_CLR, 0x00000000); - /* XXX what should this be? */ - OUT_CS_REG(RADEON_DP_WRITE_MASK, 0x00000000); - OUT_CS_REG(RADEON_DP_CNTL, - RADEON_DST_X_LEFT_TO_RIGHT | RADEON_DST_Y_TOP_TO_BOTTOM); - OUT_CS_REG(RADEON_DST_PITCH_OFFSET, 0x0); - OUT_CS_RELOC(dst_buffer, 0, 0, RADEON_GEM_DOMAIN_VRAM, 0); + util_blitter_save_fragment_sampler_textures( + r300->blitter, r300->texture_count, + (struct pipe_texture**)r300->textures); - /* Do the actual paint. */ - OUT_CS_REG(RADEON_DST_Y_X, (y << 16) | x); - OUT_CS_REG(RADEON_DST_HEIGHT_WIDTH, (h << 16) | w); + /* Do a copy */ + util_blitter_copy(r300->blitter, + dst, dstx, dsty, src, srcx, srcy, width, height, TRUE); +} + +/* Fill a region of a surface with a constant value. */ +void r300_surface_fill(struct pipe_context* pipe, + struct pipe_surface* dst, + unsigned dstx, unsigned dsty, + unsigned width, unsigned height, + unsigned value) +{ + struct r300_context* r300 = r300_context(pipe); - /* Let the 2D engine settle. */ - OUT_CS_REG(RADEON_DSTCACHE_CTLSTAT, RADEON_RB2D_DC_FLUSH_ALL); - OUT_CS_REG(RADEON_WAIT_UNTIL, - RADEON_WAIT_2D_IDLECLEAN | RADEON_WAIT_DMA_GUI_IDLE); + r300_blitter_save_states(r300); + util_blitter_save_framebuffer(r300->blitter, r300->fb_state.state); - END_CS; -#endif - return 1; + util_blitter_fill(r300->blitter, + dst, dstx, dsty, width, height, value); }