diff options
Diffstat (limited to 'src/gallium/drivers/r300/r300_surface.c')
-rw-r--r-- | src/gallium/drivers/r300/r300_surface.c | 101 |
1 files changed, 95 insertions, 6 deletions
diff --git a/src/gallium/drivers/r300/r300_surface.c b/src/gallium/drivers/r300/r300_surface.c index db18975a10f..96b63986ea7 100644 --- a/src/gallium/drivers/r300/r300_surface.c +++ b/src/gallium/drivers/r300/r300_surface.c @@ -113,7 +113,32 @@ static void r300_surface_fill(struct pipe_context* pipe, r300_emit_rs_block_state(r300, &r300_rs_block_clear_state); } - BEGIN_CS(21); + BEGIN_CS(31); + + /* VAP stream control, mapping from input memory to PVS/RS memory */ + if (caps->has_tcl) { + OUT_CS_REG(R300_VAP_PROG_STREAM_CNTL_0, + (R300_DATA_TYPE_FLOAT_4 << R300_DATA_TYPE_0_SHIFT) | + ((R300_LAST_VEC | (1 << R300_DST_VEC_LOC_SHIFT) | + R300_DATA_TYPE_FLOAT_4) << R300_DATA_TYPE_1_SHIFT)); + } else { + OUT_CS_REG(R300_VAP_PROG_STREAM_CNTL_0, + (R300_DATA_TYPE_FLOAT_4 << R300_DATA_TYPE_0_SHIFT) | + ((R300_LAST_VEC | (2 << R300_DST_VEC_LOC_SHIFT) | + R300_DATA_TYPE_FLOAT_4) << R300_DATA_TYPE_1_SHIFT)); + } + OUT_CS_REG(R300_VAP_PROG_STREAM_CNTL_EXT_0, + (R300_VAP_SWIZZLE_XYZW << R300_SWIZZLE0_SHIFT) | + (R300_VAP_SWIZZLE_XYZW << R300_SWIZZLE1_SHIFT)); + + /* VAP format controls */ + OUT_CS_REG(R300_VAP_OUTPUT_VTX_FMT_0, + R300_VAP_OUTPUT_VTX_FMT_0__POS_PRESENT | + R300_VAP_OUTPUT_VTX_FMT_0__COLOR_0_PRESENT); + OUT_CS_REG(R300_VAP_OUTPUT_VTX_FMT_1, 0x0); + + /* Disable textures */ + OUT_CS_REG(R300_TX_ENABLE, 0x0); /* Viewport setup */ OUT_CS_REG_SEQ(R300_SE_VPORT_XSCALE, 6); @@ -132,7 +157,7 @@ static void r300_surface_fill(struct pipe_context* pipe, /* Packet3 with our point vertex */ OUT_CS_PKT3(R200_3D_DRAW_IMMD_2, 8); OUT_CS(R300_PRIM_TYPE_POINT | R300_PRIM_WALK_RING | - (1 << R300_PRIM_NUM_VERTICES_SHIFT)); + (1 << R300_PRIM_NUM_VERTICES_SHIFT)); OUT_CS_32F(w / 2.0); OUT_CS_32F(h / 2.0); /* XXX this should be the depth value to clear to */ @@ -163,6 +188,7 @@ static void r300_surface_copy(struct pipe_context* pipe, { struct r300_context* r300 = r300_context(pipe); CS_LOCALS(r300); + struct r300_capabilities* caps = r300_screen(pipe->screen)->caps; struct r300_texture* srctex = (struct r300_texture*)src->texture; struct r300_texture* desttex = (struct r300_texture*)dest->texture; @@ -171,14 +197,77 @@ static void r300_surface_copy(struct pipe_context* pipe, " dimensions %dx%d (pixel pitch %d)\n", src, srcx, srcy, dest, destx, desty, w, h, pixpitch); - /* if ((srctex == desttex) && + if ((srctex == desttex) && ((destx < srcx + w) || (srcx < destx + w)) && - ((desty < srcy + h) || (srcy < destx + h))) { */ - if (TRUE) { + ((desty < srcy + h) || (srcy < desty + h))) { debug_printf("r300: Falling back on surface_copy\n"); - return util_surface_copy(pipe, FALSE, dest, destx, desty, src, + util_surface_copy(pipe, FALSE, dest, destx, desty, src, srcx, srcy, w, h); } + + r300_emit_sampler(r300, &r300_sampler_copy_state, 0); + r300_emit_texture(r300, srctex, 0); + r300_flush_textures(r300); + + /* Fragment shader setup */ + if (caps->is_r500) { + r500_emit_fragment_shader(r300, &r500_texture_fragment_shader); + r300_emit_rs_block_state(r300, &r500_rs_block_copy_state); + } else { + r300_emit_fragment_shader(r300, &r300_texture_fragment_shader); + r300_emit_rs_block_state(r300, &r300_rs_block_copy_state); + } + + /* VAP stream control, mapping from input memory to PVS/RS memory */ + if (caps->has_tcl) { + OUT_CS_REG(R300_VAP_PROG_STREAM_CNTL_0, + (R300_DATA_TYPE_FLOAT_2 << R300_DATA_TYPE_0_SHIFT) | + ((R300_LAST_VEC | (1 << R300_DST_VEC_LOC_SHIFT) | + R300_DATA_TYPE_FLOAT_2) << R300_DATA_TYPE_1_SHIFT)); + } else { + OUT_CS_REG(R300_VAP_PROG_STREAM_CNTL_0, + (R300_DATA_TYPE_FLOAT_2 << R300_DATA_TYPE_0_SHIFT) | + ((R300_LAST_VEC | (6 << R300_DST_VEC_LOC_SHIFT) | + R300_DATA_TYPE_FLOAT_2) << R300_DATA_TYPE_1_SHIFT)); + } + OUT_CS_REG(R300_VAP_PROG_STREAM_CNTL_EXT_0, + (R300_VAP_SWIZZLE_XYZW << R300_SWIZZLE0_SHIFT) | + (R300_VAP_SWIZZLE_XYZW << R300_SWIZZLE1_SHIFT)); + + /* VAP format controls */ + OUT_CS_REG(R300_VAP_OUTPUT_VTX_FMT_0, + R300_VAP_OUTPUT_VTX_FMT_0__POS_PRESENT); + /* Two components of texture 0 */ + OUT_CS_REG(R300_VAP_OUTPUT_VTX_FMT_1, 0x2); + + /* Packet3 with our texcoords */ + OUT_CS_PKT3(R200_3D_DRAW_IMMD_2, 8); + OUT_CS(R300_PRIM_TYPE_QUADS | R300_PRIM_WALK_RING | + (4 << R300_PRIM_NUM_VERTICES_SHIFT)); + /* (x , y ) */ + OUT_CS_32F((float)destx); + OUT_CS_32F((float)desty); + OUT_CS_32F((float)srcx); + OUT_CS_32F((float)srcy); + /* (x , y + h) */ + OUT_CS_32F((float)destx); + OUT_CS_32F((float)(desty + h)); + OUT_CS_32F((float)srcx); + OUT_CS_32F((float)(srcy + h)); + /* (x + w, y + h) */ + OUT_CS_32F((float)(destx + w)); + OUT_CS_32F((float)(desty + h)); + OUT_CS_32F((float)(srcx + w)); + OUT_CS_32F((float)(srcy + h)); + /* (x + w, y ) */ + OUT_CS_32F((float)(destx + w)); + OUT_CS_32F((float)desty); + OUT_CS_32F((float)(srcx + w)); + OUT_CS_32F((float)srcy); + + OUT_CS_REG(R300_RB3D_DSTCACHE_CTLSTAT, 0xA); + + r300->dirty_hw++; } void r300_init_surface_functions(struct r300_context* r300) |