summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarek Olšák <[email protected]>2012-04-13 19:27:45 +0200
committerMarek Olšák <[email protected]>2012-04-18 16:19:38 +0200
commit76d9a99d6bafa5b2ad7839a79deda1a7d5e6d902 (patch)
tree53b5c5da342ad6271c7cc02c50490982928eae6a
parent0ef90e52d1c1898ae1e4618536a85622689c0b19 (diff)
st/mesa: use u_upload_mgr to upload vertices for glBitmap
instead of recreating the vertex buffer for each draw_vbo call.
-rw-r--r--src/mesa/state_tracker/st_cb_bitmap.c75
-rw-r--r--src/mesa/state_tracker/st_context.c3
-rw-r--r--src/mesa/state_tracker/st_context.h4
3 files changed, 23 insertions, 59 deletions
diff --git a/src/mesa/state_tracker/st_cb_bitmap.c b/src/mesa/state_tracker/st_cb_bitmap.c
index 7c0254d8d22..c60a6fc93ae 100644
--- a/src/mesa/state_tracker/st_cb_bitmap.c
+++ b/src/mesa/state_tracker/st_cb_bitmap.c
@@ -52,6 +52,7 @@
#include "util/u_inlines.h"
#include "util/u_draw_quad.h"
#include "util/u_simple_shaders.h"
+#include "util/u_upload_mgr.h"
#include "program/prog_instruction.h"
#include "cso_cache/cso_context.h"
@@ -327,12 +328,13 @@ make_bitmap_texture(struct gl_context *ctx, GLsizei width, GLsizei height,
return pt;
}
-static GLuint
+static void
setup_bitmap_vertex_data(struct st_context *st, bool normalized,
int x, int y, int width, int height,
- float z, const float color[4])
+ float z, const float color[4],
+ struct pipe_resource **vbuf,
+ unsigned *vbuf_offset)
{
- struct pipe_context *pipe = st->pipe;
const struct gl_framebuffer *fb = st->ctx->DrawBuffer;
const GLfloat fb_width = (GLfloat)fb->Width;
const GLfloat fb_height = (GLfloat)fb->Height;
@@ -346,7 +348,6 @@ setup_bitmap_vertex_data(struct st_context *st, bool normalized,
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 = 1; /* 4096 / sizeof(st->bitmap.vertices); */
GLuint i;
if(!normalized)
@@ -355,33 +356,6 @@ setup_bitmap_vertex_data(struct st_context *st, bool normalized,
tBot = (GLfloat) height;
}
- /* XXX: Need to improve buffer_write to allow NO_WAIT (as well as
- * no_flush) updates to buffers where we know there is no conflict
- * with previous data. Currently using max_slots > 1 will cause
- * synchronous rendering if the driver flushes its command buffers
- * between one bitmap and the next. Our flush hook below isn't
- * sufficient to catch this as the driver doesn't tell us when it
- * flushes its own command buffers. Until this gets fixed, pay the
- * price of allocating a new buffer for each bitmap cache-flush to
- * avoid synchronous rendering.
- */
- if (st->bitmap.vbuf_slot >= max_slots) {
- pipe_resource_reference(&st->bitmap.vbuf, NULL);
- st->bitmap.vbuf_slot = 0;
- }
-
- if (!st->bitmap.vbuf) {
- st->bitmap.vbuf = pipe_buffer_create(pipe->screen,
- PIPE_BIND_VERTEX_BUFFER,
- PIPE_USAGE_STREAM,
- max_slots *
- sizeof(st->bitmap.vertices));
- if (!st->bitmap.vbuf) {
- /* out of memory */
- return 0;
- }
- }
-
/* Positions are in clip coords since we need to do clipping in case
* the bitmap quad goes beyond the window bounds.
*/
@@ -417,15 +391,11 @@ setup_bitmap_vertex_data(struct st_context *st, bool normalized,
st->bitmap.vertices[i][2][3] = 1.0; /*Q*/
}
- /* put vertex data into vbuf */
- pipe_buffer_write_nooverlap(st->pipe,
- st->bitmap.vbuf,
- st->bitmap.vbuf_slot
- * sizeof(st->bitmap.vertices),
- sizeof st->bitmap.vertices,
- st->bitmap.vertices);
-
- return st->bitmap.vbuf_slot++ * sizeof st->bitmap.vertices;
+ /* Note: *vbuf will be NULL if there's a failure. */
+ u_upload_data(st->uploader, 0,
+ sizeof(st->bitmap.vertices), st->bitmap.vertices,
+ vbuf_offset, vbuf);
+ u_upload_unmap(st->uploader);
}
@@ -446,6 +416,7 @@ draw_bitmap_quad(struct gl_context *ctx, GLint x, GLint y, GLfloat z,
struct st_fp_variant_key key;
GLuint maxSize;
GLuint offset;
+ struct pipe_resource *vbuf = NULL;
memset(&key, 0, sizeof(key));
key.st = st;
@@ -551,12 +522,11 @@ draw_bitmap_quad(struct gl_context *ctx, GLint x, GLint y, GLfloat z,
z = z * 2.0f - 1.0f;
/* draw textured quad */
- offset = setup_bitmap_vertex_data(st,
- sv->texture->target != PIPE_TEXTURE_RECT,
- x, y, width, height, z, color);
+ setup_bitmap_vertex_data(st, sv->texture->target != PIPE_TEXTURE_RECT,
+ x, y, width, height, z, color, &vbuf, &offset);
- if (st->bitmap.vbuf) {
- util_draw_vertex_buffer(pipe, st->cso_context, st->bitmap.vbuf, offset,
+ if (vbuf) {
+ util_draw_vertex_buffer(pipe, st->cso_context, vbuf, offset,
PIPE_PRIM_TRIANGLE_FAN,
4, /* verts */
3); /* attribs/vert */
@@ -573,6 +543,8 @@ draw_bitmap_quad(struct gl_context *ctx, GLint x, GLint y, GLfloat z,
cso_restore_vertex_elements(cso);
cso_restore_vertex_buffers(cso);
cso_restore_stream_outputs(cso);
+
+ pipe_resource_reference(&vbuf, NULL);
}
@@ -709,18 +681,12 @@ st_flush_bitmap_cache(struct st_context *st)
/**
- * Flush bitmap cache and release vertex buffer.
+ * Flush bitmap cache.
*/
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_resource_reference(&st->bitmap.vbuf, NULL);
- st->bitmap.vbuf_slot = 0;
}
@@ -914,11 +880,6 @@ st_destroy_bitmap(struct st_context *st)
st->bitmap.vs = NULL;
}
- if (st->bitmap.vbuf) {
- pipe_resource_reference(&st->bitmap.vbuf, NULL);
- st->bitmap.vbuf = NULL;
- }
-
if (cache) {
if (cache->trans) {
pipe_transfer_unmap(pipe, cache->trans);
diff --git a/src/mesa/state_tracker/st_context.c b/src/mesa/state_tracker/st_context.c
index a3fd4dbcb7f..0245fd92b3e 100644
--- a/src/mesa/state_tracker/st_context.c
+++ b/src/mesa/state_tracker/st_context.c
@@ -63,6 +63,7 @@
#include "st_program.h"
#include "pipe/p_context.h"
#include "util/u_inlines.h"
+#include "util/u_upload_mgr.h"
#include "cso_cache/cso_context.h"
@@ -130,6 +131,7 @@ st_create_context_priv( struct gl_context *ctx, struct pipe_context *pipe )
st->dirty.mesa = ~0;
st->dirty.st = ~0;
+ st->uploader = u_upload_create(st->pipe, 65536, 4, PIPE_BIND_VERTEX_BUFFER);
st->cso_context = cso_create_context(pipe);
st_init_atoms( st );
@@ -235,6 +237,7 @@ static void st_destroy_context_priv( struct st_context *st )
st->default_texture = NULL;
}
+ u_upload_destroy(st->uploader);
free( st );
}
diff --git a/src/mesa/state_tracker/st_context.h b/src/mesa/state_tracker/st_context.h
index da03719fdec..0135e3c6777 100644
--- a/src/mesa/state_tracker/st_context.h
+++ b/src/mesa/state_tracker/st_context.h
@@ -40,6 +40,7 @@ struct draw_stage;
struct gen_mipmap_state;
struct st_context;
struct st_fragment_program;
+struct u_upload_mgr;
#define ST_NEW_MESA 0x1 /* Mesa state has changed */
@@ -71,6 +72,7 @@ struct st_context
struct pipe_context *pipe;
+ struct u_upload_mgr *uploader;
struct draw_context *draw; /**< For selection/feedback/rastpos only */
struct draw_stage *feedback_stage; /**< For GL_FEEDBACK rendermode */
struct draw_stage *selection_stage; /**< For GL_SELECT rendermode */
@@ -154,8 +156,6 @@ struct st_context
enum pipe_format tex_format;
void *vs;
float vertices[4][3][4]; /**< vertex pos + color + texcoord */
- struct pipe_resource *vbuf;
- unsigned vbuf_slot; /* next free slot in vbuf */
struct bitmap_cache *cache;
} bitmap;