Make python surface just a dumb (texture, face, level, zslice) tuple.tags/mesa_7_5_rc1
| @@ -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; | |||
| @@ -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; | |||
| } | |||
| }; | |||
| @@ -59,13 +59,36 @@ | |||
| } | |||
| 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; | |||
| } | |||
| }; | |||
| @@ -34,18 +34,19 @@ | |||
| %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; | |||
| @@ -78,22 +79,57 @@ | |||
| } | |||
| /** 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 | |||
| @@ -309,6 +345,26 @@ | |||
| }; | |||
| %{ | |||
| 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_; | |||
| @@ -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); | |||
| @@ -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)); | |||
| } | |||
| } | |||
| @@ -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_ */ | |||