From 76d9a99d6bafa5b2ad7839a79deda1a7d5e6d902 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Marek=20Ol=C5=A1=C3=A1k?= Date: Fri, 13 Apr 2012 19:27:45 +0200 Subject: [PATCH] st/mesa: use u_upload_mgr to upload vertices for glBitmap instead of recreating the vertex buffer for each draw_vbo call. --- src/mesa/state_tracker/st_cb_bitmap.c | 75 +++++++++-------------------------- src/mesa/state_tracker/st_context.c | 3 ++ src/mesa/state_tracker/st_context.h | 4 +- 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 7c0254d..c60a6fc 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 a3fd4db..0245fd9 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 da03719..0135e3c 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; -- 2.7.4