* \file
* Vertex buffer drawing stage.
*
- * \author José Fonseca <jrfonsec@tungstengraphics.com>
+ * \author Jose Fonseca <jrfonsec@tungstengraphics.com>
* \author Keith Whitwell <keith@tungstengraphics.com>
*/
-#include "pipe/p_debug.h"
+#include "util/u_debug.h"
#include "util/u_math.h"
#include "util/u_memory.h"
}
- static void vbuf_flush_indices( struct vbuf_stage *vbuf );
static void vbuf_flush_vertices( struct vbuf_stage *vbuf );
static void vbuf_alloc_vertices( struct vbuf_stage *vbuf );
static INLINE void
check_space( struct vbuf_stage *vbuf, unsigned nr )
{
- if (vbuf->nr_vertices + nr > vbuf->max_vertices ) {
- vbuf_flush_vertices(vbuf);
- vbuf_alloc_vertices(vbuf);
+ if (vbuf->nr_vertices + nr > vbuf->max_vertices ||
+ vbuf->nr_indices + nr > vbuf->max_indices)
+ {
+ vbuf_flush_vertices( vbuf );
+ vbuf_alloc_vertices( vbuf );
}
-
- if (vbuf->nr_indices + nr > vbuf->max_indices )
- vbuf_flush_indices(vbuf);
}
* will be flushed if needed and a new one allocated.
*/
static void
- vbuf_set_prim( struct vbuf_stage *vbuf, uint prim )
+ vbuf_start_prim( struct vbuf_stage *vbuf, uint prim )
{
struct translate_key hw_key;
unsigned dst_offset;
* state change.
*/
vbuf->vinfo = vbuf->render->get_vertex_info(vbuf->render);
-
- if (vbuf->vertex_size != vbuf->vinfo->size * sizeof(float)) {
- vbuf_flush_vertices(vbuf);
- vbuf->vertex_size = vbuf->vinfo->size * sizeof(float);
- }
+ vbuf->vertex_size = vbuf->vinfo->size * sizeof(float);
/* Translate from pipeline vertices to hw vertices.
*/
/* Allocate new buffer?
*/
- if (!vbuf->vertices)
- vbuf_alloc_vertices(vbuf);
+ assert(vbuf->vertices == NULL);
+ vbuf_alloc_vertices(vbuf);
}
{
struct vbuf_stage *vbuf = vbuf_stage( stage );
- vbuf_flush_indices( vbuf );
+ vbuf_flush_vertices( vbuf );
+ vbuf_start_prim(vbuf, PIPE_PRIM_TRIANGLES);
stage->tri = vbuf_tri;
- vbuf_set_prim(vbuf, PIPE_PRIM_TRIANGLES);
stage->tri( stage, prim );
}
{
struct vbuf_stage *vbuf = vbuf_stage( stage );
- vbuf_flush_indices( vbuf );
+ vbuf_flush_vertices( vbuf );
+ vbuf_start_prim(vbuf, PIPE_PRIM_LINES);
stage->line = vbuf_line;
- vbuf_set_prim(vbuf, PIPE_PRIM_LINES);
stage->line( stage, prim );
}
{
struct vbuf_stage *vbuf = vbuf_stage( stage );
- vbuf_flush_indices( vbuf );
+ vbuf_flush_vertices(vbuf);
+ vbuf_start_prim(vbuf, PIPE_PRIM_POINTS);
stage->point = vbuf_point;
- vbuf_set_prim(vbuf, PIPE_PRIM_POINTS);
stage->point( stage, prim );
}
- static void
- vbuf_flush_indices( struct vbuf_stage *vbuf )
- {
- if(!vbuf->nr_indices)
- return;
-
- assert((uint) (vbuf->vertex_ptr - vbuf->vertices) ==
- vbuf->nr_vertices * vbuf->vertex_size / sizeof(unsigned));
-
- vbuf->render->draw(vbuf->render, vbuf->indices, vbuf->nr_indices);
-
- vbuf->nr_indices = 0;
- }
-
/**
* Flush existing vertex buffer and allocate a new one.
- *
- * XXX: We separate flush-on-index-full and flush-on-vb-full, but may
- * raise issues uploading vertices if the hardware wants to flush when
- * we flush.
*/
static void
vbuf_flush_vertices( struct vbuf_stage *vbuf )
{
- if(vbuf->vertices) {
- vbuf_flush_indices(vbuf);
-
+ if(vbuf->vertices) {
+
+ vbuf->render->unmap_vertices( vbuf->render, 0, vbuf->nr_vertices - 1 );
+
+ if (vbuf->nr_indices)
+ {
+ vbuf->render->draw(vbuf->render,
+ vbuf->indices,
+ vbuf->nr_indices );
+
+ vbuf->nr_indices = 0;
+ }
+
/* Reset temporary vertices ids */
if(vbuf->nr_vertices)
draw_reset_vertex_ids( vbuf->stage.draw );
/* Free the vertex buffer */
- vbuf->render->release_vertices(vbuf->render,
- vbuf->vertices,
- vbuf->vertex_size,
- vbuf->nr_vertices);
+ vbuf->render->release_vertices( vbuf->render );
+
vbuf->max_vertices = vbuf->nr_vertices = 0;
vbuf->vertex_ptr = vbuf->vertices = NULL;
-
}
}
* and it will flush itself if necessary to do so. If this does
* fail, we are basically without usable hardware.
*/
- vbuf->vertices = (uint *) vbuf->render->allocate_vertices(vbuf->render,
- (ushort) vbuf->vertex_size,
- (ushort) vbuf->max_vertices);
+ vbuf->render->allocate_vertices(vbuf->render,
+ (ushort) vbuf->vertex_size,
+ (ushort) vbuf->max_vertices);
+
+ vbuf->vertices = (uint *) vbuf->render->map_vertices( vbuf->render );
+
vbuf->vertex_ptr = vbuf->vertices;
}
{
struct vbuf_stage *vbuf = vbuf_stage( stage );
- vbuf_flush_indices( vbuf );
+ vbuf_flush_vertices( vbuf );
stage->point = vbuf_first_point;
stage->line = vbuf_first_line;
stage->tri = vbuf_first_tri;
-
- if (flags & DRAW_FLUSH_BACKEND)
- vbuf_flush_vertices( vbuf );
}
#include "draw/draw_context.h"
#include "draw/draw_vbuf.h"
-#include "pipe/p_debug.h"
+#include "util/u_debug.h"
#include "pipe/p_inlines.h"
#include "pipe/internal/p_winsys_screen.h"
#include "util/u_math.h"
struct i915_context *i915;
/** Vertex size in bytes */
- unsigned vertex_size;
+ size_t vertex_size;
/** Software primitive */
unsigned prim;
size_t vbo_offset;
void *vbo_ptr;
size_t vbo_alloc_size;
+ size_t vbo_max_used;
};
}
- static void *
+ static boolean
i915_vbuf_render_allocate_vertices( struct vbuf_render *render,
ushort vertex_size,
ushort nr_vertices )
if (i915_render->vbo_size > size + i915_render->vbo_offset && !i915->vbo_flushed) {
} else {
i915->vbo_flushed = 0;
- pipe_buffer_reference(screen, &i915_render->vbo, NULL);
+ if (i915_render->vbo)
+ pipe_buffer_reference(screen, &i915_render->vbo, NULL);
}
if (!i915_render->vbo) {
64,
I915_BUFFER_USAGE_LIT_VERTEX,
i915_render->vbo_size);
- i915_render->vbo_ptr = pipe_buffer_map(screen,
- i915_render->vbo,
- PIPE_BUFFER_USAGE_CPU_WRITE);
- pipe_buffer_unmap(screen, i915_render->vbo);
+
}
+ i915_render->vertex_size = vertex_size;
i915->vbo = i915_render->vbo;
i915->vbo_offset = i915_render->vbo_offset;
i915->dirty |= I915_NEW_VBO;
+ if (!i915_render->vbo)
+ return FALSE;
+ return TRUE;
+ }
+
+
+ static void *
+ i915_vbuf_render_map_vertices( struct vbuf_render *render )
+ {
+ struct i915_vbuf_render *i915_render = i915_vbuf_render(render);
+ struct i915_context *i915 = i915_render->i915;
+ struct pipe_screen *screen = i915->pipe.screen;
+
+ if (i915->vbo_flushed)
+ debug_printf("%s bad vbo flush occured stalling on hw\n");
+
+ i915_render->vbo_ptr = pipe_buffer_map(screen,
+ i915_render->vbo,
+ PIPE_BUFFER_USAGE_CPU_WRITE);
+
return (unsigned char *)i915_render->vbo_ptr + i915->vbo_offset;
}
+ static void
+ i915_vbuf_render_unmap_vertices( struct vbuf_render *render,
+ ushort min_index,
+ ushort max_index )
+ {
+ struct i915_vbuf_render *i915_render = i915_vbuf_render(render);
+ struct i915_context *i915 = i915_render->i915;
+ struct pipe_screen *screen = i915->pipe.screen;
+
+ i915_render->vbo_max_used = MAX2(i915_render->vbo_max_used, i915_render->vertex_size * (max_index + 1));
+ pipe_buffer_unmap(screen, i915_render->vbo);
+ }
static boolean
i915_vbuf_render_set_primitive( struct vbuf_render *render,
static void
- i915_vbuf_render_release_vertices( struct vbuf_render *render,
- void *vertices,
- unsigned vertex_size,
- unsigned vertices_used )
+ i915_vbuf_render_release_vertices( struct vbuf_render *render )
{
struct i915_vbuf_render *i915_render = i915_vbuf_render(render);
struct i915_context *i915 = i915_render->i915;
- size_t size = (size_t)vertex_size * (size_t)vertices_used;
assert(i915->vbo);
- i915_render->vbo_offset += size;
+ i915_render->vbo_offset += i915_render->vbo_max_used;
+ i915_render->vbo_max_used = 0;
i915->vbo = NULL;
i915->dirty |= I915_NEW_VBO;
}
i915_render->base.get_vertex_info = i915_vbuf_render_get_vertex_info;
i915_render->base.allocate_vertices = i915_vbuf_render_allocate_vertices;
+ i915_render->base.map_vertices = i915_vbuf_render_map_vertices;
+ i915_render->base.unmap_vertices = i915_vbuf_render_unmap_vertices;
i915_render->base.set_primitive = i915_vbuf_render_set_primitive;
i915_render->base.draw = i915_vbuf_render_draw;
i915_render->base.draw_arrays = i915_vbuf_render_draw_arrays;
-#include "pipe/p_debug.h"
+#include "util/u_debug.h"
#include "pipe/p_inlines.h"
#include "pipe/internal/p_winsys_screen.h"
#include "pipe/p_compiler.h"
}
- static void *
+ static boolean
nv04_vbuf_render_allocate_vertices( struct vbuf_render *render,
ushort vertex_size,
ushort nr_vertices )
nv04_render->buffer = (unsigned char*) MALLOC(VERTEX_BUFFER_SIZE);
assert(!nv04_render->buffer);
+ return nv04_render->buffer ? TRUE : FALSE;
+ }
+
+ static void *
+ nv04_vbuf_render_map_vertices( struct vbuf_render *render )
+ {
+ struct nv04_vbuf_render *nv04_render = nv04_vbuf_render(render);
return nv04_render->buffer;
}
+ static void
+ nv04_vbuf_render_unmap_vertices( struct vbuf_render *render,
+ ushort min_index,
+ ushort max_index )
+ {
+ }
static boolean
nv04_vbuf_render_set_primitive( struct vbuf_render *render,
static void
- nv04_vbuf_render_release_vertices( struct vbuf_render *render,
- void *vertices,
- unsigned vertex_size,
- unsigned vertices_used )
+ nv04_vbuf_render_release_vertices( struct vbuf_render *render )
{
struct nv04_vbuf_render *nv04_render = nv04_vbuf_render(render);
nv04_render->base.max_indices = 65536;
nv04_render->base.get_vertex_info = nv04_vbuf_render_get_vertex_info;
nv04_render->base.allocate_vertices = nv04_vbuf_render_allocate_vertices;
+ nv04_render->base.map_vertices = nv04_vbuf_render_map_vertices;
+ nv04_render->base.unmap_vertices = nv04_vbuf_render_unmap_vertices;
nv04_render->base.set_primitive = nv04_vbuf_render_set_primitive;
nv04_render->base.draw = nv04_vbuf_render_draw;
nv04_render->base.release_vertices = nv04_vbuf_render_release_vertices;
*/
-#include "pipe/p_debug.h"
+#include "util/u_debug.h"
#include "pipe/p_inlines.h"
#include "pipe/internal/p_winsys_screen.h"
return &nv10->vertex_info;
}
-
- static void *
+ static boolean
nv10_vbuf_render_allocate_vertices( struct vbuf_render *render,
ushort vertex_size,
ushort nr_vertices )
nv10->dirty |= NV10_NEW_VTXARRAYS;
+ if (nv10_render->buffer)
+ return FALSE;
+ return TRUE;
+ }
+
+ static void *
+ nv10_vbuf_render_map_vertices( struct vbuf_render *render )
+ {
+ struct nv10_vbuf_render *nv10_render = nv10_vbuf_render(render);
+ struct nv10_context *nv10 = nv10_render->nv10;
+ struct pipe_winsys *winsys = nv10->pipe.winsys;
+
return winsys->buffer_map(winsys,
nv10_render->buffer,
PIPE_BUFFER_USAGE_CPU_WRITE);
}
+ static void
+ nv10_vbuf_render_unmap_vertices( struct vbuf_render *render,
+ ushort min_index,
+ ushort max_index )
+ {
+ struct nv10_vbuf_render *nv10_render = nv10_vbuf_render(render);
+ struct nv10_context *nv10 = nv10_render->nv10;
+ struct pipe_winsys *winsys = nv10->pipe.winsys;
+
+ assert(!nv10_render->buffer);
+ winsys->buffer_unmap(winsys, nv10_render->buffer);
+ }
static boolean
nv10_vbuf_render_set_primitive( struct vbuf_render *render,
static void
- nv10_vbuf_render_release_vertices( struct vbuf_render *render,
- void *vertices,
- unsigned vertex_size,
- unsigned vertices_used )
+ nv10_vbuf_render_release_vertices( struct vbuf_render *render )
{
struct nv10_vbuf_render *nv10_render = nv10_vbuf_render(render);
struct nv10_context *nv10 = nv10_render->nv10;
- struct pipe_winsys *winsys = nv10->pipe.winsys;
struct pipe_screen *pscreen = &nv10->screen->pipe;
assert(nv10_render->buffer);
- winsys->buffer_unmap(winsys, nv10_render->buffer);
pipe_buffer_reference(pscreen, &nv10_render->buffer, NULL);
}
nv10_render->base.max_indices = 1024;
nv10_render->base.get_vertex_info = nv10_vbuf_render_get_vertex_info;
nv10_render->base.allocate_vertices = nv10_vbuf_render_allocate_vertices;
+ nv10_render->base.map_vertices = nv10_vbuf_render_map_vertices;
+ nv10_render->base.unmap_vertices = nv10_vbuf_render_unmap_vertices;
nv10_render->base.set_primitive = nv10_vbuf_render_set_primitive;
nv10_render->base.draw = nv10_vbuf_render_draw;
nv10_render->base.release_vertices = nv10_vbuf_render_release_vertices;
*/
-#include "pipe/p_debug.h"
+#include "util/u_debug.h"
#include "pipe/p_inlines.h"
#include "pipe/internal/p_winsys_screen.h"
return nv20_render->mbuffer;
}
- static void *
+ static void
nv20__allocate_pbuffer(struct nv20_vbuf_render *nv20_render, size_t size)
{
struct pipe_winsys *winsys = nv20_render->nv20->pipe.winsys;
nv20_render->pbuffer = winsys->buffer_create(winsys, 64,
PIPE_BUFFER_USAGE_VERTEX, size);
- return winsys->buffer_map(winsys,
- nv20_render->pbuffer,
- PIPE_BUFFER_USAGE_CPU_WRITE);
}
- static void *
+ static boolean
nv20_vbuf_render_allocate_vertices( struct vbuf_render *render,
ushort vertex_size,
ushort nr_vertices )
* buffer, the data will be passed directly via the fifo.
*/
/* XXX: Pipe vertex buffers don't work. */
- if (0 && size > 16 * 1024)
- buf = nv20__allocate_pbuffer(nv20_render, size);
- else
+ if (0 && size > 16 * 1024) {
+ nv20__allocate_pbuffer(nv20_render, size);
+ /* umm yeah so this is ugly */
+ buf = nv20_render->pbuffer;
+ } else {
buf = nv20__allocate_mbuffer(nv20_render, size);
+ }
if (buf)
nv20_render->nv20->dirty |= NV20_NEW_VTXARRAYS;
- return buf;
+ return buf ? TRUE : FALSE;
+ }
+
+ static void *
+ nv20_vbuf_render_map_vertices( struct vbuf_render *render )
+ {
+ struct nv20_vbuf_render *nv20_render = nv20_vbuf_render(render);
+ struct pipe_winsys *winsys = nv20_render->nv20->pipe.winsys;
+
+ if (nv20_render->pbuffer) {
+ return winsys->buffer_map(winsys,
+ nv20_render->pbuffer,
+ PIPE_BUFFER_USAGE_CPU_WRITE);
+ } else if (nv20_render->mbuffer) {
+ return nv20_render->mbuffer;
+ } else
+ assert(0);
+
+ /* warnings be gone */
+ return NULL;
+ }
+
+ static void
+ nv20_vbuf_render_unmap_vertices( struct vbuf_render *render,
+ ushort min_index,
+ ushort max_index )
+ {
+ struct nv20_vbuf_render *nv20_render = nv20_vbuf_render(render);
+ struct pipe_winsys *winsys = nv20_render->nv20->pipe.winsys;
+
+ if (nv20_render->pbuffer)
+ winsys->buffer_unmap(winsys, nv20_render->pbuffer);
}
static boolean
static void
- nv20_vbuf_render_release_vertices( struct vbuf_render *render,
- void *vertices,
- unsigned vertex_size,
- unsigned vertices_used )
+ nv20_vbuf_render_release_vertices( struct vbuf_render *render )
{
struct nv20_vbuf_render *nv20_render = nv20_vbuf_render(render);
struct nv20_context *nv20 = nv20_render->nv20;
- struct pipe_winsys *winsys = nv20->pipe.winsys;
struct pipe_screen *pscreen = &nv20->screen->pipe;
if (nv20_render->pbuffer) {
- winsys->buffer_unmap(winsys, nv20_render->pbuffer);
pipe_buffer_reference(pscreen, &nv20_render->pbuffer, NULL);
} else if (nv20_render->mbuffer) {
FREE(nv20_render->mbuffer);
nv20_render->base.get_vertex_info = nv20_vbuf_render_get_vertex_info;
nv20_render->base.allocate_vertices =
nv20_vbuf_render_allocate_vertices;
+ nv20_render->base.map_vertices = nv20_vbuf_render_map_vertices;
+ nv20_render->base.unmap_vertices = nv20_vbuf_render_unmap_vertices;
nv20_render->base.set_primitive = nv20_vbuf_render_set_primitive;
nv20_render->base.draw = nv20_vbuf_render_draw;
nv20_render->base.release_vertices = nv20_vbuf_render_release_vertices;