softpipe: fix vertex shader texture sampling
authorBrian Paul <brian.paul@tungstengraphics.com>
Thu, 18 Dec 2008 01:59:58 +0000 (18:59 -0700)
committerBrian Paul <brian.paul@tungstengraphics.com>
Thu, 18 Dec 2008 01:59:58 +0000 (18:59 -0700)
Need to disable/bypass lambda calculation since derivatives of texcoords
are meaningless for adjacent vertices.

src/gallium/drivers/softpipe/sp_context.c
src/gallium/drivers/softpipe/sp_context.h
src/gallium/drivers/softpipe/sp_quad_fs.c
src/gallium/drivers/softpipe/sp_tex_sample.c
src/gallium/drivers/softpipe/sp_tex_sample.h

index 99b52748575d4b948365261def904d658ff2522d..800f944838ad1728b08fbb46125bff88f186a1fb 100644 (file)
@@ -2,6 +2,7 @@
  * 
  * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
  * All Rights Reserved.
+ * Copyright 2008 VMware, Inc.  All rights reserved.
  * 
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the
@@ -221,12 +222,22 @@ softpipe_create( struct pipe_screen *screen,
       softpipe->quad[i].output = sp_quad_output_stage(softpipe);
    }
 
+   /* vertex shader samplers */
    for (i = 0; i < PIPE_MAX_SAMPLERS; i++) {
-      softpipe->tgsi.samplers[i].base.get_samples = sp_get_samples;
-      softpipe->tgsi.samplers[i].unit = i;
-      softpipe->tgsi.samplers[i].sp = softpipe;
-      softpipe->tgsi.samplers[i].cache = softpipe->tex_cache[i];
-      softpipe->tgsi.samplers_list[i] = &softpipe->tgsi.samplers[i];
+      softpipe->tgsi.vert_samplers[i].base.get_samples = sp_get_samples_vertex;
+      softpipe->tgsi.vert_samplers[i].unit = i;
+      softpipe->tgsi.vert_samplers[i].sp = softpipe;
+      softpipe->tgsi.vert_samplers[i].cache = softpipe->tex_cache[i];
+      softpipe->tgsi.vert_samplers_list[i] = &softpipe->tgsi.vert_samplers[i];
+   }
+
+   /* fragment shader samplers */
+   for (i = 0; i < PIPE_MAX_SAMPLERS; i++) {
+      softpipe->tgsi.frag_samplers[i].base.get_samples = sp_get_samples_fragment;
+      softpipe->tgsi.frag_samplers[i].unit = i;
+      softpipe->tgsi.frag_samplers[i].sp = softpipe;
+      softpipe->tgsi.frag_samplers[i].cache = softpipe->tex_cache[i];
+      softpipe->tgsi.frag_samplers_list[i] = &softpipe->tgsi.frag_samplers[i];
    }
 
    /*
@@ -237,7 +248,9 @@ softpipe_create( struct pipe_screen *screen,
       goto fail;
 
    draw_texture_samplers(softpipe->draw,
-                         PIPE_MAX_SAMPLERS, softpipe->tgsi.samplers_list);
+                         PIPE_MAX_SAMPLERS,
+                         (struct tgsi_sampler **)
+                            softpipe->tgsi.vert_samplers_list);
 
    softpipe->setup = sp_draw_render_stage(softpipe);
    if (!softpipe->setup)
index 790143aecc9d4fa203013992be91f9e61bfbc1f6..7ab12a6d7024c352b5dd2f3548e80ad2d84eee9b 100644 (file)
@@ -142,8 +142,10 @@ struct softpipe_context {
 
    /** TGSI exec things */
    struct {
-      struct sp_shader_sampler samplers[PIPE_MAX_SAMPLERS];
-      struct sp_shader_sampler *samplers_list[PIPE_MAX_SAMPLERS];
+      struct sp_shader_sampler vert_samplers[PIPE_MAX_SAMPLERS];
+      struct sp_shader_sampler *vert_samplers_list[PIPE_MAX_SAMPLERS];
+      struct sp_shader_sampler frag_samplers[PIPE_MAX_SAMPLERS];
+      struct sp_shader_sampler *frag_samplers_list[PIPE_MAX_SAMPLERS];
    } tgsi;
 
    /** The primitive drawing context */
