st/mesa: attempt to fix TFP by using sampler views (v1)
authorDave Airlie <airlied@redhat.com>
Sat, 24 Apr 2010 08:53:55 +0000 (18:53 +1000)
committerDave Airlie <airlied@redhat.com>
Tue, 8 Jun 2010 09:08:36 +0000 (19:08 +1000)
Okay I think this is good enough for now, I can't see any other reason
for mesa to want to use a sampler view so lets just leave it at all the A->X conversions for now.

I've been running gnome-shell under r300g with this for day or so and it seems fine.

Signed-off-by: Dave Airlie <airlied@redhat.com>
src/mesa/state_tracker/st_atom_texture.c
src/mesa/state_tracker/st_cb_texture.c
src/mesa/state_tracker/st_format.c
src/mesa/state_tracker/st_format.h
src/mesa/state_tracker/st_manager.c

index 65b57f15911d36f86b0b5859eee8b3e40b6c7138..895681cb230cfa26e84d8ddd502401bb3b96526a 100644 (file)
@@ -38,6 +38,7 @@
 #include "st_context.h"
 #include "st_atom.h"
 #include "st_texture.h"
+#include "st_format.h"
 #include "st_cb_texture.h"
 #include "pipe/p_context.h"
 #include "util/u_inlines.h"
