From: José Fonseca Date: Thu, 1 Nov 2007 18:14:44 +0000 (+0000) Subject: Render primitives using indirect vertices in a vertex buffer. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=3c393b8df302493c4f48a750bfd7bd1c6aadbabb;p=mesa.git Render primitives using indirect vertices in a vertex buffer. --- diff --git a/src/mesa/pipe/i915simple/i915_prim_vbuf.c b/src/mesa/pipe/i915simple/i915_prim_vbuf.c index dc6e091681e..6f497879ad9 100644 --- a/src/mesa/pipe/i915simple/i915_prim_vbuf.c +++ b/src/mesa/pipe/i915simple/i915_prim_vbuf.c @@ -110,7 +110,7 @@ static boolean check_space( struct vbuf_stage *vbuf ) { if (overflow( vbuf->vertex_map, vbuf->vertex_ptr, - 4 * vbuf->vertex_size, + vbuf->vertex_size, VBUF_SIZE )) return FALSE; @@ -274,12 +274,11 @@ static void vbuf_draw( struct draw_stage *stage ) { struct vbuf_stage *vbuf = vbuf_stage( stage ); struct i915_context *i915 = vbuf->i915; - struct pipe_winsys *winsys = i915->pipe.winsys; unsigned nr = vbuf->nr_elements; unsigned vertex_size = i915->current.vertex_info.size * 4; /* in bytes */ unsigned hwprim; unsigned i; - char *ptr; + unsigned *ptr; switch(vbuf->prim) { case PIPE_PRIM_POINTS: @@ -295,40 +294,20 @@ static void vbuf_draw( struct draw_stage *stage ) assert(0); return; } - + assert(vbuf->vertex_ptr - vbuf->vertex_map == vbuf->nr_vertices * vertex_size / 4); - /* FIXME: handle failure */ - if(!vbuf->buf) - vbuf->buf = winsys->buffer_create(winsys, 64); - - winsys->buffer_data(winsys, vbuf->buf, 8 + nr * vertex_size, NULL); - ptr = winsys->buffer_map(winsys, vbuf->buf, PIPE_BUFFER_FLAG_WRITE); - *(unsigned *)ptr = _3DPRIMITIVE | - hwprim | - ((4 + vertex_size * nr)/4 - 2); - ptr += 4; - for (i = 0; i < nr; i++) { - memcpy(ptr, - (char*)vbuf->vertex_map + vbuf->element_map[i]*vertex_size, - vertex_size ); - ptr += vertex_size; - } - *(unsigned *)ptr = MI_BATCH_BUFFER_END; - ptr += 4; - winsys->buffer_unmap(winsys, vbuf->buf); - if (i915->dirty) i915_update_derived( i915 ); if (i915->hardware_dirty) i915_emit_hardware_state( i915 ); - ptr = BEGIN_BATCH( 2, 1 ); + ptr = BEGIN_BATCH( 4 + (nr + 1)/2, 1 ); #if 1 assert(ptr); #else - /* XXX: below is bogues as ptr always nonzero except in fatal errors */ + /* XXX: below is bogus as ptr always nonzero except in fatal errors */ if (ptr == 0) { FLUSH_BATCH(); @@ -344,20 +323,35 @@ static void vbuf_draw( struct draw_stage *stage ) } } #endif - - /* chain the vertex buffer in the batch buffer */ - OUT_BATCH(MI_BATCH_BUFFER_START - | (2 << 6) /* GTT-mapped memory */); + + /* FIXME: don't do this every time */ + OUT_BATCH( _3DSTATE_LOAD_STATE_IMMEDIATE_1 | + I1_LOAD_S(0) | + I1_LOAD_S(1) | + (1)); OUT_RELOC( vbuf->buf, I915_BUFFER_ACCESS_READ, 0 ); - /* FIXME: we need to flush here since control after chained buffers returns - * directly to the ring buffer */ - FLUSH_BATCH(); + OUT_BATCH( ((vertex_size/4) << 24) | /* vertex size in dwords */ + ((vertex_size/4) << 16) ); /* vertex pitch in dwords */ + OUT_BATCH( _3DPRIMITIVE | + PRIM_INDIRECT | + hwprim | + PRIM_INDIRECT_ELTS | + nr ); + for (i = 0; i + 1 < nr; i += 2) { + OUT_BATCH( vbuf->element_map[i] | + (vbuf->element_map[i + 1] << 16) ); + } + if (i < nr) { + OUT_BATCH( vbuf->element_map[i] ); + } } static void vbuf_flush_elements( struct draw_stage *stage ) { struct vbuf_stage *vbuf = vbuf_stage( stage ); + struct i915_context *i915 = vbuf->i915; + struct pipe_winsys *winsys = i915->pipe.winsys; if (vbuf->nr_elements) { #if 0 @@ -373,7 +367,8 @@ static void vbuf_flush_elements( struct draw_stage *stage ) vbuf->nr_elements = 0; - vbuf->vertex_ptr = vbuf->vertex_map; + winsys->buffer_unmap(winsys, vbuf->buf); + vbuf->nr_vertices = 0; /* Reset vertex ids? Actually, want to not do that unless our @@ -385,6 +380,15 @@ static void vbuf_flush_elements( struct draw_stage *stage ) draw_vertex_cache_reset_vertex_ids( vbuf->i915->draw ); } + /* FIXME: handle failure */ + if(!vbuf->buf) + vbuf->buf = winsys->buffer_create(winsys, 64); + winsys->buffer_data(winsys, vbuf->buf, VBUF_SIZE, NULL); + vbuf->vertex_map = winsys->buffer_map(winsys, + vbuf->buf, + PIPE_BUFFER_FLAG_WRITE ); + vbuf->vertex_ptr = vbuf->vertex_map; + stage->tri = vbuf_first_tri; stage->line = vbuf_first_line; stage->point = vbuf_first_point; @@ -430,7 +434,7 @@ struct draw_stage *i915_draw_vbuf_stage( struct i915_context *i915 ) /* FIXME: free this memory on takedown */ vbuf->element_map = malloc( IBUF_SIZE ); - vbuf->vertex_map = malloc( VBUF_SIZE ); + vbuf->vertex_map = NULL; vbuf->vertex_ptr = vbuf->vertex_map;