python/tests: Extend the texture tests to cover cube maps.
authorJosé Fonseca <jrfonseca@tungstengraphics.com>
Wed, 16 Jul 2008 14:27:15 +0000 (23:27 +0900)
committerJosé Fonseca <jrfonseca@tungstengraphics.com>
Wed, 16 Jul 2008 14:27:15 +0000 (23:27 +0900)
src/gallium/state_trackers/python/tests/base.py
src/gallium/state_trackers/python/tests/texture.py

index c50abf7f69cefbfd676e5bbf4033d8e01bba4f01..8477aa5fc9b5a6c6d64319991ba040602cdf1458 100644 (file)
@@ -53,7 +53,7 @@ def make_image(width, height, rgba):
     for y in range(0, height):
         for x in range(0, width):
             offset = (y*width + x)*4
-            r, g, b, a = [int(rgba[offset + ch]*255) for ch in range(4)]
+            r, g, b, a = [int(min(max(rgba[offset + ch], 0.0), 1.0)*255) for ch in range(4)]
             outpixels[x, y] = r, g, b
     return outimage
 
@@ -167,6 +167,7 @@ class TestResult:
         self.passed = 0
         self.skipped = 0
         self.failed = 0
+        self.failed_descriptions = []
     
     def test_start(self, test):
         self.tests += 1
@@ -180,10 +181,13 @@ class TestResult:
         self.skipped += 1
         print "SKIP"
         
-    def test_failed(self):
+    def test_failed(self, test):
         self.failed += 1
+        self.failed_descriptions.append(test.description())
         print "FAIL"
 
     def summary(self):
         print "%u tests, %u passed, %u skipped, %u failed" % (self.tests, self.passed, self.skipped, self.failed)
+        for description in self.failed_descriptions:
+            print "  %s" % description
  
\ No newline at end of file
index 7c7245e65c6c52404b39760bfc07870c1b4561e3..448bdbcd3e28677444d7c98dad12f3093cd667f6 100644 (file)
@@ -33,10 +33,11 @@ from base import *
 from data import generate_data
 
 
-def compare_rgba(width, height, rgba1, rgba2, tol=4.0/256):
+def compare_rgba(width, height, rgba1, rgba2, tol=4.0/256, ratio=0.85):
     errors = 0
     for y in range(0, height):
         for x in range(0, width):
+            differs = 0
             for ch in range(4):
                 offset = (y*width + x)*4 + ch
                 v1 = rgba1[offset]
@@ -44,12 +45,14 @@ def compare_rgba(width, height, rgba1, rgba2, tol=4.0/256):
                 if abs(v1 - v2) > tol:
                     if errors == 0:
                         sys.stderr.write("x=%u, y=%u, ch=%u differ: %f vs %f\n" % (x, y, ch, v1, v2))
-                    if errors == 1:
+                    if errors == 1 and ch == 0:
                         sys.stderr.write("...\n")
-                    errors += 1
+                    differs = 1
+            errors += differs
+    total = height*width
     if errors:
-        sys.stderr.write("%u out of %u pixels differ\n" % (errors/4, height*width))
-    return errors == 0
+        sys.stderr.write("%u out of %u pixels differ\n" % (errors, total))
+    return float(total - errors)/float(total) >= ratio 
 
 
 def lods(*dims):
@@ -65,22 +68,87 @@ def minify(dims, level = 1):
     return [max(dim>>level, 1) for dim in dims]
 
 
+def tex_coords(texture, face, level, zslice):
+    st = [ 
+        [0.0, 0.0], 
+        [1.0, 0.0], 
+        [1.0, 1.0], 
+        [0.0, 1.0],
+    ] 
+    
+    if texture.target == PIPE_TEXTURE_2D:
+        return [[s, t, 0.0] for s, t in st]
+    elif texture.target == PIPE_TEXTURE_3D:
+        assert 0
+    elif texture.target == PIPE_TEXTURE_CUBE:
+        result = []
+        for s, t in st:
+            # See http://developer.nvidia.com/object/cube_map_ogl_tutorial.html
+            sc = 2.0*s - 1.0
+            tc = 2.0*t - 1.0
+            if face == PIPE_TEX_FACE_POS_X:
+                rx = 1.0
+                ry = -tc
+                rz = -sc
+            if face == PIPE_TEX_FACE_NEG_X:
+                rx = -1.0
+                ry = -tc
+                rz = sc
+            if face == PIPE_TEX_FACE_POS_Y:
+                rx = sc
+                ry = 1.0
+                rz = tc
+            if face == PIPE_TEX_FACE_NEG_Y:
+                rx = sc
+                ry = -1.0
+                rz = -tc
+            if face == PIPE_TEX_FACE_POS_Z:
+                rx = sc
+                ry = -tc
+                rz = 1.0
+            if face == PIPE_TEX_FACE_NEG_Z:
+                rx = -sc
+                ry = -tc
+                rz = -1.0
+            result.append([rx, ry, rz])
+        return result
+                    
+                
 class TextureTest(TestCase):
     
     def description(self):
