r300g: refrain from using immediate mode if it causes slowdown
E.g. when mapping buffers could flush CS or cause waiting for a busy buffer. The side effect of this is it also fixes progs/demos/arbocclude however a separate fix should be proposed to address this issue in other cases it might occur.
This commit is contained in:
@@ -131,9 +131,38 @@ static boolean r300_reserve_cs_space(struct r300_context *r300,
|
||||
}
|
||||
|
||||
static boolean immd_is_good_idea(struct r300_context *r300,
|
||||
unsigned count)
|
||||
unsigned count)
|
||||
{
|
||||
return count <= 4;
|
||||
struct pipe_vertex_element* velem;
|
||||
struct pipe_vertex_buffer* vbuf;
|
||||
boolean checked[PIPE_MAX_ATTRIBS] = {0};
|
||||
unsigned vertex_element_count = r300->velems->count;
|
||||
unsigned i, vbi;
|
||||
|
||||
if (count > 4) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* We shouldn't map buffers referenced by CS, busy buffers,
|
||||
* and ones placed in VRAM. */
|
||||
/* XXX Check for VRAM buffers. */
|
||||
for (i = 0; i < vertex_element_count; i++) {
|
||||
velem = &r300->velems->velem[i];
|
||||
vbi = velem->vertex_buffer_index;
|
||||
|
||||
if (!checked[vbi]) {
|
||||
vbuf = &r300->vertex_buffer[vbi];
|
||||
|
||||
if (r300->winsys->is_buffer_referenced(r300->winsys,
|
||||
vbuf->buffer)) {
|
||||
/* It's a very bad idea to map it... */
|
||||
return FALSE;
|
||||
}
|
||||
checked[vbi] = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void r300_emit_draw_arrays_immediate(struct r300_context *r300,
|
||||
|
||||
@@ -213,6 +213,18 @@ static void radeon_buffer_unmap(struct pipe_winsys *ws,
|
||||
}
|
||||
}
|
||||
|
||||
static boolean radeon_is_buffer_referenced(struct radeon_winsys *ws,
|
||||
struct pipe_buffer *buffer)
|
||||
{
|
||||
struct radeon_pipe_buffer *radeon_buffer =
|
||||
(struct radeon_pipe_buffer*)buffer;
|
||||
uint32_t domain;
|
||||
|
||||
/* Referenced by CS or HW. */
|
||||
return radeon_bo_is_referenced_by_cs(radeon_buffer->bo, ws->priv->cs) ||
|
||||
radeon_bo_is_busy(radeon_buffer->bo, &domain);
|
||||
}
|
||||
|
||||
static void radeon_buffer_set_tiling(struct radeon_winsys *ws,
|
||||
struct pipe_buffer *buffer,
|
||||
uint32_t pitch,
|
||||
@@ -370,5 +382,7 @@ struct radeon_winsys* radeon_pipe_winsys(int fd)
|
||||
radeon_ws->buffer_from_handle = radeon_buffer_from_handle;
|
||||
radeon_ws->buffer_get_handle = radeon_buffer_get_handle;
|
||||
|
||||
radeon_ws->is_buffer_referenced = radeon_is_buffer_referenced;
|
||||
|
||||
return radeon_ws;
|
||||
}
|
||||
|
||||
@@ -118,6 +118,9 @@ struct radeon_winsys {
|
||||
uint32_t pitch,
|
||||
boolean microtiled,
|
||||
boolean macrotiled);
|
||||
|
||||
boolean (*is_buffer_referenced)(struct radeon_winsys *winsys,
|
||||
struct pipe_buffer *buffer);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user