Merge branch 'softpipe-opt'
authorKeith Whitwell <keithw@vmware.com>
Wed, 23 Sep 2009 16:37:28 +0000 (17:37 +0100)
committerKeith Whitwell <keithw@vmware.com>
Wed, 23 Sep 2009 16:37:28 +0000 (17:37 +0100)
Conflicts:
progs/demos/cubemap.c
src/gallium/drivers/softpipe/sp_tex_sample.c
src/gallium/drivers/softpipe/sp_texture.c

1  2 
progs/demos/cubemap.c
src/gallium/auxiliary/util/u_math.h
src/gallium/drivers/softpipe/sp_context.c
src/gallium/drivers/softpipe/sp_state_derived.c
src/gallium/drivers/softpipe/sp_tex_sample.c
src/gallium/drivers/softpipe/sp_texture.c
src/gallium/drivers/softpipe/sp_texture.h
src/gallium/winsys/xlib/xlib_softpipe.c
src/mesa/swrast/s_texfilter.c

@@@ -56,9 -53,8 +56,11 @@@ static GLint FrameParity = 0
  static GLenum FilterIndex = 0;
  static GLint ClampIndex = 0;
  static GLboolean supportFBO = GL_FALSE;
 +static GLboolean supportSeamless = GL_FALSE;
 +static GLboolean seamless = GL_FALSE;
 +static GLuint TexObj = 0;
+ static GLint T0 = 0;
+ static GLint Frames = 0;
  
  
  static struct {
@@@ -283,7 -273,16 +283,15 @@@ util_fast_pow(float x, float y
     return util_fast_exp2(util_fast_log2(x) * y);
  }
  
+ /* Note that this counts zero as a power of two.
+  */
+ static INLINE boolean
+ util_is_power_of_two( unsigned v )
+ {
+    return (v & (v-1)) == 0;
+ }
  
 -
  /**
   * Floor(x), returned as int.
   */
@@@ -824,129 -1493,111 +1493,111 @@@ sample_compare(struct tgsi_sampler *tgs
     }
  }
  
- /**
-  * Common code for sampling 1D/2D/cube textures.
-  * Could probably extend for 3D...
+ /* Calculate cube faces.
   */
  static void
- 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])
+ sample_cube(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])
  {
-    const struct sp_shader_sampler *samp = sp_shader_sampler(tgsi_sampler);
-    const struct softpipe_context *sp = samp->sp;
-    const uint unit = samp->unit;
-    const struct pipe_texture *texture = sp->texture[unit];
-    const struct pipe_sampler_state *sampler = sp->sampler[unit];
-    unsigned level0, level1, j, imgFilter;
-    int width, height;
-    float levelBlend;
-    choose_mipmap_levels(texture, sampler, s, t, p, computeLambda, lodbias,
-                         &level0, &level1, &levelBlend, &imgFilter);
+    struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler);
+    unsigned j;
+    float ssss[4], tttt[4];
  
