st/mesa: overhaul vertex/fragment sampler and sampler views.
authorDave Airlie <airlied@redhat.com>
Sat, 14 May 2011 08:04:08 +0000 (18:04 +1000)
committerDave Airlie <airlied@redhat.com>
Sun, 15 May 2011 20:40:26 +0000 (06:40 +1000)
This fixes piglits fragment-and-vertex-texturing test on llvmpipe for me.

I've no idea if someone had another plan for this that is smarter than what
I've done here, but what I've basically done is

split fragment and vertex sampler and sampler_view setup function, factor
out the common chunks of both.

side-cleanups:
drop st->state.sampler_list - unused
don't update border color if we have no border color.

should fix https://bugs.freedesktop.org/show_bug.cgi?id=35849

Signed-off-by: Dave Airlie <airlied@redhat.com>
Reviewed-by: Brian Paul <brianp@vmware.com>
src/mesa/state_tracker/st_atom_sampler.c
src/mesa/state_tracker/st_atom_texture.c
src/mesa/state_tracker/st_context.c
src/mesa/state_tracker/st_context.h

index e3d6cbb..ccbd548 100644 (file)
@@ -120,14 +120,110 @@ gl_filter_to_img_filter(GLenum filter)
    }
 }
 
+static void convert_sampler(struct st_context *st,
+                           struct pipe_sampler_state *sampler,
+                           GLuint texUnit)
+{
+    struct gl_texture_object *texobj;
+    struct gl_sampler_object *msamp;
+
+    texobj = st->ctx->Texture.Unit[texUnit]._Current;
+    if (!texobj) {
+       texobj = st_get_default_texture(st);
+    }
+
+    msamp = _mesa_get_samplerobj(st->ctx, texUnit);
+    sampler->wrap_s = gl_wrap_xlate(msamp->WrapS);
+    sampler->wrap_t = gl_wrap_xlate(msamp->WrapT);
+    sampler->wrap_r = gl_wrap_xlate(msamp->WrapR);
+
+    sampler->min_img_filter = gl_filter_to_img_filter(msamp->MinFilter);
+    sampler->min_mip_filter = gl_filter_to_mip_filter(msamp->MinFilter);
+    sampler->mag_img_filter = gl_filter_to_img_filter(msamp->MagFilter);
+
+    if (texobj->Target != GL_TEXTURE_RECTANGLE_ARB)
+       sampler->normalized_coords = 1;
+
+    sampler->lod_bias = st->ctx->Texture.Unit[texUnit].LodBias +
+       msamp->LodBias;
+
+    sampler->min_lod = CLAMP(msamp->MinLod,
+                            0.0f,
+                            (GLfloat) texobj->MaxLevel - texobj->BaseLevel);
+    sampler->max_lod = MIN2((GLfloat) texobj->MaxLevel - texobj->BaseLevel,
+                           msamp->MaxLod);
+    if (sampler->max_lod < sampler->min_lod) {
+       /* The GL spec doesn't seem to specify what to do in this case.
+       * Swap the values.
+       */
+       float tmp = sampler->max_lod;
+       sampler->max_lod = sampler->min_lod;
+       sampler->min_lod = tmp;
+       assert(sampler->min_lod <= sampler->max_lod);
+    }
+
+    if (msamp->BorderColor.ui[0] ||
+       msamp->BorderColor.ui[1] ||
+       msamp->BorderColor.ui[2] ||
+       msamp->BorderColor.ui[3]) {
+       struct gl_texture_image *teximg;
+
+       teximg = texobj->Image[0][texobj->BaseLevel];
+
+       st_translate_color(msamp->BorderColor.f,
+                         teximg ? teximg->_BaseFormat : GL_RGBA,
+                         sampler->border_color);
+    }
+
+    sampler->max_anisotropy = (msamp->MaxAnisotropy == 1.0 ?
+                              0 : (GLuint) msamp->MaxAnisotropy);
+
+    /* only care about ARB_shadow, not SGI shadow */
+    if (msamp->CompareMode == GL_COMPARE_R_TO_TEXTURE) {
+       sampler->compare_mode = PIPE_TEX_COMPARE_R_TO_TEXTURE;
+       sampler->compare_func
+         = st_compare_func_to_pipe(msamp->CompareFunc);
+    }
+
+    sampler->seamless_cube_map =
+       st->ctx->Texture.CubeMapSeamless || msamp->CubeMapSeamless;
+}
 