-        return "%s %ux%u level=%u" % (formats[self.format], self.width, self.height, self.level)
+        target = {
+            PIPE_TEXTURE_1D: "1d", 
+            PIPE_TEXTURE_2D: "2d", 
+            PIPE_TEXTURE_3D: "3d", 
+            PIPE_TEXTURE_CUBE: "cube",
+        }[self.target]
+        format = formats[self.format]
+        if self.target == PIPE_TEXTURE_CUBE:
+            face = {
+                PIPE_TEX_FACE_POS_X: "+x",
+                PIPE_TEX_FACE_NEG_X: "-x",
+                PIPE_TEX_FACE_POS_Y: "+y",
+                PIPE_TEX_FACE_NEG_Y: "-y", 
+                PIPE_TEX_FACE_POS_Z: "+z", 
+                PIPE_TEX_FACE_NEG_Z: "-z",
+            }[self.face]
+        else:
+            face = ""
+        return "%s %s %ux%u %s level=%u" % (target, format, self.width, self.height, face, self.level)
     
     def test(self):
         dev = self.dev
         
+        target = self.target
         format = self.format
         width = self.width
         height = self.height
         level = self.level
+        face = self.face
         
         levels = lods(width, height)
 
-        
         if not dev.is_format_supported(format, PIPE_TEXTURE):
             raise TestSkip
         
@@ -128,23 +196,25 @@ class TextureTest(TestCase):
         sampler.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE
         sampler.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE
         sampler.wrap_r = PIPE_TEX_WRAP_CLAMP_TO_EDGE
-        sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NONE
+        sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NEAREST
         sampler.min_img_filter = PIPE_TEX_MIPFILTER_NEAREST
         sampler.mag_img_filter = PIPE_TEX_MIPFILTER_NEAREST
         sampler.normalized_coords = 1
-        sampler.min_lod = level
-        sampler.max_lod = level
+        sampler.min_lod = 0
+        sampler.max_lod = PIPE_MAX_TEXTURE_LEVELS - 1
         ctx.set_sampler(0, sampler)
     
         #  texture 
