summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorDave Airlie <[email protected]>2010-08-23 20:28:02 +1000
committerDave Airlie <[email protected]>2010-08-23 20:31:21 +1000
commiteb430b0e948caf02b9f4095d0e1435880073c2aa (patch)
treefbc94f4f3c9d05ab408a66b6fe3763397a3a8ba3 /src
parente607b67ebc0d15f6709fc8f9c79afeeda8ac1031 (diff)
r300g: avoid stall in no-tcl drawing when mapping vbo
the current code reuses the same vbo over and over, however after a flush we'd stall and wait for mapping on the vbo when we should just fire and forget. On a gears test this brings me from ~620 to ~750 on my rv530 in swtcl mode. Signed-off-by: Dave Airlie <[email protected]>
Diffstat (limited to 'src')
-rw-r--r--src/gallium/drivers/r300/r300_context.h4
-rw-r--r--src/gallium/drivers/r300/r300_flush.c2
-rw-r--r--src/gallium/drivers/r300/r300_render.c35
3 files changed, 26 insertions, 15 deletions
diff --git a/src/gallium/drivers/r300/r300_context.h b/src/gallium/drivers/r300/r300_context.h
index 6fa7f470f98..030bb2314f7 100644
--- a/src/gallium/drivers/r300/r300_context.h
+++ b/src/gallium/drivers/r300/r300_context.h
@@ -449,6 +449,7 @@ struct r300_context {
struct r300_screen *screen;
/* Draw module. Used mostly for SW TCL. */
struct draw_context* draw;
+ size_t draw_vbo_size;
/* Accelerated blit support. */
struct blitter_context* blitter;
/* Stencil two-sided reference value fallback. */
@@ -649,6 +650,9 @@ void r300_translate_index_buffer(struct r300_context *r300,
/* r300_render_stencilref.c */
void r300_plug_in_stencil_ref_fallback(struct r300_context *r300);
+/* r300 render */
+void r300_draw_flush_vbuf(struct r300_context *r300);
+
/* r300_state.c */
enum r300_fb_state_change {
R300_CHANGED_FB_STATE = 0,
diff --git a/src/gallium/drivers/r300/r300_flush.c b/src/gallium/drivers/r300/r300_flush.c
index fe182b6615b..f00707b0665 100644
--- a/src/gallium/drivers/r300/r300_flush.c
+++ b/src/gallium/drivers/r300/r300_flush.c
@@ -43,6 +43,8 @@ static void r300_flush(struct pipe_context* pipe,
u_upload_flush(r300->upload_vb);
u_upload_flush(r300->upload_ib);
+ if (r300->draw)
+ r300_draw_flush_vbuf(r300);
if (r300->dirty_hw) {
r300_emit_hyperz_end(r300);
r300_emit_query_end(r300);
diff --git a/src/gallium/drivers/r300/r300_render.c b/src/gallium/drivers/r300/r300_render.c
index 86b11ca0458..73447057bb6 100644
--- a/src/gallium/drivers/r300/r300_render.c
+++ b/src/gallium/drivers/r300/r300_render.c
@@ -726,8 +726,6 @@ struct r300_render {
unsigned hwprim;
/* VBO */
- struct pipe_resource* vbo;
- size_t vbo_size;
size_t vbo_offset;
size_t vbo_max_used;
void * vbo_ptr;
@@ -759,31 +757,31 @@ static boolean r300_render_allocate_vertices(struct vbuf_render* render,
struct pipe_screen* screen = r300->context.screen;
size_t size = (size_t)vertex_size * (size_t)count;
- if (size + r300render->vbo_offset > r300render->vbo_size)
+ if (size + r300render->vbo_offset > r300->draw_vbo_size)
{
- pipe_resource_reference(&r300->vbo, NULL);
- r300render->vbo = pipe_buffer_create(screen,
- PIPE_BIND_VERTEX_BUFFER,
- R300_MAX_DRAW_VBO_SIZE);
+ pipe_resource_reference(&r300->vbo, NULL);
+ r300->vbo = pipe_buffer_create(screen,
+ PIPE_BIND_VERTEX_BUFFER,
+ R300_MAX_DRAW_VBO_SIZE);
r300render->vbo_offset = 0;
- r300render->vbo_size = R300_MAX_DRAW_VBO_SIZE;
+ r300->draw_vbo_size = R300_MAX_DRAW_VBO_SIZE;
}
r300render->vertex_size = vertex_size;
- r300->vbo = r300render->vbo;
r300->vbo_offset = r300render->vbo_offset;
- return (r300render->vbo) ? TRUE : FALSE;
+ return (r300->vbo) ? TRUE : FALSE;
}
static void* r300_render_map_vertices(struct vbuf_render* render)
{
struct r300_render* r300render = r300_render(render);
+ struct r300_context* r300 = r300render->r300;
assert(!r300render->vbo_transfer);
r300render->vbo_ptr = pipe_buffer_map(&r300render->r300->context,
- r300render->vbo,
+ r300->vbo,
PIPE_TRANSFER_WRITE,
&r300render->vbo_transfer);
@@ -798,12 +796,13 @@ static void r300_render_unmap_vertices(struct vbuf_render* render,
{
struct r300_render* r300render = r300_render(render);
struct pipe_context* context = &r300render->r300->context;
+ struct r300_context* r300 = r300render->r300;
assert(r300render->vbo_transfer);
r300render->vbo_max_used = MAX2(r300render->vbo_max_used,
r300render->vertex_size * (max + 1));
- pipe_buffer_unmap(context, r300render->vbo, r300render->vbo_transfer);
+ pipe_buffer_unmap(context, r300->vbo, r300render->vbo_transfer);
r300render->vbo_transfer = NULL;
}
@@ -880,7 +879,7 @@ static void r300_render_draw_elements(struct vbuf_render* render,
struct r300_context* r300 = r300render->r300;
int i;
unsigned end_cs_dwords;
- unsigned max_index = (r300render->vbo_size - r300render->vbo_offset) /
+ unsigned max_index = (r300->draw_vbo_size - r300render->vbo_offset) /
(r300render->r300->vertex_info.size * 4) - 1;
unsigned short_count;
unsigned free_dwords;
@@ -956,8 +955,6 @@ static struct vbuf_render* r300_render_create(struct r300_context* r300)
r300render->base.release_vertices = r300_render_release_vertices;
r300render->base.destroy = r300_render_destroy;
- r300render->vbo = NULL;
- r300render->vbo_size = 0;
r300render->vbo_offset = 0;
return &r300render->base;
@@ -986,6 +983,14 @@ struct draw_stage* r300_draw_stage(struct r300_context* r300)
return stage;
}
+void r300_draw_flush_vbuf(struct r300_context *r300)
+{
+ struct r300_render *r300render;
+
+ pipe_resource_reference(&r300->vbo, NULL);
+ r300->draw_vbo_size = 0;
+}
+
/****************************************************************************
* End of SW TCL functions *
***************************************************************************/