Cache the i915 sampler state.
authorZack Rusin <zack@tungstengraphics.com>
Thu, 20 Sep 2007 16:34:31 +0000 (12:34 -0400)
committerZack Rusin <zack@tungstengraphics.com>
Thu, 20 Sep 2007 16:34:31 +0000 (12:34 -0400)
src/mesa/pipe/i915simple/i915_context.h
src/mesa/pipe/i915simple/i915_state.c
src/mesa/pipe/i915simple/i915_state_sampler.c

index c582b069d791571a83fe31477758226da95ebe51..f1e10f34332664aaaadadf583938927c9884121a 100644 (file)
@@ -141,6 +141,11 @@ struct i915_rasterizer_state {
    union { float f; unsigned u; } ds[2];
 };
 
+struct i915_sampler_state {
+   unsigned state[3];
+   const struct pipe_sampler_state *templ;
+};
+
 struct i915_context
 {
    struct pipe_context pipe; 
@@ -150,7 +155,7 @@ struct i915_context
    /* The most recent drawing state as set by the driver:
     */
    const struct i915_blend_state           *blend;
-   const struct pipe_sampler_state *sampler[PIPE_MAX_SAMPLERS];
+   const struct i915_sampler_state         *sampler[PIPE_MAX_SAMPLERS];
    const struct i915_depth_stencil_state   *depth_stencil;
    const struct i915_rasterizer_state      *rasterizer;
    const struct pipe_shader_state *fs;
index c7086c17f5af3de2291d0bc0cfae5d8c03e12730..525f8ce13a26659b087e9da5a40804e59715ba2d 100644 (file)
 #include "i915_state.h"
 #include "i915_state_inlines.h"
 
-/* None of this state is actually used for anything yet.
+
+/* The i915 (and related graphics cores) do not support GL_CLAMP.  The
+ * Intel drivers for "other operating systems" implement GL_CLAMP as
+ * GL_CLAMP_TO_EDGE, so the same is done here.
  */
+static unsigned
+translate_wrap_mode(unsigned wrap)
+{
+   switch (wrap) {
+   case PIPE_TEX_WRAP_REPEAT:
+      return TEXCOORDMODE_WRAP;
+   case PIPE_TEX_WRAP_CLAMP:
+      return TEXCOORDMODE_CLAMP_EDGE;   /* not quite correct */
+   case PIPE_TEX_WRAP_CLAMP_TO_EDGE:
+      return TEXCOORDMODE_CLAMP_EDGE;
+   case PIPE_TEX_WRAP_CLAMP_TO_BORDER:
+      return TEXCOORDMODE_CLAMP_BORDER;
+//   case PIPE_TEX_WRAP_MIRRORED_REPEAT:
+//      return TEXCOORDMODE_MIRROR;
+   default:
+      return TEXCOORDMODE_WRAP;
+   }
+}
 
+static unsigned translate_img_filter( unsigned filter )
+{
+   switch (filter) {
+   case PIPE_TEX_FILTER_NEAREST:
+      return FILTER_NEAREST;
+   case PIPE_TEX_FILTER_LINEAR:
+      return FILTER_LINEAR;
+   default:
+      assert(0);
+      return FILTER_NEAREST;
+   }
+}
+
+static unsigned translate_mip_filter( unsigned filter )
+{
+   switch (filter) {
+   case PIPE_TEX_MIPFILTER_NONE:
+      return MIPFILTER_NONE;
+   case PIPE_TEX_MIPFILTER_NEAREST:
+      return MIPFILTER_NEAREST;
+   case PIPE_TEX_FILTER_LINEAR:
+      return MIPFILTER_LINEAR;
+   default:
+      assert(0);
+      return MIPFILTER_NONE;
+   }
+}
+
+static unsigned translate_compare_func(unsigned func)
+{
+   switch (func) {
+   case PIPE_FUNC_NEVER:
+   case PIPE_FUNC_LESS:
+   case PIPE_FUNC_EQUAL:
+   case PIPE_FUNC_LEQUAL:
+   case PIPE_FUNC_GREATER:
+   case PIPE_FUNC_NOTEQUAL:
+   case PIPE_FUNC_GEQUAL:
+   case PIPE_FUNC_ALWAYS:
+      return 0;
+   default:
+      assert(0);
+      return 0;
+   }
+}
+
+
+/* None of this state is actually used for anything yet.
+ */
 static void *
 i915_create_blend_state(struct pipe_context *pipe,
                         const struct pipe_blend_state *blend)
@@ -147,7 +217,59 @@ static void *
 i915_create_sampler_state(struct pipe_context *pipe,
                           const struct pipe_sampler_state *sampler)
 {
-   return 0;
+   struct i915_sampler_state *cso = calloc(1, sizeof(struct i915_sampler_state));
+   cso->templ = sampler;
+
+   const unsigned ws = sampler->wrap_s;
+   const unsigned wt = sampler->wrap_t;
+   const unsigned wr = sampler->wrap_r;
+   unsigned minFilt, magFilt;
+   unsigned mipFilt;
+
+   mipFilt = translate_mip_filter(sampler->min_mip_filter);
+   if (sampler->max_anisotropy > 1.0) {
+      minFilt = FILTER_ANISOTROPIC;
+      magFilt = FILTER_ANISOTROPIC;
+   }
+   else {
+      minFilt = translate_img_filter( sampler->min_img_filter );
+      magFilt = translate_img_filter( sampler->mag_img_filter );
+   }
+
+   {
+      int b = sampler->lod_bias * 16.0;
+      b = CLAMP(b, -256, 255);
+      cso->state[0] |= ((b << SS2_LOD_BIAS_SHIFT) & SS2_LOD_BIAS_MASK);
+   }
+
+   /* Shadow:
+    */
+   if (sampler->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE) 
+   {
+      cso->state[0] |= (SS2_SHADOW_ENABLE |
+                        translate_compare_func(sampler->compare_func));
+
+      minFilt = FILTER_4X4_FLAT;
+      magFilt = FILTER_4X4_FLAT;
+   }
+
+   cso->state[0] |= ((minFilt << SS2_MIN_FILTER_SHIFT) |
+                     (mipFilt << SS2_MIP_FILTER_SHIFT) |
+                     (magFilt << SS2_MAG_FILTER_SHIFT));
+
+   cso->state[1] |=
+      ((translate_wrap_mode(ws) << SS3_TCX_ADDR_MODE_SHIFT) |
+       (translate_wrap_mode(wt) << SS3_TCY_ADDR_MODE_SHIFT) |
+       (translate_wrap_mode(wr) << SS3_TCZ_ADDR_MODE_SHIFT));
+
+   {
+      ubyte r = float_to_ubyte(sampler->border_color[0]);
+      ubyte g = float_to_ubyte(sampler->border_color[1]);
+      ubyte b = float_to_ubyte(sampler->border_color[2]);
+      ubyte a = float_to_ubyte(sampler->border_color[3]);
+      cso->state[2] = I915PACKCOLOR8888(r, g, b, a);
+   }
+   return cso;
 }
 
 static void i915_bind_sampler_state(struct pipe_context *pipe,
@@ -156,7 +278,7 @@ static void i915_bind_sampler_state(struct pipe_context *pipe,
    struct i915_context *i915 = i915_context(pipe);
 
    assert(unit < PIPE_MAX_SAMPLERS);
-   i915->sampler[unit] = (const struct pipe_sampler_state *)sampler;
+   i915->sampler[unit] = (const struct i915_sampler_state*)sampler;
 
    i915->dirty |= I915_NEW_SAMPLER;
 }
@@ -164,6 +286,7 @@ static void i915_bind_sampler_state(struct pipe_context *pipe,
 static void i915_delete_sampler_state(struct pipe_context *pipe,
                                       void *sampler)
 {
+   free(sampler);
 }
 
 
index 419a156136c2dde2f2d182d8bacb5e17653d0f7c..ebfd29fadb37f95e1ae6f7c9d71a4a22600c326e 100644 (file)
 #include "i915_state.h"
 //#include "i915_cache.h"
 
-
-
-
-
-
-/* The i915 (and related graphics cores) do not support GL_CLAMP.  The
- * Intel drivers for "other operating systems" implement GL_CLAMP as
- * GL_CLAMP_TO_EDGE, so the same is done here.
- */
-static unsigned
-translate_wrap_mode(unsigned wrap)
-{
-   switch (wrap) {
-   case PIPE_TEX_WRAP_REPEAT:
-      return TEXCOORDMODE_WRAP;
-   case PIPE_TEX_WRAP_CLAMP:
-      return TEXCOORDMODE_CLAMP_EDGE;   /* not quite correct */
-   case PIPE_TEX_WRAP_CLAMP_TO_EDGE:
-      return TEXCOORDMODE_CLAMP_EDGE;
-   case PIPE_TEX_WRAP_CLAMP_TO_BORDER:
-      return TEXCOORDMODE_CLAMP_BORDER;
-//   case PIPE_TEX_WRAP_MIRRORED_REPEAT:
-//      return TEXCOORDMODE_MIRROR;
-   default:
-      return TEXCOORDMODE_WRAP;
-   }
-}
-
-static unsigned translate_img_filter( unsigned filter )
-{
-   switch (filter) {
-   case PIPE_TEX_FILTER_NEAREST:
-      return FILTER_NEAREST;
-   case PIPE_TEX_FILTER_LINEAR:
-      return FILTER_LINEAR;
-   default:
-      assert(0);
-      return FILTER_NEAREST;
-   }
-}
-
-static unsigned translate_mip_filter( unsigned filter )
-{
-   switch (filter) {
-   case PIPE_TEX_MIPFILTER_NONE:
-      return MIPFILTER_NONE;
-   case PIPE_TEX_MIPFILTER_NEAREST:
-      return MIPFILTER_NEAREST;
-   case PIPE_TEX_FILTER_LINEAR:
-      return MIPFILTER_LINEAR;
-   default:
-      assert(0);
-      return MIPFILTER_NONE;
-   }
-}
-
-static unsigned translate_compare_func(unsigned func)
-{
-   switch (func) {
-   case PIPE_FUNC_NEVER:
-   case PIPE_FUNC_LESS:
-   case PIPE_FUNC_EQUAL:
-   case PIPE_FUNC_LEQUAL:
-   case PIPE_FUNC_GREATER:
-   case PIPE_FUNC_NOTEQUAL:
-   case PIPE_FUNC_GEQUAL:
-   case PIPE_FUNC_ALWAYS:
-      return 0;
-   default:
-      assert(0);
-      return 0;
-   }
-}
-
-
 static uint
 bitcount(uint k)
 {
@@ -153,60 +78,21 @@ is_power_of_two_texture(const struct pipe_mipmap_tree *mt)
  */
 static void update_sampler(struct i915_context *i915,
                            uint unit,
-                          const struct pipe_sampler_state *sampler,
+                          const struct i915_sampler_state *sampler,
                           const struct pipe_mipmap_tree *mt,
                           unsigned state[3] )
 {
-   const unsigned ws = sampler->wrap_s;
-   const unsigned wt = sampler->wrap_t;
-   const unsigned wr = sampler->wrap_r;
-
    /* Need to do this after updating the maps, which call the
     * intel_finalize_mipmap_tree and hence can update firstLevel:
     */
-   unsigned minFilt, magFilt;
-   unsigned mipFilt;
-
-   state[0] = state[1] = state[2] = 0;
-
-   mipFilt = translate_mip_filter( sampler->min_mip_filter );
-
-   if (sampler->max_anisotropy > 1.0) {
-      minFilt = FILTER_ANISOTROPIC;
-      magFilt = FILTER_ANISOTROPIC;
-   }
-   else {
-      minFilt = translate_img_filter( sampler->min_img_filter );
-      magFilt = translate_img_filter( sampler->mag_img_filter );
-   }
-
-   {
-      int b = sampler->lod_bias * 16.0;
-      b = CLAMP(b, -256, 255);
-      state[0] |= ((b << SS2_LOD_BIAS_SHIFT) & SS2_LOD_BIAS_MASK);
-   }
+   state[0] = sampler->state[0];
+   state[1] = sampler->state[1];
+   state[2] = sampler->state[2];
 
    if (mt->format == PIPE_FORMAT_YCBCR ||
        mt->format == PIPE_FORMAT_YCBCR_REV)
       state[0] |= SS2_COLORSPACE_CONVERSION;
 
-
-   /* Shadow:
-    */
-   if (sampler->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE) 
-   {
-      state[0] |= (SS2_SHADOW_ENABLE |
-                  translate_compare_func(sampler->compare_func));
-
-      minFilt = FILTER_4X4_FLAT;
-      magFilt = FILTER_4X4_FLAT;
-   }
-
-   state[0] |= ((minFilt << SS2_MIN_FILTER_SHIFT) |
-               (mipFilt << SS2_MIP_FILTER_SHIFT) |
-               (magFilt << SS2_MAG_FILTER_SHIFT));
-
-   
    /* 3D textures don't seem to respect the border color.
     * Fallback if there's ever a danger that they might refer to
     * it.  
@@ -217,45 +103,36 @@ static void update_sampler(struct i915_context *i915,
     * XXX: Check if this is true on i945.  
     * XXX: Check if this bug got fixed in release silicon.
     */
-   if (mt->target == PIPE_TEXTURE_3D &&
-       (sampler->min_img_filter != PIPE_TEX_FILTER_NEAREST ||
-        sampler->mag_img_filter != PIPE_TEX_FILTER_NEAREST) &&
-       (ws == PIPE_TEX_WRAP_CLAMP ||
-        wt == PIPE_TEX_WRAP_CLAMP ||
-        wr == PIPE_TEX_WRAP_CLAMP ||
-        ws == PIPE_TEX_WRAP_CLAMP_TO_BORDER ||
-        wt == PIPE_TEX_WRAP_CLAMP_TO_BORDER || 
-        wr == PIPE_TEX_WRAP_CLAMP_TO_BORDER)) {
 #if 0
-      if (i915->strict_conformance) {
-         assert(0);
-         /*        sampler->fallback = true; */
-         /* TODO */
+   {
+      const unsigned ws = sampler->templ->wrap_s;
+      const unsigned wt = sampler->templ->wrap_t;
+      const unsigned wr = sampler->templ->wrap_r;
+      if (mt->target == PIPE_TEXTURE_3D &&
+          (sampler->templ->min_img_filter != PIPE_TEX_FILTER_NEAREST ||
+           sampler->templ->mag_img_filter != PIPE_TEX_FILTER_NEAREST) &&
+          (ws == PIPE_TEX_WRAP_CLAMP ||
+           wt == PIPE_TEX_WRAP_CLAMP ||
+           wr == PIPE_TEX_WRAP_CLAMP ||
+           ws == PIPE_TEX_WRAP_CLAMP_TO_BORDER ||
+           wt == PIPE_TEX_WRAP_CLAMP_TO_BORDER || 
+           wr == PIPE_TEX_WRAP_CLAMP_TO_BORDER)) {
+         if (i915->strict_conformance) {
+            assert(0);
+            /*             sampler->fallback = true; */
+            /* TODO */
+         }
       }
-#endif
    }
+#endif
 
-   state[1] =
-      ((translate_wrap_mode(ws) << SS3_TCX_ADDR_MODE_SHIFT) |
-       (translate_wrap_mode(wt) << SS3_TCY_ADDR_MODE_SHIFT) |
-       (translate_wrap_mode(wr) << SS3_TCZ_ADDR_MODE_SHIFT) |
-       (unit << SS3_TEXTUREMAP_INDEX_SHIFT));
+   state[1] |= (unit << SS3_TEXTUREMAP_INDEX_SHIFT);
 
    if (is_power_of_two_texture(mt)) {
       state[1] |= SS3_NORMALIZED_COORDS;
    }
-
-   {
-      ubyte r = float_to_ubyte(sampler->border_color[0]);
-      ubyte g = float_to_ubyte(sampler->border_color[1]);
-      ubyte b = float_to_ubyte(sampler->border_color[2]);
-      ubyte a = float_to_ubyte(sampler->border_color[3]);
-      state[2] = I915PACKCOLOR8888(r, g, b, a);
-   }
 }
 
-
-
 void i915_update_samplers( struct i915_context *i915 )
 {
    uint unit;