u_gen_mipmap: Use untampered cubemap texture coords when generating mipmaps.
authorJosé Fonseca <jfonseca@vmware.com>
Tue, 19 Nov 2013 18:54:53 +0000 (18:54 +0000)
committerJosé Fonseca <jfonseca@vmware.com>
Wed, 20 Nov 2013 07:12:59 +0000 (07:12 +0000)
It's not necessary to scale down cubemap texture coords when generating
mipmaps: we are doing a 2x minification therefore it's guaranteed that
the texture coords will always be at least 1 texel away of the edges.

Scaling down can actually be harmful, as it may cause artefacts when
generating mipmaps with nearest filtering.  Sample points will lie
exactly in the middle each 2x2 texels, so the scaling factor was causing
different texels to be take on each quadrant of the cube face.  This is
apparent with a 1x1 checkerboard pattern in the base mipmap level:
instead of next mipmap level receiving a constant color throughout the
face, it will have different colors for each quadrant of the face.

The behaviour for blits is left untouched for now, but the cubemap
texture coord scaling hack should be reconsidered eventually.

Reviewed-by: Brian Paul <brianp@vmware.com>
src/gallium/auxiliary/util/u_blit.c
src/gallium/auxiliary/util/u_blitter.c
src/gallium/auxiliary/util/u_gen_mipmap.c
src/gallium/auxiliary/util/u_texture.c
src/gallium/auxiliary/util/u_texture.h

index 4ba71b9290190f5e906ec64518cef8b01bc4948f..595287d3b81663d2e9e3596c9589b291a22d7462 100644 (file)
@@ -272,7 +272,8 @@ setup_vertex_data_tex(struct blit_state *ctx,
       const unsigned stride = sizeof ctx->vertices[0] / sizeof ctx->vertices[0][0][0];
       util_map_texcoords2d_onto_cubemap(src_face,
                                         &ctx->vertices[0][1][0], stride,
-                                        &ctx->vertices[0][1][0], stride);
+                                        &ctx->vertices[0][1][0], stride,
+                                        TRUE);
    }
 
    offset = get_next_slot( ctx );
index 096d3bc2b98845b22a3493fc5ae45a02fbda4cd2..b95cbab126f06151b8e6bf8dfc59d4a6868733e7 100644 (file)
@@ -659,7 +659,8 @@ static void blitter_set_texcoords(struct blitter_context_priv *ctx,
       util_map_texcoords2d_onto_cubemap(layer % 6,
                                         /* pointer, stride in floats */
                                         &face_coord[0][0], 2,
-                                        &ctx->vertices[0][1][0], 8);
+                                        &ctx->vertices[0][1][0], 8,
+                                        TRUE);
    } else {
       set_texcoords_in_vertices(coord, &ctx->vertices[0][1][0], 8);
    }
index a885f2b0f28883b36dc9c56404a149fd9311fd55..84bf30f08b01b5ea872a251328d223fb27833729 100644 (file)
@@ -1409,7 +1409,8 @@ set_vertex_data(struct gen_mipmap_state *ctx,
       };
 
       util_map_texcoords2d_onto_cubemap(layer, &st[0][0], 2,
-                                        &ctx->vertices[0][1][0], 8);
+                                        &ctx->vertices[0][1][0], 8,
+                                        FALSE);
    }
    else if (tex_target == PIPE_TEXTURE_1D_ARRAY) {
       /* 1D texture array  */
index d97e57a7903b320bd53f35b65773576cf1bfd697..e865f8e73d08fe967393bf302d32e10bda646a1f 100644 (file)
@@ -42,7 +42,8 @@
 
 void util_map_texcoords2d_onto_cubemap(unsigned face,
                                        const float *in_st, unsigned in_stride,
-                                       float *out_str, unsigned out_stride)
+                                       float *out_str, unsigned out_stride,
+                                       boolean allow_scale)
 {
    int i;
    float rx, ry, rz;
@@ -52,8 +53,14 @@ void util_map_texcoords2d_onto_cubemap(unsigned face,
       /* Compute sc = +/-scale and tc = +/-scale.
        * Not +/-1 to avoid cube face selection ambiguity near the edges,
        * though that can still sometimes happen with this scale factor...
+       *
+       * XXX: Yep, there is no safe scale factor that will prevent sampling
+       * the neighbouring face when stretching out.  A more reliable solution
+       * would be to clamp (sc, tc) against +/- 1.0-1.0/mipsize, in the shader.
+       *
+       * Also, this is not necessary when minifying, or 1:1 blits.
        */
-      const float scale = 0.9999f;
+      const float scale = allow_scale ? 0.9999f : 1.0f;
       const float sc = (2 * in_st[0] - 1) * scale;
       const float tc = (2 * in_st[1] - 1) * scale;
 
index 93b2f1e4c9722ccec8f850d63d6808c67ffe242f..b1c8c709146f3250e22517464964b95e859ef448 100644 (file)
@@ -27,6 +27,8 @@
 #ifndef U_TEXTURE_H
 #define U_TEXTURE_H
 
+#include "pipe/p_compiler.h"
+
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -44,7 +46,8 @@ extern "C" {
  */
 void util_map_texcoords2d_onto_cubemap(unsigned face,
                                        const float *in_st, unsigned in_stride,
-                                       float *out_str, unsigned out_stride);
+                                       float *out_str, unsigned out_stride,
+                                       boolean allow_scale);
 
 
 #ifdef __cplusplus