@@ -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); | |||
@@ -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); | |||
@@ -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 |
@@ -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); |
@@ -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 */ |
@@ -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) |
@@ -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 */ |