-static void 
-update_samplers(struct st_context *st)
+static void
+update_vertex_samplers(struct st_context *st)
 {
    struct gl_vertex_program *vprog = st->ctx->VertexProgram._Current;
+   GLuint su;
+
+   st->state.num_vertex_samplers = 0;
+
+   /* loop over sampler units (aka tex image units) */
+   for (su = 0; su < st->ctx->Const.MaxVertexTextureImageUnits; su++) {
+      struct pipe_sampler_state *sampler = st->state.vertex_samplers + su;
+
+      memset(sampler, 0, sizeof(*sampler));
+
+      if (vprog->Base.SamplersUsed & (1 << su)) {
+        GLuint texUnit;
+
+        texUnit = vprog->Base.SamplerUnits[su];
+
+        convert_sampler(st, sampler, texUnit);
+
+        st->state.num_vertex_samplers = su + 1;
+
+        cso_single_vertex_sampler(st->cso_context, su, sampler);
+      } else {
+        cso_single_vertex_sampler(st->cso_context, su, NULL);
+      }
+   }
+   cso_single_vertex_sampler_done(st->cso_context);
+}
+
+static void
+update_fragment_samplers(struct st_context *st)
+{
    struct gl_fragment_program *fprog = st->ctx->FragmentProgram._Current;
-   const GLbitfield samplersUsed = (vprog->Base.SamplersUsed |
-                                    fprog->Base.SamplersUsed);
    GLuint su;
 
    st->state.num_samplers = 0;
@@ -138,95 +234,33 @@ update_samplers(struct st_context *st)
 
       memset(sampler, 0, sizeof(*sampler));
 
-      if (samplersUsed & (1 << su)) {
-         struct gl_texture_object *texobj;
-         struct gl_texture_image *teximg;
-         struct gl_sampler_object *msamp;
+      if (fprog->Base.SamplersUsed & (1 << su)) {
          GLuint texUnit;
 
-         if (fprog->Base.SamplersUsed & (1 << su))
-            texUnit = fprog->Base.SamplerUnits[su];
-         else
-            texUnit = vprog->Base.SamplerUnits[su];
-
-         texobj = st->ctx->Texture.Unit[texUnit]._Current;
-         if (!texobj) {
-            texobj = st_get_default_texture(st);
-         }
-
-         teximg = texobj->Image[0][texobj->BaseLevel];
-
-         msamp = _mesa_get_samplerobj(st->ctx, texUnit);
-
-         sampler->wrap_s = gl_wrap_xlate(msamp->WrapS);
-         sampler->wrap_t = gl_wrap_xlate(msamp->WrapT);
-         sampler->wrap_r = gl_wrap_xlate(msamp->WrapR);
-
-         sampler->min_img_filter = gl_filter_to_img_filter(msamp->MinFilter);
-         sampler->min_mip_filter = gl_filter_to_mip_filter(msamp->MinFilter);
-         sampler->mag_img_filter = gl_filter_to_img_filter(msamp->MagFilter);
-
-         if (texobj->Target != GL_TEXTURE_RECTANGLE_ARB)
-            sampler->normalized_coords = 1;
-
-         sampler->lod_bias = st->ctx->Texture.Unit[texUnit].LodBias +
-            msamp->LodBias;
-
-         sampler->min_lod = CLAMP(msamp->MinLod,
-                                  0.0f,
-                                  (GLfloat) texobj->MaxLevel - texobj->BaseLevel);
-         sampler->max_lod = MIN2((GLfloat) texobj->MaxLevel - texobj->BaseLevel,
-                                 msamp->MaxLod);
-         if (sampler->max_lod < sampler->min_lod) {
-            /* The GL spec doesn't seem to specify what to do in this case.
-             * Swap the values.
-             */
-            float tmp = sampler->max_lod;
-            sampler->max_lod = sampler->min_lod;
-            sampler->min_lod = tmp;
-            assert(sampler->min_lod <= sampler->max_lod);
-         }
-
-         st_translate_color(msamp->BorderColor.f,
-                            teximg ? teximg->_BaseFormat : GL_RGBA,
-                            sampler->border_color);
-
-        sampler->max_anisotropy = (msamp->MaxAnisotropy == 1.0 ?
-                                    0 : (GLuint) msamp->MaxAnisotropy);
-
-         /* only care about ARB_shadow, not SGI shadow */
-         if (msamp->CompareMode == GL_COMPARE_R_TO_TEXTURE) {
-            sampler->compare_mode = PIPE_TEX_COMPARE_R_TO_TEXTURE;
-            sampler->compare_func
-               = st_compare_func_to_pipe(msamp->CompareFunc);
-         }
-
-         sampler->seamless_cube_map =
-               st->ctx->Texture.CubeMapSeamless || msamp->CubeMapSeamless;
+        texUnit = fprog->Base.SamplerUnits[su];
+
+        convert_sampler(st, sampler, texUnit);
 
          st->state.num_samplers = su + 1;
 
          /*printf("%s su=%u non-null\n", __FUNCTION__, su);*/
          cso_single_sampler(st->cso_context, su, sampler);
-         if (su < st->ctx->Const.MaxVertexTextureImageUnits) {
-            cso_single_vertex_sampler(st->cso_context, su, sampler);
-         }
       }
       else {
          /*printf("%s su=%u null\n", __FUNCTION__, su);*/
          cso_single_sampler(st->cso_context, su, NULL);
-         if (su < st->ctx->Const.MaxVertexTextureImageUnits) {
-            cso_single_vertex_sampler(st->cso_context, su, NULL);
-         }
       }
    }
 
    cso_single_sampler_done(st->cso_context);
-   if (st->ctx->Const.MaxVertexTextureImageUnits > 0) {
-      cso_single_vertex_sampler_done(st->cso_context);
-   }
 }
 
