summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/gallium/drivers/r300/r300_emit.c2
-rw-r--r--src/gallium/drivers/r300/r300_emit.h2
-rw-r--r--src/gallium/drivers/r300/r300_reg.h3
-rw-r--r--src/gallium/drivers/r300/r300_state_invariant.c17
-rw-r--r--src/gallium/drivers/r300/r300_state_shader.h54
-rw-r--r--src/gallium/drivers/r300/r300_surface.c101
-rw-r--r--src/gallium/drivers/r300/r300_surface.h29
7 files changed, 184 insertions, 24 deletions
diff --git a/src/gallium/drivers/r300/r300_emit.c b/src/gallium/drivers/r300/r300_emit.c
index 16455e48ce8..a2e9cca39ba 100644
--- a/src/gallium/drivers/r300/r300_emit.c
+++ b/src/gallium/drivers/r300/r300_emit.c
@@ -343,7 +343,7 @@ void r300_emit_viewport_state(struct r300_context* r300,
END_CS;
}
-static void r300_flush_textures(struct r300_context* r300)
+void r300_flush_textures(struct r300_context* r300)
{
CS_LOCALS(r300);
diff --git a/src/gallium/drivers/r300/r300_emit.h b/src/gallium/drivers/r300/r300_emit.h
index 0bc1f90e6ab..9d92b090ace 100644
--- a/src/gallium/drivers/r300/r300_emit.h
+++ b/src/gallium/drivers/r300/r300_emit.h
@@ -67,6 +67,8 @@ void r300_emit_vertex_format_state(struct r300_context* r300);
void r300_emit_viewport_state(struct r300_context* r300,
struct r300_viewport_state* viewport);
+void r300_flush_textures(struct r300_context* r300);
+
/* Emit all dirty state. */
void r300_emit_dirty_state(struct r300_context* r300);
diff --git a/src/gallium/drivers/r300/r300_reg.h b/src/gallium/drivers/r300/r300_reg.h
index 3fe45e13932..c9a195a6ce4 100644
--- a/src/gallium/drivers/r300/r300_reg.h
+++ b/src/gallium/drivers/r300/r300_reg.h
@@ -1191,6 +1191,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
# define R300_RS_INST_COUNT_MASK 0x0000000f
# define R300_RS_TX_OFFSET_SHIFT 5
# define R300_RS_TX_OFFSET_MASK 0x000000e0
+# define R300_RS_TX_OFFSET(x) ((x) << 5)
/* gap */
@@ -1434,6 +1435,8 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
# define R300_TX_MAX_ANISO_8_TO_1 (3 << 21)
# define R300_TX_MAX_ANISO_16_TO_1 (4 << 21)
# define R300_TX_MAX_ANISO_MASK (7 << 21)
+# define R300_TX_WRAP_S(x) ((x) << 0)
+# define R300_TX_WRAP_T(x) ((x) << 3)
#define R300_TX_FILTER1_0 0x4440
# define R300_CHROMA_KEY_MODE_DISABLE 0
diff --git a/src/gallium/drivers/r300/r300_state_invariant.c b/src/gallium/drivers/r300/r300_state_invariant.c
index e1837b63801..3705ff98db5 100644
--- a/src/gallium/drivers/r300/r300_state_invariant.c
+++ b/src/gallium/drivers/r300/r300_state_invariant.c
@@ -141,28 +141,11 @@ void r300_emit_invariant_state(struct r300_context* r300)
OUT_CS_REG(R300_ZB_DEPTHCLEARVALUE, 0x00000000);
OUT_CS_REG(R300_ZB_HIZ_OFFSET, 0x00000000);
OUT_CS_REG(R300_ZB_HIZ_PITCH, 0x00000000);
- 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));
OUT_CS_REG(R300_VAP_VTX_STATE_CNTL, 0x1);
OUT_CS_REG(R300_VAP_VSM_VTX_ASSM, 0x405);
OUT_CS_REG(R300_SE_VTE_CNTL, 0x0000043F);
/* Vertex size. */
OUT_CS_REG(R300_VAP_VTX_SIZE, 0x8);
- OUT_CS_REG(R300_VAP_OUTPUT_VTX_FMT_0, 0x00000003);
- OUT_CS_REG(R300_VAP_OUTPUT_VTX_FMT_1, 0x00000000);
- OUT_CS_REG(R300_TX_ENABLE, 0x0);
/* XXX */
OUT_CS_REG(R300_SC_CLIP_RULE, 0xaaaa);
diff --git a/src/gallium/drivers/r300/r300_state_shader.h b/src/gallium/drivers/r300/r300_state_shader.h
index 7cbb41ffdb9..3c5f036d2ae 100644
--- a/src/gallium/drivers/r300/r300_state_shader.h
+++ b/src/gallium/drivers/r300/r300_state_shader.h
@@ -158,4 +158,58 @@ static const struct r500_fragment_shader r500_passthrough_fragment_shader = {
R500_ALU_RGBA_A_SWIZ_0,
};
+static const struct r300_fragment_shader r300_texture_fragment_shader = {
+ /* XXX This is the emission code. TODO: decode
+ OUT_CS_REG(R300_US_CONFIG, 0);
+ OUT_CS_REG(R300_US_CODE_OFFSET, 0x0);
+ OUT_CS_REG(R300_US_CODE_ADDR_0, 0x0);
+ OUT_CS_REG(R300_US_CODE_ADDR_1, 0x0);
+ OUT_CS_REG(R300_US_CODE_ADDR_2, 0x0);
+ OUT_CS_REG(R300_US_CODE_ADDR_3, 0x400000);
+*/
+ .alu_instruction_count = 1,
+ .tex_instruction_count = 0,
+ .indirections = 0,
+ .shader.stack_size = 1,
+
+ .instructions[0].alu_rgb_inst = R300_RGB_SWIZA(R300_ALU_ARGC_SRC0C_XYZ) |
+ R300_RGB_SWIZB(R300_ALU_ARGC_SRC0C_XYZ) |
+ R300_RGB_SWIZC(R300_ALU_ARGC_ZERO) |
+ R300_ALU_OUTC_CMP,
+ .instructions[0].alu_rgb_addr = R300_RGB_ADDR0(0) | R300_RGB_ADDR1(0) |
+ R300_RGB_ADDR2(0) | R300_ALU_DSTC_OUTPUT_XYZ,
+ .instructions[0].alu_alpha_inst = R300_ALPHA_SWIZA(R300_ALU_ARGA_SRC0A) |
+ R300_ALPHA_SWIZB(R300_ALU_ARGA_SRC0A) |
+ R300_ALPHA_SWIZC(R300_ALU_ARGA_ZERO) |
+ R300_ALU_OUTA_CMP,
+ .instructions[0].alu_alpha_addr = R300_ALPHA_ADDR0(0) |
+ R300_ALPHA_ADDR1(0) | R300_ALPHA_ADDR2(0) | R300_ALU_DSTA_OUTPUT,
+};
+
+static const struct r500_fragment_shader r500_texture_fragment_shader = {
+ .shader.stack_size = 0,
+ .instruction_count = 1,
+ .instructions[0].inst0 = R500_INST_TYPE_OUT |
+ R500_INST_TEX_SEM_WAIT | R500_INST_LAST |
+ R500_INST_RGB_OMASK_RGB | R500_INST_ALPHA_OMASK |
+ R500_INST_RGB_CLAMP | R500_INST_ALPHA_CLAMP,
+ .instructions[0].inst1 =
+ R500_RGB_ADDR0(0) | R500_RGB_ADDR1(0) | R500_RGB_ADDR1_CONST |
+ R500_RGB_ADDR2(0) | R500_RGB_ADDR2_CONST,
+ .instructions[0].inst2 =
+ R500_ALPHA_ADDR0(0) | R500_ALPHA_ADDR1(0) | R500_ALPHA_ADDR1_CONST |
+ R500_ALPHA_ADDR2(0) | R500_ALPHA_ADDR2_CONST,
+ .instructions[0].inst3 =
+ R500_ALU_RGB_SEL_A_SRC0 | R500_ALU_RGB_R_SWIZ_A_R |
+ R500_ALU_RGB_G_SWIZ_A_G | R500_ALU_RGB_B_SWIZ_A_B |
+ R500_ALU_RGB_SEL_B_SRC0 | R500_ALU_RGB_R_SWIZ_B_R |
+ R500_ALU_RGB_B_SWIZ_B_G | R500_ALU_RGB_G_SWIZ_B_B,
+ .instructions[0].inst4 =
+ R500_ALPHA_OP_CMP | R500_ALPHA_SWIZ_A_A | R500_ALPHA_SWIZ_B_A,
+ .instructions[0].inst5 =
+ R500_ALU_RGBA_OP_CMP | R500_ALU_RGBA_R_SWIZ_0 |
+ R500_ALU_RGBA_G_SWIZ_0 | R500_ALU_RGBA_B_SWIZ_0 |
+ R500_ALU_RGBA_A_SWIZ_0,
+};
+
#endif /* R300_STATE_SHADER_H */
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)
diff --git a/src/gallium/drivers/r300/r300_surface.h b/src/gallium/drivers/r300/r300_surface.h
index b75b3ab84cf..465b8476edf 100644
--- a/src/gallium/drivers/r300/r300_surface.h
+++ b/src/gallium/drivers/r300/r300_surface.h
@@ -91,4 +91,33 @@ const struct r300_rs_block r500_rs_block_clear_state = {
.inst_count = 0,
};
+/* The following state is used for surface_copy only. */
+
+const struct r300_rs_block r300_rs_block_copy_state = {
+ .ip[0] = R500_RS_SEL_S(R300_RS_SEL_K0) |
+ R500_RS_SEL_T(R300_RS_SEL_K0) |
+ R500_RS_SEL_R(R300_RS_SEL_K0) |
+ R500_RS_SEL_Q(R300_RS_SEL_K1),
+ .inst[0] = R300_RS_INST_COL_CN_WRITE,
+ .count = R300_IT_COUNT(2) | R300_IC_COUNT(0) | R300_HIRES_EN,
+ .inst_count = R300_RS_TX_OFFSET(6),
+};
+
+const struct r300_rs_block r500_rs_block_copy_state = {
+ .ip[0] = R500_RS_SEL_S(R500_RS_IP_PTR_K0) |
+ R500_RS_SEL_T(R500_RS_IP_PTR_K0) |
+ R500_RS_SEL_R(R500_RS_IP_PTR_K0) |
+ R500_RS_SEL_Q(R500_RS_IP_PTR_K1),
+ .inst[0] = R500_RS_INST_COL_CN_WRITE,
+ .count = R300_IT_COUNT(2) | R300_IC_COUNT(0) | R300_HIRES_EN,
+ .inst_count = R300_RS_TX_OFFSET(6),
+};
+
+const struct r300_sampler_state r300_sampler_copy_state = {
+ .filter0 = R300_TX_WRAP_S(R300_TX_CLAMP) |
+ R300_TX_WRAP_T(R300_TX_CLAMP) |
+ R300_TX_MAG_FILTER_NEAREST |
+ R300_TX_MIN_FILTER_NEAREST,
+};
+
#endif /* R300_SURFACE_H */