python: Set the surface GPU access flags.
authorJosé Fonseca <jfonseca@vmware.com>
Mon, 30 Mar 2009 15:02:21 +0000 (16:02 +0100)
committerJosé Fonseca <jfonseca@vmware.com>
Mon, 30 Mar 2009 16:19:10 +0000 (17:19 +0100)
Make python surface just a dumb (texture, face, level, zslice) tuple.

src/gallium/state_trackers/python/gallium.i
src/gallium/state_trackers/python/p_context.i
src/gallium/state_trackers/python/p_state.i
src/gallium/state_trackers/python/p_texture.i
src/gallium/state_trackers/python/st_device.h
src/gallium/state_trackers/python/st_sample.c
src/gallium/state_trackers/python/st_sample.h

index 38f8245adf5e1eb8ce4b30b795bca9b633ef9d27..3f79cc1a3d74be0afc1790bb29c054613c85f3c3 100644 (file)
@@ -69,7 +69,7 @@
 %rename(Device) st_device;
 %rename(Context) st_context;
 %rename(Texture) pipe_texture;
-%rename(Surface) pipe_surface;
+%rename(Surface) st_surface;
 %rename(Buffer) pipe_buffer;
 
 %rename(BlendColor) pipe_blend_color;
index 6dcd38e7d146d82331dbcbb5a6964cefdf8f2df3..a0bf063d8146eb9302baecfb5d83b8308fedcc21 100644 (file)
@@ -124,7 +124,9 @@ struct st_context {
       $self->pipe->set_constant_buffer($self->pipe, shader, index, &state);
    }
 