+static void
+update_samplers(struct st_context *st)
+{
+    update_fragment_samplers(st);
+    update_vertex_samplers(st);
+}
 
 const struct st_tracked_state st_update_sampler = {
    "st_update_sampler",                                        /* name */
index 9d437ad..990b504 100644 (file)
@@ -182,90 +182,132 @@ st_get_texture_sampler_view_from_stobj(struct st_texture_object *stObj,
    return stObj->sampler_view;
 }
 
+static GLboolean
+update_single_texture(struct st_context *st, struct pipe_sampler_view **sampler_view,
+                     GLuint texUnit)
+{
+   struct pipe_context *pipe = st->pipe;
+   const struct gl_sampler_object *samp;
+   struct gl_texture_object *texObj;
+   struct st_texture_object *stObj;
+   enum pipe_format st_view_format;
+   GLboolean retval;
+
+   samp = _mesa_get_samplerobj(st->ctx, texUnit);
+
+   texObj = st->ctx->Texture.Unit[texUnit]._Current;
+
+   if (!texObj) {
+      texObj = st_get_default_texture(st);
+      samp = &texObj->Sampler;
+   }
+   stObj = st_texture_object(texObj);
+
+   retval = st_finalize_texture(st->ctx, st->pipe, texObj);
+   if (!retval) {
+      /* out of mem */
+      return GL_FALSE;
+   }
+
+   /* Determine the format of the texture sampler view */
+   st_view_format = stObj->pt->format;
+   {
+      const struct st_texture_image *firstImage =
+        st_texture_image(stObj->base.Image[0][stObj->base.BaseLevel]);
+      const gl_format texFormat = firstImage->base.TexFormat;
+      enum pipe_format firstImageFormat =
+        st_mesa_format_to_pipe_format(texFormat);
+
+      if ((samp->sRGBDecode == GL_SKIP_DECODE_EXT) &&
+         (_mesa_get_format_color_encoding(texFormat) == GL_SRGB)) {
+        /* don't do sRGB->RGB conversion.  Interpret the texture
+         * texture data as linear values.
+         */
+        const gl_format linearFormat =
+           _mesa_get_srgb_format_linear(texFormat);
+        firstImageFormat = st_mesa_format_to_pipe_format(linearFormat);
+      }
+
+      if (firstImageFormat != stObj->pt->format)
+        st_view_format = firstImageFormat;
+   }
+
+
+   /* if sampler view has changed dereference it */
+   if (stObj->sampler_view) {
+      if (check_sampler_swizzle(stObj->sampler_view,
+                               stObj->base._Swizzle,
+                               samp->DepthMode) ||
+         (st_view_format != stObj->sampler_view->format) ||
+         stObj->base.BaseLevel != stObj->sampler_view->u.tex.first_level) {
+        pipe_sampler_view_reference(&stObj->sampler_view, NULL);
+      }
+   }
+
+   *sampler_view = st_get_texture_sampler_view_from_stobj(stObj, pipe,
+                                                         samp,
+                                                         st_view_format);
+   return GL_TRUE;
+}
 
 static void 
-update_textures(struct st_context *st)
+update_vertex_textures(struct st_context *st)
 {
-   struct pipe_context *pipe = st->pipe;
    struct gl_vertex_program *vprog = st->ctx->VertexProgram._Current;
-   struct gl_fragment_program *fprog = st->ctx->FragmentProgram._Current;
-   const GLbitfield samplersUsed = (vprog->Base.SamplersUsed |
-                                    fprog->Base.SamplersUsed);
    GLuint su;
 
-   st->state.num_textures = 0;
+   st->state.num_vertex_textures = 0;
 
    /* loop over sampler units (aka tex image units) */
    for (su = 0; su < st->ctx->Const.MaxTextureImageUnits; su++) {
       struct pipe_sampler_view *sampler_view = NULL;
-      enum pipe_format st_view_format;
-      if (samplersUsed & (1 << su)) {
-         struct gl_texture_object *texObj;
-         struct st_texture_object *stObj;
+      if (vprog->Base.SamplersUsed & (1 << su)) {
          GLboolean retval;
          GLuint texUnit;
-         const struct gl_sampler_object *samp;
 
-         if (fprog->Base.SamplersUsed & (1 << su))
-            texUnit = fprog->Base.SamplerUnits[su];
-         else
-            texUnit = vprog->Base.SamplerUnits[su];
+        texUnit = vprog->Base.SamplerUnits[su];
 
-         samp = _mesa_get_samplerobj(st->ctx, texUnit);
+        retval = update_single_texture(st, &sampler_view, texUnit);
+        if (retval == GL_FALSE)
+           continue;
 
-         texObj = st->ctx->Texture.Unit[texUnit]._Current;
+        st->state.num_vertex_textures = su + 1;
 
-         if (!texObj) {
-            texObj = st_get_default_texture(st);
-            samp = &texObj->Sampler;
-         }
-         stObj = st_texture_object(texObj);
+      }
+      pipe_sampler_view_reference(&st->state.sampler_vertex_views[su], sampler_view);
+   }
 
-         retval = st_finalize_texture(st->ctx, st->pipe, texObj);
-         if (!retval) {
-            /* out of mem */
-            continue;
-         }
+   if (st->ctx->Const.MaxVertexTextureImageUnits > 0) {
+      GLuint numUnits = MIN2(st->state.num_vertex_textures,
+                             st->ctx->Const.MaxVertexTextureImageUnits);
+      cso_set_vertex_sampler_views(st->cso_context,
+                                   numUnits,
+                                   st->state.sampler_vertex_views);
+   }
+}
 
-         /* Determine the format of the texture sampler view */
-        st_view_format = stObj->pt->format;
-        {
-           const struct st_texture_image *firstImage =
-               st_texture_image(stObj->base.Image[0][stObj->base.BaseLevel]);
-            const gl_format texFormat = firstImage->base.TexFormat;
-           enum pipe_format firstImageFormat =
-               st_mesa_format_to_pipe_format(texFormat);
-
-           if ((samp->sRGBDecode == GL_SKIP_DECODE_EXT) &&
-                (_mesa_get_format_color_encoding(texFormat) == GL_SRGB)) {
-               /* don't do sRGB->RGB conversion.  Interpret the texture
-                * texture data as linear values.
-                */
-               const gl_format linearFormat =
-                  _mesa_get_srgb_format_linear(texFormat);
-              firstImageFormat = st_mesa_format_to_pipe_format(linearFormat);
-           }
-
-           if (firstImageFormat != stObj->pt->format)
-              st_view_format = firstImageFormat;
-        }
+static void 
+update_fragment_textures(struct st_context *st)
+{
+   struct gl_fragment_program *fprog = st->ctx->FragmentProgram._Current;
+   GLuint su;
 
-         st->state.num_textures = su + 1;
+   st->state.num_textures = 0;
 
-        /* if sampler view has changed dereference it */
-        if (stObj->sampler_view) {
-            if (check_sampler_swizzle(stObj->sampler_view,
-                                      stObj->base._Swizzle,
-                                      samp->DepthMode) ||
-                (st_view_format != stObj->sampler_view->format) ||
-                stObj->base.BaseLevel != stObj->sampler_view->u.tex.first_level) {
-              pipe_sampler_view_reference(&stObj->sampler_view, NULL);
-            }
-         }
+   /* loop over sampler units (aka tex image units) */
+   for (su = 0; su < st->ctx->Const.MaxTextureImageUnits; su++) {
+      struct pipe_sampler_view *sampler_view = NULL;
+      if (fprog->Base.SamplersUsed & (1 << su)) {
+         GLboolean retval;
+         GLuint texUnit;
+
+        texUnit = fprog->Base.SamplerUnits[su];
 
-         sampler_view = st_get_texture_sampler_view_from_stobj(stObj, pipe,
-                                                               samp,
-                                                               st_view_format);
+        retval = update_single_texture(st, &sampler_view, texUnit);
+        if (retval == GL_FALSE)
+           continue;
+
+         st->state.num_textures = su + 1;
       }
       pipe_sampler_view_reference(&st->state.sampler_views[su], sampler_view);
    }
@@ -273,16 +315,14 @@ update_textures(struct st_context *st)
    cso_set_fragment_sampler_views(st->cso_context,
                                   st->state.num_textures,
                                   st->state.sampler_views);
-
-   if (st->ctx->Const.MaxVertexTextureImageUnits > 0) {
-      GLuint numUnits = MIN2(st->state.num_textures,
-                             st->ctx->Const.MaxVertexTextureImageUnits);
-      cso_set_vertex_sampler_views(st->cso_context,
-                                   numUnits,
-                                   st->state.sampler_views);
-   }
 }
 
+static void 
+update_textures(struct st_context *st)
+{
+  update_fragment_textures(st);
+  update_vertex_textures(st);
+}
 
 const struct st_tracked_state st_update_texture = {
    "st_update_texture",                                        /* name */
@@ -293,9 +333,6 @@ const struct st_tracked_state st_update_texture = {
    update_textures                                     /* update */
 };
 
-
-
-
 static void 
 finalize_textures(struct st_context *st)
 {
index ce78956..6eddbfc 100644 (file)
@@ -133,9 +133,6 @@ st_create_context_priv( struct gl_context *ctx, struct pipe_context *pipe )
    else
       st->internal_target = PIPE_TEXTURE_RECT;
 
-   for (i = 0; i < PIPE_MAX_SAMPLERS; i++)
-      st->state.sampler_list[i] = &st->state.samplers[i];
-
    for (i = 0; i < 3; i++) {
       memset(&st->velems_util_draw[i], 0, sizeof(struct pipe_vertex_element));
       st->velems_util_draw[i].src_offset = i * 4 * sizeof(float);
index 1fc9c10..c6fc318 100644 (file)
@@ -90,7 +90,7 @@ struct st_context
       struct pipe_depth_stencil_alpha_state depth_stencil;
       struct pipe_rasterizer_state          rasterizer;
       struct pipe_sampler_state             samplers[PIPE_MAX_SAMPLERS];
-      struct pipe_sampler_state             *sampler_list[PIPE_MAX_SAMPLERS];
+      struct pipe_sampler_state             vertex_samplers[PIPE_MAX_VERTEX_SAMPLERS];
       struct pipe_clip_state clip;
       struct {
          void *ptr;
@@ -98,12 +98,15 @@ struct st_context
       } constants[PIPE_SHADER_TYPES];
       struct pipe_framebuffer_state framebuffer;
       struct pipe_sampler_view *sampler_views[PIPE_MAX_SAMPLERS];
+      struct pipe_sampler_view *sampler_vertex_views[PIPE_MAX_VERTEX_SAMPLERS];
       struct pipe_scissor_state scissor;
       struct pipe_viewport_state viewport;
       unsigned sample_mask;
 
       GLuint num_samplers;
+      GLuint num_vertex_samplers;
       GLuint num_textures;
+      GLuint num_vertex_textures;
 
       GLuint poly_stipple[32];  /**< In OpenGL's bottom-to-top order */
    } state;