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_blit.c88
-rw-r--r--src/gallium/auxiliary/util/u_blit.h4
-rw-r--r--src/gallium/auxiliary/util/u_draw_quad.c5
-rw-r--r--src/gallium/auxiliary/util/u_draw_quad.h2
-rw-r--r--src/gallium/auxiliary/util/u_gen_mipmap.c51
-rw-r--r--src/gallium/auxiliary/util/u_gen_mipmap.h5
6 files changed, 120 insertions, 35 deletions
diff --git a/src/gallium/auxiliary/util/u_blit.c b/src/gallium/auxiliary/util/u_blit.c
index d28201ac8d..2cef3338b5 100644
--- a/src/gallium/auxiliary/util/u_blit.c
+++ b/src/gallium/auxiliary/util/u_blit.c
@@ -66,6 +66,8 @@ struct blit_state
void *fs;
struct pipe_buffer *vbuf; /**< quad vertices */
+ unsigned vbuf_slot;
+
float vertices[4][2][4]; /**< vertex/texcoords for quad */
};
@@ -138,17 +140,7 @@ util_create_blit(struct pipe_context *pipe, struct cso_context *cso)
/* fragment shader */
ctx->fs = util_make_fragment_tex_shader(pipe, &ctx->frag_shader);
-
- ctx->vbuf = pipe_buffer_create(pipe->screen,
- 32,
- PIPE_BUFFER_USAGE_VERTEX,
- sizeof(ctx->vertices));
- if (!ctx->vbuf) {
- FREE(ctx);
- ctx->pipe->delete_fs_state(ctx->pipe, ctx->fs);
- ctx->pipe->delete_vs_state(ctx->pipe, ctx->vs);
- return NULL;
- }
+ ctx->vbuf = NULL;
/* init vertex data that doesn't change */
for (i = 0; i < 4; i++) {
@@ -181,15 +173,35 @@ util_destroy_blit(struct blit_state *ctx)
}
+static unsigned get_next_slot( struct blit_state *ctx )
+{
+ const unsigned max_slots = 4096 / sizeof ctx->vertices;
+
+ if (ctx->vbuf_slot >= max_slots)
+ util_blit_flush( ctx );
+
+ if (!ctx->vbuf) {
+ ctx->vbuf = pipe_buffer_create(ctx->pipe->screen,
+ 32,
+ PIPE_BUFFER_USAGE_VERTEX,
+ max_slots * sizeof ctx->vertices);
+ }
+
+ return ctx->vbuf_slot++ * sizeof ctx->vertices;
+}
+
+
+
/**
* Setup vertex data for the textured quad we'll draw.
* Note: y=0=top
*/
-static void
+static unsigned
setup_vertex_data(struct blit_state *ctx,
float x0, float y0, float x1, float y1, float z)
{
void *buf;
+ unsigned offset;
ctx->vertices[0][0][0] = x0;
ctx->vertices[0][0][1] = y0;
@@ -215,12 +227,16 @@ setup_vertex_data(struct blit_state *ctx,
ctx->vertices[3][1][0] = 0.0f;
ctx->vertices[3][1][1] = 1.0f;
+ offset = get_next_slot( ctx );
+
buf = pipe_buffer_map(ctx->pipe->screen, ctx->vbuf,
PIPE_BUFFER_USAGE_CPU_WRITE);
- memcpy(buf, ctx->vertices, sizeof(ctx->vertices));
+ memcpy((char *)buf + offset, ctx->vertices, sizeof(ctx->vertices));
pipe_buffer_unmap(ctx->pipe->screen, ctx->vbuf);
+
+ return offset;
}
@@ -228,13 +244,14 @@ setup_vertex_data(struct blit_state *ctx,
* Setup vertex data for the textured quad we'll draw.
* Note: y=0=top
*/
-static void
+static unsigned
setup_vertex_data_tex(struct blit_state *ctx,
float x0, float y0, float x1, float y1,
float s0, float t0, float s1, float t1,
float z)
{
void *buf;
+ unsigned offset;
ctx->vertices[0][0][0] = x0;
ctx->vertices[0][0][1] = y0;
@@ -260,12 +277,16 @@ setup_vertex_data_tex(struct blit_state *ctx,
ctx->vertices[3][1][0] = s0;
ctx->vertices[3][1][1] = t1;
+ offset = get_next_slot( ctx );
+
buf = pipe_buffer_map(ctx->pipe->screen, ctx->vbuf,
PIPE_BUFFER_USAGE_CPU_WRITE);
- memcpy(buf, ctx->vertices, sizeof(ctx->vertices));
+ memcpy((char *)buf + offset, ctx->vertices, sizeof(ctx->vertices));
pipe_buffer_unmap(ctx->pipe->screen, ctx->vbuf);
+
+ return offset;
}
/**
* Copy pixel block from src surface to dst surface.
@@ -291,6 +312,7 @@ util_blit_pixels(struct blit_state *ctx,
const int srcH = abs(srcY1 - srcY0);
const int srcLeft = MIN2(srcX0, srcX1);
const int srcTop = MIN2(srcY0, srcY1);
+ unsigned offset;
assert(filter == PIPE_TEX_MIPFILTER_NEAREST ||
filter == PIPE_TEX_MIPFILTER_LINEAR);
@@ -398,11 +420,11 @@ util_blit_pixels(struct blit_state *ctx,
cso_set_framebuffer(ctx->cso, &fb);
/* draw quad */
- setup_vertex_data(ctx,
- (float) dstX0, (float) dstY0,
- (float) dstX1, (float) dstY1, z);
+ offset = setup_vertex_data(ctx,
+ (float) dstX0, (float) dstY0,
+ (float) dstX1, (float) dstY1, z);
- util_draw_vertex_buffer(ctx->pipe, ctx->vbuf,
+ util_draw_vertex_buffer(ctx->pipe, ctx->vbuf, offset,
PIPE_PRIM_TRIANGLE_FAN,
4, /* verts */
2); /* attribs/vert */
@@ -421,6 +443,18 @@ util_blit_pixels(struct blit_state *ctx,
screen->texture_release(screen, &tex);
}
+
+/* Release vertex buffer at end of frame to avoid synchronous
+ * rendering.
+ */
+void util_blit_flush( struct blit_state *ctx )
+{
+ pipe_buffer_reference(ctx->pipe->screen, &ctx->vbuf, NULL);
+ ctx->vbuf_slot = 0;
+}
+
+
+
/**
* Copy pixel block from src texture to dst surface.
* Overlapping regions are acceptable.
@@ -442,6 +476,7 @@ util_blit_pixels_tex(struct blit_state *ctx,
struct pipe_screen *screen = pipe->screen;
struct pipe_framebuffer_state fb;
float s0, t0, s1, t1;
+ unsigned offset;
assert(filter == PIPE_TEX_MIPFILTER_NEAREST ||
filter == PIPE_TEX_MIPFILTER_LINEAR);
@@ -496,13 +531,14 @@ util_blit_pixels_tex(struct blit_state *ctx,
cso_set_framebuffer(ctx->cso, &fb);
/* draw quad */
- setup_vertex_data_tex(ctx,
- (float) dstX0, (float) dstY0,
- (float) dstX1, (float) dstY1,
- s0, t0, s1, t1,
- z);
-
- util_draw_vertex_buffer(ctx->pipe, ctx->vbuf,
+ offset = setup_vertex_data_tex(ctx,
+ (float) dstX0, (float) dstY0,
+ (float) dstX1, (float) dstY1,
+ s0, t0, s1, t1,
+ z);
+
+ util_draw_vertex_buffer(ctx->pipe,
+ ctx->vbuf, offset,
PIPE_PRIM_TRIANGLE_FAN,
4, /* verts */
2); /* attribs/vert */
diff --git a/src/gallium/auxiliary/util/u_blit.h b/src/gallium/auxiliary/util/u_blit.h
index 308075698f..c35beceda8 100644
--- a/src/gallium/auxiliary/util/u_blit.h
+++ b/src/gallium/auxiliary/util/u_blit.h
@@ -70,6 +70,10 @@ util_blit_pixels_tex(struct blit_state *ctx,
int dstX1, int dstY1,
float z, uint filter);
+/* Call at end of frame to avoid synchronous rendering.
+ */
+extern void
+util_blit_flush( struct blit_state *ctx );
#ifdef __cplusplus
}
diff --git a/src/gallium/auxiliary/util/u_draw_quad.c b/src/gallium/auxiliary/util/u_draw_quad.c
index 8ecae71b64..d7bb74b87b 100644
--- a/src/gallium/auxiliary/util/u_draw_quad.c
+++ b/src/gallium/auxiliary/util/u_draw_quad.c
@@ -40,6 +40,7 @@
void
util_draw_vertex_buffer(struct pipe_context *pipe,
struct pipe_buffer *vbuf,
+ uint offset,
uint prim_type,
uint num_verts,
uint num_attribs)
@@ -53,7 +54,7 @@ util_draw_vertex_buffer(struct pipe_context *pipe,
/* tell pipe about the vertex buffer */
vbuffer.buffer = vbuf;
vbuffer.pitch = num_attribs * 4 * sizeof(float); /* vertex size */
- vbuffer.buffer_offset = 0;
+ vbuffer.buffer_offset = offset;
pipe->set_vertex_buffers(pipe, 1, &vbuffer);
/* tell pipe about the vertex attributes */
@@ -124,7 +125,7 @@ util_draw_texquad(struct pipe_context *pipe,
v[29] = 1.0;
pipe_buffer_unmap(pipe->screen, vbuf);
- util_draw_vertex_buffer(pipe, vbuf, PIPE_PRIM_TRIANGLE_FAN, 4, 2);
+ util_draw_vertex_buffer(pipe, vbuf, 0, PIPE_PRIM_TRIANGLE_FAN, 4, 2);
}
pipe_buffer_reference(pipe->screen, &vbuf, NULL);
diff --git a/src/gallium/auxiliary/util/u_draw_quad.h b/src/gallium/auxiliary/util/u_draw_quad.h
index ec4862ead3..00d3f5b715 100644
--- a/src/gallium/auxiliary/util/u_draw_quad.h
+++ b/src/gallium/auxiliary/util/u_draw_quad.h
@@ -37,7 +37,7 @@ struct pipe_buffer;
extern void
util_draw_vertex_buffer(struct pipe_context *pipe,
- struct pipe_buffer *vbuf,
+ struct pipe_buffer *vbuf, uint offset,
uint num_attribs, uint num_verts, uint prim_type);
diff --git a/src/gallium/auxiliary/util/u_gen_mipmap.c b/src/gallium/auxiliary/util/u_gen_mipmap.c
index 9d305ad763..5f395ec6e9 100644
--- a/src/gallium/auxiliary/util/u_gen_mipmap.c
+++ b/src/gallium/auxiliary/util/u_gen_mipmap.c
@@ -69,6 +69,8 @@ struct gen_mipmap_state
void *fs;
struct pipe_buffer *vbuf; /**< quad vertices */
+ unsigned vbuf_slot;
+
float vertices[4][2][4]; /**< vertex/texcoords for quad */
};
@@ -779,10 +781,28 @@ util_create_gen_mipmap(struct pipe_context *pipe,
}
-static void
+static unsigned get_next_slot( struct gen_mipmap_state *ctx )
+{
+ const unsigned max_slots = 4096 / sizeof ctx->vertices;
+
+ if (ctx->vbuf_slot >= max_slots)
+ util_gen_mipmap_flush( ctx );
+
+ if (!ctx->vbuf) {
+ ctx->vbuf = pipe_buffer_create(ctx->pipe->screen,
+ 32,
+ PIPE_BUFFER_USAGE_VERTEX,
+ max_slots * sizeof ctx->vertices);
+ }
+
+ return ctx->vbuf_slot++ * sizeof ctx->vertices;
+}
+
+static unsigned
set_vertex_data(struct gen_mipmap_state *ctx, float width, float height)
{
void *buf;
+ unsigned offset;
ctx->vertices[0][0][0] = 0.0f; /*x*/
ctx->vertices[0][0][1] = 0.0f; /*y*/
@@ -804,12 +824,16 @@ set_vertex_data(struct gen_mipmap_state *ctx, float width, float height)
ctx->vertices[3][1][0] = 0.0f;
ctx->vertices[3][1][1] = 1.0f;
+ offset = get_next_slot( ctx );
+
buf = pipe_buffer_map(ctx->pipe->screen, ctx->vbuf,
PIPE_BUFFER_USAGE_CPU_WRITE);
- memcpy(buf, ctx->vertices, sizeof(ctx->vertices));
+ memcpy((char *)buf + offset, ctx->vertices, sizeof(ctx->vertices));
pipe_buffer_unmap(ctx->pipe->screen, ctx->vbuf);
+
+ return offset;
}
@@ -834,6 +858,17 @@ util_destroy_gen_mipmap(struct gen_mipmap_state *ctx)
}
+
+/* Release vertex buffer at end of frame to avoid synchronous
+ * rendering.
+ */
+void util_gen_mipmap_flush( struct gen_mipmap_state *ctx )
+{
+ pipe_buffer_reference(ctx->pipe->screen, &ctx->vbuf, NULL);
+ ctx->vbuf_slot = 0;
+}
+
+
/**
* Generate mipmap images. It's assumed all needed texture memory is
* already allocated.
@@ -855,6 +890,7 @@ util_gen_mipmap(struct gen_mipmap_state *ctx,
struct pipe_framebuffer_state fb;
uint dstLevel;
uint zslice = 0;
+ uint offset;
/* check if we can render in the texture's format */
if (!screen->is_format_supported(screen, pt->format, PIPE_TEXTURE_2D,
@@ -925,10 +961,13 @@ util_gen_mipmap(struct gen_mipmap_state *ctx,
cso_set_sampler_textures(ctx->cso, 1, &pt);
/* quad coords in window coords (bypassing clipping, viewport mapping) */
- set_vertex_data(ctx,
- (float) pt->width[dstLevel],
- (float) pt->height[dstLevel]);
- util_draw_vertex_buffer(ctx->pipe, ctx->vbuf,
+ offset = set_vertex_data(ctx,
+ (float) pt->width[dstLevel],
+ (float) pt->height[dstLevel]);
+
+ util_draw_vertex_buffer(ctx->pipe,
+ ctx->vbuf,
+ offset,
PIPE_PRIM_TRIANGLE_FAN,
4, /* verts */
2); /* attribs/vert */
diff --git a/src/gallium/auxiliary/util/u_gen_mipmap.h b/src/gallium/auxiliary/util/u_gen_mipmap.h
index 3277024f07..54608f9466 100644
--- a/src/gallium/auxiliary/util/u_gen_mipmap.h
+++ b/src/gallium/auxiliary/util/u_gen_mipmap.h
@@ -50,6 +50,11 @@ util_create_gen_mipmap(struct pipe_context *pipe, struct cso_context *cso);
extern void
util_destroy_gen_mipmap(struct gen_mipmap_state *ctx);
+/* Release vertex buffer at end of frame to avoid synchronous
+ * rendering.
+ */
+extern void
+util_gen_mipmap_flush( struct gen_mipmap_state *ctx );
extern void