index 963a2b44f55f6fb1bf2f37dcb3ba1d0db1a9ad11..40329a956273b034eee930f5e916bf79a0d08a05 100644 (file)
@@ -2,6 +2,7 @@
  * 
  * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
  * All Rights Reserved.
+ * Copyright 2008 VMware, Inc.  All rights reserved.
  * 
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the
@@ -51,8 +52,6 @@
 struct quad_shade_stage
 {
    struct quad_stage stage;  /**< base class */
-   struct sp_shader_sampler samplers[PIPE_MAX_SAMPLERS];
-   struct sp_shader_sampler *samplers_list[PIPE_MAX_SAMPLERS];
    struct tgsi_exec_machine machine;
    struct tgsi_exec_vector *inputs, *outputs;
 };
@@ -151,7 +150,8 @@ static void shade_begin(struct quad_stage *qs)
 
    softpipe->fs->prepare( softpipe->fs, 
                          &qss->machine,
-                         (struct tgsi_sampler **) qss->samplers_list );
+                         (struct tgsi_sampler **)
+                             softpipe->tgsi.frag_samplers_list );
 
    qs->next->begin(qs->next);
 }
@@ -184,16 +184,6 @@ struct quad_stage *sp_quad_shade_stage( struct softpipe_context *softpipe )
    qss->stage.run = shade_quad;
    qss->stage.destroy = shade_destroy;
 
-   /* setup TGSI sampler state */
-   for (i = 0; i < PIPE_MAX_SAMPLERS; i++) {
-      assert(softpipe->tex_cache[i]);
-      qss->samplers[i].base.get_samples = sp_get_samples;
-      qss->samplers[i].unit = i;
-      qss->samplers[i].sp = softpipe;
-      qss->samplers[i].cache = softpipe->tex_cache[i];
-      qss->samplers_list[i] = &qss->samplers[i];
-   }
-
    tgsi_exec_machine_init( &qss->machine );
 
    return &qss->stage;
index 631c60966c2e423d744a883a870901e40850e186..32aa5025e43251757745baee4604df5d77fcce6d 100644 (file)
@@ -2,6 +2,7 @@
  * 
  * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
  * All Rights Reserved.
+ * Copyright 2008 VMware, Inc.  All rights reserved.
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the
 #include "sp_tile_cache.h"
 #include "pipe/p_context.h"
 #include "pipe/p_defines.h"
-#include "tgsi/tgsi_exec.h"
 #include "util/u_math.h"
 #include "util/u_memory.h"
 
 
+
 /*
  * Note, the FRAC macro has to work perfectly.  Otherwise you'll sometimes
  * see 1-pixel bands of improperly weighted linear-filtered textures.
@@ -583,6 +584,7 @@ choose_mipmap_levels(const struct pipe_texture *texture,
                      const float s[QUAD_SIZE],
                      const float t[QUAD_SIZE],
                      const float p[QUAD_SIZE],
+                     boolean computeLambda,
                      float lodbias,
                      unsigned *level0, unsigned *level1, float *levelBlend,
                      unsigned *imgFilter)
@@ -611,7 +613,7 @@ choose_mipmap_levels(const struct pipe_texture *texture,
    else {
       float lambda;
 
-      if (1)
+      if (computeLambda)
          /* fragment shader */
          lambda = compute_lambda(texture, sampler, s, t, p, lodbias);
       else
@@ -755,6 +757,7 @@ sp_get_samples_2d_common(const struct tgsi_sampler *tgsi_sampler,
                          const float s[QUAD_SIZE],
                          const float t[QUAD_SIZE],
                          const float p[QUAD_SIZE],
+                         boolean computeLambda,
                          float lodbias,
                          float rgba[NUM_CHANNELS][QUAD_SIZE],
                          const unsigned faces[4])
