diff options
Diffstat (limited to 'src/gallium/auxiliary/util')
-rw-r--r-- | src/gallium/auxiliary/util/u_blitter.c | 20 | ||||
-rw-r--r-- | src/gallium/auxiliary/util/u_blitter.h | 10 | ||||
-rw-r--r-- | src/gallium/auxiliary/util/u_debug.c | 2 | ||||
-rw-r--r-- | src/gallium/auxiliary/util/u_math.h | 14 | ||||
-rw-r--r-- | src/gallium/auxiliary/util/u_pointer.h | 11 | ||||
-rw-r--r-- | src/gallium/auxiliary/util/u_prim.h | 46 | ||||
-rw-r--r-- | src/gallium/auxiliary/util/u_surface.c | 108 | ||||
-rw-r--r-- | src/gallium/auxiliary/util/u_surface.h | 8 | ||||
-rw-r--r-- | src/gallium/auxiliary/util/u_upload_mgr.c | 2 |
9 files changed, 208 insertions, 13 deletions
diff --git a/src/gallium/auxiliary/util/u_blitter.c b/src/gallium/auxiliary/util/u_blitter.c index ae4c80c645..98d5a25a3f 100644 --- a/src/gallium/auxiliary/util/u_blitter.c +++ b/src/gallium/auxiliary/util/u_blitter.c @@ -97,8 +97,6 @@ struct blitter_context_priv /* Rasterizer state. */ void *rs_state; - struct pipe_sampler_view *sampler_view; - /* Viewport state. */ struct pipe_viewport_state viewport; @@ -260,10 +258,6 @@ void util_blitter_destroy(struct blitter_context *blitter) if (ctx->sampler_state[i]) pipe->delete_sampler_state(pipe, ctx->sampler_state[i]); - if (ctx->sampler_view) { - pipe_sampler_view_reference(&ctx->sampler_view, NULL); - } - pipe_resource_reference(&ctx->vbuf, NULL); FREE(ctx); } @@ -282,6 +276,7 @@ static void blitter_check_saved_CSOs(struct blitter_context_priv *ctx) static void blitter_restore_CSOs(struct blitter_context_priv *ctx) { struct pipe_context *pipe = ctx->pipe; + unsigned i; /* restore the state objects which are always required to be saved */ pipe->bind_blend_state(pipe, ctx->blitter.saved_blend_state); @@ -328,6 +323,13 @@ static void blitter_restore_CSOs(struct blitter_context_priv *ctx) pipe->set_vertex_buffers(pipe, ctx->blitter.saved_num_vertex_buffers, ctx->blitter.saved_vertex_buffers); + + for (i = 0; i < ctx->blitter.saved_num_vertex_buffers; i++) { + if (ctx->blitter.saved_vertex_buffers[i].buffer) { + pipe_resource_reference(&ctx->blitter.saved_vertex_buffers[i].buffer, + NULL); + } + } ctx->blitter.saved_num_vertex_buffers = ~0; } } @@ -728,11 +730,6 @@ void util_blitter_copy_region(struct blitter_context *blitter, u_sampler_view_default_template(&viewTempl, src, src->format); view = pipe->create_sampler_view(pipe, src, &viewTempl); - if (ctx->sampler_view) { - pipe_sampler_view_reference(&ctx->sampler_view, NULL); - } - ctx->sampler_view = view; - /* Set rasterizer state, shaders, and textures. */ pipe->bind_rasterizer_state(pipe, ctx->rs_state); pipe->bind_vs_state(pipe, ctx->vs_tex); @@ -768,6 +765,7 @@ void util_blitter_copy_region(struct blitter_context *blitter, blitter_restore_CSOs(ctx); pipe_surface_reference(&dstsurf, NULL); + pipe_sampler_view_reference(&view, NULL); } /* Clear a region of a color surface to a constant value. */ diff --git a/src/gallium/auxiliary/util/u_blitter.h b/src/gallium/auxiliary/util/u_blitter.h index 10143a5e0f..22849280ab 100644 --- a/src/gallium/auxiliary/util/u_blitter.h +++ b/src/gallium/auxiliary/util/u_blitter.h @@ -27,6 +27,7 @@ #ifndef U_BLITTER_H #define U_BLITTER_H +#include "util/u_inlines.h" #include "util/u_memory.h" #include "pipe/p_state.h" @@ -259,9 +260,18 @@ util_blitter_save_vertex_buffers(struct blitter_context *blitter, int num_vertex_buffers, struct pipe_vertex_buffer *vertex_buffers) { + unsigned i; assert(num_vertex_buffers <= Elements(blitter->saved_vertex_buffers)); blitter->saved_num_vertex_buffers = num_vertex_buffers; + + for (i = 0; i < num_vertex_buffers; i++) { + if (vertex_buffers[i].buffer) { + pipe_resource_reference(&blitter->saved_vertex_buffers[i].buffer, + vertex_buffers[i].buffer); + } + } + memcpy(blitter->saved_vertex_buffers, vertex_buffers, num_vertex_buffers * sizeof(struct pipe_vertex_buffer)); diff --git a/src/gallium/auxiliary/util/u_debug.c b/src/gallium/auxiliary/util/u_debug.c index 954f5706ef..5e373ff24c 100644 --- a/src/gallium/auxiliary/util/u_debug.c +++ b/src/gallium/auxiliary/util/u_debug.c @@ -195,7 +195,7 @@ debug_get_flags_option(const char *name, namealign = MAX2(namealign, strlen(flags->name)); for (flags = orig; flags->name; ++flags) debug_printf("| %*s [0x%0*lx]%s%s\n", namealign, flags->name, - sizeof(unsigned long)*CHAR_BIT/4, flags->value, + (int)sizeof(unsigned long)*CHAR_BIT/4, flags->value, flags->desc ? " " : "", flags->desc ? flags->desc : ""); } else { diff --git a/src/gallium/auxiliary/util/u_math.h b/src/gallium/auxiliary/util/u_math.h index 6370e77986..fe19466436 100644 --- a/src/gallium/auxiliary/util/u_math.h +++ b/src/gallium/auxiliary/util/u_math.h @@ -567,12 +567,26 @@ util_bswap16(uint16_t n) #define MAX3( A, B, C ) MAX2( MAX2( A, B ), C ) +/** + * Align a value, only works pot alignemnts. + */ static INLINE int align(int value, int alignment) { return (value + alignment - 1) & ~(alignment - 1); } +/** + * Works like align but on npot alignments. + */ +static INLINE size_t +util_align_npot(size_t value, size_t alignment) +{ + if (value % alignment) + return value + (alignment - (value % alignment)); + return value; +} + static INLINE unsigned u_minify(unsigned value, unsigned levels) { diff --git a/src/gallium/auxiliary/util/u_pointer.h b/src/gallium/auxiliary/util/u_pointer.h index ae6f43bff8..cce0c7430e 100644 --- a/src/gallium/auxiliary/util/u_pointer.h +++ b/src/gallium/auxiliary/util/u_pointer.h @@ -111,6 +111,17 @@ pointer_to_func( void *p ) return pf.f; } +static INLINE void * +func_to_pointer( func_pointer f ) +{ + union { + void *p; + func_pointer f; + } pf; + pf.f = f; + return pf.p; +} + #ifdef __cplusplus } diff --git a/src/gallium/auxiliary/util/u_prim.h b/src/gallium/auxiliary/util/u_prim.h index 64390e1385..606b9b5c6b 100644 --- a/src/gallium/auxiliary/util/u_prim.h +++ b/src/gallium/auxiliary/util/u_prim.h @@ -169,6 +169,52 @@ u_vertices_per_prim(int primitive) } } +/** + * Returns the number of decomposed primitives for the given + * vertex count. + * Geometry shader is invoked once for each triangle in + * triangle strip, triangle fans and triangles and once + * for each line in line strip, line loop, lines. + */ +static INLINE unsigned +u_gs_prims_for_vertices(int primitive, int vertices) +{ + switch(primitive) { + case PIPE_PRIM_POINTS: + return vertices; + case PIPE_PRIM_LINES: + return vertices / 2; + case PIPE_PRIM_LINE_LOOP: + return vertices; + case PIPE_PRIM_LINE_STRIP: + return vertices - 1; + case PIPE_PRIM_TRIANGLES: + return vertices / 3; + case PIPE_PRIM_TRIANGLE_STRIP: + return vertices - 2; + case PIPE_PRIM_TRIANGLE_FAN: + return vertices - 2; + case PIPE_PRIM_LINES_ADJACENCY: + return vertices / 2; + case PIPE_PRIM_LINE_STRIP_ADJACENCY: + return vertices - 1; + case PIPE_PRIM_TRIANGLES_ADJACENCY: + return vertices / 3; + case PIPE_PRIM_TRIANGLE_STRIP_ADJACENCY: + return vertices - 2; + + /* following primitives should never be used + * with geometry shaders abd their size is + * undefined */ + case PIPE_PRIM_POLYGON: + case PIPE_PRIM_QUADS: + case PIPE_PRIM_QUAD_STRIP: + default: + debug_printf("Unrecognized geometry shader primitive"); + return 3; + } +} + const char *u_prim_name( unsigned pipe_prim ); #endif diff --git a/src/gallium/auxiliary/util/u_surface.c b/src/gallium/auxiliary/util/u_surface.c index 9dd1002f5f..cab7691c70 100644 --- a/src/gallium/auxiliary/util/u_surface.c +++ b/src/gallium/auxiliary/util/u_surface.c @@ -199,7 +199,6 @@ util_resource_copy_region(struct pipe_context *pipe, * Fallback for pipe->clear_render_target() function. * XXX this looks too hackish to be really useful. * cpp > 4 looks like a gross hack at best... - * and we're missing the equivalent clear_depth_stencil fallback. * Plus can't use these transfer fallbacks when clearing * multisampled surfaces for instance. */ @@ -278,3 +277,110 @@ util_clear_render_target(struct pipe_context *pipe, pipe->transfer_unmap(pipe, dst_trans); pipe->transfer_destroy(pipe, dst_trans); } + +/** + * Fallback for pipe->clear_stencil() function. + * sw fallback doesn't look terribly useful here. + * Plus can't use these transfer fallbacks when clearing + * multisampled surfaces for instance. + */ +void +util_clear_depth_stencil(struct pipe_context *pipe, + struct pipe_surface *dst, + unsigned clear_flags, + double depth, + unsigned stencil, + unsigned dstx, unsigned dsty, + unsigned width, unsigned height) +{ + struct pipe_transfer *dst_trans; + ubyte *dst_map; + boolean need_rmw = FALSE; + + if ((clear_flags & PIPE_CLEAR_DEPTHSTENCIL) && + ((clear_flags & PIPE_CLEAR_DEPTHSTENCIL) != PIPE_CLEAR_DEPTHSTENCIL) && + util_format_is_depth_and_stencil(dst->format)) + need_rmw = TRUE; + + assert(dst->texture); + if (!dst->texture) + return; + dst_trans = pipe_get_transfer(pipe, + dst->texture, + dst->face, + dst->level, + dst->zslice, + (need_rmw ? PIPE_TRANSFER_READ_WRITE : + PIPE_TRANSFER_WRITE), + dstx, dsty, width, height); + + dst_map = pipe->transfer_map(pipe, dst_trans); + + assert(dst_map); + + if (dst_map) { + unsigned dst_stride = dst_trans->stride; + unsigned zstencil = util_pack_z_stencil(dst->texture->format, depth, stencil); + unsigned i, j; + assert(dst_trans->stride > 0); + + switch (util_format_get_blocksize(dst->format)) { + case 1: + assert(dst->format == PIPE_FORMAT_S8_USCALED); + if(dst_stride == width) + memset(dst_map, (ubyte) zstencil, height * width); + else { + for (i = 0; i < height; i++) { + memset(dst_map, (ubyte) zstencil, width); + dst_map += dst_stride; + } + } + break; + case 2: + assert(dst->format == PIPE_FORMAT_Z16_UNORM); + for (i = 0; i < height; i++) { + uint16_t *row = (uint16_t *)dst_map; + for (j = 0; j < width; j++) + *row++ = (uint16_t) zstencil; + dst_map += dst_stride; + } + break; + case 4: + if (!need_rmw) { + for (i = 0; i < height; i++) { + uint32_t *row = (uint32_t *)dst_map; + for (j = 0; j < width; j++) + *row++ = zstencil; + dst_map += dst_stride; + } + } + else { + uint32_t dst_mask; + if (dst->format == PIPE_FORMAT_Z24_UNORM_S8_USCALED) + dst_mask = 0xffffff00; + else { + assert(dst->format == PIPE_FORMAT_S8_USCALED_Z24_UNORM); + dst_mask = 0xffffff; + } + if (clear_flags & PIPE_CLEAR_DEPTH) + dst_mask = ~dst_mask; + for (i = 0; i < height; i++) { + uint32_t *row = (uint32_t *)dst_map; + for (j = 0; j < width; j++) { + uint32_t tmp = *row & dst_mask; + *row++ = tmp & (zstencil & ~dst_mask); + } + dst_map += dst_stride; + } + } + break; + case 8: + default: + assert(0); + break; + } + } + + pipe->transfer_unmap(pipe, dst_trans); + pipe->transfer_destroy(pipe, dst_trans); +} diff --git a/src/gallium/auxiliary/util/u_surface.h b/src/gallium/auxiliary/util/u_surface.h index d8fb9f1d6f..6cd12af3a8 100644 --- a/src/gallium/auxiliary/util/u_surface.h +++ b/src/gallium/auxiliary/util/u_surface.h @@ -63,6 +63,14 @@ util_clear_render_target(struct pipe_context *pipe, unsigned dstx, unsigned dsty, unsigned width, unsigned height); +extern void +util_clear_depth_stencil(struct pipe_context *pipe, + struct pipe_surface *dst, + unsigned clear_flags, + double depth, + unsigned stencil, + unsigned dstx, unsigned dsty, + unsigned width, unsigned height); #endif /* U_SURFACE_H */ diff --git a/src/gallium/auxiliary/util/u_upload_mgr.c b/src/gallium/auxiliary/util/u_upload_mgr.c index 75d44432d9..af229e61a0 100644 --- a/src/gallium/auxiliary/util/u_upload_mgr.c +++ b/src/gallium/auxiliary/util/u_upload_mgr.c @@ -59,6 +59,8 @@ struct u_upload_mgr *u_upload_create( struct pipe_context *pipe, unsigned usage ) { struct u_upload_mgr *upload = CALLOC_STRUCT( u_upload_mgr ); + if (!upload) + return NULL; upload->pipe = pipe; upload->default_size = default_size; |