-   void set_framebuffer(const struct pipe_framebuffer_state *state ) {
+   void set_framebuffer(const struct pipe_framebuffer_state *state ) 
+   {
+      memcpy(&$self->framebuffer, state, sizeof *state);
       cso_set_framebuffer($self->cso, state);
    }
 
@@ -265,23 +267,86 @@ error1:
     * Surface functions
     */
    
-   void surface_copy(struct pipe_surface *dest,
+   void surface_copy(struct st_surface *dst,
                      unsigned destx, unsigned desty,
-                     struct pipe_surface *src,
+                     struct st_surface *src,
                      unsigned srcx, unsigned srcy,
-                     unsigned width, unsigned height) {
-      $self->pipe->surface_copy($self->pipe, dest, destx, desty, src, srcx, srcy, width, height);
+                     unsigned width, unsigned height) 
+   {
+      struct pipe_surface *_dst = NULL;
+      struct pipe_surface *_src = NULL;
+      
+      _dst = st_pipe_surface(dst, PIPE_BUFFER_USAGE_GPU_WRITE);
+      if(!_dst)
+         SWIG_exception(SWIG_ValueError, "couldn't acquire destination surface for writing");
+
+      _src = st_pipe_surface(src, PIPE_BUFFER_USAGE_GPU_READ);
+      if(!_src)
+         SWIG_exception(SWIG_ValueError, "couldn't acquire source surface for reading");
+      
+      $self->pipe->surface_copy($self->pipe, _dst, destx, desty, _src, srcx, srcy, width, height);
+      
+   fail:
+      pipe_surface_reference(&_src, NULL);
+      pipe_surface_reference(&_dst, NULL);
    }
 
-   void surface_fill(struct pipe_surface *dst,
+   void surface_fill(struct st_surface *dst,
                      unsigned x, unsigned y,
                      unsigned width, unsigned height,
-                     unsigned value) {
-      $self->pipe->surface_fill($self->pipe, dst, x, y, width, height, value);
+                     unsigned value) 
+   {
+      struct pipe_surface *_dst = NULL;
+      
+      _dst = st_pipe_surface(dst, PIPE_BUFFER_USAGE_GPU_WRITE);
+      if(!_dst)
+         SWIG_exception(SWIG_ValueError, "couldn't acquire destination surface for writing");
+
+      $self->pipe->surface_fill($self->pipe, _dst, x, y, width, height, value);
+      
+   fail:
+      pipe_surface_reference(&_dst, NULL);
    }
 
-   void surface_clear(struct pipe_surface *surface, unsigned value = 0) {
-      $self->pipe->clear($self->pipe, surface, value);
+   void surface_clear(struct st_surface *surface, unsigned value = 0) 
+   {
+      unsigned i;
+      struct pipe_surface *_surface = NULL;
+      if(!surface)
+          SWIG_exception(SWIG_TypeError, "surface must not be null");
+  
+      for(i = 0; i < $self->framebuffer.nr_cbufs; ++i) {
+         struct pipe_surface *cbuf = $self->framebuffer.cbufs[i];
+         if(cbuf) {
+            if(cbuf->texture == surface->texture &&
+               cbuf->face == surface->face &&
+               cbuf->level == surface->level &&
+               cbuf->zslice == surface->zslice) {                  
+               _surface = cbuf;
+               break;
+            }
+         }
+      }
+
+      if(!_surface) {
+         struct pipe_surface *zsbuf = $self->framebuffer.zsbuf;
+         if(zsbuf) {
+            if(zsbuf->texture == surface->texture &&
+               zsbuf->face == surface->face &&
+               zsbuf->level == surface->level &&
+               zsbuf->zslice == surface->zslice) {                  
+               _surface = zsbuf;
+            }
+         }
+      }
+
+      if(!_surface)
+         SWIG_exception(SWIG_ValueError, "surface not bound");
+      
+      $self->pipe->clear($self->pipe, _surface, value);
+   fail:
+      return;
    }
 
 };
index 110b3d5da432d0480497b574bc3466758bd30626..fc8607ba72ff9f75904a895355303d813c16b9a5 100644 (file)
    }
    
    void
-   set_cbuf(unsigned index, struct pipe_surface *surface) {
-      pipe_surface_reference(&$self->cbufs[index], surface);
+   set_cbuf(unsigned index, struct st_surface *surface) 
+   {
+      struct pipe_surface *_surface = NULL;
+
+      if(index >= PIPE_MAX_COLOR_BUFS)
+         SWIG_exception(SWIG_ValueError, "index out of bounds");
+      
+      _surface = st_pipe_surface(surface, PIPE_BUFFER_USAGE_GPU_WRITE);
+      if(!_surface)
+         SWIG_exception(SWIG_ValueError, "couldn't acquire surface for writing");
+
+      pipe_surface_reference(&$self->cbufs[index], _surface);
+      
+   fail:
+      return;
    }
    
    void
-   set_zsbuf(struct pipe_surface *surface) {
-      pipe_surface_reference(&$self->zsbuf, surface);
+   set_zsbuf(struct st_surface *surface) 
+   {
+      struct pipe_surface *_surface = NULL;
+
+      _surface = st_pipe_surface(surface, PIPE_BUFFER_USAGE_GPU_WRITE);
+      if(!_surface)
+         SWIG_exception(SWIG_ValueError, "couldn't acquire surface for writing");
+
+      pipe_surface_reference(&$self->zsbuf, _surface);
+
+   fail:
+      return;
    }
    
 };
index fee9fb0bf84c781e25e0bb48d96c00c85013f06c..543a0cf33f8307a3500f9c0fe252d8fa73f2d4e7 100644 (file)
 
 
 %nodefaultctor pipe_texture;
-%nodefaultctor pipe_surface;
+%nodefaultctor st_surface;
 %nodefaultctor pipe_buffer;
 
 %nodefaultdtor pipe_texture;
-%nodefaultdtor pipe_surface;
+%nodefaultdtor st_surface;
 %nodefaultdtor pipe_buffer;
 
 %ignore pipe_texture::screen;
 
-%ignore pipe_surface::winsys;
-%immutable pipe_surface::texture;
-%immutable pipe_surface::buffer;
+%immutable st_surface::texture;
+%immutable st_surface::face;
+%immutable st_surface::level;
+%immutable st_surface::zslice;
 
 %newobject pipe_texture::get_surface;
 
    }
    
    /** Get a surface which is a "view" into a texture */
-   struct pipe_surface *
-   get_surface(unsigned face=0, unsigned level=0, unsigned zslice=0 )
+   struct st_surface *
+   get_surface(unsigned face=0, unsigned level=0, unsigned zslice=0)
    {
-      const usage = PIPE_BUFFER_USAGE_GPU_READ_WRITE;
-      struct pipe_screen *screen = $self->screen;
-      return screen->get_tex_surface(screen, $self, face, level, zslice, usage);
+      struct st_surface *surface;
+      
+      if(face >= ($self->target == PIPE_TEXTURE_CUBE ? 6 : 1))
+         SWIG_exception(SWIG_ValueError, "face out of bounds");
+      if(level > $self->last_level)
+         SWIG_exception(SWIG_ValueError, "level out of bounds");
+      if(zslice >= $self->depth[level])
+         SWIG_exception(SWIG_ValueError, "zslice out of bounds");
+      
+      surface = CALLOC_STRUCT(st_surface);
+      if(!surface)
+         return NULL;
+      
+      pipe_texture_reference(&surface->texture, $self);
+      surface->face = face;
+      surface->level = level;
+      surface->zslice = zslice;
+      
+      return surface;
+
+   fail:
+      return NULL;
    }
    
 };
 
+struct st_surface
+{
+   %immutable;
+   
+   struct pipe_texture *texture;
+   unsigned face;
+   unsigned level;
+   unsigned zslice;
+   
+};
 
-%extend pipe_surface {
+%extend st_surface {
+   
+   %immutable;
    
-   ~pipe_surface() {
-      struct pipe_surface *ptr = $self;
-      pipe_surface_reference(&ptr, NULL);
+   unsigned format;
+   unsigned width;
+   unsigned height;
+   
+   ~st_surface() {
+      pipe_texture_reference(&$self->texture, NULL);
+      FREE($self);
    }
    
    void
 
 };
 
+%{
+   static enum pipe_format
+   st_surface_format_get(struct st_surface *surface)
+   {
+      return surface->texture->format;
+   }
+   
+   static unsigned
+   st_surface_width_get(struct st_surface *surface)
+   {
+      return surface->texture->width[surface->level];
+   }
+   
+   static unsigned
+   st_surface_height_get(struct st_surface *surface)
+   {
+      return surface->texture->height[surface->level];
+   }
+%}
+
 /* Avoid naming conflict with p_inlines.h's pipe_buffer_read/write */ 
 %rename(read) pipe_buffer_read_; 
 %rename(write) pipe_buffer_write_; 
index d1bd8c31f4ff932fbc1de393f707f351f0c9b6ce..a246b6a1f25b495e5e3f03d7679fc598f043f60e 100644 (file)
@@ -38,6 +38,15 @@ struct pipe_context;
 struct st_winsys; 
 
 
+struct st_surface
+{
+   struct pipe_texture *texture;
+   unsigned face;
+   unsigned level;
+   unsigned zslice;
+};
+
+
 struct st_context {
    struct st_device *st_dev;
    
@@ -57,6 +66,8 @@ struct st_context {
    
    unsigned num_vertex_elements;
    struct pipe_vertex_element vertex_elements[PIPE_MAX_ATTRIBS];
+   
+   struct pipe_framebuffer_state framebuffer;
 };
 
 
@@ -71,6 +82,14 @@ struct st_device {
 };
 
 
+static INLINE struct pipe_surface *
+st_pipe_surface(struct st_surface *surface, unsigned usage) 
+{
+   struct pipe_texture *texture = surface->texture;
+   struct pipe_screen *screen = texture->screen;
+   return screen->get_tex_surface(screen, texture, surface->face, surface->level, surface->zslice, usage);
+}
+
 struct st_context *
 st_context_create(struct st_device *st_dev);
 
index c2ffe9fce1d513bf689f9f33d9714c5390ec3afa..70ca16c23dd75efd07252385d99f7949e4f0e477 100644 (file)
@@ -34,6 +34,7 @@
 #include "util/u_math.h"
 #include "util/u_memory.h"
 
+#include "st_device.h"
 #include "st_sample.h"
 
 
@@ -523,10 +524,13 @@ st_sample_pixel_block(enum pipe_format format,
 
 
 void
-st_sample_surface(struct pipe_surface *surface, float *rgba) 
+st_sample_surface(struct st_surface *surface, float *rgba) 
 {
-   struct pipe_screen *screen = surface->texture->screen;
-   uint rgba_stride = surface->width * 4;
+   struct pipe_texture *texture = surface->texture;
+   struct pipe_screen *screen = texture->screen;
+   unsigned width = texture->width[surface->level];
+   unsigned height = texture->height[surface->level];
+   uint rgba_stride = width * 4;
    struct pipe_transfer *transfer;
    void *raw;
 
@@ -537,25 +541,25 @@ st_sample_surface(struct pipe_surface *surface, float *rgba)
                                        surface->zslice,
                                        PIPE_TRANSFER_READ,
                                        0, 0,
-                                       surface->width,
-                                       surface->height);
+                                       width,
+                                       height);
    if (!transfer)
       return;
 
    raw = screen->transfer_map(screen, transfer);
    if (raw) {
-      const struct pipe_format_block *block = &transfer->block;
+      const struct pipe_format_block *block = &texture->block;
       uint x, y;
 
       for (y = 0; y < transfer->nblocksy; ++y) {
          for (x = 0; x < transfer->nblocksx; ++x) {
-            st_sample_pixel_block(surface->format,
+            st_sample_pixel_block(texture->format,
                                   block,
                                   (uint8_t *) raw + y * transfer->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));
+                                  MIN2(block->width, width - x*block->width),
+                                  MIN2(block->height, height - y*block->height));
          }
       }
 
index ff04a12613f1fd51357dcd5c92e391aca97d2cdf..0a27083549fa6dc6281891ec95449a5659188b5b 100644 (file)
@@ -41,7 +41,7 @@ st_sample_pixel_block(enum pipe_format format,
                       unsigned w, unsigned h);
 
 void
-st_sample_surface(struct pipe_surface *surface, float *rgba);
+st_sample_surface(struct st_surface *surface, float *rgba);
 
 
 #endif /* ST_SAMPLE_H_ */