@@ -769,7 +772,7 @@ sp_get_samples_2d_common(const struct tgsi_sampler *tgsi_sampler,
    int width, height;
    float levelBlend;
 
-   choose_mipmap_levels(texture, sampler, s, t, p, lodbias,
+   choose_mipmap_levels(texture, sampler, s, t, p, computeLambda, lodbias,
                         &level0, &level1, &levelBlend, &imgFilter);
 
    assert(sampler->normalized_coords);
@@ -883,12 +886,14 @@ sp_get_samples_1d(const struct tgsi_sampler *sampler,
                   const float s[QUAD_SIZE],
                   const float t[QUAD_SIZE],
                   const float p[QUAD_SIZE],
+                  boolean computeLambda,
                   float lodbias,
                   float rgba[NUM_CHANNELS][QUAD_SIZE])
 {
    static const unsigned faces[4] = {0, 0, 0, 0};
    static const float tzero[4] = {0, 0, 0, 0};
-   sp_get_samples_2d_common(sampler, s, tzero, NULL, lodbias, rgba, faces);
+   sp_get_samples_2d_common(sampler, s, tzero, NULL,
+                            computeLambda, lodbias, rgba, faces);
 }
 
 
@@ -897,11 +902,13 @@ sp_get_samples_2d(const struct tgsi_sampler *sampler,
                   const float s[QUAD_SIZE],
                   const float t[QUAD_SIZE],
                   const float p[QUAD_SIZE],
+                  boolean computeLambda,
                   float lodbias,
                   float rgba[NUM_CHANNELS][QUAD_SIZE])
 {
    static const unsigned faces[4] = {0, 0, 0, 0};
-   sp_get_samples_2d_common(sampler, s, t, p, lodbias, rgba, faces);
+   sp_get_samples_2d_common(sampler, s, t, p,
+                            computeLambda, lodbias, rgba, faces);
 }
 
 
@@ -910,6 +917,7 @@ sp_get_samples_3d(const struct tgsi_sampler *tgsi_sampler,
                   const float s[QUAD_SIZE],
                   const float t[QUAD_SIZE],
                   const float p[QUAD_SIZE],
+                  boolean computeLambda,
                   float lodbias,
                   float rgba[NUM_CHANNELS][QUAD_SIZE])
 {
@@ -924,7 +932,7 @@ sp_get_samples_3d(const struct tgsi_sampler *tgsi_sampler,
    float levelBlend;
    const uint face = 0;
 
-   choose_mipmap_levels(texture, sampler, s, t, p, lodbias,
+   choose_mipmap_levels(texture, sampler, s, t, p, computeLambda, lodbias,
                         &level0, &level1, &levelBlend, &imgFilter);
 
    assert(sampler->normalized_coords);
@@ -1037,6 +1045,7 @@ sp_get_samples_cube(const struct tgsi_sampler *sampler,
                     const float s[QUAD_SIZE],
                     const float t[QUAD_SIZE],
                     const float p[QUAD_SIZE],
+                    boolean computeLambda,
                     float lodbias,
                     float rgba[NUM_CHANNELS][QUAD_SIZE])
 {
@@ -1045,7 +1054,8 @@ sp_get_samples_cube(const struct tgsi_sampler *sampler,
    for (j = 0; j < QUAD_SIZE; j++) {
       faces[j] = choose_cube_face(s[j], t[j], p[j], ssss + j, tttt + j);
    }
-   sp_get_samples_2d_common(sampler, ssss, tttt, NULL, lodbias, rgba, faces);
+   sp_get_samples_2d_common(sampler, ssss, tttt, NULL,
+                            computeLambda, lodbias, rgba, faces);
 }
 
 
@@ -1054,6 +1064,7 @@ sp_get_samples_rect(const struct tgsi_sampler *tgsi_sampler,
                     const float s[QUAD_SIZE],
                     const float t[QUAD_SIZE],
                     const float p[QUAD_SIZE],
+                    boolean computeLambda,
                     float lodbias,
                     float rgba[NUM_CHANNELS][QUAD_SIZE])
 {
@@ -1068,7 +1079,7 @@ sp_get_samples_rect(const struct tgsi_sampler *tgsi_sampler,
    int width, height;
    float levelBlend;
 
-   choose_mipmap_levels(texture, sampler, s, t, p, lodbias,
+   choose_mipmap_levels(texture, sampler, s, t, p, computeLambda, lodbias,
                         &level0, &level1, &levelBlend, &imgFilter);
 
    /* texture RECTS cannot be mipmapped */
@@ -1127,14 +1138,14 @@ sp_get_samples_rect(const struct tgsi_sampler *tgsi_sampler,
 
 
 /**
- * Called via tgsi_sampler::get_samples()
- * Get four filtered RGBA values from the sampler's texture.
+ * Common code for vertex/fragment program texture sampling.
  */
-void
+static INLINE void
 sp_get_samples(struct tgsi_sampler *tgsi_sampler,
                const float s[QUAD_SIZE],
                const float t[QUAD_SIZE],
                const float p[QUAD_SIZE],
+               boolean computeLambda,
                float lodbias,
                float rgba[NUM_CHANNELS][QUAD_SIZE])
 {
@@ -1150,21 +1161,21 @@ sp_get_samples(struct tgsi_sampler *tgsi_sampler,
    switch (texture->target) {
    case PIPE_TEXTURE_1D:
       assert(sampler->normalized_coords);
-      sp_get_samples_1d(tgsi_sampler, s, t, p, lodbias, rgba);
+      sp_get_samples_1d(tgsi_sampler, s, t, p, computeLambda, lodbias, rgba);
       break;
    case PIPE_TEXTURE_2D:
       if (sampler->normalized_coords)
-         sp_get_samples_2d(tgsi_sampler, s, t, p, lodbias, rgba);
+         sp_get_samples_2d(tgsi_sampler, s, t, p, computeLambda, lodbias, rgba);
       else
-         sp_get_samples_rect(tgsi_sampler, s, t, p, lodbias, rgba);
+         sp_get_samples_rect(tgsi_sampler, s, t, p, computeLambda, lodbias, rgba);
       break;
    case PIPE_TEXTURE_3D:
       assert(sampler->normalized_coords);
-      sp_get_samples_3d(tgsi_sampler, s, t, p, lodbias, rgba);
+      sp_get_samples_3d(tgsi_sampler, s, t, p, computeLambda, lodbias, rgba);
       break;
    case PIPE_TEXTURE_CUBE:
       assert(sampler->normalized_coords);
-      sp_get_samples_cube(tgsi_sampler, s, t, p, lodbias, rgba);
+      sp_get_samples_cube(tgsi_sampler, s, t, p, computeLambda, lodbias, rgba);
       break;
    default:
       assert(0);
@@ -1185,3 +1196,34 @@ sp_get_samples(struct tgsi_sampler *tgsi_sampler,
 #endif
 }
 
+
+/**
+ * Called via tgsi_sampler::get_samples() when running a fragment shader.
+ * Get four filtered RGBA values from the sampler's texture.
+ */
+void
+sp_get_samples_fragment(struct tgsi_sampler *tgsi_sampler,
+                        const float s[QUAD_SIZE],
+                        const float t[QUAD_SIZE],
+                        const float p[QUAD_SIZE],
+                        float lodbias,
+                        float rgba[NUM_CHANNELS][QUAD_SIZE])
+{
+   sp_get_samples(tgsi_sampler, s, t, p, TRUE, lodbias, rgba);
+}
+
+
+/**
+ * Called via tgsi_sampler::get_samples() when running a vertex shader.
+ * Get four filtered RGBA values from the sampler's texture.
+ */
+void
+sp_get_samples_vertex(struct tgsi_sampler *tgsi_sampler,
+                      const float s[QUAD_SIZE],
+                      const float t[QUAD_SIZE],
+                      const float p[QUAD_SIZE],
+                      float lodbias,
+                      float rgba[NUM_CHANNELS][QUAD_SIZE])
+{
+   sp_get_samples(tgsi_sampler, s, t, p, FALSE, lodbias, rgba);
+}
index f0a8a7877825d14557f29458b748f0da975dfcdb..40d8eb2c2a89050cacb8f94e85f322ae14506a78 100644 (file)
@@ -54,12 +54,20 @@ sp_shader_sampler(const struct tgsi_sampler *sampler)
 
 
 extern void
-sp_get_samples(struct tgsi_sampler *sampler,
-               const float s[QUAD_SIZE],
-               const float t[QUAD_SIZE],
-               const float p[QUAD_SIZE],
-               float lodbias,
-               float rgba[NUM_CHANNELS][QUAD_SIZE]);
+sp_get_samples_fragment(struct tgsi_sampler *tgsi_sampler,
+                        const float s[QUAD_SIZE],
+                        const float t[QUAD_SIZE],
+                        const float p[QUAD_SIZE],
+                        float lodbias,
+                        float rgba[NUM_CHANNELS][QUAD_SIZE]);
+
+extern void
+sp_get_samples_vertex(struct tgsi_sampler *tgsi_sampler,
+                      const float s[QUAD_SIZE],
+                      const float t[QUAD_SIZE],
+                      const float p[QUAD_SIZE],
+                      float lodbias,
+                      float rgba[NUM_CHANNELS][QUAD_SIZE]);
 
 
 #endif /* SP_TEX_SAMPLE_H */