From 28de69d6819eab289a400482d15797b662e4d633 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Jos=C3=A9=20Fonseca?= Date: Mon, 30 Mar 2009 16:02:21 +0100 Subject: [PATCH] python: Set the surface GPU access flags. Make python surface just a dumb (texture, face, level, zslice) tuple. --- src/gallium/state_trackers/python/gallium.i | 2 +- src/gallium/state_trackers/python/p_context.i | 85 ++++++++++++++++--- src/gallium/state_trackers/python/p_state.i | 31 ++++++- src/gallium/state_trackers/python/p_texture.i | 84 +++++++++++++++--- src/gallium/state_trackers/python/st_device.h | 19 +++++ src/gallium/state_trackers/python/st_sample.c | 22 +++-- src/gallium/state_trackers/python/st_sample.h | 2 +- 7 files changed, 206 insertions(+), 39 deletions(-) diff --git a/src/gallium/state_trackers/python/gallium.i b/src/gallium/state_trackers/python/gallium.i index 38f8245adf5..3f79cc1a3d7 100644 --- a/src/gallium/state_trackers/python/gallium.i +++ b/src/gallium/state_trackers/python/gallium.i @@ -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; diff --git a/src/gallium/state_trackers/python/p_context.i b/src/gallium/state_trackers/python/p_context.i index 6dcd38e7d14..a0bf063d814 100644 --- a/src/gallium/state_trackers/python/p_context.i +++ b/src/gallium/state_trackers/python/p_context.i @@ -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; } }; diff --git a/src/gallium/state_trackers/python/p_state.i b/src/gallium/state_trackers/python/p_state.i index 110b3d5da43..fc8607ba72f 100644 --- a/src/gallium/state_trackers/python/p_state.i +++ b/src/gallium/state_trackers/python/p_state.i @@ -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; } }; diff --git a/src/gallium/state_trackers/python/p_texture.i b/src/gallium/state_trackers/python/p_texture.i index fee9fb0bf84..543a0cf33f8 100644 --- a/src/gallium/state_trackers/python/p_texture.i +++ b/src/gallium/state_trackers/python/p_texture.i @@ -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_; diff --git a/src/gallium/state_trackers/python/st_device.h b/src/gallium/state_trackers/python/st_device.h index d1bd8c31f4f..a246b6a1f25 100644 --- a/src/gallium/state_trackers/python/st_device.h +++ b/src/gallium/state_trackers/python/st_device.h @@ -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); diff --git a/src/gallium/state_trackers/python/st_sample.c b/src/gallium/state_trackers/python/st_sample.c index c2ffe9fce1d..70ca16c23dd 100644 --- a/src/gallium/state_trackers/python/st_sample.c +++ b/src/gallium/state_trackers/python/st_sample.c @@ -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)); } } diff --git a/src/gallium/state_trackers/python/st_sample.h b/src/gallium/state_trackers/python/st_sample.h index ff04a12613f..0a27083549f 100644 --- a/src/gallium/state_trackers/python/st_sample.h +++ b/src/gallium/state_trackers/python/st_sample.h @@ -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_ */ -- 2.30.2