diff options
Diffstat (limited to 'src/gallium/drivers/r300/r300_surface.c')
-rw-r--r-- | src/gallium/drivers/r300/r300_surface.c | 147 |
1 files changed, 132 insertions, 15 deletions
diff --git a/src/gallium/drivers/r300/r300_surface.c b/src/gallium/drivers/r300/r300_surface.c index db18975a10..79bed03253 100644 --- a/src/gallium/drivers/r300/r300_surface.c +++ b/src/gallium/drivers/r300/r300_surface.c @@ -29,10 +29,10 @@ static void r300_surface_setup(struct pipe_context* pipe, unsigned w, unsigned h) { struct r300_context* r300 = r300_context(pipe); - CS_LOCALS(r300); struct r300_capabilities* caps = r300_screen(pipe->screen)->caps; struct r300_texture* tex = (struct r300_texture*)dest->texture; unsigned pixpitch = tex->stride / tex->tex.block.size; + CS_LOCALS(r300); r300_emit_blend_state(r300, &blend_clear_state); r300_emit_blend_color_state(r300, &blend_color_clear_state); @@ -80,14 +80,15 @@ static void r300_surface_fill(struct pipe_context* pipe, unsigned w, unsigned h, unsigned color) { + int i; + float r, g, b, a, depth; struct r300_context* r300 = r300_context(pipe); - CS_LOCALS(r300); struct r300_capabilities* caps = r300_screen(pipe->screen)->caps; struct r300_texture* tex = (struct r300_texture*)dest->texture; - int i; - float r, g, b, a, depth; unsigned pixpitch = tex->stride / tex->tex.block.size; + CS_LOCALS(r300); + a = (float)((color >> 24) & 0xff) / 255.0f; r = (float)((color >> 16) & 0xff) / 255.0f; g = (float)((color >> 8) & 0xff) / 255.0f; b = (float)((color >> 0) & 0xff) / 255.0f; @@ -96,7 +97,7 @@ static void r300_surface_fill(struct pipe_context* pipe, dest, x, y, w, h, pixpitch, color); /* Fallback? */ - if (tex->tex.format != PIPE_FORMAT_A8R8G8B8_UNORM) { + if (FALSE) { debug_printf("r300: Falling back on surface clear..."); util_surface_fill(pipe, dest, x, y, w, h, color); return; @@ -104,6 +105,19 @@ static void r300_surface_fill(struct pipe_context* pipe, r300_surface_setup(r300, dest, x, y, w, h); + /* Vertex shader setup */ + if (caps->has_tcl) { + r300_emit_vertex_shader(r300, &r300_passthrough_vertex_shader); + } else { + BEGIN_CS(4); + OUT_CS_REG(R300_VAP_CNTL_STATUS, R300_VAP_TCL_BYPASS); + OUT_CS_REG(R300_VAP_CNTL, R300_PVS_NUM_SLOTS(5) | + R300_PVS_NUM_CNTLRS(5) | + R300_PVS_NUM_FPUS(caps->num_vert_fpus) | + R300_PVS_VF_MAX_VTX_NUM(12)); + END_CS; + } + /* Fragment shader setup */ if (caps->is_r500) { r500_emit_fragment_shader(r300, &r500_passthrough_fragment_shader); @@ -113,7 +127,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,16 +171,17 @@ 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)); + /* Position */ OUT_CS_32F(w / 2.0); OUT_CS_32F(h / 2.0); - /* XXX this should be the depth value to clear to */ OUT_CS_32F(1.0); OUT_CS_32F(1.0); + /* Color */ OUT_CS_32F(r); OUT_CS_32F(g); OUT_CS_32F(b); - OUT_CS_32F(1.0); + OUT_CS_32F(a); /* XXX figure out why this is 0xA and not 0x2 */ OUT_CS_REG(R300_RB3D_DSTCACHE_CTLSTAT, 0xA); @@ -162,23 +202,100 @@ static void r300_surface_copy(struct pipe_context* pipe, unsigned w, unsigned h) { 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; - unsigned pixpitch = srctex->stride / srctex->tex.block.size; + CS_LOCALS(r300); + debug_printf("r300: Copying surface %p at (%d,%d) to %p at (%d, %d)," " 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); + + /* Vertex shader setup */ + if (caps->has_tcl) { + r300_emit_vertex_shader(r300, &r300_texture_vertex_shader); + } else { + BEGIN_CS(4); + OUT_CS_REG(R300_VAP_CNTL_STATUS, R300_VAP_TCL_BYPASS); + OUT_CS_REG(R300_VAP_CNTL, R300_PVS_NUM_SLOTS(5) | + R300_PVS_NUM_CNTLRS(5) | + R300_PVS_NUM_FPUS(caps->num_vert_fpus) | + R300_PVS_VF_MAX_VTX_NUM(12)); + END_CS; + } + + /* 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) |