python: New state tracker which exposes the pipe driver to python scripts.
authorJosé Fonseca <jrfonseca@tungstengraphics.com>
Sun, 13 Jul 2008 14:36:59 +0000 (23:36 +0900)
committerJosé Fonseca <jrfonseca@tungstengraphics.com>
Sun, 13 Jul 2008 14:37:40 +0000 (23:37 +0900)
Still under development. Just barely works.

SConstruct
src/gallium/SConscript
src/gallium/state_trackers/python/README [new file with mode: 0644]
src/gallium/state_trackers/python/SConscript [new file with mode: 0644]
src/gallium/state_trackers/python/gallium.i [new file with mode: 0644]
src/gallium/state_trackers/python/p_format.i [new file with mode: 0644]
src/gallium/state_trackers/python/samples/simple.py [new file with mode: 0644]
src/gallium/state_trackers/python/st_device.c [new file with mode: 0644]
src/gallium/state_trackers/python/st_device.h [new file with mode: 0644]
src/gallium/state_trackers/python/st_softpipe_winsys.c [new file with mode: 0644]
src/gallium/state_trackers/python/st_winsys.h [new file with mode: 0644]

index a3bf5c5d5791ab5b5a362a8c4defe0bcfff131dc..6e166502f8f9c1e5151348fae35fa81fd6b9b05a 100644 (file)
@@ -29,23 +29,22 @@ import common
 #######################################################################
 # Configuration options
 
+default_statetrackers = 'mesa'
+
 if common.default_platform in ('linux', 'freebsd', 'darwin'):
-       default_statetrackers = 'all'
        default_drivers = 'softpipe,failover,i915simple,i965simple'
        default_winsys = 'xlib'
 elif common.default_platform in ('winddk',):
-       default_statetrackers = 'all'
        default_drivers = 'softpipe,i915simple'
        default_winsys = 'all'
 else:
