summaryrefslogtreecommitdiff
path: root/src/gallium/auxiliary/util
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/auxiliary/util')
-rw-r--r--src/gallium/auxiliary/util/u_blitter.c20
-rw-r--r--src/gallium/auxiliary/util/u_blitter.h10
-rw-r--r--src/gallium/auxiliary/util/u_debug.c2
-rw-r--r--src/gallium/auxiliary/util/u_math.h14
-rw-r--r--src/gallium/auxiliary/util/u_pointer.h11
-rw-r--r--src/gallium/auxiliary/util/u_prim.h46
-rw-r--r--src/gallium/auxiliary/util/u_surface.c108
-rw-r--r--src/gallium/auxiliary/util/u_surface.h8
-rw-r--r--src/gallium/auxiliary/util/u_upload_mgr.c2
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;