summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKeith Whitwell <keith@tungstengraphics.com>2008-12-12 16:46:34 +0000
committerKeith Whitwell <keith@tungstengraphics.com>2008-12-12 16:57:39 +0000
commitd2c2e9316d043ab584794a3524f22776deb4c777 (patch)
tree1d6045093cd7c935ceb26a3afb6c57b177c0ac62
parenteb20e2984e51e632ef1a51620db7aca3eb89dafa (diff)
gallium: avoid mapping same vertex buffer in subsequent frames
Quite a few util modules were maintaining a single vertex buffer over multiple frames, and potentially reusing it in subsequent frames. Unfortunately that would force us into syncrhonous rendering as the buffer manager would be forced to wait for the previous rendering to complete prior to allowing the map. This resolves that issue, but requires the state tracker to issue a few new flush() calls at the end of each frame.
-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
-rw-r--r--src/mesa/state_tracker/st_cb_accum.c3
-rw-r--r--src/mesa/state_tracker/st_cb_bitmap.c60
-rw-r--r--src/mesa/state_tracker/st_cb_bitmap.h6
-rw-r--r--src/mesa/state_tracker/st_cb_clear.c31
-rw-r--r--src/mesa/state_tracker/st_cb_clear.h3
-rw-r--r--src/mesa/state_tracker/st_cb_drawpixels.c2
-rw-r--r--src/mesa/state_tracker/st_cb_fbo.c2
-rw-r--r--src/mesa/state_tracker/st_cb_flush.c11
-rw-r--r--src/mesa/state_tracker/st_cb_readpixels.c4
-rw-r--r--src/mesa/state_tracker/st_context.h2
16 files changed, 219 insertions, 60 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
diff --git a/src/mesa/state_tracker/st_cb_accum.c b/src/mesa/state_tracker/st_cb_accum.c
index cf3a99e7e9..a4e72b48ed 100644
--- a/src/mesa/state_tracker/st_cb_accum.c
+++ b/src/mesa/state_tracker/st_cb_accum.c
@@ -38,6 +38,7 @@
#include "st_cb_accum.h"
#include "st_cb_fbo.h"
#include "st_draw.h"
+#include "st_public.h"
#include "st_format.h"
#include "pipe/p_context.h"
#include "pipe/p_defines.h"
@@ -324,7 +325,7 @@ st_Accum(GLcontext *ctx, GLenum op, GLfloat value)
const GLint height = ctx->DrawBuffer->_Ymax - ypos;
/* make sure color bufs aren't cached */
- pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE, NULL);
+ st_flush( st, PIPE_FLUSH_RENDER_CACHE, NULL );
switch (op) {
case GL_ADD:
diff --git a/src/mesa/state_tracker/st_cb_bitmap.c b/src/mesa/state_tracker/st_cb_bitmap.c
index 73645201cc..bc05ca6a2f 100644
--- a/src/mesa/state_tracker/st_cb_bitmap.c
+++ b/src/mesa/state_tracker/st_cb_bitmap.c
@@ -349,8 +349,7 @@ make_bitmap_texture(GLcontext *ctx, GLsizei width, GLsizei height,
return pt;
}
-
-static void
+static GLuint
setup_bitmap_vertex_data(struct st_context *st,
int x, int y, int width, int height,
float z, const float color[4])
@@ -369,12 +368,18 @@ setup_bitmap_vertex_data(struct st_context *st,
const GLfloat clip_y0 = (GLfloat)(y0 / fb_height * 2.0 - 1.0);
const GLfloat clip_x1 = (GLfloat)(x1 / fb_width * 2.0 - 1.0);
const GLfloat clip_y1 = (GLfloat)(y1 / fb_height * 2.0 - 1.0);
+ const GLuint max_slots = 4096 / sizeof(st->bitmap.vertices);
GLuint i;
- void *buf;
+
+ if (st->bitmap.vbuf_slot >= max_slots) {
+ pipe_buffer_reference(pipe->screen, &st->bitmap.vbuf, NULL);
+ st->bitmap.vbuf_slot = 0;
+ }
if (!st->bitmap.vbuf) {
- st->bitmap.vbuf = pipe_buffer_create(pipe->screen, 32, PIPE_BUFFER_USAGE_VERTEX,
- sizeof(st->bitmap.vertices));
+ st->bitmap.vbuf = pipe_buffer_create(pipe->screen, 32,
+ PIPE_BUFFER_USAGE_VERTEX,
+ max_slots * sizeof(st->bitmap.vertices));
}
/* Positions are in clip coords since we need to do clipping in case
@@ -413,9 +418,19 @@ setup_bitmap_vertex_data(struct st_context *st,
}
/* put vertex data into vbuf */
- buf = pipe_buffer_map(pipe->screen, st->bitmap.vbuf, PIPE_BUFFER_USAGE_CPU_WRITE);
- memcpy(buf, st->bitmap.vertices, sizeof(st->bitmap.vertices));
- pipe_buffer_unmap(pipe->screen, st->bitmap.vbuf);
+ {
+ char *buf = pipe_buffer_map(pipe->screen,
+ st->bitmap.vbuf,
+ PIPE_BUFFER_USAGE_CPU_WRITE);
+
+ memcpy(buf + st->bitmap.vbuf_slot * sizeof st->bitmap.vertices,
+ st->bitmap.vertices,
+ sizeof st->bitmap.vertices);
+
+ pipe_buffer_unmap(pipe->screen, st->bitmap.vbuf);
+ }
+
+ return st->bitmap.vbuf_slot++ * sizeof st->bitmap.vertices;
}
@@ -434,6 +449,7 @@ draw_bitmap_quad(GLcontext *ctx, GLint x, GLint y, GLfloat z,
struct cso_context *cso = ctx->st->cso_context;
struct st_fragment_program *stfp;
GLuint maxSize;
+ GLuint offset;
stfp = combined_bitmap_fragment_program(ctx);
@@ -518,11 +534,11 @@ draw_bitmap_quad(GLcontext *ctx, GLint x, GLint y, GLfloat z,
}
/* draw textured quad */
- setup_bitmap_vertex_data(st, x, y, width, height,
- ctx->Current.RasterPos[2],
- color);
+ offset = setup_bitmap_vertex_data(st, x, y, width, height,
+ ctx->Current.RasterPos[2],
+ color);
- util_draw_vertex_buffer(pipe, st->bitmap.vbuf,
+ util_draw_vertex_buffer(pipe, st->bitmap.vbuf, offset,
PIPE_PRIM_TRIANGLE_FAN,
4, /* verts */
3); /* attribs/vert */
@@ -592,12 +608,12 @@ st_flush_bitmap_cache(struct st_context *st)
struct pipe_screen *screen = pipe->screen;
assert(cache->xmin <= cache->xmax);
- /*
- printf("flush size %d x %d at %d, %d\n",
+
+/* printf("flush size %d x %d at %d, %d\n",
cache->xmax - cache->xmin,
cache->ymax - cache->ymin,
cache->xpos, cache->ypos);
- */
+*/
/* The texture surface has been mapped until now.
* So unmap and release the texture surface before drawing.
@@ -623,6 +639,20 @@ st_flush_bitmap_cache(struct st_context *st)
}
}
+/* Flush bitmap cache and release vertex buffer.
+ */
+void
+st_flush_bitmap( struct st_context *st )
+{
+ st_flush_bitmap_cache(st);
+
+ /* Release vertex buffer to avoid synchronous rendering if we were
+ * to map it in the next frame.
+ */
+ pipe_buffer_reference(st->pipe->screen, &st->bitmap.vbuf, NULL);
+ st->bitmap.vbuf_slot = 0;
+}
+
/**
* Try to accumulate this glBitmap call in the bitmap cache.
diff --git a/src/mesa/state_tracker/st_cb_bitmap.h b/src/mesa/state_tracker/st_cb_bitmap.h
index aae11d34c9..81cf61981d 100644
--- a/src/mesa/state_tracker/st_cb_bitmap.h
+++ b/src/mesa/state_tracker/st_cb_bitmap.h
@@ -42,5 +42,11 @@ st_destroy_bitmap(struct st_context *st);
extern void
st_flush_bitmap_cache(struct st_context *st);
+/* Flush bitmap cache and release vertex buffer. Needed at end of
+ * frame to avoid synchronous rendering.
+ */
+extern void
+st_flush_bitmap(struct st_context *st);
+
#endif /* ST_CB_BITMAP_H */
diff --git a/src/mesa/state_tracker/st_cb_clear.c b/src/mesa/state_tracker/st_cb_clear.c
index bc3055c3fd..b6cea16163 100644
--- a/src/mesa/state_tracker/st_cb_clear.c
+++ b/src/mesa/state_tracker/st_cb_clear.c
@@ -148,12 +148,18 @@ draw_quad(GLcontext *ctx,
{
struct st_context *st = ctx->st;
struct pipe_context *pipe = st->pipe;
+ const GLuint max_slots = 1024 / sizeof(st->clear.vertices);
GLuint i;
void *buf;
+ if (st->clear.vbuf_slot >= max_slots) {
+ pipe_buffer_reference(pipe->screen, &st->clear.vbuf, NULL);
+ st->clear.vbuf_slot = 0;
+ }
+
if (!st->clear.vbuf) {
st->clear.vbuf = pipe_buffer_create(pipe->screen, 32, PIPE_BUFFER_USAGE_VERTEX,
- sizeof(st->clear.vertices));
+ max_slots * sizeof(st->clear.vertices));
}
/* positions */
@@ -181,14 +187,23 @@ draw_quad(GLcontext *ctx,
/* put vertex data into vbuf */
buf = pipe_buffer_map(pipe->screen, st->clear.vbuf, PIPE_BUFFER_USAGE_CPU_WRITE);
- memcpy(buf, st->clear.vertices, sizeof(st->clear.vertices));
+
+ memcpy((char *)buf + st->clear.vbuf_slot * sizeof(st->clear.vertices),
+ st->clear.vertices,
+ sizeof(st->clear.vertices));
+
pipe_buffer_unmap(pipe->screen, st->clear.vbuf);
/* draw */
- util_draw_vertex_buffer(pipe, st->clear.vbuf,
+ util_draw_vertex_buffer(pipe,
+ st->clear.vbuf,
+ st->clear.vbuf_slot * sizeof(st->clear.vertices),
PIPE_PRIM_TRIANGLE_FAN,
4, /* verts */
2); /* attribs/vert */
+
+ /* Increment slot */
+ st->clear.vbuf_slot++;
}
@@ -508,6 +523,16 @@ clear_depth_stencil_buffer(GLcontext *ctx, struct gl_renderbuffer *rb)
}
+void st_flush_clear( struct st_context *st )
+{
+ /* Release vertex buffer to avoid synchronous rendering if we were
+ * to map it in the next frame.
+ */
+ pipe_buffer_reference(st->pipe->screen, &st->clear.vbuf, NULL);
+ st->clear.vbuf_slot = 0;
+}
+
+
/**
* Called via ctx->Driver.Clear()
diff --git a/src/mesa/state_tracker/st_cb_clear.h b/src/mesa/state_tracker/st_cb_clear.h
index f49387747d..bc035ac25c 100644
--- a/src/mesa/state_tracker/st_cb_clear.h
+++ b/src/mesa/state_tracker/st_cb_clear.h
@@ -37,6 +37,9 @@ st_init_clear(struct st_context *st);
extern void
st_destroy_clear(struct st_context *st);
+extern void
+st_flush_clear(struct st_context *st);
+
extern void
st_init_clear_functions(struct dd_function_table *functions);
diff --git a/src/mesa/state_tracker/st_cb_drawpixels.c b/src/mesa/state_tracker/st_cb_drawpixels.c
index 5b24b9f068..32bf21411d 100644
--- a/src/mesa/state_tracker/st_cb_drawpixels.c
+++ b/src/mesa/state_tracker/st_cb_drawpixels.c
@@ -494,7 +494,7 @@ draw_quad(GLcontext *ctx, GLfloat x0, GLfloat y0, GLfloat z,
memcpy(map, verts, sizeof(verts));
pipe_buffer_unmap(pipe->screen, buf);
- util_draw_vertex_buffer(pipe, buf,
+ util_draw_vertex_buffer(pipe, buf, 0,
PIPE_PRIM_QUADS,
4, /* verts */
3); /* attribs/vert */
diff --git a/src/mesa/state_tracker/st_cb_fbo.c b/src/mesa/state_tracker/st_cb_fbo.c
index 00076f61e0..eece7dee11 100644
--- a/src/mesa/state_tracker/st_cb_fbo.c
+++ b/src/mesa/state_tracker/st_cb_fbo.c
@@ -426,7 +426,7 @@ st_finish_render_texture(GLcontext *ctx,
if (!strb)
return;
- ctx->st->pipe->flush(ctx->st->pipe, PIPE_FLUSH_RENDER_CACHE, NULL);
+ st_flush( ctx->st, PIPE_FLUSH_RENDER_CACHE, NULL );
if (strb->surface)
screen->tex_surface_release( screen, &strb->surface );
diff --git a/src/mesa/state_tracker/st_cb_flush.c b/src/mesa/state_tracker/st_cb_flush.c
index cc40467941..072f2e92ad 100644
--- a/src/mesa/state_tracker/st_cb_flush.c
+++ b/src/mesa/state_tracker/st_cb_flush.c
@@ -37,11 +37,14 @@
#include "st_context.h"
#include "st_cb_bitmap.h"
#include "st_cb_flush.h"
+#include "st_cb_clear.h"
#include "st_cb_fbo.h"
#include "st_public.h"
#include "pipe/p_context.h"
#include "pipe/p_defines.h"
#include "pipe/p_winsys.h"
+#include "util/u_gen_mipmap.h"
+#include "util/u_blit.h"
static INLINE GLboolean
@@ -78,7 +81,13 @@ void st_flush( struct st_context *st, uint pipeFlushFlags,
{
FLUSH_VERTICES(st->ctx, 0);
- st_flush_bitmap_cache(st);
+ /* Release any vertex buffers that might potentially be accessed in
+ * successive frames:
+ */
+ st_flush_bitmap(st);
+ st_flush_clear(st);
+ util_blit_flush(st->blit);
+ util_gen_mipmap_flush(st->gen_mipmap);
st->pipe->flush( st->pipe, pipeFlushFlags, fence );
}
diff --git a/src/mesa/state_tracker/st_cb_readpixels.c b/src/mesa/state_tracker/st_cb_readpixels.c
index c801532788..646eaff190 100644
--- a/src/mesa/state_tracker/st_cb_readpixels.c
+++ b/src/mesa/state_tracker/st_cb_readpixels.c
@@ -317,10 +317,8 @@ st_readpixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height,
if (!dest)
return;
- st_flush_bitmap_cache(ctx->st);
-
/* make sure rendering has completed */
- pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE, NULL);
+ st_flush(ctx->st, PIPE_FLUSH_RENDER_CACHE, NULL);
if (format == GL_STENCIL_INDEX) {
st_read_stencil_pixels(ctx, x, y, width, height, type, pack, dest);
diff --git a/src/mesa/state_tracker/st_context.h b/src/mesa/state_tracker/st_context.h
index 5bcb87ce20..695ac4a96f 100644
--- a/src/mesa/state_tracker/st_context.h
+++ b/src/mesa/state_tracker/st_context.h
@@ -154,6 +154,7 @@ struct st_context
void *vs;
float vertices[4][3][4]; /**< vertex pos + color + texcoord */
struct pipe_buffer *vbuf;
+ unsigned vbuf_slot; /* next free slot in vbuf */
struct bitmap_cache *cache;
} bitmap;
@@ -173,6 +174,7 @@ struct st_context
void *fs;
float vertices[4][2][4]; /**< vertex pos + color */
struct pipe_buffer *vbuf;
+ unsigned vbuf_slot;
} clear;
void *passthrough_fs; /**< simple pass-through frag shader */