r300: enable PIPE_CAP_TGSI_TEXCOORD
authorPavel Ondračka <pavel.ondracka@gmail.com>
Fri, 28 Apr 2023 11:17:52 +0000 (13:17 +0200)
committerMarge Bot <emma+marge@anholt.net>
Mon, 5 Jun 2023 10:31:40 +0000 (10:31 +0000)
Signed-off-by: Pavel Ondračka <pavel.ondracka@gmail.com>
Acked-by: Emma Anholt <emma@anholt.net>
Reviewed-by: Filip Gawin <filip.gawin@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/23299>

src/gallium/drivers/r300/r300_fs.c
src/gallium/drivers/r300/r300_render.c
src/gallium/drivers/r300/r300_screen.c
src/gallium/drivers/r300/r300_shader_semantics.h
src/gallium/drivers/r300/r300_state.c
src/gallium/drivers/r300/r300_state_derived.c
src/gallium/drivers/r300/r300_vs.c

index 94a5505..201949c 100644 (file)
@@ -58,6 +58,15 @@ void r300_shader_read_fs_inputs(struct tgsi_shader_info* info,
                 fs_inputs->color[index] = i;
                 break;
 
+            case TGSI_SEMANTIC_PCOORD:
+                fs_inputs->pcoord = i;
+                break;
+
+            case TGSI_SEMANTIC_TEXCOORD:
+                assert(index < ATTR_TEXCOORD_COUNT);
+                fs_inputs->texcoord[index] = i;
+                break;
+
             case TGSI_SEMANTIC_GENERIC:
                 assert(index < ATTR_GENERIC_COUNT);
                 fs_inputs->generic[index] = i;
@@ -133,6 +142,14 @@ static void allocate_hardware_inputs(
             allocate(mydata, inputs->generic[i], reg++);
         }
     }
+    for (i = 0; i < ATTR_TEXCOORD_COUNT; i++) {
+        if (inputs->texcoord[i] != ATTR_UNUSED) {
+            allocate(mydata, inputs->texcoord[i], reg++);
+        }
+    }
+    if (inputs->pcoord != ATTR_UNUSED) {
+        allocate(mydata, inputs->pcoord, reg++);
+    }
     if (inputs->fog != ATTR_UNUSED) {
         allocate(mydata, inputs->fog, reg++);
     }
index 9b8d943..ba6e3db 100644 (file)
@@ -41,6 +41,7 @@
 #include "r300_emit.h"
 #include "r300_reg.h"
 #include "r300_vs.h"
+#include "r300_fs.h"
 
 #include <limits.h>
 
@@ -801,11 +802,13 @@ static void r300_draw_vbo(struct pipe_context* pipe,
         return;
     }
 
-    if (r300->sprite_coord_enable != 0)
+    if (r300->sprite_coord_enable != 0 ||
+        r300_fs(r300)->shader->inputs.pcoord != ATTR_UNUSED) {
         if ((info.mode == MESA_PRIM_POINTS) != r300->is_point) {
             r300->is_point = !r300->is_point;
             r300_mark_atom_dirty(r300, &r300->rs_block_state);
         }
+    }
 
     r300_update_derived_state(r300);
 
@@ -888,11 +891,14 @@ static void r300_swtcl_draw_vbo(struct pipe_context* pipe,
                          info->index_size, ~0);
     }
 
-    if (r300->sprite_coord_enable != 0)
+    if (r300->sprite_coord_enable != 0 ||
+        r300_fs(r300)->shader->inputs.pcoord != ATTR_UNUSED) {
         if ((info->mode == MESA_PRIM_POINTS) != r300->is_point) {
             r300->is_point = !r300->is_point;
             r300_mark_atom_dirty(r300, &r300->rs_block_state);
         }
+    }
+
 
     r300_update_derived_state(r300);
 
index ef85f00..6c4d259 100644 (file)
@@ -144,6 +144,7 @@ static int r300_get_param(struct pipe_screen* pscreen, enum pipe_cap param)
         case PIPE_CAP_CLIP_HALFZ:
         case PIPE_CAP_ALLOW_MAPPED_BUFFERS_DURING_EXECUTION:
         case PIPE_CAP_LEGACY_MATH_RULES:
+        case PIPE_CAP_TGSI_TEXCOORD:
             return 1;
 
         case PIPE_CAP_TEXTURE_TRANSFER_MODES:
index 93bbc9d..b474a3e 100644 (file)
@@ -26,6 +26,7 @@
 #define ATTR_UNUSED             (-1)
 #define ATTR_COLOR_COUNT        2
 #define ATTR_GENERIC_COUNT      32
