summaryrefslogtreecommitdiff
path: root/src/gallium/drivers/r300/r300_surface.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/drivers/r300/r300_surface.c')
-rw-r--r--src/gallium/drivers/r300/r300_surface.c147
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)