diff options
Diffstat (limited to 'src/gallium/state_trackers/python')
24 files changed, 4648 insertions, 0 deletions
| diff --git a/src/gallium/state_trackers/python/README b/src/gallium/state_trackers/python/README new file mode 100644 index 0000000000..8f45fb6d1b --- /dev/null +++ b/src/gallium/state_trackers/python/README @@ -0,0 +1,33 @@ +This directory contains Python bindings to Gallium3D. It looks like a state +tracker from the pipe driver perspective, and it looks like a pipe driver from +the python script perspective. + + +To build you'll need: +* Python (with development packages) +* SCons +* SWIG +* Python Imaging Library with TK support (for the samples) + +Invoke scons on the top dir as +  + scons statetrackers=python + +To use do + + export PYTHONPATH=build/XXXX-XXXX-XXXX/gallium/state_trackers/python + +and then try running + +  python src/gallium/state_trackers/python/samples/tri.py + +which should show a triangle. + + +This is still work in progress: +- errors are not handled properly and almost always result in crash +- state atoms with array members are awkward to set +- there no efficient way to view images + +-- +Jose Fonseca <jrfonseca@tungstengraphics.com> diff --git a/src/gallium/state_trackers/python/SConscript b/src/gallium/state_trackers/python/SConscript new file mode 100644 index 0000000000..1581182aec --- /dev/null +++ b/src/gallium/state_trackers/python/SConscript @@ -0,0 +1,34 @@ +import sys +import os.path + +Import('*') + +if 'python' in env['statetrackers']: + +    env = env.Clone() +     +    env.Tool('python') +     +    env.Tool('swig') +    env.Append(SWIGPATH = ['#src/gallium/include', '#src/gallium/include/pipe']) +    env.Append(SWIGFLAGS = ['-python', '-keyword']) +     +    env.Append(CPPPATH = '.') + +    pyst = env.ConvenienceLibrary( +        target = 'pyst', +        source = [ +            'gallium.i', +            'st_device.c', +            'st_sample.c', +            'st_softpipe_winsys.c', +        ], +    ) + +    env.SharedLibrary( +        target = '_gallium', +        source = [ +            'st_hardpipe_winsys.c', +        ], +        LIBS = [pyst, softpipe, trace] + auxiliaries + env['LIBS'], +    ) diff --git a/src/gallium/state_trackers/python/gallium.i b/src/gallium/state_trackers/python/gallium.i new file mode 100644 index 0000000000..f4c4b36ea7 --- /dev/null +++ b/src/gallium/state_trackers/python/gallium.i @@ -0,0 +1,103 @@ + /************************************************************************** + *  + * 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. + *  + **************************************************************************/ + +/** + * @file + * SWIG interface definion for Gallium types. + * + * @author Jose Fonseca <jrfonseca@tungstengraphics.com> + */ + +%module gallium; + +%{ + +#include <stdio.h> +#include <Python.h> + +#include "pipe/p_screen.h" +#include "pipe/p_context.h" +#include "pipe/p_inlines.h" +#include "util/u_memory.h" +#include "pipe/p_shader_tokens.h"  +#include "cso_cache/cso_context.h" +#include "util/u_draw_quad.h"  +#include "util/u_tile.h"  +#include "tgsi/tgsi_text.h"  +#include "tgsi/tgsi_dump.h"  + +#include "st_device.h" +#include "st_sample.h" + +%} + +%include "typemaps.i" + +%include "cstring.i" + +%include "carrays.i" +%array_class(unsigned char, ByteArray); +%array_class(int, IntArray); +%array_class(unsigned, UnsignedArray); +%array_class(float, FloatArray); + + +%rename(Device) st_device; +%rename(Context) st_context; +%rename(Texture) pipe_texture; +%rename(Surface) pipe_surface; +%rename(Buffer) st_buffer; + +%rename(BlendColor) pipe_blend_color; +%rename(Blend) pipe_blend_state; +%rename(Clip) pipe_clip_state; +%rename(ConstantBuffer) pipe_constant_buffer; +%rename(Depth) pipe_depth_state; +%rename(Stencil) pipe_stencil_state; +%rename(Alpha) pipe_alpha_state; +%rename(DepthStencilAlpha) pipe_depth_stencil_alpha_state; +%rename(FormatBlock) pipe_format_block; +%rename(Framebuffer) pipe_framebuffer_state; +%rename(PolyStipple) pipe_poly_stipple; +%rename(Rasterizer) pipe_rasterizer_state; +%rename(Sampler) pipe_sampler_state; +%rename(Scissor) pipe_scissor_state; +%rename(Shader) pipe_shader_state; +%rename(VertexBuffer) pipe_vertex_buffer; +%rename(VertexElement) pipe_vertex_element; +%rename(Viewport) pipe_viewport_state; + + +%include "p_compiler.i" +%include "pipe/p_defines.h"; +%include "p_format.i" + +%include "p_device.i" +%include "p_context.i" +%include "p_texture.i" +%include "p_state.i" + diff --git a/src/gallium/state_trackers/python/p_compiler.i b/src/gallium/state_trackers/python/p_compiler.i new file mode 100644 index 0000000000..15f6ba5b9d --- /dev/null +++ b/src/gallium/state_trackers/python/p_compiler.i @@ -0,0 +1,29 @@ + /************************************************************************** + *  + * 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. + *  + **************************************************************************/ + + +typedef unsigned char ubyte; diff --git a/src/gallium/state_trackers/python/p_context.i b/src/gallium/state_trackers/python/p_context.i new file mode 100644 index 0000000000..1fdcec639f --- /dev/null +++ b/src/gallium/state_trackers/python/p_context.i @@ -0,0 +1,289 @@ + /************************************************************************** + *  + * 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. + *  + **************************************************************************/ + +/** + * @file + * SWIG interface definion for Gallium types. + * + * @author Jose Fonseca <jrfonseca@tungstengraphics.com> + */ + +%nodefaultctor st_context; +%nodefaultdtor st_context; + +struct st_context { +}; + +%extend st_context { +    +   ~st_context() { +      st_context_destroy($self); +   } +    +   /* +    * State functions (create/bind/destroy state objects) +    */ + +   void set_blend( const struct pipe_blend_state *state ) { +      cso_set_blend($self->cso, state); +   } +    +   void set_sampler( unsigned index, const struct pipe_sampler_state *state ) { +      cso_single_sampler($self->cso, index, state); +      cso_single_sampler_done($self->cso); +   } + +   void set_rasterizer( const struct pipe_rasterizer_state *state ) { +      cso_set_rasterizer($self->cso, state); +   } + +   void set_depth_stencil_alpha(const struct pipe_depth_stencil_alpha_state *state) { +      cso_set_depth_stencil_alpha($self->cso, state); +   } + +   void set_fragment_shader( const struct pipe_shader_state *state ) { +      void *fs; +       +      if(!state) { +         cso_set_fragment_shader_handle($self->cso, NULL); +         return; +      } +       +      fs = $self->pipe->create_fs_state($self->pipe, state); +      if(!fs) +         return; +       +      if(cso_set_fragment_shader_handle($self->cso, fs) != PIPE_OK) +         return; + +      cso_delete_fragment_shader($self->cso, $self->fs); +      $self->fs = fs; +   } + +   void set_vertex_shader( const struct pipe_shader_state *state ) { +      void *vs; +       +      if(!state) { +         cso_set_vertex_shader_handle($self->cso, NULL); +         return; +      } +       +      vs = $self->pipe->create_vs_state($self->pipe, state); +      if(!vs) +         return; +       +      if(cso_set_vertex_shader_handle($self->cso, vs) != PIPE_OK) +         return; + +      cso_delete_vertex_shader($self->cso, $self->vs); +      $self->vs = vs; +   } + +   /* +    * Parameter-like state (or properties) +    */ +    +   void set_blend_color(const struct pipe_blend_color *state ) { +      cso_set_blend_color($self->cso, state); +   } + +   void set_clip(const struct pipe_clip_state *state ) { +      $self->pipe->set_clip_state($self->pipe, state); +   } + +   void set_constant_buffer(unsigned shader, unsigned index, +                            struct st_buffer *buffer )  +   { +      struct pipe_constant_buffer state; +      memset(&state, 0, sizeof(state)); +      state.buffer = buffer ? buffer->buffer : NULL; +      state.size = buffer->buffer->size; +      $self->pipe->set_constant_buffer($self->pipe, shader, index, &state); +   } + +   void set_framebuffer(const struct pipe_framebuffer_state *state ) { +      cso_set_framebuffer($self->cso, state); +   } + +   void set_polygon_stipple(const struct pipe_poly_stipple *state ) { +      $self->pipe->set_polygon_stipple($self->pipe, state); +   } + +   void set_scissor(const struct pipe_scissor_state *state ) { +      $self->pipe->set_scissor_state($self->pipe, state); +   } + +   void set_viewport(const struct pipe_viewport_state *state) { +      cso_set_viewport($self->cso, state); +   } + +   void set_sampler_texture(unsigned index, +                            struct pipe_texture *texture) { +      if(!texture) +         texture = $self->default_texture; +      pipe_texture_reference(&$self->sampler_textures[index], texture); +      $self->pipe->set_sampler_textures($self->pipe,  +                                        PIPE_MAX_SAMPLERS, +                                        $self->sampler_textures); +   } + +   void set_vertex_buffer(unsigned index, +                          unsigned pitch,  +                          unsigned max_index, +                          unsigned buffer_offset, +                          struct st_buffer *buffer) +   { +      unsigned i; +      struct pipe_vertex_buffer state; +       +      memset(&state, 0, sizeof(state)); +      state.pitch = pitch; +      state.max_index = max_index; +      state.buffer_offset = buffer_offset; +      state.buffer = buffer ? buffer->buffer : NULL; + +      memcpy(&$self->vertex_buffers[index], &state, sizeof(state)); +       +      for(i = 0; i < PIPE_MAX_ATTRIBS; ++i) +         if(self->vertex_buffers[i].buffer) +            $self->num_vertex_buffers = i + 1; +       +      $self->pipe->set_vertex_buffers($self->pipe,  +                                      $self->num_vertex_buffers,  +                                      $self->vertex_buffers); +   } + +   void set_vertex_element(unsigned index, +                           const struct pipe_vertex_element *element)  +   { +      memcpy(&$self->vertex_elements[index], element, sizeof(*element)); +   } + +   void set_vertex_elements(unsigned num)  +   { +      $self->num_vertex_elements = num; +      $self->pipe->set_vertex_elements($self->pipe,  +                                       $self->num_vertex_elements,  +                                       $self->vertex_elements); +   } + +   /* +    * Draw functions +    */ +    +   void draw_arrays(unsigned mode, unsigned start, unsigned count) { +      $self->pipe->draw_arrays($self->pipe, mode, start, count); +   } + +   void draw_elements( struct st_buffer *indexBuffer, +                       unsigned indexSize, +                       unsigned mode, unsigned start, unsigned count)  +   { +      $self->pipe->draw_elements($self->pipe,  +                                 indexBuffer->buffer,  +                                 indexSize,  +                                 mode, start, count); +   } + +   void draw_range_elements( struct st_buffer *indexBuffer, +                             unsigned indexSize, unsigned minIndex, unsigned maxIndex, +                             unsigned mode, unsigned start, unsigned count) +   { +      $self->pipe->draw_range_elements($self->pipe,  +                                       indexBuffer->buffer,  +                                       indexSize, minIndex, maxIndex, +                                       mode, start, count); +   } + +   void draw_vertices(unsigned prim, +                      unsigned num_verts, +                      unsigned num_attribs, +                      const float *vertices)  +   { +      struct pipe_context *pipe = $self->pipe; +      struct pipe_screen *screen = pipe->screen; +      struct pipe_buffer *vbuf; +      float *map; +      unsigned size; + +      size = num_verts * num_attribs * 4 * sizeof(float); + +      vbuf = pipe_buffer_create(screen, +                                32, +                                PIPE_BUFFER_USAGE_VERTEX,  +                                size); +      if(!vbuf) +         goto error1; +       +      map = pipe_buffer_map(screen, vbuf, PIPE_BUFFER_USAGE_CPU_WRITE); +      if (!map) +         goto error2; +      memcpy(map, vertices, size); +      pipe_buffer_unmap(screen, vbuf); +       +      util_draw_vertex_buffer(pipe, vbuf, prim, num_verts, num_attribs); +       +error2: +      pipe_buffer_reference(screen, &vbuf, NULL); +error1: +      ; +   } +    +   void +   flush(unsigned flags = 0) { +      struct pipe_fence_handle *fence = NULL;  +      $self->pipe->flush($self->pipe, flags | PIPE_FLUSH_RENDER_CACHE, &fence); +      /* TODO: allow asynchronous operation */  +      $self->pipe->winsys->fence_finish( $self->pipe->winsys, fence, 0 ); +      $self->pipe->winsys->fence_reference( $self->pipe->winsys, &fence, NULL ); +   } + +   /* +    * Surface functions +    */ +    +   void surface_copy(int do_flip, +                     struct pipe_surface *dest, +                     unsigned destx, unsigned desty, +                     struct pipe_surface *src, +                     unsigned srcx, unsigned srcy, +                     unsigned width, unsigned height) { +      $self->pipe->surface_copy($self->pipe, do_flip, dest, destx, desty, src, srcx, srcy, width, height); +   } + +   void surface_fill(struct pipe_surface *dst, +                     unsigned x, unsigned y, +                     unsigned width, unsigned height, +                     unsigned value) { +      $self->pipe->surface_fill($self->pipe, dst, x, y, width, height, value); +   } + +   void surface_clear(struct pipe_surface *surface, unsigned value = 0) { +      $self->pipe->clear($self->pipe, surface, value); +   } + +}; diff --git a/src/gallium/state_trackers/python/p_device.i b/src/gallium/state_trackers/python/p_device.i new file mode 100644 index 0000000000..84fd2e4349 --- /dev/null +++ b/src/gallium/state_trackers/python/p_device.i @@ -0,0 +1,130 @@ + /************************************************************************** + *  + * 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. + *  + **************************************************************************/ + +/** + * @file + * SWIG interface definion for Gallium types. + * + * @author Jose Fonseca <jrfonseca@tungstengraphics.com> + */ + + +%nodefaultctor st_device; +%nodefaultdtor st_device; + + +struct st_device { +}; + +%newobject st_device::texture_create; +%newobject st_device::context_create; +%newobject st_device::buffer_create; + +%extend st_device { +    +   st_device(int hardware = 1) { +      return st_device_create(hardware ? TRUE : FALSE); +   } + +   ~st_device() { +      st_device_destroy($self); +   } +    +   const char * get_name( void ) { +      return $self->screen->get_name($self->screen); +   } + +   const char * get_vendor( void ) { +      return $self->screen->get_vendor($self->screen); +   } + +   /** +    * Query an integer-valued capability/parameter/limit +    * \param param  one of PIPE_CAP_x +    */ +   int get_param( int param ) { +      return $self->screen->get_param($self->screen, param); +   } + +   /** +    * Query a float-valued capability/parameter/limit +    * \param param  one of PIPE_CAP_x +    */ +   float get_paramf( int param ) { +      return $self->screen->get_paramf($self->screen, param); +   } + +   /** +    * Check if the given pipe_format is supported as a texture or +    * drawing surface. +    * \param type  one of PIPE_TEXTURE, PIPE_SURFACE +    */ +   int is_format_supported( enum pipe_format format,  +                            enum pipe_texture_target target, +                            unsigned tex_usage,  +                            unsigned geom_flags ) { +      return $self->screen->is_format_supported( $self->screen,  +                                                 format,  +                                                 target,  +                                                 tex_usage,  +                                                 geom_flags ); +   } + +   struct st_context * +   context_create(void) { +      return st_context_create($self); +   } + +   struct pipe_texture *  +   texture_create( +         enum pipe_format format, +         unsigned width, +         unsigned height, +         unsigned depth = 1, +         unsigned last_level = 0, +         enum pipe_texture_target target = PIPE_TEXTURE_2D, +         unsigned tex_usage = 0 +      ) { +      struct pipe_texture templat; +      memset(&templat, 0, sizeof(templat)); +      templat.format = format; +      pf_get_block(templat.format, &templat.block); +      templat.width[0] = width; +      templat.height[0] = height; +      templat.depth[0] = depth; +      templat.last_level = last_level; +      templat.target = target; +      templat.tex_usage = tex_usage; +      return $self->screen->texture_create($self->screen, &templat); +   } +    +   struct st_buffer * +   buffer_create(unsigned size, unsigned alignment = 0, unsigned usage = 0) { +      return st_buffer_create($self, alignment, usage, size); +   } + +}; diff --git a/src/gallium/state_trackers/python/p_format.i b/src/gallium/state_trackers/python/p_format.i new file mode 100644 index 0000000000..26fb12b387 --- /dev/null +++ b/src/gallium/state_trackers/python/p_format.i @@ -0,0 +1,162 @@ +/************************************************************************** + *  + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * Copyright (c) 2008 VMware, Inc. + * 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. + *  + **************************************************************************/ + +/*  + * XXX: SWIG can't parse p_format.h, so we need to duplicate the relevant  + * declarations here  + */ + +%{ +#include "pipe/p_format.h"  +%} + +enum pipe_format { +   PIPE_FORMAT_NONE, +   PIPE_FORMAT_A8R8G8B8_UNORM, +   PIPE_FORMAT_X8R8G8B8_UNORM, +   PIPE_FORMAT_B8G8R8A8_UNORM, +   PIPE_FORMAT_B8G8R8X8_UNORM, +   PIPE_FORMAT_A1R5G5B5_UNORM, +   PIPE_FORMAT_A4R4G4B4_UNORM, +   PIPE_FORMAT_R5G6B5_UNORM, +   PIPE_FORMAT_A2B10G10R10_UNORM, +   PIPE_FORMAT_L8_UNORM, +   PIPE_FORMAT_A8_UNORM, +   PIPE_FORMAT_I8_UNORM, +   PIPE_FORMAT_A8L8_UNORM, +   PIPE_FORMAT_L16_UNORM, +   PIPE_FORMAT_YCBCR, +   PIPE_FORMAT_YCBCR_REV, +   PIPE_FORMAT_Z16_UNORM, +   PIPE_FORMAT_Z32_UNORM, +   PIPE_FORMAT_Z32_FLOAT, +   PIPE_FORMAT_S8Z24_UNORM, +   PIPE_FORMAT_Z24S8_UNORM, +   PIPE_FORMAT_X8Z24_UNORM, +   PIPE_FORMAT_Z24X8_UNORM, +   PIPE_FORMAT_S8_UNORM, +   PIPE_FORMAT_R64_FLOAT, +   PIPE_FORMAT_R64G64_FLOAT, +   PIPE_FORMAT_R64G64B64_FLOAT, +   PIPE_FORMAT_R64G64B64A64_FLOAT, +   PIPE_FORMAT_R32_FLOAT, +   PIPE_FORMAT_R32G32_FLOAT, +   PIPE_FORMAT_R32G32B32_FLOAT, +   PIPE_FORMAT_R32G32B32A32_FLOAT, +   PIPE_FORMAT_R32_UNORM, +   PIPE_FORMAT_R32G32_UNORM, +   PIPE_FORMAT_R32G32B32_UNORM, +   PIPE_FORMAT_R32G32B32A32_UNORM, +   PIPE_FORMAT_R32_USCALED, +   PIPE_FORMAT_R32G32_USCALED, +   PIPE_FORMAT_R32G32B32_USCALED, +   PIPE_FORMAT_R32G32B32A32_USCALED, +   PIPE_FORMAT_R32_SNORM, +   PIPE_FORMAT_R32G32_SNORM, +   PIPE_FORMAT_R32G32B32_SNORM, +   PIPE_FORMAT_R32G32B32A32_SNORM, +   PIPE_FORMAT_R32_SSCALED, +   PIPE_FORMAT_R32G32_SSCALED, +   PIPE_FORMAT_R32G32B32_SSCALED, +   PIPE_FORMAT_R32G32B32A32_SSCALED, +   PIPE_FORMAT_R16_UNORM, +   PIPE_FORMAT_R16G16_UNORM, +   PIPE_FORMAT_R16G16B16_UNORM, +   PIPE_FORMAT_R16G16B16A16_UNORM, +   PIPE_FORMAT_R16_USCALED, +   PIPE_FORMAT_R16G16_USCALED, +   PIPE_FORMAT_R16G16B16_USCALED, +   PIPE_FORMAT_R16G16B16A16_USCALED, +   PIPE_FORMAT_R16_SNORM, +   PIPE_FORMAT_R16G16_SNORM, +   PIPE_FORMAT_R16G16B16_SNORM, +   PIPE_FORMAT_R16G16B16A16_SNORM, +   PIPE_FORMAT_R16_SSCALED, +   PIPE_FORMAT_R16G16_SSCALED, +   PIPE_FORMAT_R16G16B16_SSCALED, +   PIPE_FORMAT_R16G16B16A16_SSCALED, +   PIPE_FORMAT_R8_UNORM, +   PIPE_FORMAT_R8G8_UNORM, +   PIPE_FORMAT_R8G8B8_UNORM, +   PIPE_FORMAT_R8G8B8A8_UNORM, +   PIPE_FORMAT_R8G8B8X8_UNORM, +   PIPE_FORMAT_R8_USCALED, +   PIPE_FORMAT_R8G8_USCALED, +   PIPE_FORMAT_R8G8B8_USCALED, +   PIPE_FORMAT_R8G8B8A8_USCALED, +   PIPE_FORMAT_R8G8B8X8_USCALED, +   PIPE_FORMAT_R8_SNORM, +   PIPE_FORMAT_R8G8_SNORM, +   PIPE_FORMAT_R8G8B8_SNORM, +   PIPE_FORMAT_R8G8B8A8_SNORM, +   PIPE_FORMAT_R8G8B8X8_SNORM, +   PIPE_FORMAT_B6G5R5_SNORM, +   PIPE_FORMAT_A8B8G8R8_SNORM, +   PIPE_FORMAT_X8B8G8R8_SNORM, +   PIPE_FORMAT_R8_SSCALED, +   PIPE_FORMAT_R8G8_SSCALED, +   PIPE_FORMAT_R8G8B8_SSCALED, +   PIPE_FORMAT_R8G8B8A8_SSCALED, +   PIPE_FORMAT_R8G8B8X8_SSCALED, +   PIPE_FORMAT_R32_FIXED, +   PIPE_FORMAT_R32G32_FIXED, +   PIPE_FORMAT_R32G32B32_FIXED, +   PIPE_FORMAT_R32G32B32A32_FIXED, + +   PIPE_FORMAT_L8_SRGB, +   PIPE_FORMAT_A8L8_SRGB, +   PIPE_FORMAT_R8G8B8_SRGB, +   PIPE_FORMAT_R8G8B8A8_SRGB, +   PIPE_FORMAT_R8G8B8X8_SRGB, +   PIPE_FORMAT_A8R8G8B8_SRGB, +   PIPE_FORMAT_X8R8G8B8_SRGB, +   PIPE_FORMAT_B8G8R8A8_SRGB, +   PIPE_FORMAT_B8G8R8X8_SRGB, + +   PIPE_FORMAT_X8UB8UG8SR8S_NORM, +   PIPE_FORMAT_B6UG5SR5S_NORM, + +   PIPE_FORMAT_DXT1_RGB, +   PIPE_FORMAT_DXT1_RGBA, +   PIPE_FORMAT_DXT3_RGBA, +   PIPE_FORMAT_DXT5_RGBA, + +   PIPE_FORMAT_DXT1_SRGB, +   PIPE_FORMAT_DXT1_SRGBA, +   PIPE_FORMAT_DXT3_SRGBA, +   PIPE_FORMAT_DXT5_SRGBA, +}; + + +struct pipe_format_block +{ +   unsigned size; +   unsigned width; +   unsigned height; +}; + diff --git a/src/gallium/state_trackers/python/p_state.i b/src/gallium/state_trackers/python/p_state.i new file mode 100644 index 0000000000..7f5760b3b6 --- /dev/null +++ b/src/gallium/state_trackers/python/p_state.i @@ -0,0 +1,109 @@ + /************************************************************************** + *  + * 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. + *  + **************************************************************************/ + +/** + * @file + * SWIG interface definion for Gallium types. + * + * @author Jose Fonseca <jrfonseca@tungstengraphics.com> + */ + +%module gallium; + +%ignore winsys; +%ignore pipe_vertex_buffer::buffer; + +%include "pipe/p_state.h"; + + +%array_class(struct pipe_stencil_state, StencilArray); + + +%extend pipe_framebuffer_state { +    +   pipe_framebuffer_state(void) { +      return CALLOC_STRUCT(pipe_framebuffer_state); +   } +    +   ~pipe_framebuffer_state() { +      unsigned index; +      for(index = 0; index < PIPE_MAX_COLOR_BUFS; ++index) +         pipe_surface_reference(&$self->cbufs[index], NULL); +      pipe_surface_reference(&$self->zsbuf, NULL); +      FREE($self); +   } +    +   void +   set_cbuf(unsigned index, struct pipe_surface *surface) { +      pipe_surface_reference(&$self->cbufs[index], surface); +   } +    +   void +   set_zsbuf(struct pipe_surface *surface) { +      pipe_surface_reference(&$self->zsbuf, surface); +   } +    +}; + + +%extend pipe_shader_state { +    +   pipe_shader_state(const char *text, unsigned num_tokens = 1024) { +      struct tgsi_token *tokens; +      struct pipe_shader_state *shader; +       +      tokens = MALLOC(num_tokens * sizeof(struct tgsi_token)); +      if(!tokens) +         goto error1; +       +      if(tgsi_text_translate(text, tokens, num_tokens ) != TRUE) +         goto error2; +       +      shader = CALLOC_STRUCT(pipe_shader_state); +      if(!shader) +         goto error3; +       +      shader->tokens = tokens; +       +      return shader; +       +error3: +error2: +      FREE(tokens); +error1:       +      return NULL; +   } +    +   ~pipe_shader_state() { +      FREE((void*)$self->tokens); +      FREE($self); +   } + +   void dump(unsigned flags = 0) { +      tgsi_dump($self->tokens, flags); +   } +} diff --git a/src/gallium/state_trackers/python/p_texture.i b/src/gallium/state_trackers/python/p_texture.i new file mode 100644 index 0000000000..08ba0ebe4d --- /dev/null +++ b/src/gallium/state_trackers/python/p_texture.i @@ -0,0 +1,232 @@ + /************************************************************************** + *  + * 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. + *  + **************************************************************************/ + +/** + * @file + * SWIG interface definion for Gallium types. + * + * @author Jose Fonseca <jrfonseca@tungstengraphics.com> + */ + + +%nodefaultctor pipe_texture; +%nodefaultctor pipe_surface; +%nodefaultctor st_buffer; + +%nodefaultdtor pipe_texture; +%nodefaultdtor pipe_surface; +%nodefaultdtor st_buffer; + +%ignore pipe_texture::screen; + +%ignore pipe_surface::winsys; +%immutable pipe_surface::texture; +%immutable pipe_surface::buffer; + +%newobject pipe_texture::get_surface; + + +%extend pipe_texture { +    +   ~pipe_texture() { +      struct pipe_texture *ptr = $self; +      pipe_texture_reference(&ptr, NULL); +   } +    +   unsigned get_width(unsigned level=0) { +      return $self->width[level]; +   } +    +   unsigned get_height(unsigned level=0) { +      return $self->height[level]; +   } +    +   unsigned get_depth(unsigned level=0) { +      return $self->depth[level]; +   } +    +   unsigned get_nblocksx(unsigned level=0) { +      return $self->nblocksx[level]; +   } +    +   unsigned get_nblocksy(unsigned level=0) { +      return $self->nblocksy[level]; +   } +    +   /** Get a surface which is a "view" into a texture */ +   struct pipe_surface * +   get_surface(unsigned face=0, unsigned level=0, unsigned zslice=0, unsigned usage=0 ) +   { +      struct pipe_screen *screen = $self->screen; +      return screen->get_tex_surface(screen, $self, face, level, zslice, usage); +   } +    +}; + + +%extend pipe_surface { +    +   ~pipe_surface() { +      struct pipe_surface *ptr = $self; +      pipe_surface_reference(&ptr, NULL); +   } +    +   // gets mapped to pipe_surface_map automatically +   void * map( unsigned flags ); + +   // gets mapped to pipe_surface_unmap automatically +   void unmap( void ); + +   void +   get_tile_raw(unsigned x, unsigned y, unsigned w, unsigned h, char *raw, unsigned stride) { +      pipe_get_tile_raw($self, x, y, w, h, raw, stride); +   } + +   void +   put_tile_raw(unsigned x, unsigned y, unsigned w, unsigned h, const char *raw, unsigned stride) { +      pipe_put_tile_raw($self, x, y, w, h, raw, stride); +   } + +   void +   get_tile_rgba(unsigned x, unsigned y, unsigned w, unsigned h, float *rgba) { +      pipe_get_tile_rgba($self, x, y, w, h, rgba); +   } + +   void +   put_tile_rgba(unsigned x, unsigned y, unsigned w, unsigned h, const float *rgba) { +      pipe_put_tile_rgba($self, x, y, w, h, rgba); +   } + +   void +   get_tile_z(unsigned x, unsigned y, unsigned w, unsigned h, unsigned *z) { +      pipe_get_tile_z($self, x, y, w, h, z); +   } + +   void +   put_tile_z(unsigned x, unsigned y, unsigned w, unsigned h, const unsigned *z) { +      pipe_put_tile_z($self, x, y, w, h, z); +   } +    +   void +   sample_rgba(float *rgba) { +      st_sample_surface($self, rgba); +   } +    +   unsigned +   compare_tile_rgba(unsigned x, unsigned y, unsigned w, unsigned h, const float *rgba, float tol = 0.0)  +   { +      float *rgba2; +      const float *p1; +      const float *p2; +      unsigned i, j, n; +       +      rgba2 = MALLOC(h*w*4*sizeof(float)); +      if(!rgba2) +         return ~0; + +      pipe_get_tile_rgba($self, x, y, w, h, rgba2); + +      p1 = rgba; +      p2 = rgba2; +      n = 0; +      for(i = h*w; i; --i) { +         unsigned differs = 0; +         for(j = 4; j; --j) { +            float delta = *p2++ - *p1++; +            if (delta < -tol || delta > tol) +                differs = 1; +         } +         n += differs; +      } +       +      FREE(rgba2); +       +      return n; +   } + +}; + +struct st_buffer { +}; + +%extend st_buffer { +    +   ~st_buffer() { +      st_buffer_destroy($self); +   } +    +   unsigned __len__(void)  +   { +      assert($self->buffer->refcount); +      return $self->buffer->size; +   } +    +   %cstring_output_allocate_size(char **STRING, int *LENGTH, free(*$1)); +   void read(char **STRING, int *LENGTH) +   { +      struct pipe_screen *screen = $self->st_dev->screen; +      const char *map; +       +      assert($self->buffer->refcount); +       +      *LENGTH = $self->buffer->size; +      *STRING = (char *) malloc($self->buffer->size); +      if(!*STRING) +         return; +       +      map = pipe_buffer_map(screen, $self->buffer, PIPE_BUFFER_USAGE_CPU_READ); +      if(map) { +         memcpy(*STRING, map, $self->buffer->size); +         pipe_buffer_unmap(screen, $self->buffer); +      } +   } +    +   %cstring_input_binary(const char *STRING, unsigned LENGTH); +   void write(const char *STRING, unsigned LENGTH, unsigned offset = 0)  +   { +      struct pipe_screen *screen = $self->st_dev->screen; +      char *map; +       +      assert($self->buffer->refcount); +       +      if(offset > $self->buffer->size) { +         PyErr_SetString(PyExc_ValueError, "offset must be smaller than buffer size"); +         return; +      } + +      if(offset + LENGTH > $self->buffer->size) { +         PyErr_SetString(PyExc_ValueError, "data length must fit inside the buffer"); +         return; +      } + +      map = pipe_buffer_map(screen, $self->buffer, PIPE_BUFFER_USAGE_CPU_WRITE); +      if(map) { +         memcpy(map + offset, STRING, LENGTH); +         pipe_buffer_unmap(screen, $self->buffer); +      } +   } +}; diff --git a/src/gallium/state_trackers/python/retrace/README b/src/gallium/state_trackers/python/retrace/README new file mode 100644 index 0000000000..822cd11404 --- /dev/null +++ b/src/gallium/state_trackers/python/retrace/README @@ -0,0 +1,17 @@ +This is an application written in python to replay the traces captured by the + trace pipe driver.  + + +To use it follow the instructions in src/gallium/drivers/trace/README and +src/gallium/state_trackers/python/README, and then do + +  python src/gallium/state_trackers/python/samples/retrace/interpreter.py filename.trace + + +This is still work in progress: +- not everything is captured/replayed +  - surface/textures contents +- any tiny error will result in a crash + +-- +Jose Fonseca <jrfonseca@tungstengraphics.com> diff --git a/src/gallium/state_trackers/python/retrace/format.py b/src/gallium/state_trackers/python/retrace/format.py new file mode 100755 index 0000000000..0bf6baf0b9 --- /dev/null +++ b/src/gallium/state_trackers/python/retrace/format.py @@ -0,0 +1,100 @@ +#!/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. +# +########################################################################## + + +class Formatter: +    '''Plain formatter''' + +    def __init__(self, stream): +        self.stream = stream + +    def text(self, text): +        self.stream.write(text) + +    def newline(self): +        self.text('\n') + +    def function(self, name): +        self.text(name) + +    def variable(self, name): +        self.text(name) + +    def literal(self, value): +        self.text(str(value)) + +    def address(self, addr): +        self.text(str(addr)) + + +class AnsiFormatter(Formatter): +    '''Formatter for plain-text files which outputs ANSI escape codes. See +    http://en.wikipedia.org/wiki/ANSI_escape_code for more information +    concerning ANSI escape codes. +    ''' + +    _csi = '\33[' + +    _normal = '0m' +    _bold = '1m' +    _italic = '3m' +    _red = '31m' +    _green = '32m' +    _blue = '34m' + +    def _escape(self, code): +        self.text(self._csi + code) + +    def function(self, name): +        self._escape(self._bold) +        Formatter.function(self, name) +        self._escape(self._normal) + +    def variable(self, name): +        self._escape(self._italic) +        Formatter.variable(self, name) +        self._escape(self._normal) + +    def literal(self, value): +        self._escape(self._blue) +        Formatter.literal(self, value) +        self._escape(self._normal) + +    def address(self, value): +        self._escape(self._green) +        Formatter.address(self, value) +        self._escape(self._normal) + + + +def DefaultFormatter(stream): +    if stream.isatty(): +        return AnsiFormatter(stream) +    else: +        return Formatter(stream) + diff --git a/src/gallium/state_trackers/python/retrace/interpreter.py b/src/gallium/state_trackers/python/retrace/interpreter.py new file mode 100755 index 0000000000..f418f80d7b --- /dev/null +++ b/src/gallium/state_trackers/python/retrace/interpreter.py @@ -0,0 +1,578 @@ +#!/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 +import struct + +import gallium +import model +import parser + + +def make_image(surface): +    pixels = gallium.FloatArray(surface.height*surface.width*4) +    surface.get_tile_rgba(0, 0, surface.width, surface.height, pixels) + +    import Image +    outimage = Image.new( +        mode='RGB', +        size=(surface.width, surface.height), +        color=(0,0,0)) +    outpixels = outimage.load() +    for y in range(0, surface.height): +        for x in range(0, surface.width): +            offset = (y*surface.width + x)*4 +            r, g, b, a = [int(pixels[offset + ch]*255) for ch in range(4)] +            outpixels[x, y] = r, g, b +    return outimage + +def save_image(filename, surface): +    outimage = make_image(surface) +    outimage.save(filename, "PNG") + +def show_image(surface): +    outimage = make_image(surface) +     +    import Tkinter as tk +    from PIL import Image, ImageTk +    root = tk.Tk() +     +    root.title('background image') +     +    image1 = ImageTk.PhotoImage(outimage) +    w = image1.width() +    h = image1.height() +    x = 100 +    y = 100 +    root.geometry("%dx%d+%d+%d" % (w, h, x, y)) +    panel1 = tk.Label(root, image=image1) +    panel1.pack(side='top', fill='both', expand='yes') +    panel1.image = image1 +    root.mainloop() + + + + +class Struct: +    """C-like struct""" + +    # A basic Python class can pass as a C-like structure +    pass + + +struct_factories = { +    "pipe_blend_color": gallium.BlendColor, +    "pipe_blend_state": gallium.Blend, +    #"pipe_clip_state": gallium.Clip, +    #"pipe_constant_buffer": gallium.ConstantBuffer, +    "pipe_depth_state": gallium.Depth, +    "pipe_stencil_state": gallium.Stencil, +    "pipe_alpha_state": gallium.Alpha, +    "pipe_depth_stencil_alpha_state": gallium.DepthStencilAlpha, +    "pipe_format_block": gallium.FormatBlock, +    #"pipe_framebuffer_state": gallium.Framebuffer, +    "pipe_poly_stipple": gallium.PolyStipple, +    "pipe_rasterizer_state": gallium.Rasterizer, +    "pipe_sampler_state": gallium.Sampler, +    "pipe_scissor_state": gallium.Scissor, +    #"pipe_shader_state": gallium.Shader, +    #"pipe_vertex_buffer": gallium.VertexBuffer, +    "pipe_vertex_element": gallium.VertexElement, +    "pipe_viewport_state": gallium.Viewport, +    #"pipe_texture": gallium.Texture, +} + + +member_array_factories = { +    "pipe_rasterizer_state": {"sprite_coord_mode": gallium.ByteArray},                           +    "pipe_poly_stipple": {"stipple": gallium.UnsignedArray},                           +    "pipe_viewport_state": {"scale": gallium.FloatArray, "translate": gallium.FloatArray},                           +    #"pipe_clip_state": {"ucp": gallium.FloatArray}, +    "pipe_depth_stencil_alpha_state": {"stencil": gallium.StencilArray}, +    "pipe_blend_color": {"color": gallium.FloatArray}, +    "pipe_sampler_state": {"border_color": gallium.FloatArray},               +} + + +class Translator(model.Visitor): +    """Translate model arguments into regular Python objects""" + +    def __init__(self, interpreter): +        self.interpreter = interpreter +        self.result = None + +    def visit(self, node): +        self.result = None +        node.visit(self) +        return self.result +         +    def visit_literal(self, node): +        self.result = node.value +     +    def visit_named_constant(self, node): +        # lookup the named constant in the gallium module +        self.result = getattr(gallium, node.name) +     +    def visit_array(self, node): +        array = [] +        for element in node.elements: +            array.append(self.visit(element)) +        self.result = array +     +    def visit_struct(self, node): +        struct_factory = struct_factories.get(node.name, Struct) +        struct = struct_factory() +        for member_name, member_node in node.members: +            member_value = self.visit(member_node) +            try: +                array_factory = member_array_factories[node.name][member_name] +            except KeyError: +                pass +            else: +                assert isinstance(member_value, list) +                array = array_factory(len(member_value)) +                for i in range(len(member_value)): +                    array[i] = member_value[i] +                member_value = array +            #print node.name, member_name, member_value +            assert isinstance(struct, Struct) or hasattr(struct, member_name) +            setattr(struct, member_name, member_value) +        self.result = struct +     +    def visit_pointer(self, node): +        self.result = self.interpreter.lookup_object(node.address) + + +class Object: +     +    def __init__(self, interpreter, real): +        self.interpreter = interpreter +        self.real = real +         + +class Global(Object): + +    def __init__(self, interpreter, real): +        self.interpreter = interpreter +        self.real = real +         +    def pipe_winsys_create(self): +        return Winsys(self.interpreter, gallium.Device()) + +    def pipe_screen_create(self, winsys): +        return Screen(self.interpreter, winsys.real) +     +    def pipe_context_create(self, screen): +        context = screen.real.context_create() +        return Context(self.interpreter, context) + +     +class Winsys(Object): +     +    def __init__(self, interpreter, real): +        self.interpreter = interpreter +        self.real = real + +    def get_name(self): +        pass +     +    def user_buffer_create(self, data, size): +        # We don't really care to distinguish between user and regular buffers +        buffer = self.real.buffer_create(size,  +                                         4,  +                                         gallium.PIPE_BUFFER_USAGE_CPU_READ | +                                         gallium.PIPE_BUFFER_USAGE_CPU_WRITE ) +        assert size == len(data) +        buffer.write(data) +        return buffer +     +    def buffer_create(self, alignment, usage, size): +        return self.real.buffer_create(size, alignment, usage) +     +    def buffer_destroy(self, buffer): +        pass +     +    def buffer_write(self, buffer, data, size): +        assert size == len(data) +        buffer.write(data) +         +    def fence_finish(self, fence, flags): +        pass +     +    def fence_reference(self, dst, src): +        pass +     +    def flush_frontbuffer(self, surface): +        pass + +    def surface_alloc(self): +        return None +     +    def surface_release(self, surface): +        pass + + +class Screen(Object): +     +    def destroy(self): +        pass + +    def get_name(self): +        pass +     +    def get_vendor(self): +        pass +     +    def get_param(self, param): +        pass +     +    def get_paramf(self, param): +        pass +     +    def is_format_supported(self, format, target, tex_usage, geom_flags): +        return self.real.is_format_supported(format, target, tex_usage, geom_flags) +     +    def texture_create(self, template): +        return self.real.texture_create( +            format = template.format, +            width = template.width[0], +            height = template.height[0], +            depth = template.depth[0], +            last_level = template.last_level, +            target = template.target, +            tex_usage = template.tex_usage, +        ) + +    def texture_destroy(self, texture): +        self.interpreter.unregister_object(texture) + +    def texture_release(self, surface): +        pass + +    def get_tex_surface(self, texture, face, level, zslice, usage): +        return texture.get_surface(face, level, zslice, usage) +     +    def tex_surface_destroy(self, surface): +        self.interpreter.unregister_object(surface) + +    def tex_surface_release(self, surface): +        pass + +    def surface_write(self, surface, data, stride, size): +        assert surface.nblocksy * stride == size  +        surface.put_tile_raw(0, 0, surface.width, surface.height, data, stride) + + +class Context(Object): +     +    def __init__(self, interpreter, real): +        Object.__init__(self, interpreter, real) +        self.cbufs = [] +        self.zsbuf = None +        self.vbufs = [] +        self.velems = [] + +    def destroy(self): +        pass +     +    def create_blend_state(self, state): +        return state + +    def bind_blend_state(self, state): +        if state is not None: +            self.real.set_blend(state) + +    def delete_blend_state(self, state): +        pass +     +    def create_sampler_state(self, state): +        return state + +    def delete_sampler_state(self, state): +        pass + +    def bind_sampler_states(self, n, states): +        for i in range(n): +            self.real.set_sampler(i, states[i]) +         +    def create_rasterizer_state(self, state): +        return state + +    def bind_rasterizer_state(self, state): +        if state is not None: +            self.real.set_rasterizer(state) +         +    def delete_rasterizer_state(self, state): +        pass +     +    def create_depth_stencil_alpha_state(self, state): +        return state + +    def bind_depth_stencil_alpha_state(self, state): +        if state is not None: +            self.real.set_depth_stencil_alpha(state) +             +    def delete_depth_stencil_alpha_state(self, state): +        pass + +    def create_fs_state(self, state): +        tokens = str(state.tokens) +        shader = gallium.Shader(tokens) +        return shader + +    create_vs_state = create_fs_state +     +    def bind_fs_state(self, state): +        self.real.set_fragment_shader(state) +         +    def bind_vs_state(self, state): +        self.real.set_vertex_shader(state) + +    def delete_fs_state(self, state): +        pass +     +    delete_vs_state = delete_fs_state +     +    def set_blend_color(self, state): +        self.real.set_blend_color(state) + +    def set_clip_state(self, state): +        _state = gallium.Clip() +        _state.nr = state.nr +        if state.nr: +            # FIXME +            ucp = gallium.FloatArray(gallium.PIPE_MAX_CLIP_PLANES*4) +            for i in range(len(state.ucp)): +                for j in range(len(state.ucp[i])): +                    ucp[i*4 + j] = state.ucp[i][j] +            _state.ucp = ucp +        self.real.set_clip(_state) + +    def set_constant_buffer(self, shader, index, state): +        if state is not None: +            self.real.set_constant_buffer(shader, index, state.buffer) + +            if 1: +                data = state.buffer.read() +                format = '4f' +                index = 0 +                for offset in range(0, len(data), struct.calcsize(format)): +                    x, y, z, w = struct.unpack_from(format, data, offset) +                    sys.stdout.write('\tCONST[%2u] = {%10.4f, %10.4f, %10.4f, %10.4f}\n' % (index, x, y, z, w)) +                    index += 1 + +    def set_framebuffer_state(self, state): +        _state = gallium.Framebuffer() +        _state.width = state.width +        _state.height = state.height +        _state.num_cbufs = state.num_cbufs +        for i in range(len(state.cbufs)): +            _state.set_cbuf(i, state.cbufs[i]) +        _state.set_zsbuf(state.zsbuf)     +        self.real.set_framebuffer(_state) +         +        self.cbufs = state.cbufs +        self.zsbuf = state.zsbuf + +    def set_polygon_stipple(self, state): +        self.real.set_polygon_stipple(state) + +    def set_scissor_state(self, state): +        self.real.set_scissor(state) + +    def set_viewport_state(self, state): +        self.real.set_viewport(state) + +    def set_sampler_textures(self, n, textures): +        for i in range(n): +            self.real.set_sampler_texture(i, textures[i]) + +    def set_vertex_buffers(self, n, vbufs): +        self.vbufs = vbufs[0:n] +        for i in range(n): +            vbuf = vbufs[i] +            self.real.set_vertex_buffer( +                i, +                pitch = vbuf.pitch, +                max_index = vbuf.max_index, +                buffer_offset = vbuf.buffer_offset, +                buffer = vbuf.buffer, +            ) + +    def set_vertex_elements(self, n, elements): +        self.velems = elements[0:n] +        for i in range(n): +            self.real.set_vertex_element(i, elements[i]) +        self.real.set_vertex_elements(n) + +    def set_edgeflags(self, bitfield): +        # FIXME +        pass +     +    def dump_vertices(self, start, count): +        for index in range(start, start + count): +            if index >= start + 16: +                sys.stdout.write('\t...\n') +                break +            sys.stdout.write('\t{\n') +            for velem in self.velems: +                vbuf = self.vbufs[velem.vertex_buffer_index] + +                offset = vbuf.buffer_offset + velem.src_offset + vbuf.pitch*index +                format = { +                    gallium.PIPE_FORMAT_R32_FLOAT: 'f', +                    gallium.PIPE_FORMAT_R32G32_FLOAT: '2f', +                    gallium.PIPE_FORMAT_R32G32B32_FLOAT: '3f', +                    gallium.PIPE_FORMAT_R32G32B32A32_FLOAT: '4f', +                    gallium.PIPE_FORMAT_B8G8R8A8_UNORM: '4B', +                }[velem.src_format] + +                data = vbuf.buffer.read() +                values = struct.unpack_from(format, data, offset) +                sys.stdout.write('\t\t{' + ', '.join(map(str, values)) + '},\n') +                assert len(values) == velem.nr_components +            sys.stdout.write('\t},\n') + +    def dump_indices(self, ibuf, isize, start, count): +        format = { +            1: 'B', +            2: 'H', +            4: 'I', +        }[isize] + +        assert struct.calcsize(format) == isize + +        data = ibuf.read() +        maxindex, minindex = 0, 0xffffffff + +        sys.stdout.write('\t{\n') +        for i in range(start, start + count): +            if i >= start + 16: +                sys.stdout.write('\t...\n') +                break +            offset = i*isize +            index, = struct.unpack_from(format, data, offset) +            sys.stdout.write('\t\t%u,\n' % index) +            minindex = min(minindex, index) +            maxindex = max(maxindex, index) +        sys.stdout.write('\t},\n') + +        return minindex, maxindex + +    def draw_arrays(self, mode, start, count): +        self.dump_vertices(start, count) +             +        self.real.draw_arrays(mode, start, count) +     +    def draw_elements(self, indexBuffer, indexSize, mode, start, count): +        minindex, maxindex = self.dump_indices(indexBuffer, indexSize, start, count) +        self.dump_vertices(minindex, maxindex - minindex) + +        self.real.draw_elements(indexBuffer, indexSize, mode, start, count) +         +    def draw_range_elements(self, indexBuffer, indexSize, minIndex, maxIndex, mode, start, count): +        minindex, maxindex = self.dump_indices(indexBuffer, indexSize, start, count) +        minindex = min(minindex, minIndex) +        maxindex = min(maxindex, maxIndex) +        self.dump_vertices(minindex, maxindex - minindex) + +        self.real.draw_range_elements(indexBuffer, indexSize, minIndex, maxIndex, mode, start, count) +         +    def flush(self, flags): +        self.real.flush(flags) +        if flags & gallium.PIPE_FLUSH_FRAME: +            self._update() +        return None + +    def clear(self, surface, value): +        self.real.surface_clear(surface, value) +         +    def _update(self): +        self.real.flush() +     +        if self.cbufs and self.cbufs[0]: +            show_image(self.cbufs[0]) +     + +class Interpreter(parser.TraceDumper): +     +    ignore_calls = set(( +            ('pipe_screen', 'is_format_supported'), +            ('pipe_screen', 'get_param'), +            ('pipe_screen', 'get_paramf'), +    )) + +    def __init__(self, stream): +        parser.TraceDumper.__init__(self, stream) +        self.objects = {} +        self.result = None +        self.globl = Global(self, None) + +    def register_object(self, address, object): +        self.objects[address] = object +         +    def unregister_object(self, object): +        # FIXME: +        pass + +    def lookup_object(self, address): +        return self.objects[address] +     +    def interpret(self, trace): +        for call in trace.calls: +            self.interpret_call(call) + +    def handle_call(self, call): + +        if (call.klass, call.method) in self.ignore_calls: +            return + +        parser.TraceDumper.handle_call(self, call) +         +        args = [self.interpret_arg(arg) for name, arg in call.args]  +         +        if call.klass: +            obj = args[0] +            args = args[1:] +        else: +            obj = self.globl +             +        method = getattr(obj, call.method) +        ret = method(*args) +         +        if call.ret and isinstance(call.ret, model.Pointer): +            self.register_object(call.ret.address, ret) + +    def interpret_arg(self, node): +        translator = Translator(self) +        return translator.visit(node) +     + +if __name__ == '__main__': +    parser.main(Interpreter) diff --git a/src/gallium/state_trackers/python/retrace/model.py b/src/gallium/state_trackers/python/retrace/model.py new file mode 100755 index 0000000000..ae0f4327d7 --- /dev/null +++ b/src/gallium/state_trackers/python/retrace/model.py @@ -0,0 +1,211 @@ +#!/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. +#  +########################################################################## + + +'''Trace data model.''' + + +import sys +import string +import format + +try: +    from cStringIO import StringIO +except ImportError: +    from StringIO import StringIO + + +class Node: +     +    def visit(self, visitor): +        raise NotImplementedError + +    def __str__(self): +        stream = StringIO() +        formatter = format.DefaultFormatter(stream) +        pretty_printer = PrettyPrinter(formatter) +        self.visit(pretty_printer) +        return stream.getvalue() + + +class Literal(Node): +     +    def __init__(self, value): +        self.value = value + +    def visit(self, visitor): +        visitor.visit_literal(self) + + +class NamedConstant(Node): +     +    def __init__(self, name): +        self.name = name + +    def visit(self, visitor): +        visitor.visit_named_constant(self) +     + +class Array(Node): +     +    def __init__(self, elements): +        self.elements = elements + +    def visit(self, visitor): +        visitor.visit_array(self) + + +class Struct(Node): +     +    def __init__(self, name, members): +        self.name = name +        self.members = members         + +    def visit(self, visitor): +        visitor.visit_struct(self) + +         +class Pointer(Node): +     +    def __init__(self, address): +        self.address = address + +    def visit(self, visitor): +        visitor.visit_pointer(self) + + +class Call: +     +    def __init__(self, klass, method, args, ret): +        self.klass = klass +        self.method = method +        self.args = args +        self.ret = ret +         +    def visit(self, visitor): +        visitor.visit_call(self) + + +class Trace: +     +    def __init__(self, calls): +        self.calls = calls +         +    def visit(self, visitor): +        visitor.visit_trace(self) +     +     +class Visitor: +     +    def visit_literal(self, node): +        raise NotImplementedError +     +    def visit_named_constant(self, node): +        raise NotImplementedError +     +    def visit_array(self, node): +        raise NotImplementedError +     +    def visit_struct(self, node): +        raise NotImplementedError +     +    def visit_pointer(self, node): +        raise NotImplementedError +     +    def visit_call(self, node): +        raise NotImplementedError +     +    def visit_trace(self, node): +        raise NotImplementedError + + +class PrettyPrinter: + +    def __init__(self, formatter): +        self.formatter = formatter +     +    def visit_literal(self, node): +        if isinstance(node.value, basestring): +            if len(node.value) >= 4096 or node.value.strip(string.printable): +                self.formatter.text('...') +                return + +            self.formatter.literal('"' + node.value + '"') +            return + +        self.formatter.literal(repr(node.value)) +     +    def visit_named_constant(self, node): +        self.formatter.literal(node.name) +     +    def visit_array(self, node): +        self.formatter.text('{') +        sep = '' +        for value in node.elements: +            self.formatter.text(sep) +            value.visit(self)  +            sep = ', ' +        self.formatter.text('}') +     +    def visit_struct(self, node): +        self.formatter.text('{') +        sep = '' +        for name, value in node.members: +            self.formatter.text(sep) +            self.formatter.variable(name) +            self.formatter.text(' = ') +            value.visit(self)  +            sep = ', ' +        self.formatter.text('}') +     +    def visit_pointer(self, node): +        self.formatter.address(node.address) +     +    def visit_call(self, node): +        if node.klass is not None: +            self.formatter.function(node.klass + '::' + node.method) +        else: +            self.formatter.function(node.method) +        self.formatter.text('(') +        sep = '' +        for name, value in node.args: +            self.formatter.text(sep) +            self.formatter.variable(name) +            self.formatter.text(' = ') +            value.visit(self)  +            sep = ', ' +        self.formatter.text(')') +        if node.ret is not None: +            self.formatter.text(' = ') +            node.ret.visit(self) +     +    def visit_trace(self, node): +        for call in node.calls: +            call.visit(self) +            self.formatter.newline() + diff --git a/src/gallium/state_trackers/python/retrace/parser.py b/src/gallium/state_trackers/python/retrace/parser.py new file mode 100755 index 0000000000..5205f2d8dd --- /dev/null +++ b/src/gallium/state_trackers/python/retrace/parser.py @@ -0,0 +1,357 @@ +#!/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 +import xml.parsers.expat +import binascii + +from model import * + + +ELEMENT_START, ELEMENT_END, CHARACTER_DATA, EOF = range(4) + + +class XmlToken: + +    def __init__(self, type, name_or_data, attrs = None, line = None, column = None): +        assert type in (ELEMENT_START, ELEMENT_END, CHARACTER_DATA, EOF) +        self.type = type +        self.name_or_data = name_or_data +        self.attrs = attrs +        self.line = line +        self.column = column + +    def __str__(self): +        if self.type == ELEMENT_START: +            return '<' + self.name_or_data + ' ...>' +        if self.type == ELEMENT_END: +            return '</' + self.name_or_data + '>' +        if self.type == CHARACTER_DATA: +            return self.name_or_data +        if self.type == EOF: +            return 'end of file' +        assert 0 + + +class XmlTokenizer: +    """Expat based XML tokenizer.""" + +    def __init__(self, fp, skip_ws = True): +        self.fp = fp +        self.tokens = [] +        self.index = 0 +        self.final = False +        self.skip_ws = skip_ws +         +        self.character_pos = 0, 0 +        self.character_data = '' +         +        self.parser = xml.parsers.expat.ParserCreate() +        self.parser.StartElementHandler  = self.handle_element_start +        self.parser.EndElementHandler    = self.handle_element_end +        self.parser.CharacterDataHandler = self.handle_character_data +     +    def handle_element_start(self, name, attributes): +        self.finish_character_data() +        line, column = self.pos() +        token = XmlToken(ELEMENT_START, name, attributes, line, column) +        self.tokens.append(token) +     +    def handle_element_end(self, name): +        self.finish_character_data() +        line, column = self.pos() +        token = XmlToken(ELEMENT_END, name, None, line, column) +        self.tokens.append(token) + +    def handle_character_data(self, data): +        if not self.character_data: +            self.character_pos = self.pos() +        self.character_data += data +     +    def finish_character_data(self): +        if self.character_data: +            if not self.skip_ws or not self.character_data.isspace():  +                line, column = self.character_pos +                token = XmlToken(CHARACTER_DATA, self.character_data, None, line, column) +                self.tokens.append(token) +            self.character_data = '' +     +    def next(self): +        size = 16*1024 +        while self.index >= len(self.tokens) and not self.final: +            self.tokens = [] +            self.index = 0 +            data = self.fp.read(size) +            self.final = len(data) < size +            data = data.rstrip('\0') +            try: +                self.parser.Parse(data, self.final) +            except xml.parsers.expat.ExpatError, e: +                #if e.code == xml.parsers.expat.errors.XML_ERROR_NO_ELEMENTS: +                if e.code == 3: +                    pass +                else: +                    raise e +        if self.index >= len(self.tokens): +            line, column = self.pos() +            token = XmlToken(EOF, None, None, line, column) +        else: +            token = self.tokens[self.index] +            self.index += 1 +        return token + +    def pos(self): +        return self.parser.CurrentLineNumber, self.parser.CurrentColumnNumber + + +class TokenMismatch(Exception): + +    def __init__(self, expected, found): +        self.expected = expected +        self.found = found + +    def __str__(self): +        return '%u:%u: %s expected, %s found' % (self.found.line, self.found.column, str(self.expected), str(self.found)) + + + +class XmlParser: +    """Base XML document parser.""" + +    def __init__(self, fp): +        self.tokenizer = XmlTokenizer(fp) +        self.consume() +     +    def consume(self): +        self.token = self.tokenizer.next() + +    def match_element_start(self, name): +        return self.token.type == ELEMENT_START and self.token.name_or_data == name +     +    def match_element_end(self, name): +        return self.token.type == ELEMENT_END and self.token.name_or_data == name + +    def element_start(self, name): +        while self.token.type == CHARACTER_DATA: +            self.consume() +        if self.token.type != ELEMENT_START: +            raise TokenMismatch(XmlToken(ELEMENT_START, name), self.token) +        if self.token.name_or_data != name: +            raise TokenMismatch(XmlToken(ELEMENT_START, name), self.token) +        attrs = self.token.attrs +        self.consume() +        return attrs +     +    def element_end(self, name): +        while self.token.type == CHARACTER_DATA: +            self.consume() +        if self.token.type != ELEMENT_END: +            raise TokenMismatch(XmlToken(ELEMENT_END, name), self.token) +        if self.token.name_or_data != name: +            raise TokenMismatch(XmlToken(ELEMENT_END, name), self.token) +        self.consume() + +    def character_data(self, strip = True): +        data = '' +        while self.token.type == CHARACTER_DATA: +            data += self.token.name_or_data +            self.consume() +        if strip: +            data = data.strip() +        return data + + +class TraceParser(XmlParser): + +    def parse(self): +        self.element_start('trace') +        while self.token.type not in (ELEMENT_END, EOF): +            call = self.parse_call() +            self.handle_call(call) +        if self.token.type != EOF: +            self.element_end('trace') + +    def parse_call(self): +        attrs = self.element_start('call') +        klass = attrs['class'] +        method = attrs['method'] +        args = [] +        ret = None +        while self.token.type == ELEMENT_START: +            if self.token.name_or_data == 'arg': +                arg = self.parse_arg() +                args.append(arg) +            elif self.token.name_or_data == 'ret': +                ret = self.parse_ret() +            elif self.token.name_or_data == 'call': +                # ignore nested function calls +                self.parse_call() +            else: +                raise TokenMismatch("<arg ...> or <ret ...>", self.token) +        self.element_end('call') +         +        return Call(klass, method, args, ret) + +    def parse_arg(self): +        attrs = self.element_start('arg') +        name = attrs['name'] +        value = self.parse_value() +        self.element_end('arg') + +        return name, value + +    def parse_ret(self): +        attrs = self.element_start('ret') +        value = self.parse_value() +        self.element_end('ret') + +        return value + +    def parse_value(self): +        expected_tokens = ('null', 'bool', 'int', 'uint', 'float', 'string', 'enum', 'array', 'struct', 'ptr', 'bytes') +        if self.token.type == ELEMENT_START: +            if self.token.name_or_data in expected_tokens: +                method = getattr(self, 'parse_' +  self.token.name_or_data) +                return method() +        raise TokenMismatch(" or " .join(expected_tokens), self.token) + +    def parse_null(self): +        self.element_start('null') +        self.element_end('null') +        return Literal(None) +         +    def parse_bool(self): +        self.element_start('bool') +        value = int(self.character_data()) +        self.element_end('bool') +        return Literal(value) +         +    def parse_int(self): +        self.element_start('int') +        value = int(self.character_data()) +        self.element_end('int') +        return Literal(value) +         +    def parse_uint(self): +        self.element_start('uint') +        value = int(self.character_data()) +        self.element_end('uint') +        return Literal(value) +         +    def parse_float(self): +        self.element_start('float') +        value = float(self.character_data()) +        self.element_end('float') +        return Literal(value) +         +    def parse_enum(self): +        self.element_start('enum') +        name = self.character_data() +        self.element_end('enum') +        return NamedConstant(name) +         +    def parse_string(self): +        self.element_start('string') +        value = self.character_data() +        self.element_end('string') +        return Literal(value) +         +    def parse_bytes(self): +        self.element_start('bytes') +        value = binascii.a2b_hex(self.character_data()) +        self.element_end('bytes') +        return Literal(value) +         +    def parse_array(self): +        self.element_start('array') +        elems = [] +        while self.token.type != ELEMENT_END: +            elems.append(self.parse_elem()) +        self.element_end('array') +        return Array(elems) + +    def parse_elem(self): +        self.element_start('elem') +        value = self.parse_value() +        self.element_end('elem') +        return value + +    def parse_struct(self): +        attrs = self.element_start('struct') +        name = attrs['name'] +        members = [] +        while self.token.type != ELEMENT_END: +            members.append(self.parse_member()) +        self.element_end('struct') +        return Struct(name, members) + +    def parse_member(self): +        attrs = self.element_start('member') +        name = attrs['name'] +        value = self.parse_value() +        self.element_end('member') + +        return name, value + +    def parse_ptr(self): +        self.element_start('ptr') +        address = self.character_data() +        self.element_end('ptr') + +        return Pointer(address) + +    def handle_call(self, call): +        pass +     +     +class TraceDumper(TraceParser): +     +    def __init__(self, fp): +        TraceParser.__init__(self, fp) +        self.formatter = format.DefaultFormatter(sys.stdout) +        self.pretty_printer = PrettyPrinter(self.formatter) + +    def handle_call(self, call): +        call.visit(self.pretty_printer) +        self.formatter.newline() +         + +def main(ParserFactory): +    for arg in sys.argv[1:]: +        if arg.endswith('.gz'): +            import gzip +            stream = gzip.GzipFile(arg, 'rt') +        else: +            stream = open(arg, 'rt') +        parser = ParserFactory(stream) +        parser.parse() + + +if __name__ == '__main__': +    main(TraceDumper) diff --git a/src/gallium/state_trackers/python/samples/tri.py b/src/gallium/state_trackers/python/samples/tri.py new file mode 100644 index 0000000000..193479f7d6 --- /dev/null +++ b/src/gallium/state_trackers/python/samples/tri.py @@ -0,0 +1,229 @@ +#!/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. +#  +########################################################################## + + +from gallium import * + + +def make_image(surface): +    pixels = FloatArray(surface.height*surface.width*4) +    surface.get_tile_rgba(0, 0, surface.width, surface.height, pixels) + +    import Image +    outimage = Image.new( +        mode='RGB', +        size=(surface.width, surface.height), +        color=(0,0,0)) +    outpixels = outimage.load() +    for y in range(0, surface.height): +        for x in range(0, surface.width): +            offset = (y*surface.width + x)*4 +            r, g, b, a = [int(pixels[offset + ch]*255) for ch in range(4)] +            outpixels[x, y] = r, g, b +    return outimage + +def save_image(filename, surface): +    outimage = make_image(surface) +    outimage.save(filename, "PNG") + +def show_image(surface): +    outimage = make_image(surface) +     +    import Tkinter as tk +    from PIL import Image, ImageTk +    root = tk.Tk() +     +    root.title('background image') +     +    image1 = ImageTk.PhotoImage(outimage) +    w = image1.width() +    h = image1.height() +    x = 100 +    y = 100 +    root.geometry("%dx%d+%d+%d" % (w, h, x, y)) +    panel1 = tk.Label(root, image=image1) +    panel1.pack(side='top', fill='both', expand='yes') +    panel1.image = image1 +    root.mainloop() + + +def test(dev): +    ctx = dev.context_create() + +    width = 255 +    height = 255 + +    # 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.scissor = 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_NONE +    sampler.min_img_filter = PIPE_TEX_MIPFILTER_NEAREST +    sampler.mag_img_filter = PIPE_TEX_MIPFILTER_NEAREST +    sampler.normalized_coords = 1 +    ctx.set_sampler(0, sampler) + +    # scissor +    scissor = Scissor() +    scissor.minx = 0 +    scissor.miny = 0 +    scissor.maxx = width +    scissor.maxy = height +    ctx.set_scissor(scissor) + +    clip = Clip() +    clip.nr = 0 +    ctx.set_clip(clip) + +    # framebuffer +    cbuf = dev.texture_create( +        PIPE_FORMAT_X8R8G8B8_UNORM,  +        width, height, +        tex_usage=PIPE_TEXTURE_USAGE_DISPLAY_TARGET, +    ) +    _cbuf = cbuf.get_surface(usage = PIPE_BUFFER_USAGE_GPU_READ|PIPE_BUFFER_USAGE_GPU_WRITE) +    fb = Framebuffer() +    fb.width = width +    fb.height = height +    fb.num_cbufs = 1 +    fb.set_cbuf(0, _cbuf) +    ctx.set_framebuffer(fb) +    _cbuf.clear_value = 0x00000000 +    ctx.surface_clear(_cbuf, _cbuf.clear_value) +    del _cbuf +     +    # vertex shader +    vs = Shader(''' +        VERT1.1 +        DCL IN[0], POSITION, CONSTANT +        DCL IN[1], COLOR, CONSTANT +        DCL OUT[0], POSITION, CONSTANT +        DCL OUT[1], COLOR, CONSTANT +        0:MOV OUT[0], IN[0] +        1:MOV OUT[1], IN[1] +        2:END +    ''') +    ctx.set_vertex_shader(vs) + +    # fragment shader +    fs = Shader(''' +        FRAG1.1 +        DCL IN[0], COLOR, LINEAR +        DCL OUT[0], COLOR, CONSTANT +        0:MOV OUT[0], IN[0] +        1:END +    ''') +    ctx.set_fragment_shader(fs) + +    nverts = 3 +    nattrs = 2 +    verts = FloatArray(nverts * nattrs * 4) + +    verts[ 0] = 128.0 # x1 +    verts[ 1] =  32.0 # y1 +    verts[ 2] =   0.0 # z1 +    verts[ 3] =   1.0 # w1 +    verts[ 4] =   1.0 # r1 +    verts[ 5] =   0.0 # g1 +    verts[ 6] =   0.0 # b1 +    verts[ 7] =   1.0 # a1 +    verts[ 8] =  32.0 # x2 +    verts[ 9] = 224.0 # y2 +    verts[10] =   0.0 # z2 +    verts[11] =   1.0 # w2 +    verts[12] =   0.0 # r2 +    verts[13] =   1.0 # g2 +    verts[14] =   0.0 # b2 +    verts[15] =   1.0 # a2 +    verts[16] = 224.0 # x3 +    verts[17] = 224.0 # y3 +    verts[18] =   0.0 # z3 +    verts[19] =   1.0 # w3 +    verts[20] =   0.0 # r3 +    verts[21] =   0.0 # g3 +    verts[22] =   1.0 # b3 +    verts[23] =   1.0 # a3 + +    ctx.draw_vertices(PIPE_PRIM_TRIANGLES, +                      nverts,  +                      nattrs,  +                      verts) + +    ctx.flush() +     +    show_image(cbuf.get_surface(usage = PIPE_BUFFER_USAGE_CPU_READ|PIPE_BUFFER_USAGE_CPU_WRITE)) +    #save_image('tri.png', cbuf.get_surface(usage = PIPE_BUFFER_USAGE_CPU_READ|PIPE_BUFFER_USAGE_CPU_WRITE)) + + + +def main(): +    dev = Device() +    test(dev) + + +if __name__ == '__main__': +    main() diff --git a/src/gallium/state_trackers/python/st_device.c b/src/gallium/state_trackers/python/st_device.c new file mode 100644 index 0000000000..95c1378a03 --- /dev/null +++ b/src/gallium/state_trackers/python/st_device.c @@ -0,0 +1,323 @@ +/************************************************************************** + *  + * 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. + *  + **************************************************************************/ + + +#include "pipe/p_winsys.h" +#include "pipe/p_context.h" +#include "pipe/p_shader_tokens.h" +#include "pipe/p_inlines.h" +#include "cso_cache/cso_context.h" +#include "util/u_math.h" +#include "util/u_memory.h" +#include "util/u_simple_shaders.h" +#include "trace/tr_screen.h" +#include "trace/tr_context.h" + +#include "st_device.h" +#include "st_winsys.h" + + +static void +st_device_really_destroy(struct st_device *st_dev)  +{ +   if(st_dev->screen) +      st_dev->screen->destroy(st_dev->screen); +    +   FREE(st_dev); +} + + +void +st_device_destroy(struct st_device *st_dev)  +{ +   if(!--st_dev->refcount) +      st_device_really_destroy(st_dev); +} + + +static struct st_device * +st_device_create_from_st_winsys(const struct st_winsys *st_ws)  +{ +   struct st_device *st_dev; +    +   if(!st_ws->screen_create || +      !st_ws->context_create) +      return NULL; +    +   st_dev = CALLOC_STRUCT(st_device); +   if(!st_dev) +      return NULL; +    +   st_dev->refcount = 1; +   st_dev->st_ws = st_ws; +    +   st_dev->real_screen = st_ws->screen_create(); +   if(!st_dev->real_screen) { +      st_device_destroy(st_dev); +      return NULL; +   } + +   st_dev->screen = trace_screen_create(st_dev->real_screen); +   if(!st_dev->screen) { +      st_device_destroy(st_dev); +      return NULL; +   } +    +   return st_dev; +} + + +struct st_device * +st_device_create(boolean hardware) { +   if(hardware) +      return st_device_create_from_st_winsys(&st_hardpipe_winsys); +   else +      return st_device_create_from_st_winsys(&st_softpipe_winsys); +} + + +void +st_context_destroy(struct st_context *st_ctx)  +{ +   unsigned i; +    +   if(st_ctx) { +      struct st_device *st_dev = st_ctx->st_dev; +       +      if(st_ctx->cso) { +         cso_delete_vertex_shader(st_ctx->cso, st_ctx->vs); +         cso_delete_fragment_shader(st_ctx->cso, st_ctx->fs); +          +         cso_destroy_context(st_ctx->cso); +      } +       +      if(st_ctx->pipe) +         st_ctx->pipe->destroy(st_ctx->pipe); +       +      for(i = 0; i < PIPE_MAX_SAMPLERS; ++i) +         pipe_texture_reference(&st_ctx->sampler_textures[i], NULL); +      pipe_texture_reference(&st_ctx->default_texture, NULL); + +      FREE(st_ctx); +       +      if(!--st_dev->refcount) +         st_device_really_destroy(st_dev); +   } +} + + +struct st_context * +st_context_create(struct st_device *st_dev)  +{ +   struct st_context *st_ctx; +    +   st_ctx = CALLOC_STRUCT(st_context); +   if(!st_ctx) +      return NULL; +    +   st_ctx->st_dev = st_dev; +   ++st_dev->refcount; +    +   st_ctx->real_pipe = st_dev->st_ws->context_create(st_dev->real_screen); +   if(!st_ctx->real_pipe) { +      st_context_destroy(st_ctx); +      return NULL; +   } +    +   st_ctx->pipe = trace_context_create(st_dev->screen, st_ctx->real_pipe); +   if(!st_ctx->pipe) { +      st_context_destroy(st_ctx); +      return NULL; +   } + +   st_ctx->cso = cso_create_context(st_ctx->pipe); +   if(!st_ctx->cso) { +      st_context_destroy(st_ctx); +      return NULL; +   } +    +   /* disabled blending/masking */ +   { +      struct pipe_blend_state blend; +      memset(&blend, 0, sizeof(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; +      cso_set_blend(st_ctx->cso, &blend); +   } + +   /* no-op depth/stencil/alpha */ +   { +      struct pipe_depth_stencil_alpha_state depthstencil; +      memset(&depthstencil, 0, sizeof(depthstencil)); +      cso_set_depth_stencil_alpha(st_ctx->cso, &depthstencil); +   } + +   /* rasterizer */ +   { +      struct pipe_rasterizer_state rasterizer; +      memset(&rasterizer, 0, sizeof(rasterizer)); +      rasterizer.front_winding = PIPE_WINDING_CW; +      rasterizer.cull_mode = PIPE_WINDING_NONE; +      rasterizer.bypass_clipping = 1; +      /*rasterizer.bypass_vs = 1;*/ +      cso_set_rasterizer(st_ctx->cso, &rasterizer); +   } + +   /* identity viewport */ +   { +      struct pipe_viewport_state viewport; +      viewport.scale[0] = 1.0; +      viewport.scale[1] = 1.0; +      viewport.scale[2] = 1.0; +      viewport.scale[3] = 1.0; +      viewport.translate[0] = 0.0; +      viewport.translate[1] = 0.0; +      viewport.translate[2] = 0.0; +      viewport.translate[3] = 0.0; +      cso_set_viewport(st_ctx->cso, &viewport); +   } + +   /* samplers */ +   { +      struct pipe_sampler_state sampler; +      unsigned i; +      memset(&sampler, 0, sizeof(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; +      for (i = 0; i < PIPE_MAX_SAMPLERS; i++) +         cso_single_sampler(st_ctx->cso, i, &sampler); +      cso_single_sampler_done(st_ctx->cso); +   } + +   /* default textures */ +   { +      struct pipe_screen *screen = st_dev->screen; +      struct pipe_texture templat; +      struct pipe_surface *surface; +      unsigned i; + +      memset( &templat, 0, sizeof( templat ) ); +      templat.target = PIPE_TEXTURE_2D; +      templat.format = PIPE_FORMAT_A8R8G8B8_UNORM; +      templat.block.size = 4; +      templat.block.width = 1; +      templat.block.height = 1; +      templat.width[0] = 1; +      templat.height[0] = 1; +      templat.depth[0] = 1; +      templat.last_level = 0; +    +      st_ctx->default_texture = screen->texture_create( screen, &templat ); +      if(st_ctx->default_texture) { +         surface = screen->get_tex_surface( screen,  +                                            st_ctx->default_texture, 0, 0, 0, +                                            PIPE_BUFFER_USAGE_CPU_WRITE ); +         if(surface) { +            uint32_t *map; +            map = (uint32_t *) pipe_surface_map(surface, PIPE_BUFFER_USAGE_CPU_WRITE ); +            if(map) { +               *map = 0x00000000; +               pipe_surface_unmap( surface ); +            } +            pipe_surface_reference(&surface, NULL); +         } +      } +    +      for (i = 0; i < PIPE_MAX_SAMPLERS; i++) +         pipe_texture_reference(&st_ctx->sampler_textures[i], st_ctx->default_texture); +       +      cso_set_sampler_textures(st_ctx->cso, PIPE_MAX_SAMPLERS, st_ctx->sampler_textures); +   } +    +   /* vertex shader */ +   { +      struct pipe_shader_state vert_shader; + +      const uint semantic_names[] = { TGSI_SEMANTIC_POSITION, +                                      TGSI_SEMANTIC_GENERIC }; +      const uint semantic_indexes[] = { 0, 0 }; +      st_ctx->vs = util_make_vertex_passthrough_shader(st_ctx->pipe,  +                                                       2,  +                                                       semantic_names, +                                                       semantic_indexes, +                                                       &vert_shader); +      cso_set_vertex_shader_handle(st_ctx->cso, st_ctx->vs); +   } + +   /* fragment shader */ +   { +      struct pipe_shader_state frag_shader; +      st_ctx->fs = util_make_fragment_passthrough_shader(st_ctx->pipe,  +                                                         &frag_shader); +      cso_set_fragment_shader_handle(st_ctx->cso, st_ctx->fs); +   } + +   return st_ctx; +} + + +void +st_buffer_destroy(struct st_buffer *st_buf) +{ +   if(st_buf) { +      struct pipe_screen *screen = st_buf->st_dev->screen; +      pipe_buffer_reference(screen, &st_buf->buffer, NULL); +      FREE(st_buf); +   } +} + + +struct st_buffer * +st_buffer_create(struct st_device *st_dev, +                 unsigned alignment, unsigned usage, unsigned size) +{ +   struct pipe_screen *screen = st_dev->screen; +   struct st_buffer *st_buf; +    +   st_buf = CALLOC_STRUCT(st_buffer); +   if(!st_buf) +      return NULL; + +   st_buf->st_dev = st_dev; +    +   st_buf->buffer = pipe_buffer_create(screen, alignment, usage, size); +   if(!st_buf->buffer) { +      st_buffer_destroy(st_buf); +      return NULL; +   } +    +   return st_buf; +} + diff --git a/src/gallium/state_trackers/python/st_device.h b/src/gallium/state_trackers/python/st_device.h new file mode 100644 index 0000000000..7cfe6de9f6 --- /dev/null +++ b/src/gallium/state_trackers/python/st_device.h @@ -0,0 +1,101 @@ +/************************************************************************** + *  + * 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. + *  + **************************************************************************/ + + +#ifndef ST_DEVICE_H_ +#define ST_DEVICE_H_ + + +#include "pipe/p_state.h" + +struct cso_context; +struct pipe_screen; +struct pipe_context; +struct st_winsys;  + + +struct st_buffer { +   struct st_device *st_dev; +    +   struct pipe_buffer *buffer; +}; + + +struct st_context { +   struct st_device *st_dev; +    +   struct pipe_context *real_pipe; +   struct pipe_context *pipe; +    +   struct cso_context *cso; +    +   void *vs; +   void *fs; + +   struct pipe_texture *default_texture; +   struct pipe_texture *sampler_textures[PIPE_MAX_SAMPLERS]; +    +   unsigned num_vertex_buffers; +   struct pipe_vertex_buffer vertex_buffers[PIPE_MAX_ATTRIBS]; +    +   unsigned num_vertex_elements; +   struct pipe_vertex_element vertex_elements[PIPE_MAX_ATTRIBS]; +}; + + +struct st_device { +   const struct st_winsys *st_ws;  + +   struct pipe_screen *real_screen; +   struct pipe_screen *screen; +    +   /* FIXME: we also need to refcount for textures and surfaces... */ +   unsigned refcount; +}; + + +struct st_buffer * +st_buffer_create(struct st_device *st_dev, +                 unsigned alignment, unsigned usage, unsigned size); + +void +st_buffer_destroy(struct st_buffer *st_buf); + +struct st_context * +st_context_create(struct st_device *st_dev); + +void +st_context_destroy(struct st_context *st_ctx); + +struct st_device * +st_device_create(boolean hardware); + +void +st_device_destroy(struct st_device *st_dev); + + +#endif /* ST_DEVICE_H_ */ diff --git a/src/gallium/state_trackers/python/st_hardpipe_winsys.c b/src/gallium/state_trackers/python/st_hardpipe_winsys.c new file mode 100644 index 0000000000..8b33c70fd7 --- /dev/null +++ b/src/gallium/state_trackers/python/st_hardpipe_winsys.c @@ -0,0 +1,62 @@ +/************************************************************************** + *  + * Copyright 2008 Tungsten Graphics, Inc., Bismarck, ND., USA + * 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 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 + * THE COPYRIGHT HOLDERS, AUTHORS 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. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + *  + *  + **************************************************************************/ + +/** + * @file + * Stub for hardware pipe driver support. + */ + + +#include "pipe/p_compiler.h" + +#include "st_winsys.h" + + +/* XXX: Force init_gallium symbol to be linked */ +extern void init_gallium(void); +void (*force_init_gallium_linkage)(void) = &init_gallium; + + +static struct pipe_screen * +st_hardpipe_screen_create(void) +{ +   return st_softpipe_winsys.screen_create(); +} + + +static struct pipe_context * +st_hardpipe_context_create(struct pipe_screen *screen) +{ +   return st_softpipe_winsys.context_create(screen); +} + + +const struct st_winsys st_hardpipe_winsys = { +   &st_hardpipe_screen_create, +   &st_hardpipe_context_create +}; diff --git a/src/gallium/state_trackers/python/st_sample.c b/src/gallium/state_trackers/python/st_sample.c new file mode 100644 index 0000000000..7765df3c4a --- /dev/null +++ b/src/gallium/state_trackers/python/st_sample.c @@ -0,0 +1,549 @@ +/************************************************************************** + *  + * 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. + *  + **************************************************************************/ + + +#include "pipe/p_compiler.h" +#include "pipe/p_format.h" +#include "pipe/p_state.h" +#include "pipe/p_inlines.h" +#include "util/u_tile.h" +#include "util/u_math.h" +#include "util/u_memory.h" + +#include "st_sample.h" + + +/** + * Use our own pseudo random generator to ensure consistent runs among + * multiple runs and platforms. + *  + * @sa http://en.wikipedia.org/wiki/Linear_congruential_generator + */ +static uint32_t st_random(void) { +   static uint64_t seed = UINT64_C(0xbb9a063afb0a739d); + +   seed = UINT64_C(134775813) * seed + UINT64_C(1); +    +   return (uint16_t)(seed >> 32);  +} + + +/** + * We don't want to include the patent-encumbered DXT code here, so instead + * we store several uncompressed/compressed data pairs for hardware testing + * purposes.  + */ +struct dxt_data +{ +   uint8_t rgba[16*4]; +   uint8_t raw[16]; +}; + + +static const struct dxt_data  +dxt1_rgb_data[] = { +   { +      { +         0x99, 0xb0, 0x8e, 0xff, +         0x5d, 0x62, 0x89, 0xff, +         0x99, 0xb0, 0x8e, 0xff, +         0x99, 0xb0, 0x8e, 0xff, +         0xd6, 0xff, 0x94, 0xff, +         0x5d, 0x62, 0x89, 0xff, +         0x99, 0xb0, 0x8e, 0xff, +         0xd6, 0xff, 0x94, 0xff, +         0x5d, 0x62, 0x89, 0xff, +         0x5d, 0x62, 0x89, 0xff, +         0x99, 0xb0, 0x8e, 0xff, +         0x21, 0x14, 0x84, 0xff, +         0x5d, 0x62, 0x89, 0xff, +         0x21, 0x14, 0x84, 0xff, +         0x21, 0x14, 0x84, 0xff, +         0x99, 0xb0, 0x8e, 0xff +      }, +      {0xf2, 0xd7, 0xb0, 0x20, 0xae, 0x2c, 0x6f, 0x97} +   }, +   { +      { +         0xb5, 0xcf, 0x9c, 0xff, +         0x83, 0x8c, 0x8b, 0xff, +         0x21, 0x08, 0x6b, 0xff, +         0x83, 0x8c, 0x8b, 0xff, +         0x52, 0x4a, 0x7b, 0xff, +         0x83, 0x8c, 0x8b, 0xff, +         0x83, 0x8c, 0x8b, 0xff, +         0xb5, 0xcf, 0x9c, 0xff, +         0x21, 0x08, 0x6b, 0xff, +         0xb5, 0xcf, 0x9c, 0xff, +         0x83, 0x8c, 0x8b, 0xff, +         0x52, 0x4a, 0x7b, 0xff, +         0xb5, 0xcf, 0x9c, 0xff, +         0x83, 0x8c, 0x8b, 0xff, +         0x52, 0x4a, 0x7b, 0xff, +         0x83, 0x8c, 0x8b, 0xff +      }, +      {0x73, 0xb6, 0x4d, 0x20, 0x98, 0x2b, 0xe1, 0xb8} +   }, +   { +      { +         0x00, 0x2c, 0xff, 0xff, +         0x94, 0x8d, 0x7b, 0xff, +         0x4a, 0x5c, 0xbd, 0xff, +         0x4a, 0x5c, 0xbd, 0xff, +         0x4a, 0x5c, 0xbd, 0xff, +         0x94, 0x8d, 0x7b, 0xff, +         0x94, 0x8d, 0x7b, 0xff, +         0x94, 0x8d, 0x7b, 0xff, +         0xde, 0xbe, 0x39, 0xff, +         0x94, 0x8d, 0x7b, 0xff, +         0xde, 0xbe, 0x39, 0xff, +         0xde, 0xbe, 0x39, 0xff, +         0xde, 0xbe, 0x39, 0xff, +         0xde, 0xbe, 0x39, 0xff, +         0xde, 0xbe, 0x39, 0xff, +         0x94, 0x8d, 0x7b, 0xff +      }, +      {0xe7, 0xdd, 0x7f, 0x01, 0xf9, 0xab, 0x08, 0x80} +   }, +   { +      { +         0x6b, 0x24, 0x21, 0xff, +         0x7b, 0x4f, 0x5d, 0xff, +         0x7b, 0x4f, 0x5d, 0xff, +         0x8b, 0x7a, 0x99, 0xff, +         0x7b, 0x4f, 0x5d, 0xff, +         0x7b, 0x4f, 0x5d, 0xff, +         0x6b, 0x24, 0x21, 0xff, +         0x8b, 0x7a, 0x99, 0xff, +         0x9c, 0xa6, 0xd6, 0xff, +         0x6b, 0x24, 0x21, 0xff, +         0x7b, 0x4f, 0x5d, 0xff, +         0x8b, 0x7a, 0x99, 0xff, +         0x6b, 0x24, 0x21, 0xff, +         0x8b, 0x7a, 0x99, 0xff, +         0x7b, 0x4f, 0x5d, 0xff, +         0x9c, 0xa6, 0xd6, 0xff +      }, +      {0x3a, 0x9d, 0x24, 0x69, 0xbd, 0x9f, 0xb4, 0x39} +   } +}; + + +static const struct dxt_data  +dxt1_rgba_data[] = { +   { +      { +         0x00, 0x00, 0x00, 0x00, +         0x4e, 0xaa, 0x90, 0xff, +         0x4e, 0xaa, 0x90, 0xff, +         0x00, 0x00, 0x00, 0x00, +         0x4e, 0xaa, 0x90, 0xff, +         0x29, 0xff, 0xff, 0xff, +         0x00, 0x00, 0x00, 0x00, +         0x4e, 0xaa, 0x90, 0xff, +         0x73, 0x55, 0x21, 0xff, +         0x00, 0x00, 0x00, 0x00, +         0x00, 0x00, 0x00, 0x00, +         0x4e, 0xaa, 0x90, 0xff, +         0x4e, 0xaa, 0x90, 0xff, +         0x00, 0x00, 0x00, 0x00, +         0x00, 0x00, 0x00, 0x00, +         0x4e, 0xaa, 0x90, 0xff +      }, +      {0xff, 0x2f, 0xa4, 0x72, 0xeb, 0xb2, 0xbd, 0xbe} +   }, +   { +      { +         0xb5, 0xe3, 0x63, 0xff, +         0x00, 0x00, 0x00, 0x00, +         0x6b, 0x24, 0x84, 0xff, +         0xb5, 0xe3, 0x63, 0xff, +         0x00, 0x00, 0x00, 0x00, +         0xb5, 0xe3, 0x63, 0xff, +         0x00, 0x00, 0x00, 0x00, +         0x00, 0x00, 0x00, 0x00, +         0x00, 0x00, 0x00, 0x00, +         0x00, 0x00, 0x00, 0x00, +         0x6b, 0x24, 0x84, 0xff, +         0x6b, 0x24, 0x84, 0xff, +         0x00, 0x00, 0x00, 0x00, +         0xb5, 0xe3, 0x63, 0xff, +         0x90, 0x83, 0x73, 0xff, +         0xb5, 0xe3, 0x63, 0xff +      }, +      {0x30, 0x69, 0x0c, 0xb7, 0x4d, 0xf7, 0x0f, 0x67} +   }, +   { +      { +         0x00, 0x00, 0x00, 0x00, +         0xc6, 0x86, 0x8c, 0xff, +         0xc6, 0x86, 0x8c, 0xff, +         0x21, 0x65, 0x42, 0xff, +         0x21, 0x65, 0x42, 0xff, +         0x21, 0x65, 0x42, 0xff, +         0x21, 0x65, 0x42, 0xff, +         0x00, 0x00, 0x00, 0x00, +         0x00, 0x00, 0x00, 0x00, +         0x21, 0x65, 0x42, 0xff, +         0xc6, 0x86, 0x8c, 0xff, +         0x00, 0x00, 0x00, 0x00, +         0x00, 0x00, 0x00, 0x00, +         0x00, 0x00, 0x00, 0x00, +         0x00, 0x00, 0x00, 0x00, +         0xc6, 0x86, 0x8c, 0xff +      }, +      {0x28, 0x23, 0x31, 0xc4, 0x17, 0xc0, 0xd3, 0x7f} +   }, +   { +      { +         0x00, 0x00, 0x00, 0x00, +         0x00, 0x00, 0x00, 0x00, +         0x00, 0x00, 0x00, 0x00, +         0xc6, 0xe3, 0x9c, 0xff, +         0x7b, 0x1c, 0x52, 0xff, +         0x00, 0x00, 0x00, 0x00, +         0x00, 0x00, 0x00, 0x00, +         0x00, 0x00, 0x00, 0x00, +         0x00, 0x00, 0x00, 0x00, +         0x7b, 0x1c, 0x52, 0xff, +         0x00, 0x00, 0x00, 0x00, +         0x7b, 0x1c, 0x52, 0xff, +         0xa0, 0x7f, 0x77, 0xff, +         0xc6, 0xe3, 0x9c, 0xff, +         0x00, 0x00, 0x00, 0x00, +         0xa0, 0x7f, 0x77, 0xff +      }, +      {0xea, 0x78, 0x13, 0xc7, 0x7f, 0xfc, 0x33, 0xb6} +   }, +}; + + +static const struct dxt_data  +dxt3_rgba_data[] = { +   { +      { +         0x6d, 0xc6, 0x96, 0x77, +         0x6d, 0xc6, 0x96, 0xee, +         0x6d, 0xc6, 0x96, 0xaa, +         0x8c, 0xff, 0xb5, 0x44, +         0x6d, 0xc6, 0x96, 0xff, +         0x6d, 0xc6, 0x96, 0x88, +         0x31, 0x55, 0x5a, 0x66, +         0x6d, 0xc6, 0x96, 0x99, +         0x31, 0x55, 0x5a, 0xbb, +         0x31, 0x55, 0x5a, 0x55, +         0x31, 0x55, 0x5a, 0x11, +         0x6d, 0xc6, 0x96, 0xcc, +         0x6d, 0xc6, 0x96, 0xcc, +         0x6d, 0xc6, 0x96, 0x11, +         0x31, 0x55, 0x5a, 0x44, +         0x31, 0x55, 0x5a, 0x88 +      }, +      {0xe7, 0x4a, 0x8f, 0x96, 0x5b, 0xc1, 0x1c, 0x84, 0xf6, 0x8f, 0xab, 0x32, 0x2a, 0x9a, 0x95, 0x5a} +   }, +   { +      { +         0xad, 0xeb, 0x73, 0x99, +         0x97, 0xaa, 0x86, 0x66, +         0x6b, 0x28, 0xad, 0x99, +         0xad, 0xeb, 0x73, 0x99, +         0x6b, 0x28, 0xad, 0x22, +         0xad, 0xeb, 0x73, 0xff, +         0x97, 0xaa, 0x86, 0x55, +         0x6b, 0x28, 0xad, 0x55, +         0x6b, 0x28, 0xad, 0x44, +         0xad, 0xeb, 0x73, 0x33, +         0x6b, 0x28, 0xad, 0xee, +         0x6b, 0x28, 0xad, 0x99, +         0x97, 0xaa, 0x86, 0x66, +         0xad, 0xeb, 0x73, 0xbb, +         0x97, 0xaa, 0x86, 0x99, +         0xad, 0xeb, 0x73, 0xbb +      }, +      {0x69, 0x99, 0xf2, 0x55, 0x34, 0x9e, 0xb6, 0xb9, 0x4e, 0xaf, 0x55, 0x69, 0x18, 0x61, 0x51, 0x22} +   }, +   { +      { +         0x63, 0xd7, 0xd6, 0x00, +         0x57, 0x62, 0x5d, 0xdd, +         0x57, 0x62, 0x5d, 0xcc, +         0x57, 0x62, 0x5d, 0xbb, +         0x52, 0x28, 0x21, 0xaa, +         0x57, 0x62, 0x5d, 0xcc, +         0x57, 0x62, 0x5d, 0xcc, +         0x57, 0x62, 0x5d, 0x66, +         0x57, 0x62, 0x5d, 0x22, +         0x57, 0x62, 0x5d, 0xdd, +         0x63, 0xd7, 0xd6, 0xee, +         0x57, 0x62, 0x5d, 0x33, +         0x63, 0xd7, 0xd6, 0x55, +         0x52, 0x28, 0x21, 0x55, +         0x57, 0x62, 0x5d, 0x11, +         0x5d, 0x9c, 0x99, 0xee +      }, +      {0xd0, 0xbc, 0xca, 0x6c, 0xd2, 0x3e, 0x55, 0xe1, 0xba, 0x66, 0x44, 0x51, 0xfc, 0xfd, 0xcf, 0xb4} +   }, +   { +      { +         0x94, 0x6f, 0x60, 0x22, +         0x94, 0x6f, 0x60, 0x22, +         0xc5, 0xab, 0x76, 0x11, +         0xc5, 0xab, 0x76, 0xee, +         0x63, 0x34, 0x4a, 0xdd, +         0x63, 0x34, 0x4a, 0x33, +         0x94, 0x6f, 0x60, 0x77, +         0xf7, 0xe7, 0x8c, 0x00, +         0x94, 0x6f, 0x60, 0x33, +         0x63, 0x34, 0x4a, 0xaa, +         0x94, 0x6f, 0x60, 0x77, +         0x63, 0x34, 0x4a, 0xcc, +         0x94, 0x6f, 0x60, 0xaa, +         0xf7, 0xe7, 0x8c, 0x99, +         0x63, 0x34, 0x4a, 0x44, +         0xc5, 0xab, 0x76, 0xaa +      }, +      {0x22, 0xe1, 0x3d, 0x07, 0xa3, 0xc7, 0x9a, 0xa4, 0x31, 0xf7, 0xa9, 0x61, 0xaf, 0x35, 0x77, 0x93} +   }, +}; + + +static const struct dxt_data  +dxt5_rgba_data[] = { +   { +      { +         0x6d, 0xc6, 0x96, 0x74, +         0x6d, 0xc6, 0x96, 0xf8, +         0x6d, 0xc6, 0x96, 0xb6, +         0x8c, 0xff, 0xb5, 0x53, +         0x6d, 0xc6, 0x96, 0xf8, +         0x6d, 0xc6, 0x96, 0x95, +         0x31, 0x55, 0x5a, 0x53, +         0x6d, 0xc6, 0x96, 0x95, +         0x31, 0x55, 0x5a, 0xb6, +         0x31, 0x55, 0x5a, 0x53, +         0x31, 0x55, 0x5a, 0x11, +         0x6d, 0xc6, 0x96, 0xd7, +         0x6d, 0xc6, 0x96, 0xb6, +         0x6d, 0xc6, 0x96, 0x11, +         0x31, 0x55, 0x5a, 0x32, +         0x31, 0x55, 0x5a, 0x95 +      }, +      {0xf8, 0x11, 0xc5, 0x0c, 0x9a, 0x73, 0xb4, 0x9c, 0xf6, 0x8f, 0xab, 0x32, 0x2a, 0x9a, 0x95, 0x5a} +   }, +   { +      { +         0xad, 0xeb, 0x73, 0xa1, +         0x97, 0xaa, 0x86, 0x65, +         0x6b, 0x28, 0xad, 0xa1, +         0xad, 0xeb, 0x73, 0xa1, +         0x6b, 0x28, 0xad, 0x2a, +         0xad, 0xeb, 0x73, 0xfb, +         0x97, 0xaa, 0x86, 0x47, +         0x6b, 0x28, 0xad, 0x65, +         0x6b, 0x28, 0xad, 0x47, +         0xad, 0xeb, 0x73, 0x47, +         0x6b, 0x28, 0xad, 0xdd, +         0x6b, 0x28, 0xad, 0xa1, +         0x97, 0xaa, 0x86, 0x65, +         0xad, 0xeb, 0x73, 0xbf, +         0x97, 0xaa, 0x86, 0xa1, +         0xad, 0xeb, 0x73, 0xbf +      }, +      {0xfb, 0x2a, 0x34, 0x19, 0xdc, 0xbf, 0xe8, 0x71, 0x4e, 0xaf, 0x55, 0x69, 0x18, 0x61, 0x51, 0x22} +   }, +   { +      { +         0x63, 0xd7, 0xd6, 0x00, +         0x57, 0x62, 0x5d, 0xf5, +         0x57, 0x62, 0x5d, 0xd2, +         0x57, 0x62, 0x5d, 0xaf, +         0x52, 0x28, 0x21, 0xaf, +         0x57, 0x62, 0x5d, 0xd2, +         0x57, 0x62, 0x5d, 0xd2, +         0x57, 0x62, 0x5d, 0x69, +         0x57, 0x62, 0x5d, 0x23, +         0x57, 0x62, 0x5d, 0xd2, +         0x63, 0xd7, 0xd6, 0xf5, +         0x57, 0x62, 0x5d, 0x46, +         0x63, 0xd7, 0xd6, 0x46, +         0x52, 0x28, 0x21, 0x69, +         0x57, 0x62, 0x5d, 0x23, +         0x5d, 0x9c, 0x99, 0xf5 +      }, +      {0xf5, 0x00, 0x81, 0x36, 0xa9, 0x17, 0xec, 0x1e, 0xba, 0x66, 0x44, 0x51, 0xfc, 0xfd, 0xcf, 0xb4} +   }, +   { +      { +         0x94, 0x6f, 0x60, 0x25, +         0x94, 0x6f, 0x60, 0x25, +         0xc5, 0xab, 0x76, 0x05, +         0xc5, 0xab, 0x76, 0xe8, +         0x63, 0x34, 0x4a, 0xe8, +         0x63, 0x34, 0x4a, 0x25, +         0x94, 0x6f, 0x60, 0x86, +         0xf7, 0xe7, 0x8c, 0x05, +         0x94, 0x6f, 0x60, 0x25, +         0x63, 0x34, 0x4a, 0xa7, +         0x94, 0x6f, 0x60, 0x66, +         0x63, 0x34, 0x4a, 0xc7, +         0x94, 0x6f, 0x60, 0xa7, +         0xf7, 0xe7, 0x8c, 0xa7, +         0x63, 0x34, 0x4a, 0x45, +         0xc5, 0xab, 0x76, 0xa7 +      }, +      {0xe8, 0x05, 0x7f, 0x80, 0x33, 0x5f, 0xb5, 0x79, 0x31, 0xf7, 0xa9, 0x61, 0xaf, 0x35, 0x77, 0x93} +   }, +}; + + +static INLINE void  +st_sample_dxt_pixel_block(enum pipe_format format,  +                          const struct pipe_format_block *block, +                          uint8_t *raw, +                          float *rgba, unsigned rgba_stride,  +                          unsigned w, unsigned h) +{ +   const struct dxt_data *data; +   unsigned n; +   unsigned i; +   unsigned x, y, ch; +    +   switch(format) { +   case PIPE_FORMAT_DXT1_RGB: +      data = dxt1_rgb_data; +      n = sizeof(dxt1_rgb_data)/sizeof(dxt1_rgb_data[0]); +      break; +   case PIPE_FORMAT_DXT1_RGBA: +      data = dxt1_rgba_data; +      n = sizeof(dxt1_rgba_data)/sizeof(dxt1_rgba_data[0]); +      break; +   case PIPE_FORMAT_DXT3_RGBA: +      data = dxt3_rgba_data; +      n = sizeof(dxt3_rgba_data)/sizeof(dxt3_rgba_data[0]); +      break; +   case PIPE_FORMAT_DXT5_RGBA: +      data = dxt5_rgba_data; +      n = sizeof(dxt5_rgba_data)/sizeof(dxt5_rgba_data[0]); +      break; +   default: +      assert(0); +   } +    +   i = st_random() % n; +    +   for(y = 0; y < h; ++y) +      for(x = 0; x < w; ++x) +         for(ch = 0; ch < 4; ++ch) +            rgba[y*rgba_stride + x*4 + ch] = (float)(data[i].rgba[y*4*4 + x*4 + ch])/255.0f; +    +   memcpy(raw, data[i].raw, block->size); +} + + +static INLINE void  +st_sample_generic_pixel_block(enum pipe_format format,  +                              const struct pipe_format_block *block, +                              uint8_t *raw, +                              float *rgba, unsigned rgba_stride, +                              unsigned w, unsigned h) +{ +   unsigned i; +   unsigned x, y, ch; +    +   for(i = 0; i < block->size; ++i) +      raw[i] = (uint8_t)st_random(); +    +    +   pipe_tile_raw_to_rgba(format, +                         raw, +                         w, h, +                         rgba, rgba_stride); +  +   if(format == PIPE_FORMAT_YCBCR || format == PIPE_FORMAT_YCBCR_REV) { +      for(y = 0; y < h; ++y) { +         for(x = 0; x < w; ++x) { +            for(ch = 0; ch < 4; ++ch) { +               unsigned offset = y*rgba_stride + x*4 + ch; +               rgba[offset] = CLAMP(rgba[offset], 0.0f, 1.0f); +            } +         } +      } +   } +} + + +/** + * Randomly sample pixels. + */ +void  +st_sample_pixel_block(enum pipe_format format, +                      const struct pipe_format_block *block, +                      void *raw, +                      float *rgba, unsigned rgba_stride, +                      unsigned w, unsigned h) +{ +   switch(format) { +   case PIPE_FORMAT_DXT1_RGB: +   case PIPE_FORMAT_DXT1_RGBA: +   case PIPE_FORMAT_DXT3_RGBA: +   case PIPE_FORMAT_DXT5_RGBA: +      st_sample_dxt_pixel_block(format, block, raw, rgba, rgba_stride, w, h); +      break; + +   default: +      st_sample_generic_pixel_block(format, block, raw, rgba, rgba_stride, w, h); +      break; +   } +} + + +void +st_sample_surface(struct pipe_surface *surface, float *rgba)  +{ +   const struct pipe_format_block *block = &surface->block; +   unsigned rgba_stride = surface->width*4; +   void *raw; +   unsigned x, y; + +   raw = pipe_surface_map(surface, PIPE_BUFFER_USAGE_CPU_READ); +   if(!raw) +      return; + +   for (y = 0; y < surface->nblocksy; ++y) { +      for(x = 0; x < surface->nblocksx; ++x) { +         st_sample_pixel_block(surface->format, +                               block, +                               (uint8_t*)raw + y*surface->stride + x*block->size,  +                               rgba + y*block->height*rgba_stride + x*block->width*4, +                               rgba_stride, +                               MIN2(block->width, surface->width - x*block->width),  +                               MIN2(block->height, surface->height - y*block->height)); +       } +   } +    +   pipe_surface_unmap(surface); +} diff --git a/src/gallium/state_trackers/python/st_sample.h b/src/gallium/state_trackers/python/st_sample.h new file mode 100644 index 0000000000..ff04a12613 --- /dev/null +++ b/src/gallium/state_trackers/python/st_sample.h @@ -0,0 +1,47 @@ +/************************************************************************** + *  + * 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. + *  + **************************************************************************/ + + +#ifndef ST_SAMPLE_H_ +#define ST_SAMPLE_H_ + + +#include "pipe/p_format.h" + + +void  +st_sample_pixel_block(enum pipe_format format, +                      const struct pipe_format_block *block, +                      void *raw, +                      float *rgba, unsigned rgba_stride, +                      unsigned w, unsigned h); + +void +st_sample_surface(struct pipe_surface *surface, float *rgba); + + +#endif /* ST_SAMPLE_H_ */ diff --git a/src/gallium/state_trackers/python/st_softpipe_winsys.c b/src/gallium/state_trackers/python/st_softpipe_winsys.c new file mode 100644 index 0000000000..f62113a469 --- /dev/null +++ b/src/gallium/state_trackers/python/st_softpipe_winsys.c @@ -0,0 +1,311 @@ +/************************************************************************** + *  + * Copyright 2007 Tungsten Graphics, Inc., Bismarck, ND., USA + * 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 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 + * THE COPYRIGHT HOLDERS, AUTHORS 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. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + *  + *  + **************************************************************************/ + +/** + * @file + * Softpipe support.  + *  + * @author Keith Whitwell + * @author Brian Paul + * @author Jose Fonseca + */ + + +#include "pipe/p_winsys.h" +#include "pipe/p_format.h" +#include "pipe/p_context.h" +#include "pipe/p_inlines.h" +#include "util/u_math.h" +#include "util/u_memory.h" +#include "softpipe/sp_winsys.h" +#include "st_winsys.h" + + +struct st_softpipe_buffer +{ +   struct pipe_buffer base; +   boolean userBuffer;  /** Is this a user-space buffer? */ +   void *data; +   void *mapped; +}; + + +/** Cast wrapper */ +static INLINE struct st_softpipe_buffer * +st_softpipe_buffer( struct pipe_buffer *buf ) +{ +   return (struct st_softpipe_buffer *)buf; +} + + +static void * +st_softpipe_buffer_map(struct pipe_winsys *winsys,  +                       struct pipe_buffer *buf, +                       unsigned flags) +{ +   struct st_softpipe_buffer *st_softpipe_buf = st_softpipe_buffer(buf); +   st_softpipe_buf->mapped = st_softpipe_buf->data; +   return st_softpipe_buf->mapped; +} + + +static void +st_softpipe_buffer_unmap(struct pipe_winsys *winsys,  +                         struct pipe_buffer *buf) +{ +   struct st_softpipe_buffer *st_softpipe_buf = st_softpipe_buffer(buf); +   st_softpipe_buf->mapped = NULL; +} + + +static void +st_softpipe_buffer_destroy(struct pipe_winsys *winsys, +                           struct pipe_buffer *buf) +{ +   struct st_softpipe_buffer *oldBuf = st_softpipe_buffer(buf); + +   if (oldBuf->data) { +      if (!oldBuf->userBuffer) +         align_free(oldBuf->data); + +      oldBuf->data = NULL; +   } + +   FREE(oldBuf); +} + + +static void +st_softpipe_flush_frontbuffer(struct pipe_winsys *winsys, +                              struct pipe_surface *surf, +                              void *context_private) +{ +} + + + +static const char * +st_softpipe_get_name(struct pipe_winsys *winsys) +{ +   return "softpipe"; +} + + +static struct pipe_buffer * +st_softpipe_buffer_create(struct pipe_winsys *winsys,  +                          unsigned alignment,  +                          unsigned usage, +                          unsigned size) +{ +   struct st_softpipe_buffer *buffer = CALLOC_STRUCT(st_softpipe_buffer); + +   buffer->base.refcount = 1; +   buffer->base.alignment = alignment; +   buffer->base.usage = usage; +   buffer->base.size = size; + +   buffer->data = align_malloc(size, alignment); + +   return &buffer->base; +} + + +/** + * Create buffer which wraps user-space data. + */ +static struct pipe_buffer * +st_softpipe_user_buffer_create(struct pipe_winsys *winsys,  +                               void *ptr,  +                               unsigned bytes) +{ +   struct st_softpipe_buffer *buffer; +    +   buffer = CALLOC_STRUCT(st_softpipe_buffer); +   if(!buffer) +      return NULL; +    +   buffer->base.refcount = 1; +   buffer->base.size = bytes; +   buffer->userBuffer = TRUE; +   buffer->data = ptr; + +   return &buffer->base; +} + + +/** + * Round n up to next multiple. + */ +static INLINE unsigned +round_up(unsigned n, unsigned multiple) +{ +   return (n + multiple - 1) & ~(multiple - 1); +} + + +static int +st_softpipe_surface_alloc_storage(struct pipe_winsys *winsys, +                                  struct pipe_surface *surf, +                                  unsigned width, unsigned height, +                                  enum pipe_format format,  +                                  unsigned flags, +                                  unsigned tex_usage) +{ +   const unsigned alignment = 64; + +   surf->width = width; +   surf->height = height; +   surf->format = format; +   pf_get_block(format, &surf->block); +   surf->nblocksx = pf_get_nblocksx(&surf->block, width); +   surf->nblocksy = pf_get_nblocksy(&surf->block, height); +   surf->stride = round_up(surf->nblocksx * surf->block.size, alignment); +   surf->usage = flags; + +   assert(!surf->buffer); +   surf->buffer = winsys->buffer_create(winsys, alignment, +                                        PIPE_BUFFER_USAGE_PIXEL, +                                        surf->stride * surf->nblocksy); +   if(!surf->buffer) +      return -1; +    +   return 0; +} + + +static struct pipe_surface * +st_softpipe_surface_alloc(struct pipe_winsys *winsys) +{ +   struct pipe_surface *surface = CALLOC_STRUCT(pipe_surface); + +   assert(winsys); + +   surface->refcount = 1; +   surface->winsys = winsys; + +   return surface; +} + + +static void +st_softpipe_surface_release(struct pipe_winsys *winsys,  +                            struct pipe_surface **s) +{ +   struct pipe_surface *surf = *s; +   assert(!surf->texture); +   surf->refcount--; +   if (surf->refcount == 0) { +      if (surf->buffer) +	winsys_buffer_reference(winsys, &surf->buffer, NULL); +      free(surf); +   } +   *s = NULL; +} + + +static void +st_softpipe_fence_reference(struct pipe_winsys *winsys,  +                            struct pipe_fence_handle **ptr, +                            struct pipe_fence_handle *fence) +{ +} + + +static int +st_softpipe_fence_signalled(struct pipe_winsys *winsys,  +                            struct pipe_fence_handle *fence, +                            unsigned flag) +{ +   return 0; +} + + +static int +st_softpipe_fence_finish(struct pipe_winsys *winsys,  +                         struct pipe_fence_handle *fence, +                         unsigned flag) +{ +   return 0; +} + + +static void +st_softpipe_destroy(struct pipe_winsys *winsys) +{ +   FREE(winsys); +} + + +static struct pipe_screen * +st_softpipe_screen_create(void) +{ +   static struct pipe_winsys *winsys; +   struct pipe_screen *screen; + +   winsys = CALLOC_STRUCT(pipe_winsys); +   if(!winsys) +      return NULL; + +   winsys->destroy = st_softpipe_destroy; +    +   winsys->buffer_create = st_softpipe_buffer_create; +   winsys->user_buffer_create = st_softpipe_user_buffer_create; +   winsys->buffer_map = st_softpipe_buffer_map; +   winsys->buffer_unmap = st_softpipe_buffer_unmap; +   winsys->buffer_destroy = st_softpipe_buffer_destroy; + +   winsys->surface_alloc = st_softpipe_surface_alloc; +   winsys->surface_alloc_storage = st_softpipe_surface_alloc_storage; +   winsys->surface_release = st_softpipe_surface_release; + +   winsys->fence_reference = st_softpipe_fence_reference; +   winsys->fence_signalled = st_softpipe_fence_signalled; +   winsys->fence_finish = st_softpipe_fence_finish; + +   winsys->flush_frontbuffer = st_softpipe_flush_frontbuffer; +   winsys->get_name = st_softpipe_get_name; + +   screen = softpipe_create_screen(winsys); +   if(!screen) +      st_softpipe_destroy(winsys); + +   return screen; +} + + +static struct pipe_context * +st_softpipe_context_create(struct pipe_screen *screen) +{ +   return softpipe_create(screen, screen->winsys, NULL); +} + + +const struct st_winsys st_softpipe_winsys = { +   &st_softpipe_screen_create, +   &st_softpipe_context_create, +}; diff --git a/src/gallium/state_trackers/python/st_winsys.h b/src/gallium/state_trackers/python/st_winsys.h new file mode 100644 index 0000000000..b8cb612d86 --- /dev/null +++ b/src/gallium/state_trackers/python/st_winsys.h @@ -0,0 +1,52 @@ +/************************************************************************** + *  + * 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. + *  + **************************************************************************/ + + +#ifndef ST_WINSYS_H_ +#define ST_WINSYS_H_ + + +struct pipe_screen; +struct pipe_context; + + +struct st_winsys  +{ +   struct pipe_screen * +   (*screen_create)(void); + +   struct pipe_context * +   (*context_create)(struct pipe_screen *screen); +}; + + +extern const struct st_winsys st_softpipe_winsys; + +extern const struct st_winsys st_hardpipe_winsys; + + +#endif /* ST_WINSYS_H_ */ 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() | 