-       default_statetrackers = 'all'
        default_drivers = 'all'
        default_winsys = 'all'
 
 opts = Options('config.py')
 common.AddOptions(opts)
 opts.Add(ListOption('statetrackers', 'state trackers to build', default_statetrackers,
-                     ['mesa']))
+                     ['mesa', 'python']))
 opts.Add(ListOption('drivers', 'pipe drivers to build', default_drivers,
                      ['softpipe', 'failover', 'i915simple', 'i965simple', 'cell']))
 opts.Add(ListOption('winsys', 'winsys drivers to build', default_winsys,
index 2653f91bd28f459f31ad6092ba21d41f0ff94a1b..6a3e7e77ed83159d557c5949dafd5d51336f4787 100644 (file)
@@ -25,3 +25,5 @@ SConscript([
 
 for driver in env['drivers']:
        SConscript(os.path.join('drivers', driver, 'SConscript'))
+
+SConscript('state_trackers/python/SConscript')
diff --git a/src/gallium/state_trackers/python/README b/src/gallium/state_trackers/python/README
new file mode 100644 (file)
index 0000000..75341aa
--- /dev/null
@@ -0,0 +1,32 @@
+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 (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/simple.py
+
+which should create a simple.png
+
+
+This is still in experimental phase, and there many limitations to what you can
+do with from Python. 
+
+
+--
+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 (file)
index 0000000..57a3fb2
--- /dev/null
@@ -0,0 +1,24 @@
+Import('*')
+
+if 'python' in env['statetrackers']:
+
+    env = env.Clone()
+    
+    env.Append(CPPPATH = '.')
+    
+    env.Tool('swig')
+    env.Append(SWIGPATH = ['#src/gallium/include', '#src/gallium/include/pipe'])
+    env.Append(SWIGFLAGS = ['-python', '-keyword'])
+    
+    env.ParseConfig('python-config --cflags --ldflags --libs')
+    
+    env.SharedLibrary(
+       target = '_gallium',
+       source = [
+               'gallium.i',
+            'st_device.c',
+            'st_softpipe_winsys.c',
+       ],
+        SHLIBPREFIX = '',
+        LIBS = softpipe + 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 (file)
index 0000000..d6594f3
--- /dev/null
@@ -0,0 +1,448 @@
+ /**************************************************************************
+ * 
+ * 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 "pipe/p_util.h"
+#include "pipe/p_shader_tokens.h" 
+#include "util/u_draw_quad.h" 
+#include "util/p_tile.h" 
+#include "cso_cache/cso_context.h"
+
+#include "st_device.h"
+
+%}
+
+%include "carrays.i"
+%array_class(int, IntArray);
+%array_class(float, FloatArray);
+
+
+%rename(Device) st_device;
+%rename(Context) st_context;
+%rename(Texture) pipe_texture;
+%rename(Surface) pipe_surface;
+
+%rename(Buffer) pipe_buffer;
+%rename(BlendColor) pipe_blend_color;
+%rename(Blend) pipe_blend_state;
+%rename(Clip) pipe_clip_state;
+%rename(ConstantBuffer) pipe_constant_buffer;
+%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_format.i";
+%include "pipe/p_defines.h";
+%include "pipe/p_state.h";
+%include "pipe/p_shader_tokens.h";
+
+
+%nodefaultctor;
+%nodefaultdtor;
+
+struct st_device {
+};
+
+struct st_context {
+};
+
+
+%extend st_device {
+   
+   st_device(int hardware = 0) {
+      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, unsigned type ) {
+      return $self->screen->is_format_supported( $self->screen, format, type);
+   }
+
+   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 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 = usage;
+      return $self->screen->texture_create($self->screen, &templat);
+   }
+   
+   struct pipe_buffer *
+   buffer_create(unsigned size, unsigned alignment = 0, unsigned usage = 0) {
+      return $self->screen->winsys->buffer_create($self->screen->winsys, alignment, usage, size);
+   }
+
+};
+
+
+%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 * create_fs( const struct pipe_shader_state *state ) {
+      return $self->pipe->create_fs_state($self->pipe, state);
+   }
+   
+   void bind_fs( void *state_obj ) {
+      $self->pipe->bind_fs_state($self->pipe, state_obj);
+   }
+   
+   void delete_fs( void *state_obj ) {
+      $self->pipe->delete_fs_state($self->pipe, state_obj);
+   }
+
+   void * create_vs( const struct pipe_shader_state *state ) {
+      return $self->pipe->create_vs_state($self->pipe, state);
+   }
+   
+   void bind_vs( void *state_obj ) {
+      $self->pipe->bind_vs_state($self->pipe, state_obj);
+   }
+   
+   void delete_vs( void *state_obj ) {
+      $self->pipe->delete_vs_state($self->pipe, state_obj);
+   }
+
+   /*
+    * 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,
+                            const struct pipe_constant_buffer *buf ) {
+      $self->pipe->set_constant_buffer($self->pipe, shader, index, buf);
+   }
+
+   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) {
+      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,
+                          const struct pipe_vertex_buffer *buffer) {
+      memcpy(&$self->vertex_buffers[index], buffer, sizeof(*buffer));
+      $self->pipe->set_vertex_buffers($self->pipe, PIPE_MAX_ATTRIBS, $self->vertex_buffers);
+   }
+
+   void set_vertex_element(unsigned index,
+                           const struct pipe_vertex_element *element) {
+      memcpy(&$self->vertex_elements[index], element, sizeof(*element));
+      $self->pipe->set_vertex_elements($self->pipe, PIPE_MAX_ATTRIBS, $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 pipe_buffer *indexBuffer,
+                       unsigned indexSize,
+                       unsigned mode, unsigned start, unsigned count) {
+      $self->pipe->draw_elements($self->pipe, indexBuffer, indexSize, 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_winsys *winsys = pipe->winsys;
+      struct pipe_buffer *vbuf;
+      float *map;
+      unsigned size;
+
+      size = num_verts * num_attribs * 4 * sizeof(float);
+
+      vbuf = winsys->buffer_create(winsys,
+                                   32,
+                                   PIPE_BUFFER_USAGE_VERTEX, 
+                                   size);
+      if(!vbuf)
+         goto error1;
+      
+      map = winsys->buffer_map(winsys, vbuf, PIPE_BUFFER_USAGE_CPU_WRITE);
+      if (!map)
+         goto error2;
+      memcpy(map, vertices, size);
+      pipe->winsys->buffer_unmap(pipe->winsys, vbuf);
+      
+      util_draw_vertex_buffer(pipe, vbuf, prim, num_verts, num_attribs);
+      
+error2:
+      pipe_buffer_reference(pipe->winsys, &vbuf, NULL);
+error1:
+      ;
+   }
+   
+   void draw_quad(float x0, float y0, float x1, float y1, float z = 0.0f) {
+      util_draw_texquad($self->pipe, x0, y0, x1, y1, z);
+   }
+   
+   void
+   flush(void) {
+      struct pipe_fence_handle *fence = NULL; 
+      $self->pipe->flush($self->pipe, 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 clear(struct pipe_surface *surface, unsigned value) {
+      $self->pipe->clear($self->pipe, surface, value);
+   }
+
+};
+
+
+%extend pipe_texture {
+   
+   ~pipe_texture() {
+      struct pipe_texture *ptr = $self;
+      pipe_texture_reference(&ptr, NULL);
+   }
+   
+   /** 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_rgba(unsigned x, unsigned y, unsigned w, unsigned h, float *p) {
+      pipe_get_tile_rgba($self, x, y, w, h, p);
+   }
+
+   void
+   put_tile_rgba(unsigned x, unsigned y, unsigned w, unsigned h, const float *p) {
+      pipe_put_tile_rgba($self, x, y, w, h, p);
+   }
+
+   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);
+   }
+   
+};
+
+
+%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);
+   }
+   
+};
diff --git a/src/gallium/state_trackers/python/p_format.i b/src/gallium/state_trackers/python/p_format.i
new file mode 100644 (file)
index 0000000..51ad4be
--- /dev/null
@@ -0,0 +1,152 @@
+/**************************************************************************
+ * 
+ * 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.
+ * 
+ **************************************************************************/
+
+/* 
+ * 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_A8_L8_SRGB,
+   PIPE_FORMAT_R8G8B8_SRGB,
+   PIPE_FORMAT_R8G8B8A8_SRGB,
+   PIPE_FORMAT_R8G8B8X8_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,
+};
+
+
+struct pipe_format_block
+{
+   unsigned size;
+   unsigned width;
+   unsigned height;
+};
+
diff --git a/src/gallium/state_trackers/python/samples/simple.py b/src/gallium/state_trackers/python/samples/simple.py
new file mode 100644 (file)
index 0000000..77e182b
--- /dev/null
@@ -0,0 +1,158 @@
+#!/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 save_image(filename, 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
+    outimage.save(filename, "PNG")
+
+
+def test(dev):
+    ctx = dev.context_create()
+
+    width = 256
+    height = 256
+
+    # 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_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)
+
+    #  texture 
+    texture = dev.texture_create(PIPE_FORMAT_A8R8G8B8_UNORM, width, height, usage=PIPE_TEXTURE_USAGE_RENDER_TARGET)
+    ctx.set_sampler_texture(0, texture)
+
+    #  drawing dest 
+    surface = texture.get_surface(usage = PIPE_BUFFER_USAGE_GPU_WRITE)
+    fb = Framebuffer()
+    fb.width = surface.width
+    fb.height = surface.height
+    fb.num_cbufs = 1
+    fb.set_cbuf(0, surface)
+    ctx.set_framebuffer(fb)
+
+    # vertex shader
+    # vs = Shader()
+    #ctx.set_vertex_shader(vs)
+
+    # fragment shader
+    #fs = Shader()
+    #ctx.set_fragment_shader(fs)
+
+    if 0:
+        nverts = 4
+        nattrs = 1
+        vertices = FloatArray(n_verts * nattrs * 4)
+
+        # init vertex data that doesn't change
+        for i in range(nverts):
+            for j in range(nattrs):
+                vertices[(i*nattrs +j)*4 + 0] = 0.0
+                vertices[(i*nattrs +j)*4 + 1] = 0.0
+                vertices[(i*nattrs +j)*4 + 2] = 0.0
+                vertices[(i*nattrs +j)*4 + 3] = 0.0
+
+        ctx.draw_vertices(PIPE_PRIM_TRIANGLE_FAN,
+                          4,  #  verts 
+                          2, #  attribs/vert 
+                          vertices)
+    else:
+        ctx.draw_quad(32.0, 32.0, 224.0, 224.0)
+
+    ctx.flush()
+
+    save_image("simple.png", surface)
+
+
+
+def main():
+    dev = Device(0)
+    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 (file)
index 0000000..430a7af
--- /dev/null
@@ -0,0 +1,169 @@
+/**************************************************************************
+ * 
+ * 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_util.h"
+#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_simple_shaders.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->st_ws->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->screen_destroy ||
+      !st_ws->context_create ||
+      !st_ws->context_destroy)
+      return NULL;
+   
+   st_dev = CALLOC_STRUCT(st_device);
+   if(!st_dev)
+      return NULL;
+   
+   st_dev->st_ws = st_ws;
+   
+   st_dev->screen = st_ws->screen_create();
+   if(!st_dev->screen)
+      st_device_destroy(st_dev);
+   
+   return st_dev;
+}
+
+
+struct st_device *
+st_device_create(boolean hardware) {
+#if 0
+   if(hardware)
+      return st_device_create_from_st_winsys(&st_hardware_winsys);
+   else
+#endif
+      return st_device_create_from_st_winsys(&st_software_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->vs) {
+         st_ctx->pipe->bind_vs_state(st_ctx->pipe, NULL);
+         st_ctx->pipe->delete_vs_state(st_ctx->pipe, st_ctx->vs);
+      }
+
+      if(st_ctx->fs) {
+         st_ctx->pipe->bind_fs_state(st_ctx->pipe, NULL);
+         st_ctx->pipe->delete_fs_state(st_ctx->pipe, st_ctx->fs);
+      }
+      
+      if(st_ctx->cso)
+         cso_destroy_context(st_ctx->cso);
+      
+      if(st_ctx->pipe)
+         st_ctx->st_dev->st_ws->context_destroy(st_ctx->pipe);
+      
+      for(i = 0; i < PIPE_MAX_SAMPLERS; ++i)
+         pipe_texture_reference(&st_ctx->sampler_textures[i], 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->pipe = st_dev->st_ws->context_create(st_dev->screen);
+   if(!st_ctx->pipe)
+      st_context_destroy(st_ctx);
+   
+   st_ctx->cso = cso_create_context(st_ctx->pipe);
+   if(!st_ctx->cso)
+      st_context_destroy(st_ctx);
+   
+   /* vertex 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,
+                                                       &st_ctx->vert_shader);
+   }
+
+   /* fragment shader */
+   st_ctx->fs = util_make_fragment_passthrough_shader(st_ctx->pipe, 
+                                                      &st_ctx->frag_shader);
+   
+   st_ctx->pipe->bind_fs_state(st_ctx->pipe, st_ctx->fs);
+   st_ctx->pipe->bind_vs_state(st_ctx->pipe, st_ctx->vs);
+
+   return st_ctx;
+}
diff --git a/src/gallium/state_trackers/python/st_device.h b/src/gallium/state_trackers/python/st_device.h
new file mode 100644 (file)
index 0000000..46db20a
--- /dev/null
@@ -0,0 +1,83 @@
+/**************************************************************************
+ * 
+ * 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_context {
+   struct st_device *st_dev;
+   
+   struct pipe_context *pipe;
+   
+   struct cso_context *cso;
+   
+   struct pipe_shader_state vert_shader;
+   struct pipe_shader_state frag_shader;
+
+   void *vs;
+   void *fs;
+
+   struct pipe_texture *sampler_textures[PIPE_MAX_SAMPLERS];
+   struct pipe_vertex_buffer vertex_buffers[PIPE_MAX_ATTRIBS];
+   struct pipe_vertex_element vertex_elements[PIPE_MAX_ATTRIBS];
+};
+
+
+struct st_device {
+   const struct st_winsys *st_ws; 
+   
+   struct pipe_screen *screen;
+   
+   /* FIXME: we also need to refcount for textures and surfaces... */
+   unsigned refcount;
+};
+
+
+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_softpipe_winsys.c b/src/gallium/state_trackers/python/st_softpipe_winsys.c
new file mode 100644 (file)
index 0000000..964d60d
--- /dev/null
@@ -0,0 +1,321 @@
+/**************************************************************************
+ * 
+ * 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_util.h"
+#include "pipe/p_inlines.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)
+       pipe_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_screen_destroy(struct pipe_screen *screen)
+{
+   struct pipe_winsys *winsys = screen->winsys;
+
+   screen->destroy(screen);
+
+   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->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)
+      FREE(winsys);
+
+   return screen;
+}
+
+
+static void
+st_softpipe_context_destroy(struct pipe_context *pipe)
+{
+   pipe->destroy(pipe);
+}
+
+
+static struct pipe_context *
+st_softpipe_context_create(struct pipe_screen *screen)
+{
+   return softpipe_create(screen, screen->winsys, NULL);
+}
+
+
+const struct st_winsys st_software_winsys = {
+   &st_softpipe_screen_create,
+   &st_softpipe_screen_destroy,
+   &st_softpipe_context_create,
+   &st_softpipe_context_destroy
+};
diff --git a/src/gallium/state_trackers/python/st_winsys.h b/src/gallium/state_trackers/python/st_winsys.h
new file mode 100644 (file)
index 0000000..992fc9a
--- /dev/null
@@ -0,0 +1,58 @@
+/**************************************************************************
+ * 
+ * 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);
+
+   void
+   (*screen_destroy)(struct pipe_screen *screen);
+
+   struct pipe_context *
+   (*context_create)(struct pipe_screen *screen);
+
+   void
+   (*context_destroy)(struct pipe_context *pipe);
+};
+
+
+extern const struct st_winsys st_software_winsys;
+
+extern const struct st_winsys st_hardware_winsys;
+
+
+#endif /* ST_WINSYS_H_ */