}
}
+ /* Texcoords */
+ for (i = 0; i < ATTR_TEXCOORD_COUNT && gen_count < 8; i++) {
+ if (vs_outputs->texcoord[i] != ATTR_UNUSED &&
+ (!(r300->sprite_coord_enable & (1U << i)) || !r300->is_point)) {
+ r300_draw_emit_attrib(r300, EMIT_4F, vs_outputs->texcoord[i]);
+ gen_count++;
+ }
+ }
+
/* Fog coordinates. */
if (gen_count < 8 && vs_outputs->fog != ATTR_UNUSED) {
r300_draw_emit_attrib(r300, EMIT_4F, vs_outputs->fog);
fprintf(stderr, "r300: ERROR: FS input FACE unassigned.\n");
}
- /* Re-use color varyings for texcoords if possible.
+ /* Re-use color varyings for generics if possible.
*
* The colors are interpolated as 20-bit floats (reduced precision),
* Use this hack only if there are too many generic varyings.
- * (number of generic varyings + fog + wpos > 8) */
+ * (number of generics + texcoords + fog + wpos + pcoord > 8) */
if (r300->screen->caps.is_r500 && !any_bcolor_used && !r300->flatshade &&
- fs_inputs->face == ATTR_UNUSED &&
- vs_outputs->num_generic + (vs_outputs->fog != ATTR_UNUSED) +
- (fs_inputs->wpos != ATTR_UNUSED) > 8) {
+ fs_inputs->face == ATTR_UNUSED &&
+ vs_outputs->num_texcoord + vs_outputs->num_generic +
+ (vs_outputs->fog != ATTR_UNUSED) + (fs_inputs->wpos != ATTR_UNUSED) +
+ (vs_outputs->pcoord != ATTR_UNUSED) > 8 &&
+ fs_inputs->num_generic > fs_inputs->num_texcoord) {
for (i = 0; i < ATTR_GENERIC_COUNT && col_count < 2; i++) {
/* Cannot use color varyings for sprite coords. */
if (fs_inputs->generic[i] != ATTR_UNUSED &&
gen_offset = i;
}
- /* Rasterize texture coordinates. */
+ /* Rasterize generics. */
for (i = gen_offset; i < ATTR_GENERIC_COUNT && tex_count < 8; i++) {
boolean sprite_coord = false;
}
}
+ gen_offset = 0;
+ /* Re-use color varyings for texcoords if possible.
+ *
+ * The colors are interpolated as 20-bit floats (reduced precision),
+ * Use this hack only if there are too many generic varyings.
+ * (number of generics + texcoords + fog + wpos + pcoord > 8) */
+ if (r300->screen->caps.is_r500 && !any_bcolor_used && !r300->flatshade &&
+ fs_inputs->face == ATTR_UNUSED &&
+ vs_outputs->num_texcoord + vs_outputs->num_generic +
+ (vs_outputs->fog != ATTR_UNUSED) + (fs_inputs->wpos != ATTR_UNUSED) +
+ (vs_outputs->pcoord != ATTR_UNUSED) > 8 &&
+ fs_inputs->num_generic <= fs_inputs->num_texcoord) {
+ for (i = 0; i < ATTR_TEXCOORD_COUNT && col_count < 2; i++) {
+ /* Cannot use color varyings for sprite coords. */
+ if (fs_inputs->texcoord[i] != ATTR_UNUSED &&
+ (r300->sprite_coord_enable & (1U << i)) && r300->is_point) {
+ break;
+ }
+
+ if (vs_outputs->texcoord[i] != 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 << col_count;
+ stream_loc_notcl[loc++] = 2 + col_count;
+
+ /* 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->texcoord[i] != ATTR_UNUSED) {
+ rX00_rs_col_write(&rs, col_count, fp_offset, WRITE_COLOR);
+ fp_offset++;
+
+ DBG(r300, DBG_RS,
+ "r300: Rasterized texcoord %i redirected to color %i and written to FS.\n",
+ i, col_count);
+ } else {
+ DBG(r300, DBG_RS, "r300: Rasterized texcoord %i redirected to color %i unused.\n",
+ i, col_count);
+ }
+ 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->texcoord[i] != ATTR_UNUSED) {
+ fp_offset++;
+
+ DBG(r300, DBG_RS, "r300: FS input texcoord %i unassigned.\n", i);
+ }
+ }
+ }
+ gen_offset = i;
+ }
+
+ /* Rasterize texcords. */
+ for (i = gen_offset; i < ATTR_TEXCOORD_COUNT && tex_count < 8; i++) {
+ boolean sprite_coord = false;
+
+ if (fs_inputs->texcoord[i] != ATTR_UNUSED) {
+ sprite_coord = !!(r300->sprite_coord_enable & (1 << i)) && r300->is_point;
+ }
+
+ if (vs_outputs->texcoord[i] != ATTR_UNUSED || sprite_coord) {
+ if (!sprite_coord) {
+ /* Set up the texture coordinates in VAP. */
+ rs.vap_vsm_vtx_assm |= (R300_INPUT_CNTL_TC0 << tex_count);
+ rs.vap_out_vtx_fmt[1] |= (4 << (3 * tex_count));
+ stream_loc_notcl[loc++] = 6 + tex_count;
+ } else
+ stuffing_enable |=
+ R300_GB_TEX_ST << (R300_GB_TEX0_SOURCE_SHIFT + (tex_count*2));
+
+ /* Rasterize it. */
+ rX00_rs_tex(&rs, tex_count, tex_ptr,
+ sprite_coord ? SWIZ_XY01 : SWIZ_XYZW);
+
+ /* Write it to the FS input register if it's needed by the FS. */
+ if (fs_inputs->texcoord[i] != ATTR_UNUSED) {
+ rX00_rs_tex_write(&rs, tex_count, fp_offset);
+ fp_offset++;
+
+ DBG(r300, DBG_RS,
+ "r300: Rasterized texcoord %i written to FS%s in texcoord %d.\n",
+ i, sprite_coord ? " (sprite coord)" : "", tex_count);
+ } else {
+ DBG(r300, DBG_RS,
+ "r300: Rasterized texcoord %i unused%s.\n",
+ i, sprite_coord ? " (sprite coord)" : "");
+ }
+ tex_count++;
+ tex_ptr += sprite_coord ? 2 : 4;
+ } 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->texcoord[i] != ATTR_UNUSED) {
+ fp_offset++;
+
+ DBG(r300, DBG_RS, "r300: FS input texcoord %i unassigned%s.\n",
+ i, sprite_coord ? " (sprite coord)" : "");
+ }
+ }
+ }
+
+ /* Rasterize pointcoord. */
+ if (fs_inputs->pcoord != ATTR_UNUSED && tex_count < 8) {
+
+ stuffing_enable |=
+ R300_GB_TEX_ST << (R300_GB_TEX0_SOURCE_SHIFT + (tex_count*2));
+
+ /* Rasterize it. */
+ rX00_rs_tex(&rs, tex_count, tex_ptr, SWIZ_XY01);
+
+ /* Write it to the FS input register if it's needed by the FS. */
+ rX00_rs_tex_write(&rs, tex_count, fp_offset);
+ fp_offset++;
+
+ DBG(r300, DBG_RS,
+ "r300: Rasterized pointcoord %i written to FS%s in texcoord %d.\n",
+ i, " (sprite coord)", tex_count);
+
+ tex_count++;
+ tex_ptr += 2;
+ }
+
for (; i < ATTR_GENERIC_COUNT; i++) {
if (fs_inputs->generic[i] != ATTR_UNUSED) {
fprintf(stderr, "r300: ERROR: FS input generic %i unassigned, "
rs.inst_count = count - 1;
/* set the GB enable flags */
- if (r300->sprite_coord_enable && r300->is_point)
+ if ((r300->sprite_coord_enable || fs_inputs->pcoord != ATTR_UNUSED) &&
+ r300->is_point) {
stuffing_enable |= R300_GB_POINT_STUFF_ENABLE;
+ }
rs.gb_enable = stuffing_enable;