+ rs->ip[id] |= R500_RS_COL_PTR(ptr);
+ if (swiz == SWIZ_0001) {
+ rs->ip[id] |= R500_RS_COL_FMT(R300_RS_COL_FMT_0001);
+ } else {
+ rs->ip[id] |= R500_RS_COL_FMT(R300_RS_COL_FMT_RGBA);
+ }
+ rs->inst[id] |= R500_RS_INST_COL_ID(id);
+}
+
+static void r500_rs_col_write(struct r300_rs_block* rs, int id, int fp_offset,
+ enum r300_rs_col_write_type type)
+{
+ if (type == WRITE_FACE)
+ rs->inst[id] |= R500_RS_INST_COL_CN_WRITE_BACKFACE |
+ R500_RS_INST_COL_ADDR(fp_offset);
+ else
+ rs->inst[id] |= R500_RS_INST_COL_CN_WRITE |
+ R500_RS_INST_COL_ADDR(fp_offset);
+
+}
+
+static void r500_rs_tex(struct r300_rs_block* rs, int id, int ptr,
+ enum r300_rs_swizzle swiz)
+{
+ if (swiz == SWIZ_X001) {
+ rs->ip[id] |= R500_RS_SEL_S(ptr) |
+ 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);
+ } else if (swiz == SWIZ_XY01) {
+ rs->ip[id] |= R500_RS_SEL_S(ptr) |
+ R500_RS_SEL_T(ptr + 1) |
+ R500_RS_SEL_R(R500_RS_IP_PTR_K0) |
+ R500_RS_SEL_Q(R500_RS_IP_PTR_K1);
+ } else {
+ rs->ip[id] |= R500_RS_SEL_S(ptr) |
+ R500_RS_SEL_T(ptr + 1) |
+ R500_RS_SEL_R(ptr + 2) |
+ R500_RS_SEL_Q(ptr + 3);
+ }
+ rs->inst[id] |= R500_RS_INST_TEX_ID(id);
+}
+
+static void r500_rs_tex_write(struct r300_rs_block* rs, int id, int fp_offset)
+{
+ rs->inst[id] |= R500_RS_INST_TEX_CN_WRITE |
+ R500_RS_INST_TEX_ADDR(fp_offset);
+}
+
+/* Set up the RS block.
+ *
+ * This is the part of the chipset that is responsible for linking vertex
+ * and fragment shaders and stuffed texture coordinates.
+ *
+ * The rasterizer reads data from VAP, which produces vertex shader outputs,
+ * and GA, which produces stuffed texture coordinates. VAP outputs have
+ * precedence over GA. All outputs must be rasterized otherwise it locks up.
+ * If there are more outputs rasterized than is set in VAP/GA, it locks up
+ * too. The funky part is that this info has been pretty much obtained by trial
+ * and error. */
+static void r300_update_rs_block(struct r300_context *r300)
+{
+ struct r300_vertex_shader *vs = r300->vs_state.state;
+ struct r300_shader_semantics *vs_outputs = &vs->outputs;
+ struct r300_shader_semantics *fs_inputs = &r300_fs(r300)->shader->inputs;
+ struct r300_rs_block rs = {0};
+ int i, col_count = 0, tex_count = 0, fp_offset = 0, count, loc = 0, tex_ptr = 0;
+ void (*rX00_rs_col)(struct r300_rs_block*, int, int, enum r300_rs_swizzle);
+ void (*rX00_rs_col_write)(struct r300_rs_block*, int, int, enum r300_rs_col_write_type);
+ void (*rX00_rs_tex)(struct r300_rs_block*, int, int, enum r300_rs_swizzle);
+ void (*rX00_rs_tex_write)(struct r300_rs_block*, int, int);
+ boolean any_bcolor_used = vs_outputs->bcolor[0] != ATTR_UNUSED ||
+ vs_outputs->bcolor[1] != ATTR_UNUSED;
+ int *stream_loc_notcl = r300->stream_loc_notcl;
+ uint32_t stuffing_enable = 0;
+
+ if (r300->screen->caps.is_r500) {
+ rX00_rs_col = r500_rs_col;
+ rX00_rs_col_write = r500_rs_col_write;
+ rX00_rs_tex = r500_rs_tex;
+ rX00_rs_tex_write = r500_rs_tex_write;
+ } else {
+ rX00_rs_col = r300_rs_col;
+ rX00_rs_col_write = r300_rs_col_write;
+ rX00_rs_tex = r300_rs_tex;
+ rX00_rs_tex_write = r300_rs_tex_write;
+ }
+
+ /* 0x5555 copied from classic, which means:
+ * Select user color 0 for COLOR0 up to COLOR7.
+ * What the hell does that mean? */
+ rs.vap_vtx_state_cntl = 0x5555;
+
+ /* The position is always present in VAP. */
+ rs.vap_vsm_vtx_assm |= R300_INPUT_CNTL_POS;
+ rs.vap_out_vtx_fmt[0] |= R300_VAP_OUTPUT_VTX_FMT_0__POS_PRESENT;
+ stream_loc_notcl[loc++] = 0;
+
+ /* Set up the point size in VAP. */
+ if (vs_outputs->psize != ATTR_UNUSED) {
+ rs.vap_out_vtx_fmt[0] |= R300_VAP_OUTPUT_VTX_FMT_0__PT_SIZE_PRESENT;
+ stream_loc_notcl[loc++] = 1;
+ }
+
+ /* Set up and rasterize colors. */
+ for (i = 0; i < ATTR_COLOR_COUNT; i++) {
+ if (vs_outputs->color[i] != ATTR_UNUSED || any_bcolor_used ||
+ vs_outputs->color[1] != ATTR_UNUSED) {
+ /* Set up the color in VAP. */
+ rs.vap_vsm_vtx_assm |= R300_INPUT_CNTL_COLOR;
+ rs.vap_out_vtx_fmt[0] |=
+ R300_VAP_OUTPUT_VTX_FMT_0__COLOR_0_PRESENT << i;
+ stream_loc_notcl[loc++] = 2 + i;
+
+ /* Rasterize it. */
+ rX00_rs_col(&rs, col_count, col_count, SWIZ_XYZW);
+
+ /* Write it to the FS input register if it's needed by the FS. */
+ if (fs_inputs->color[i] != ATTR_UNUSED) {
+ rX00_rs_col_write(&rs, col_count, fp_offset, WRITE_COLOR);
+ fp_offset++;
+
+ DBG(r300, DBG_RS,
+ "r300: Rasterized color %i written to FS.\n", i);
+ } else {
+ DBG(r300, DBG_RS, "r300: Rasterized color %i unused.\n", i);
+ }
+ col_count++;
+ } else {
+ /* Skip the FS input register, leave it uninitialized. */
+ /* If we try to set it to (0,0,0,1), it will lock up. */
+ if (fs_inputs->color[i] != ATTR_UNUSED) {
+ fp_offset++;
+
+ DBG(r300, DBG_RS, "r300: FS input color %i unassigned%s.\n",
+ i);