@@ -56,14 +57,15 @@ static boolean check_sampler_swizzle(struct pipe_sampler_view *sv,
 
 static INLINE struct pipe_sampler_view *
 st_create_texture_sampler_view_from_stobj(struct pipe_context *pipe,
-                                         struct st_texture_object *stObj)
+                                         struct st_texture_object *stObj,
+                                         enum pipe_format format)
                                          
 {
    struct pipe_sampler_view templ;
 
    u_sampler_view_default_template(&templ,
                                    stObj->pt,
-                                   stObj->pt->format);
+                                   format);
 
    if (stObj->base._Swizzle != SWIZZLE_NOOP) {
       templ.swizzle_r = GET_SWZ(stObj->base._Swizzle, 0);
@@ -78,7 +80,8 @@ st_create_texture_sampler_view_from_stobj(struct pipe_context *pipe,
 
 static INLINE struct pipe_sampler_view *
 st_get_texture_sampler_view_from_stobj(struct st_texture_object *stObj,
-                                      struct pipe_context *pipe)
+                                      struct pipe_context *pipe,
+                                      enum pipe_format format)
 
 {
    if (!stObj || !stObj->pt) {
@@ -86,7 +89,7 @@ st_get_texture_sampler_view_from_stobj(struct st_texture_object *stObj,
    }
 
    if (!stObj->sampler_view) {
-      stObj->sampler_view = st_create_texture_sampler_view_from_stobj(pipe, stObj);
+      stObj->sampler_view = st_create_texture_sampler_view_from_stobj(pipe, stObj, format);
    }
 
    return stObj->sampler_view;
@@ -107,7 +110,7 @@ update_textures(struct st_context *st)
    /* 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;
@@ -132,14 +135,25 @@ update_textures(struct st_context *st)
             continue;
          }
 
+        st_view_format = stObj->pt->format;
+        {
+           struct st_texture_image *firstImage;
+           enum pipe_format firstImageFormat;
+           firstImage = st_texture_image(stObj->base.Image[0][stObj->base.BaseLevel]);
+
+           firstImageFormat = st_mesa_format_to_pipe_format(firstImage->base.TexFormat);
+           if (firstImageFormat != stObj->pt->format)
+              st_view_format = firstImageFormat;
+
+        }
          st->state.num_textures = su + 1;
 
         /* if sampler view has changed dereference it */
         if (stObj->sampler_view)
-           if (check_sampler_swizzle(stObj->sampler_view, stObj->base._Swizzle))
+           if (check_sampler_swizzle(stObj->sampler_view, stObj->base._Swizzle) || (st_view_format != stObj->sampler_view->format))
               pipe_sampler_view_reference(&stObj->sampler_view, NULL);
 
-         sampler_view = st_get_texture_sampler_view_from_stobj(stObj, pipe);
+         sampler_view = st_get_texture_sampler_view_from_stobj(stObj, pipe, st_view_format);
       }
       pipe_sampler_view_reference(&st->state.sampler_views[su], sampler_view);
    }
index 647898ef7c9a1c840f914799f35ecf6fe944197a..2101b9bc18d5e5712fc0ef7b8ca784d84cc14fd5 100644 (file)
@@ -1850,7 +1850,7 @@ st_finalize_texture(GLcontext *ctx,
     */
    if (stObj->pt) {
       if (stObj->pt->target != gl_target_to_pipe(stObj->base.Target) ||
-          stObj->pt->format != firstImageFormat ||
+          !st_sampler_compat_formats(stObj->pt->format, firstImageFormat) ||
           stObj->pt->last_level < stObj->lastLevel ||
           stObj->pt->width0 != stObj->width0 ||
           stObj->pt->height0 != stObj->height0 ||
index f7b10ea243aadad645552263bee2f130f2763be9..c9fa7a62e19131ce820c1bf8db840f20b047ea84 100644 (file)
@@ -767,3 +767,36 @@ st_equal_formats(enum pipe_format pFormat, GLenum format, GLenum type)
       return GL_FALSE;
    }
 }
+
+GLboolean
+st_sampler_compat_formats(enum pipe_format format1, enum pipe_format format2)
+{
+   if (format1 == format2)
+      return GL_TRUE;
+
+   if (format1 == PIPE_FORMAT_B8G8R8A8_UNORM &&
+       format2 == PIPE_FORMAT_B8G8R8X8_UNORM)
+      return GL_TRUE;
+
+   if (format1 == PIPE_FORMAT_B8G8R8X8_UNORM &&
+       format2 == PIPE_FORMAT_B8G8R8A8_UNORM)
+      return GL_TRUE;
+
+   if (format1 == PIPE_FORMAT_A8B8G8R8_UNORM &&
+       format2 == PIPE_FORMAT_X8B8G8R8_UNORM)
+      return GL_TRUE;
+
+   if (format1 == PIPE_FORMAT_X8B8G8R8_UNORM &&
+       format2 == PIPE_FORMAT_A8B8G8R8_UNORM)
+      return GL_TRUE;
+
+   if (format1 == PIPE_FORMAT_A8R8G8B8_UNORM &&
+       format2 == PIPE_FORMAT_X8R8G8B8_UNORM)
+      return GL_TRUE;
+
+   if (format1 == PIPE_FORMAT_X8R8G8B8_UNORM &&
+       format2 == PIPE_FORMAT_A8R8G8B8_UNORM)
+      return GL_TRUE;
+
+   return GL_FALSE;
+}
index 3288225d5d40c1b9673e5a544e411515a850b5c4..29768f296d6867def0a3897f32ad09cb62bde658 100644 (file)
@@ -62,5 +62,9 @@ st_ChooseTextureFormat(GLcontext * ctx, GLint internalFormat,
 extern GLboolean
 st_equal_formats(enum pipe_format pFormat, GLenum format, GLenum type);
 
+/* can we use a sampler view to translate these formats
+   only used to make TFP so far */
+extern GLboolean
+st_sampler_compat_formats(enum pipe_format format1, enum pipe_format format2);
 
 #endif /* ST_FORMAT_H */
index 8c3dfb3f71f46308d1f774836bfc53b479775d7b..ccfb1f4a5204773d9741e555bf77ea90c116118e 100644 (file)
@@ -550,12 +550,14 @@ st_context_teximage(struct st_context_iface *stctxi, enum st_texture_type target
        * To avoid that, internal_format is (wrongly) ignored here.  A sane fix
        * is to use a sampler view.
        */
-      if (util_format_get_component_bits(tex->format,
+      if (!st_sampler_compat_formats(tex->format, internal_format))
+        internal_format = tex->format;
+     
+      if (util_format_get_component_bits(internal_format,
                UTIL_FORMAT_COLORSPACE_RGB, 3) > 0)
          internalFormat = GL_RGBA;
       else
          internalFormat = GL_RGB;
-
       _mesa_init_teximage_fields(ctx, target, texImage,
             tex->width0, tex->height0, 1, 0, internalFormat);
       texImage->TexFormat = st_ChooseTextureFormat(ctx, internalFormat,