/************************************************************************** * * 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 */ %nodefaultctor pipe_texture; %nodefaultctor pipe_surface; %nodefaultctor pipe_buffer; %nodefaultdtor pipe_texture; %nodefaultdtor pipe_surface; %nodefaultdtor pipe_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); } void get_tile_raw(unsigned x, unsigned y, unsigned w, unsigned h, char *raw, unsigned stride) { struct pipe_screen *screen = $self->texture->screen; struct pipe_transfer *transfer; transfer = screen->get_tex_transfer(screen, $self->texture, $self->face, $self->level, $self->zslice, PIPE_TRANSFER_READ, x, y, w, h); if(transfer) { pipe_get_tile_raw(transfer, 0, 0, w, h, raw, stride); screen->tex_transfer_destroy(transfer); } } void put_tile_raw(unsigned x, unsigned y, unsigned w, unsigned h, const char *raw, unsigned stride) { struct pipe_screen *screen = $self->texture->screen; struct pipe_transfer *transfer; transfer = screen->get_tex_transfer(screen, $self->texture, $self->face, $self->level, $self->zslice, PIPE_TRANSFER_WRITE, x, y, w, h); if(transfer) { pipe_put_tile_raw(transfer, 0, 0, w, h, raw, stride); screen->tex_transfer_destroy(transfer); } } void get_tile_rgba(unsigned x, unsigned y, unsigned w, unsigned h, float *rgba) { struct pipe_screen *screen = $self->texture->screen; struct pipe_transfer *transfer; transfer = screen->get_tex_transfer(screen, $self->texture, $self->face, $self->level, $self->zslice, PIPE_TRANSFER_READ, x, y, w, h); if(transfer) { pipe_get_tile_rgba(transfer, 0, 0, w, h, rgba); screen->tex_transfer_destroy(transfer); } } void put_tile_rgba(unsigned x, unsigned y, unsigned w, unsigned h, const float *rgba) { struct pipe_screen *screen = $self->texture->screen; struct pipe_transfer *transfer; transfer = screen->get_tex_transfer(screen, $self->texture, $self->face, $self->level, $self->zslice, PIPE_TRANSFER_WRITE, x, y, w, h); if(transfer) { pipe_put_tile_rgba(transfer, 0, 0, w, h, rgba); screen->tex_transfer_destroy(transfer); } } %cstring_output_allocate_size(char **STRING, int *LENGTH, free(*$1)); void get_tile_rgba8(unsigned x, unsigned y, unsigned w, unsigned h, char **STRING, int *LENGTH) { struct pipe_screen *screen = $self->texture->screen; struct pipe_transfer *transfer; float *rgba; unsigned char *rgba8; unsigned i, j, k; *LENGTH = 0; *STRING = NULL; if (!$self) return; *LENGTH = h*w*4; *STRING = (char *) malloc(*LENGTH); if(!*STRING) return; rgba = malloc(w*4*sizeof(float)); if(!rgba) return; rgba8 = (unsigned char *) *STRING; for(j = 0; j < h; ++j) { transfer = screen->get_tex_transfer(screen, $self->texture, $self->face, $self->level, $self->zslice, PIPE_TRANSFER_READ, x, y + j, w, 1); if(transfer) { pipe_get_tile_rgba(transfer, 0, 0, w, 1, rgba); for(i = 0; i < w; ++i) for(k = 0; k <4; ++k) rgba8[j*w*4 + i*4 + k] = float_to_ubyte(rgba[i*4 + k]); screen->tex_transfer_destroy(transfer); } } free(rgba); } void get_tile_z(unsigned x, unsigned y, unsigned w, unsigned h, unsigned *z) { struct pipe_screen *screen = $self->texture->screen; struct pipe_transfer *transfer; transfer = screen->get_tex_transfer(screen, $self->texture, $self->face, $self->level, $self->zslice, PIPE_TRANSFER_READ, x, y, w, h); if(transfer) { pipe_get_tile_z(transfer, 0, 0, w, h, z); screen->tex_transfer_destroy(transfer); } } void put_tile_z(unsigned x, unsigned y, unsigned w, unsigned h, const unsigned *z) { struct pipe_screen *screen = $self->texture->screen; struct pipe_transfer *transfer; transfer = screen->get_tex_transfer(screen, $self->texture, $self->face, $self->level, $self->zslice, PIPE_TRANSFER_WRITE, x, y, w, h); if(transfer) { pipe_put_tile_z(transfer, 0, 0, w, h, z); screen->tex_transfer_destroy(transfer); } } 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) { struct pipe_screen *screen = $self->texture->screen; struct pipe_transfer *transfer; float *rgba2; const float *p1; const float *p2; unsigned i, j, n; rgba2 = MALLOC(h*w*4*sizeof(float)); if(!rgba2) return ~0; transfer = screen->get_tex_transfer(screen, $self->texture, $self->face, $self->level, $self->zslice, PIPE_TRANSFER_WRITE, x, y, w, h); if(!transfer) { FREE(rgba2); return ~0; } pipe_get_tile_rgba(transfer, 0, 0, w, h, rgba2); screen->tex_transfer_destroy(transfer); 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; } }; /* Avoid naming conflict with p_inlines.h's pipe_buffer_read/write */ %rename(read) pipe_buffer_read_; %rename(write) pipe_buffer_write_; %extend pipe_buffer { ~pipe_buffer() { struct pipe_buffer *ptr = $self; pipe_buffer_reference(&ptr, NULL); } unsigned __len__(void) { assert(p_atomic_read(&$self->reference.count) > 0); return $self->size; } %cstring_output_allocate_size(char **STRING, int *LENGTH, free(*$1)); void read_(char **STRING, int *LENGTH) { struct pipe_screen *screen = $self->screen; assert(p_atomic_read(&$self->reference.count) > 0); *LENGTH = $self->size; *STRING = (char *) malloc($self->size); if(!*STRING) return; pipe_buffer_read(screen, $self, 0, $self->size, STRING); } %cstring_input_binary(const char *STRING, unsigned LENGTH); void write_(const char *STRING, unsigned LENGTH, unsigned offset = 0) { struct pipe_screen *screen = $self->screen; assert(p_atomic_read(&$self->reference.count) > 0); if(offset > $self->size) { PyErr_SetString(PyExc_ValueError, "offset must be smaller than buffer size"); return; } if(offset + LENGTH > $self->size) { PyErr_SetString(PyExc_ValueError, "data length must fit inside the buffer"); return; } pipe_buffer_write(screen, $self, offset, LENGTH, STRING); } };