+#define ATTR_TEXCOORD_COUNT     8
 
 /* This structure contains information about what attributes are written by VS
  * or read by FS. (but not both) It's much easier to work with than
@@ -39,10 +40,13 @@ struct r300_shader_semantics {
     int color[ATTR_COLOR_COUNT];
     int bcolor[ATTR_COLOR_COUNT];
     int face;
+    int texcoord[ATTR_TEXCOORD_COUNT];
     int generic[ATTR_GENERIC_COUNT];
     int fog;
     int wpos;
+    int pcoord;
 
+    int num_texcoord;
     int num_generic;
 };
 
@@ -56,16 +60,22 @@ static inline void r300_shader_semantics_reset(
     info->face = ATTR_UNUSED;
     info->fog = ATTR_UNUSED;
     info->wpos = ATTR_UNUSED;
+    info->pcoord = ATTR_UNUSED;
 
     for (i = 0; i < ATTR_COLOR_COUNT; i++) {
         info->color[i] = ATTR_UNUSED;
         info->bcolor[i] = ATTR_UNUSED;
     }
 
+    for (i = 0; i < ATTR_TEXCOORD_COUNT; i++) {
+        info->texcoord[i] = ATTR_UNUSED;
+    }
+
     for (i = 0; i < ATTR_GENERIC_COUNT; i++) {
         info->generic[i] = ATTR_UNUSED;
     }
 
+    info->num_texcoord = 0;
     info->num_generic = 0;
 }
 
index 09300ff..8a493a9 100644 (file)
@@ -1281,17 +1281,15 @@ static void* r300_create_rs_state(struct pipe_context* pipe,
     clip_rule = state->scissor ? 0xAAAA : 0xFFFF;
 
     /* Point sprites coord mode */
-    if (rs->rs.sprite_coord_enable) {
-        switch (state->sprite_coord_mode) {
-            case PIPE_SPRITE_COORD_UPPER_LEFT:
-                point_texcoord_top = 0.0f;
-                point_texcoord_bottom = 1.0f;
-                break;
-            case PIPE_SPRITE_COORD_LOWER_LEFT:
-                point_texcoord_top = 1.0f;
-                point_texcoord_bottom = 0.0f;
-                break;
-        }
+    switch (state->sprite_coord_mode) {
+        case PIPE_SPRITE_COORD_UPPER_LEFT:
+            point_texcoord_top = 0.0f;
+            point_texcoord_bottom = 1.0f;
+            break;
+        case PIPE_SPRITE_COORD_LOWER_LEFT:
+            point_texcoord_top = 1.0f;
+            point_texcoord_bottom = 0.0f;
+            break;
     }
 
     if (r300_screen(pipe->screen)->caps.has_tcl) {
index 05a7e0e..67b8d4d 100644 (file)
@@ -108,6 +108,15 @@ static void r300_draw_emit_all_attribs(struct r300_context* r300)
         }
     }
 
+    /* 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);
@@ -429,15 +438,17 @@ static void r300_update_rs_block(struct r300_context *r300)
         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 &&
@@ -481,7 +492,7 @@ static void r300_update_rs_block(struct r300_context *r300)
        gen_offset = i;
     }
 
-    /* Rasterize texture coordinates. */
+    /* Rasterize generics. */
     for (i = gen_offset; i < ATTR_GENERIC_COUNT && tex_count < 8; i++) {
        boolean sprite_coord = false;
 
@@ -530,6 +541,131 @@ static void r300_update_rs_block(struct r300_context *r300)
         }
     }
 
+    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, "
@@ -625,8 +761,10 @@ static void r300_update_rs_block(struct r300_context *r300)
     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;
 
index dba65ae..394604c 100644 (file)
@@ -67,6 +67,12 @@ static void r300_shader_read_vs_outputs(
                 vs_outputs->bcolor[index] = i;
                 break;
 
+            case TGSI_SEMANTIC_TEXCOORD:
+                assert(index < ATTR_TEXCOORD_COUNT);
+                vs_outputs->texcoord[index] = i;
+                vs_outputs->num_texcoord++;
+                break;
+
             case TGSI_SEMANTIC_GENERIC:
                 assert(index < ATTR_GENERIC_COUNT);
                 vs_outputs->generic[index] = i;
@@ -153,6 +159,13 @@ static void set_vertex_inputs_outputs(struct r300_vertex_program_compiler * c)
     }
 
     /* Texture coordinates. */
+    for (i = 0; i < ATTR_TEXCOORD_COUNT; i++) {
+        if (outputs->texcoord[i] != ATTR_UNUSED) {
+            c->code->outputs[outputs->texcoord[i]] = reg++;
+        }
+    }
+
+    /* Generics. */
     for (i = 0; i < ATTR_GENERIC_COUNT; i++) {
         if (outputs->generic[i] != ATTR_UNUSED) {
             c->code->outputs[outputs->generic[i]] = reg++;