-        texture = dev.texture_create(format, 
-                                     width, 
-                                     height,
+        texture = dev.texture_create(target=target,
+                                     format=format, 
+                                     width=width, 
+                                     height=height,
                                      last_level = levels - 1)
         ctx.set_sampler_texture(0, texture)
         
         expected_rgba = generate_data(texture.get_surface(
             usage = PIPE_BUFFER_USAGE_CPU_READ|PIPE_BUFFER_USAGE_CPU_WRITE,
+            face = face,
             level = level))
         
         #  framebuffer 
@@ -178,14 +248,20 @@ class TextureTest(TestCase):
         ctx.set_vertex_shader(vs)
     
         # fragment shader
+        op = {
+            PIPE_TEXTURE_1D: "1D", 
+            PIPE_TEXTURE_2D: "2D", 
+            PIPE_TEXTURE_3D: "3D", 
+            PIPE_TEXTURE_CUBE: "CUBE",
+        }[target]
         fs = Shader('''
             FRAG1.1
-            DCL IN[0], GENERIC[0], PERSPECTIVE
+            DCL IN[0], GENERIC[0], LINEAR
             DCL OUT[0], COLOR, CONSTANT
             DCL SAMP[0], CONSTANT
-            0:TEX OUT[0], IN[0], SAMP[0], 2D
+            0:TEX OUT[0], IN[0], SAMP[0], %s
             1:END
-        ''')
+        ''' % op)
         #fs.dump()
         ctx.set_fragment_shader(fs)
 
@@ -197,38 +273,25 @@ class TextureTest(TestCase):
         y = 0
         w, h = minify((width, height), level)
     
-        verts[ 0] =     x # x1
-        verts[ 1] =     y # y1
-        verts[ 2] =   0.0 # z1
-        verts[ 3] =   1.0 # w1
-        verts[ 4] =   0.0 # s1
-        verts[ 5] =   0.0 # t
-        verts[ 6] =   0.0
-        verts[ 7] =   0.0
-        verts[ 8] = x + w # x2
-        verts[ 9] =     y # y2
-        verts[10] =   0.0 # z2
-        verts[11] =   1.0 # w2
-        verts[12] =   1.0 # s2
-        verts[13] =   0.0 # t2
-        verts[14] =   0.0
-        verts[15] =   0.0
-        verts[16] = x + w # x3
-        verts[17] = y + h # y3
-        verts[18] =   0.0 # z3
-        verts[19] =   1.0 # w3
-        verts[20] =   1.0 # s3
-        verts[21] =   1.0 # t3
-        verts[22] =   0.0
-        verts[23] =   0.0
-        verts[24] =     x # x4
-        verts[25] = y + h # y4
-        verts[26] =   0.0 # z4
-        verts[27] =   1.0 # w4
-        verts[28] =   0.0 # s4
-        verts[29] =   1.0 # t4
-        verts[30] =   0.0
-        verts[31] =   0.0
+        pos = [
+            [x, y],
+            [x+w, y],
+            [x+w, y+h],
+            [x, y+h],
+        ]
+    
+        tex = tex_coords(texture, face, level, zslice=0)
+    
+        for i in range(0, 4):
+            j = 8*i
+            verts[j + 0] = pos[i][0] # x
+            verts[j + 1] = pos[i][1] # y
+            verts[j + 2] = 0.0 # z
+            verts[j + 3] = 1.0 # w
+            verts[j + 4] = tex[i][0] # s
+            verts[j + 5] = tex[i][1] # r
+            verts[j + 6] = tex[i][2] # q
+            verts[j + 7] = 1.0
     
         ctx.draw_vertices(PIPE_PRIM_TRIANGLE_FAN,
                           nverts, 
@@ -243,10 +306,10 @@ class TextureTest(TestCase):
 
         if not compare_rgba(w, h, rgba, expected_rgba):
         
-            show_image(w, h, Result=rgba, Expected=expected_rgba)
-            #save_image(width, height, rgba, "result.png")
-            #save_image(width, height, expected_rgba, "expected.png")
-            sys.exit(0)
+            #show_image(w, h, Result=rgba, Expected=expected_rgba)
+            #save_image(w, h, rgba, "result.png")
+            #save_image(w, h, expected_rgba, "expected.png")
+            #sys.exit(0)
             
             raise TestFailure
 
@@ -257,14 +320,48 @@ class TextureTest(TestCase):
 def main():
     dev = Device()
     suite = TestSuite()
-    formats = [PIPE_FORMAT_A8R8G8B8_UNORM, PIPE_FORMAT_YCBCR, PIPE_FORMAT_DXT1_RGB]
-    #formats = [PIPE_FORMAT_A8R8G8B8_UNORM, PIPE_FORMAT_DXT1_RGB]
+    
+    targets = []
+    targets += [PIPE_TEXTURE_2D]
+    targets += [PIPE_TEXTURE_CUBE]
+    
+    formats = []
+    formats += [PIPE_FORMAT_A8R8G8B8_UNORM]
+    formats += [PIPE_FORMAT_R5G6B5_UNORM]
+    formats += [PIPE_FORMAT_L8_UNORM]
+    formats += [PIPE_FORMAT_YCBCR]
+    formats += [PIPE_FORMAT_DXT1_RGB]
+    
     sizes = [64, 32, 16, 8, 4, 2]
-    for format in formats:
-        for size in sizes:
-            levels = lods(size)
-            for level in range(levels):
-                suite.add_test(TextureTest(dev=dev, format=format, width=size, height=size, level=level))
+    #sizes = [16]
+    
+    for target in targets:
+        for format in formats:
+            for size in sizes:
+                if target == PIPE_TEXTURE_CUBE:
+                    faces = [
+                        PIPE_TEX_FACE_POS_X,
+                        PIPE_TEX_FACE_NEG_X,
+                        PIPE_TEX_FACE_POS_Y,
+                        PIPE_TEX_FACE_NEG_Y, 
+                        PIPE_TEX_FACE_POS_Z, 
+                        PIPE_TEX_FACE_NEG_Z,
+                    ]
+                else:
+                    faces = [0]
+                for face in faces:
+                    levels = lods(size)
+                    for level in range(levels):
+                        test = TextureTest(
+                            dev=dev,
+                            target=target,
+                            format=format, 
+                            width=size,
+                            height=size,
+                            face=face,
+                            level=level,
+                        )
+                        suite.add_test(test)
     suite.run()