diff options
| author | Brian Paul <brianp@vmware.com> | 2009-02-09 09:22:22 -0700 | 
|---|---|---|
| committer | Brian Paul <brianp@vmware.com> | 2009-02-09 09:22:22 -0700 | 
| commit | e97681c7f551a2a2a6bd5eff0f4192a870c816c0 (patch) | |
| tree | dff2bf0e6d22efb92af131f64be0621ed316977c /src/gallium/state_trackers/python/tests | |
| parent | 1a46c8a062aea59de5cf55881104489db5d609e5 (diff) | |
| parent | b907d4cd8fafe719b4f87d877562829548937485 (diff) | |
mesa: merge gallium-0.2 into gallium-master-merge
Merge commit 'origin/gallium-0.2' into gallium-master-merge
Conflicts:
	Makefile
	docs/relnotes-7.4.html
	docs/relnotes.html
	src/mesa/drivers/dri/i965/brw_wm.h
	src/mesa/main/imports.c
	src/mesa/main/mtypes.h
	src/mesa/main/texcompress.c
	src/mesa/main/texenvprogram.c
	src/mesa/main/version.h
	src/mesa/vbo/vbo_exec_api.c
	src/mesa/vbo/vbo_save_draw.c
Diffstat (limited to 'src/gallium/state_trackers/python/tests')
| -rw-r--r-- | src/gallium/state_trackers/python/tests/base.py | 193 | ||||
| -rw-r--r-- | src/gallium/state_trackers/python/tests/texture.py | 397 | 
2 files changed, 590 insertions, 0 deletions
| diff --git a/src/gallium/state_trackers/python/tests/base.py b/src/gallium/state_trackers/python/tests/base.py new file mode 100644 index 0000000000..8477aa5fc9 --- /dev/null +++ b/src/gallium/state_trackers/python/tests/base.py @@ -0,0 +1,193 @@ +#!/usr/bin/env python +########################################################################## +#  +# Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. +# All Rights Reserved. +#  +# Permission is hereby granted, free of charge, to any person obtaining a +# copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sub license, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +#  +# The above copyright notice and this permission notice (including the +# next paragraph) shall be included in all copies or substantial portions +# of the Software. +#  +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. +# IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR +# ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +#  +########################################################################## + + +"""Base classes for tests. + +Loosely inspired on Python's unittest module. +""" + + +from gallium import * + + +# Enumerate all pixel formats +formats = {} +for name, value in globals().items(): +    if name.startswith("PIPE_FORMAT_") and isinstance(value, int): +        formats[value] = name + + +def make_image(width, height, rgba): +    import Image +    outimage = Image.new( +        mode='RGB', +        size=(width, height), +        color=(0,0,0)) +    outpixels = outimage.load() +    for y in range(0, height): +        for x in range(0, width): +            offset = (y*width + x)*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 + +def save_image(width, height, rgba, filename): +    outimage = make_image(width, height, rgba) +    outimage.save(filename, "PNG") + +def show_image(width, height, **rgbas): +    import Tkinter as tk +    from PIL import Image, ImageTk + +    root = tk.Tk() +     +    x = 64 +    y = 64 +     +    labels = rgbas.keys() +    labels.sort()  +    for i in range(len(labels)): +        label = labels[i] +        outimage = make_image(width, height, rgbas[label]) +         +        if i: +            window = tk.Toplevel(root) +        else: +            window = root     +        window.title(label) +        image1 = ImageTk.PhotoImage(outimage) +        w = image1.width() +        h = image1.height() +        window.geometry("%dx%d+%d+%d" % (w, h, x, y)) +        panel1 = tk.Label(window, image=image1) +        panel1.pack(side='top', fill='both', expand='yes') +        panel1.image = image1 +        x += w + 2 +     +    root.mainloop() + + +class TestFailure(Exception): + +    pass + +class TestSkip(Exception): +     +    pass + + +class Test: + +    def __init__(self): +        pass + +    def _run(self, result): +        raise NotImplementedError +     +    def run(self): +        result = TestResult() +        self._run(result) +        result.summary() + + +class TestCase(Test): +     +    def __init__(self, dev, **kargs): +        Test.__init__(self) +        self.dev = dev +        self.__dict__.update(kargs) + +    def description(self): +        raise NotImplementedError +         +    def test(self): +        raise NotImplementedError +     +    def _run(self, result): +        result.test_start(self) +        try: +            self.test() +        except KeyboardInterrupt: +            raise +        except TestSkip: +            result.test_skipped(self) +        except TestFailure: +            result.test_failed(self) +        else: +            result.test_passed(self) + + +class TestSuite(Test): +     +    def __init__(self, tests = None): +        Test.__init__(self) +        if tests is None: +            self.tests = [] +        else: +            self.tests = tests + +    def add_test(self, test): +        self.tests.append(test)  +     +    def _run(self, result): +        for test in self.tests: +            test._run(result) + + +class TestResult: +     +    def __init__(self): +        self.tests = 0 +        self.passed = 0 +        self.skipped = 0 +        self.failed = 0 +        self.failed_descriptions = [] +     +    def test_start(self, test): +        self.tests += 1 +        print "Running %s..." % test.description() +     +    def test_passed(self, test): +        self.passed += 1 +        print "PASS" +             +    def test_skipped(self, test): +        self.skipped += 1 +        print "SKIP" +         +    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 diff --git a/src/gallium/state_trackers/python/tests/texture.py b/src/gallium/state_trackers/python/tests/texture.py new file mode 100644 index 0000000000..880a61306c --- /dev/null +++ b/src/gallium/state_trackers/python/tests/texture.py @@ -0,0 +1,397 @@ +#!/usr/bin/env python +########################################################################## +#  +# Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. +# All Rights Reserved. +#  +# Permission is hereby granted, free of charge, to any person obtaining a +# copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sub license, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +#  +# The above copyright notice and this permission notice (including the +# next paragraph) shall be included in all copies or substantial portions +# of the Software. +#  +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. +# IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR +# ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +#  +########################################################################## + + +import sys +from gallium import * +from base import * + + +def lods(*dims): +    size = max(dims) +    lods = 0 +    while size: +        lods += 1 +        size >>= 1 +    return lods + + +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: +        depth = texture.get_depth(level) +        if depth > 1: +            r = float(zslice)/float(depth - 1) +        else: +            r = 0.0 +        return [[s, t, r] for s, t in st] +    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 + +def is_pot(n): +    return n & (n - 1) == 0 +       +                 +class TextureTest(TestCase): +     +    def description(self): +        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%ux%u last_level=%u face=%s level=%u zslice=%u" % ( +            target, format,  +            self.width, self.height, self.depth, self.last_level,  +            face, self.level, self.zslice,  +        ) +     +    def test(self): +        dev = self.dev +         +        target = self.target +        format = self.format +        width = self.width +        height = self.height +        depth = self.depth +        last_level = self.last_level +        face = self.face +        level = self.level +        zslice = self.zslice +         +        tex_usage = PIPE_TEXTURE_USAGE_SAMPLER +        geom_flags = 0 +        if width != height: +            geom_flags |= PIPE_TEXTURE_GEOM_NON_SQUARE +        if not is_pot(width) or not is_pot(height) or not is_pot(depth): +            geom_flags |= PIPE_TEXTURE_GEOM_NON_POWER_OF_TWO +         +        if not dev.is_format_supported(format, target, tex_usage, geom_flags): +            raise TestSkip +         +        ctx = self.dev.context_create() +     +        # disabled blending/masking +        blend = Blend() +        blend.rgb_src_factor = PIPE_BLENDFACTOR_ONE +        blend.alpha_src_factor = PIPE_BLENDFACTOR_ONE +        blend.rgb_dst_factor = PIPE_BLENDFACTOR_ZERO +        blend.alpha_dst_factor = PIPE_BLENDFACTOR_ZERO +        blend.colormask = PIPE_MASK_RGBA +        ctx.set_blend(blend) +     +        # no-op depth/stencil/alpha +        depth_stencil_alpha = DepthStencilAlpha() +        ctx.set_depth_stencil_alpha(depth_stencil_alpha) +     +        # rasterizer +        rasterizer = Rasterizer() +        rasterizer.front_winding = PIPE_WINDING_CW +        rasterizer.cull_mode = PIPE_WINDING_NONE +        rasterizer.bypass_clipping = 1 +        #rasterizer.bypass_vs = 1 +        ctx.set_rasterizer(rasterizer) +     +        # viewport (identity, we setup vertices in wincoords) +        viewport = Viewport() +        scale = FloatArray(4) +        scale[0] = 1.0 +        scale[1] = 1.0 +        scale[2] = 1.0 +        scale[3] = 1.0 +        viewport.scale = scale +        translate = FloatArray(4) +        translate[0] = 0.0 +        translate[1] = 0.0 +        translate[2] = 0.0 +        translate[3] = 0.0 +        viewport.translate = translate +        ctx.set_viewport(viewport) +     +        # samplers +        sampler = Sampler() +        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_NEAREST +        sampler.min_img_filter = PIPE_TEX_MIPFILTER_NEAREST +        sampler.mag_img_filter = PIPE_TEX_MIPFILTER_NEAREST +        sampler.normalized_coords = 1 +        sampler.min_lod = 0 +        sampler.max_lod = PIPE_MAX_TEXTURE_LEVELS - 1 +        ctx.set_sampler(0, sampler) +     +        #  texture  +        texture = dev.texture_create( +            target = target, +            format = format,  +            width = width,  +            height = height, +            depth = depth,  +            last_level = last_level, +            tex_usage = tex_usage, +        ) +         +        expected_rgba = FloatArray(height*width*4)  +        texture.get_surface( +            usage = PIPE_BUFFER_USAGE_CPU_READ|PIPE_BUFFER_USAGE_CPU_WRITE, +            face = face, +            level = level, +            zslice = zslice, +        ).sample_rgba(expected_rgba) +         +        ctx.set_sampler_texture(0, texture) + +        #  framebuffer  +        cbuf_tex = dev.texture_create( +            PIPE_FORMAT_A8R8G8B8_UNORM,  +            width,  +            height, +            tex_usage = PIPE_TEXTURE_USAGE_RENDER_TARGET, +        ) + +        cbuf = cbuf_tex.get_surface(usage = PIPE_BUFFER_USAGE_GPU_WRITE|PIPE_BUFFER_USAGE_GPU_READ) +        fb = Framebuffer() +        fb.width = width +        fb.height = height +        fb.num_cbufs = 1 +        fb.set_cbuf(0, cbuf) +        ctx.set_framebuffer(fb) +        ctx.surface_clear(cbuf, 0x00000000) +        del fb +     +        # vertex shader +        vs = Shader(''' +            VERT1.1 +            DCL IN[0], POSITION, CONSTANT +            DCL IN[1], GENERIC, CONSTANT +            DCL OUT[0], POSITION, CONSTANT +            DCL OUT[1], GENERIC, CONSTANT +            0:MOV OUT[0], IN[0] +            1:MOV OUT[1], IN[1] +            2:END +        ''') +        #vs.dump() +        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], LINEAR +            DCL OUT[0], COLOR, CONSTANT +            DCL SAMP[0], CONSTANT +            0:TEX OUT[0], IN[0], SAMP[0], %s +            1:END +        ''' % op) +        #fs.dump() +        ctx.set_fragment_shader(fs) + +        nverts = 4 +        nattrs = 2 +        verts = FloatArray(nverts * nattrs * 4) +     +        x = 0 +        y = 0 +        w, h = minify((width, height), level) +     +        pos = [ +            [x, y], +            [x+w, y], +            [x+w, y+h], +            [x, y+h], +        ] +     +        tex = tex_coords(texture, face, level, zslice) +     +        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,  +                          nattrs,  +                          verts) +     +        ctx.flush() +     +        cbuf = cbuf_tex.get_surface(usage = PIPE_BUFFER_USAGE_CPU_READ) +         +        total = h*w +        different = cbuf.compare_tile_rgba(x, y, w, h, expected_rgba, tol=4.0/256) +        if different: +            sys.stderr.write("%u out of %u pixels differ\n" % (different, total)) + +        if float(total - different)/float(total) < 0.85: +         +            if 0: +                rgba = FloatArray(h*w*4) +                cbuf.get_tile_rgba(x, y, w, h, rgba) +                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 + +        del ctx +         + + +def main(): +    dev = Device() +    suite = TestSuite() +     +    targets = [] +    targets += [PIPE_TEXTURE_2D] +    targets += [PIPE_TEXTURE_CUBE] +    targets += [PIPE_TEXTURE_3D] +     +    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, 1] +    #sizes = [1020, 508, 252, 62, 30, 14, 6, 3] +    #sizes = [64] +    #sizes = [63] +     +    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, +                    ] +                    #faces = [PIPE_TEX_FACE_NEG_X] +                else: +                    faces = [0] +                if target == PIPE_TEXTURE_3D: +                    depth = size +                else: +                    depth = 1 +                for face in faces: +                    levels = lods(size) +                    for last_level in range(levels): +                        for level in range(0, last_level + 1): +                            zslice = 0 +                            while zslice < depth >> level: +                                test = TextureTest( +                                    dev = dev, +                                    target = target, +                                    format = format,  +                                    width = size, +                                    height = size, +                                    depth = depth, +                                    last_level = last_level, +                                    face = face, +                                    level = level, +                                    zslice = zslice, +                                ) +                                suite.add_test(test) +                                zslice = (zslice + 1)*2 - 1 +    suite.run() + + +if __name__ == '__main__': +    main() | 
