r300g: add back-face color VS outputs
authorMarek Olšák <maraeo@gmail.com>
Sat, 19 Dec 2009 22:55:34 +0000 (23:55 +0100)
committerCorbin Simpson <MostAwesomeDude@gmail.com>
Wed, 6 Jan 2010 20:49:16 +0000 (12:49 -0800)
Required for two-sided lighting. BTW we are approaching softpipe-level
quality. ;)

src/gallium/drivers/r300/r300_state_derived.c
src/gallium/drivers/r300/r300_vs.c

index 2a12a02e18a6d4640cd9be5b317c62ce0cdb280b..22660a52d9ac1d067125631fa765d78becbec26e 100644 (file)
@@ -333,6 +333,8 @@ static void r300_update_rs_block(struct r300_context* r300,
     void (*rX00_rs_col_write)(struct r300_rs_block*, int, int);
     void (*rX00_rs_tex)(struct r300_rs_block*, int, int, boolean);
     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;
 
     if (r300_screen(r300->context.screen)->caps->is_r500) {
         rX00_rs_col       = r500_rs_col;
@@ -348,7 +350,7 @@ static void r300_update_rs_block(struct r300_context* r300,
 
     /* Rasterize colors. */
     for (i = 0; i < ATTR_COLOR_COUNT; i++) {
-        if (vs_outputs->color[i] != ATTR_UNUSED) {
+        if (vs_outputs->color[i] != ATTR_UNUSED || any_bcolor_used) {
             /* Always rasterize if it's written by the VS,
              * otherwise it locks up. */
             rX00_rs_col(rs, col_count, i, FALSE);
index cb4b6ee71e720667d07b613042dd1a994878c492..68aef70872ecad450369aaa2a57b0225473b4d19 100644 (file)
@@ -96,6 +96,8 @@ static void r300_shader_vap_output_fmt(struct r300_vertex_shader* vs)
     struct r300_shader_semantics* vs_outputs = &vs->outputs;
     uint32_t* hwfmt = vs->hwfmt;
     int i, gen_count;
+    boolean any_bcolor_used = vs_outputs->bcolor[0] != ATTR_UNUSED ||
+                              vs_outputs->bcolor[1] != ATTR_UNUSED;
 
     /* Do the actual vertex_info setup.
      *
@@ -122,13 +124,19 @@ static void r300_shader_vap_output_fmt(struct r300_vertex_shader* vs)
 
     /* Colors. */
     for (i = 0; i < ATTR_COLOR_COUNT; i++) {
-        if (vs_outputs->color[i] != ATTR_UNUSED) {
+        if (vs_outputs->color[i] != ATTR_UNUSED || any_bcolor_used) {
             hwfmt[1] |= R300_INPUT_CNTL_COLOR;
             hwfmt[2] |= R300_VAP_OUTPUT_VTX_FMT_0__COLOR_0_PRESENT << i;
         }
     }
 
-    /* XXX Back-face colors. */
+    /* Back-face colors. */
+    if (any_bcolor_used) {
+        for (i = 0; i < ATTR_COLOR_COUNT; i++) {
+            hwfmt[1] |= R300_INPUT_CNTL_COLOR;
+            hwfmt[2] |= R300_VAP_OUTPUT_VTX_FMT_0__COLOR_0_PRESENT << (2+i);
+        }
+    }
 
     /* Texture coordinates. */
     gen_count = 0;
@@ -161,6 +169,8 @@ static void r300_stream_locations_notcl(
     int* stream_loc)
 {
     int i, tabi = 0, gen_count;
+    boolean any_bcolor_used = vs_outputs->bcolor[0] != ATTR_UNUSED ||
+                              vs_outputs->bcolor[1] != ATTR_UNUSED;
 
     /* Position. */
     stream_loc[tabi++] = 0;
@@ -172,14 +182,14 @@ static void r300_stream_locations_notcl(
 
     /* Colors. */
     for (i = 0; i < ATTR_COLOR_COUNT; i++) {
-        if (vs_outputs->color[i] != ATTR_UNUSED) {
+        if (vs_outputs->color[i] != ATTR_UNUSED || any_bcolor_used) {
             stream_loc[tabi++] = 2 + i;
         }
     }
 
     /* Back-face colors. */
-    for (i = 0; i < ATTR_COLOR_COUNT; i++) {
-        if (vs_outputs->bcolor[i] != ATTR_UNUSED) {
+    if (any_bcolor_used) {
+        for (i = 0; i < ATTR_COLOR_COUNT; i++) {
             stream_loc[tabi++] = 4 + i;
         }
     }
@@ -219,6 +229,8 @@ static void set_vertex_inputs_outputs(struct r300_vertex_program_compiler * c)
     struct r300_shader_semantics* outputs = &vs->outputs;
     struct tgsi_shader_info* info = &vs->info;
     int i, reg = 0;
+    boolean any_bcolor_used = outputs->bcolor[0] != ATTR_UNUSED ||
+                              outputs->bcolor[1] != ATTR_UNUSED;
 
     /* Fill in the input mapping */
     for (i = 0; i < info->num_inputs; i++)
@@ -236,14 +248,30 @@ static void set_vertex_inputs_outputs(struct r300_vertex_program_compiler * c)
         c->code->outputs[outputs->psize] = reg++;
     }
 
+    /* If we're writing back facing colors we need to send
+     * four colors to make front/back face colors selection work.
+     * If the vertex program doesn't write all 4 colors, lets
+     * pretend it does by skipping output index reg so the colors
+     * get written into appropriate output vectors.
+     */
+
     /* Colors. */
     for (i = 0; i < ATTR_COLOR_COUNT; i++) {
         if (outputs->color[i] != ATTR_UNUSED) {
             c->code->outputs[outputs->color[i]] = reg++;
+        } else if (any_bcolor_used) {
+            reg++;
         }
     }
 
-    /* XXX Back-face colors. */
+    /* Back-face colors. */
+    for (i = 0; i < ATTR_COLOR_COUNT; i++) {
+        if (outputs->bcolor[i] != ATTR_UNUSED) {
+            c->code->outputs[outputs->bcolor[i]] = reg++;
+        } else if (any_bcolor_used) {
+            reg++;
+        }
+    }
 
     /* Texture coordinates. */
     for (i = 0; i < ATTR_GENERIC_COUNT; i++) {