-    assert(sampler->normalized_coords);
+    /*
+      major axis
+      direction     target                             sc     tc    ma
+      ----------    -------------------------------    ---    ---   ---
+      +rx          TEXTURE_CUBE_MAP_POSITIVE_X_EXT    -rz    -ry   rx
+      -rx          TEXTURE_CUBE_MAP_NEGATIVE_X_EXT    +rz    -ry   rx
+      +ry          TEXTURE_CUBE_MAP_POSITIVE_Y_EXT    +rx    +rz   ry
+      -ry          TEXTURE_CUBE_MAP_NEGATIVE_Y_EXT    +rx    -rz   ry
+      +rz          TEXTURE_CUBE_MAP_POSITIVE_Z_EXT    +rx    -ry   rz
+      -rz          TEXTURE_CUBE_MAP_NEGATIVE_Z_EXT    -rx    -ry   rz
+    */
+    for (j = 0; j < QUAD_SIZE; j++) {
+       float rx = s[j];
+       float ry = t[j];
+       float rz = p[j];
+       const float arx = fabsf(rx), ary = fabsf(ry), arz = fabsf(rz);
+       unsigned face;
+       float sc, tc, ma;
 -      if (arx > ary && arx > arz) {
++      if (arx >= ary && arx >= arz) {
+          if (rx >= 0.0F) {
+             face = PIPE_TEX_FACE_POS_X;
+             sc = -rz;
+             tc = -ry;
+             ma = arx;
+          }
+          else {
+             face = PIPE_TEX_FACE_NEG_X;
+             sc = rz;
+             tc = -ry;
+             ma = arx;
+          }
+       }
 -      else if (ary > arx && ary > arz) {
++      else if (ary >= arx && ary >= arz) {
+          if (ry >= 0.0F) {
+             face = PIPE_TEX_FACE_POS_Y;
+             sc = rx;
+             tc = rz;
+             ma = ary;
+          }
+          else {
+             face = PIPE_TEX_FACE_NEG_Y;
+             sc = rx;
+             tc = -rz;
+             ma = ary;
+          }
+       }
+       else {
+          if (rz > 0.0F) {
+             face = PIPE_TEX_FACE_POS_Z;
+             sc = rx;
+             tc = -ry;
+             ma = arz;
+          }
+          else {
+             face = PIPE_TEX_FACE_NEG_Z;
+             sc = -rx;
+             tc = -ry;
+             ma = arz;
+          }
+       }
  
-    width = texture->width[level0];
-    height = texture->height[level0];
+       {
+        const float ima = 1.0 / ma;
+        ssss[j] = ( sc * ima + 1.0F ) * 0.5F;
+        tttt[j] = ( tc * ima + 1.0F ) * 0.5F;
+        samp->faces[j] = face;
+       }
+    }
  
-    assert(width > 0);
+    /* In our little pipeline, the compare stage is next.  If compare
+     * is not active, this will point somewhere deeper into the
+     * pipeline, eg. to mip_filter or even img_filter.
+     */
+    samp->compare(tgsi_sampler, ssss, tttt, NULL, lodbias, rgba);
+ }
  
-    switch (imgFilter) {
-    case PIPE_TEX_FILTER_NEAREST:
-       {
-          int x[4], y[4];
-          nearest_texcoord_4(sampler->wrap_s, s, width, x);
-          nearest_texcoord_4(sampler->wrap_t, t, height, y);
-          for (j = 0; j < QUAD_SIZE; j++) {
-             get_texel(tgsi_sampler, faces[j], level0, x[j], y[j], 0, rgba, j);
-             if (sampler->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE) {
-                shadow_compare(sampler, rgba, p, j);
-             }
  
-             if (level0 != level1) {
-                /* get texels from second mipmap level and blend */
-                float rgba2[4][4];
-                unsigned c;
-                x[j] /= 2;
-                y[j] /= 2;
-                get_texel(tgsi_sampler, faces[j], level1, x[j], y[j], 0,
-                          rgba2, j);
-                if (sampler->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE){
-                   shadow_compare(sampler, rgba2, p, j);
-                }
-                for (c = 0; c < NUM_CHANNELS; c++) {
-                   rgba[c][j] = lerp(levelBlend, rgba[c][j], rgba2[c][j]);
-                }
-             }
-          }
-       }
-       break;
-    case PIPE_TEX_FILTER_LINEAR:
-    case PIPE_TEX_FILTER_ANISO:
-       {
-          int x0[4], y0[4], x1[4], y1[4];
-          float xw[4], yw[4]; /* weights */
-          linear_texcoord_4(sampler->wrap_s, s, width, x0, x1, xw);
-          linear_texcoord_4(sampler->wrap_t, t, height, y0, y1, yw);
-          for (j = 0; j < QUAD_SIZE; j++) {
-             float tx[4][4]; /* texels */
-             int c;
-             get_texel(tgsi_sampler, faces[j], level0, x0[j], y0[j], 0, tx, 0);
-             get_texel(tgsi_sampler, faces[j], level0, x1[j], y0[j], 0, tx, 1);
-             get_texel(tgsi_sampler, faces[j], level0, x0[j], y1[j], 0, tx, 2);
-             get_texel(tgsi_sampler, faces[j], level0, x1[j], y1[j], 0, tx, 3);
-             if (sampler->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE) {
-                shadow_compare4(sampler, tx, p);
-             }
  
-             /* interpolate R, G, B, A */
-             for (c = 0; c < 4; c++) {
-                rgba[c][j] = lerp_2d(xw[j], yw[j],
-                                     tx[c][0], tx[c][1],
-                                     tx[c][2], tx[c][3]);
-             }
  
-             if (level0 != level1) {
-                /* get texels from second mipmap level and blend */
-                float rgba2[4][4];
-                x0[j] /= 2;
-                y0[j] /= 2;
-                x1[j] /= 2;
-                y1[j] /= 2;
-                get_texel(tgsi_sampler, faces[j], level1, x0[j], y0[j], 0, tx, 0);
-                get_texel(tgsi_sampler, faces[j], level1, x1[j], y0[j], 0, tx, 1);
-                get_texel(tgsi_sampler, faces[j], level1, x0[j], y1[j], 0, tx, 2);
-                get_texel(tgsi_sampler, faces[j], level1, x1[j], y1[j], 0, tx, 3);
-                if (sampler->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE){
-                   shadow_compare4(sampler, tx, p);
-                }
-                /* interpolate R, G, B, A */
-                for (c = 0; c < 4; c++) {
-                   rgba2[c][j] = lerp_2d(xw[j], yw[j],
-                                         tx[c][0], tx[c][1], tx[c][2], tx[c][3]);
-                }
-                for (c = 0; c < NUM_CHANNELS; c++) {
-                   rgba[c][j] = lerp(levelBlend, rgba[c][j], rgba2[c][j]);
-                }
-             }
-          }
-       }
-       break;
+ static wrap_nearest_func get_nearest_unorm_wrap( unsigned mode )
+ {
+    switch (mode) {
+    case PIPE_TEX_WRAP_CLAMP:
+       return wrap_nearest_unorm_clamp;
+    case PIPE_TEX_WRAP_CLAMP_TO_EDGE:
+    case PIPE_TEX_WRAP_CLAMP_TO_BORDER:
+       return wrap_nearest_unorm_clamp_to_border;
     default:
        assert(0);
+       return wrap_nearest_unorm_clamp;
     }
  }
  
@@@ -111,9 -115,12 +111,9 @@@ softpipe_displaytarget_layout(struct pi
  }
  
  
 -
 -
 -
  static struct pipe_texture *
  softpipe_texture_create(struct pipe_screen *screen,
-                         const struct pipe_texture *templat)
+                         const struct pipe_texture *template)
  {
     struct softpipe_texture *spt = CALLOC_STRUCT(softpipe_texture);
     if (!spt)
     pipe_reference_init(&spt->base.reference, 1);
     spt->base.screen = screen;
  
 -   if (spt->base.tex_usage & PIPE_TEXTURE_USAGE_DISPLAY_TARGET) {
+    spt->pot = (util_is_power_of_two(template->width[0]) &&
+                util_is_power_of_two(template->height[0]) &&
+                util_is_power_of_two(template->depth[0]));
 +   if (spt->base.tex_usage & (PIPE_TEXTURE_USAGE_DISPLAY_TARGET |
 +                              PIPE_TEXTURE_USAGE_PRIMARY)) {
        if (!softpipe_displaytarget_layout(screen, spt))
           goto fail;
     }
@@@ -363,11 -381,12 +374,11 @@@ softpipe_transfer_unmap(struct pipe_scr
     spt = softpipe_texture(transfer->texture);
  
     pipe_buffer_unmap( screen, spt->buffer );
 -}
 -
  
 -void
 -softpipe_init_texture_funcs(struct softpipe_context *sp)
 -{
 +   if (transfer->usage != PIPE_TRANSFER_READ) {
 +      /* Mark the texture as dirty to expire the tile caches. */
-       spt->modified = TRUE;
++      spt->timestamp++;
 +   }
  }
  
  
Simple merge