*
**************************************************************************/
-#include "pipe/p_util.h"
+#include "util/u_memory.h"
#include "draw/draw_context.h"
#include "draw/draw_private.h"
#include "draw/draw_vbuf.h"
struct translate *translate;
struct translate_cache *cache;
+ unsigned prim;
+
+ const struct vertex_info *vinfo;
};
void draw_pt_emit_prepare( struct pt_emit *emit,
- unsigned prim )
+ unsigned prim,
+ unsigned *max_vertices )
{
struct draw_context *draw = emit->draw;
const struct vertex_info *vinfo;
struct translate_key hw_key;
unsigned i;
boolean ok;
+
+ /* XXX: need to flush to get prim_vbuf.c to release its allocation??
+ */
+ draw_do_flush( draw, DRAW_FLUSH_BACKEND );
+
- ok = draw->render->set_primitive(draw->render, prim);
+ /* XXX: may need to defensively reset this later on as clipping can
+ * clobber this state in the render backend.
+ */
+ emit->prim = prim;
+
+ ok = draw->render->set_primitive(draw->render, emit->prim);
if (!ok) {
assert(0);
return;
/* Must do this after set_primitive() above:
*/
- vinfo = draw->render->get_vertex_info(draw->render);
+ emit->vinfo = vinfo = draw->render->get_vertex_info(draw->render);
/* Translate from pipeline vertices to hw vertices.
unsigned emit_sz = 0;
unsigned src_buffer = 0;
unsigned output_format;
- unsigned src_offset = (vinfo->src_index[i] * 4 * sizeof(float) );
+ unsigned src_offset = (vinfo->attrib[i].src_index * 4 * sizeof(float) );
- switch (vinfo->emit[i]) {
+ switch (vinfo->attrib[i].emit) {
case EMIT_4F:
output_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
emit_sz = 4 * sizeof(float);
case EMIT_4UB:
output_format = PIPE_FORMAT_B8G8R8A8_UNORM;
emit_sz = 4 * sizeof(ubyte);
+ break;
default:
assert(0);
output_format = PIPE_FORMAT_NONE;
hw_key.output_stride = vinfo->size * 4;
if (!emit->translate ||
- memcmp(&emit->translate->key, &hw_key, sizeof(hw_key)) != 0)
+ translate_key_compare(&emit->translate->key, &hw_key) != 0)
{
+ translate_key_sanitize(&hw_key);
emit->translate = translate_cache_find(emit->cache, &hw_key);
}
+
+ *max_vertices = (draw->render->max_vertex_buffer_bytes /
+ (vinfo->size * 4));
+
+ /* even number */
+ *max_vertices = *max_vertices & ~1;
}
*/
draw_do_flush( draw, DRAW_FLUSH_BACKEND );
- hw_verts = render->allocate_vertices(render,
- (ushort)translate->key.output_stride,
- (ushort)count);
+ if (vertex_count == 0)
+ return;
+
+ if (vertex_count >= UNDEFINED_VERTEX_ID) {
+ assert(0);
+ return;
+ }
+
+ /* XXX: and work out some way to coordinate the render primitive
+ * between vbuf.c and here...
+ */
+ if (!draw->render->set_primitive(draw->render, emit->prim)) {
+ assert(0);
+ return;
+ }
+
+ render->allocate_vertices(render,
+ (ushort)translate->key.output_stride,
+ (ushort)vertex_count);
+
+ hw_verts = render->map_vertices( render );
if (!hw_verts) {
assert(0);
return;
vertex_count,
hw_verts );
+ render->unmap_vertices( render,
+ 0,
+ vertex_count - 1 );
+
render->draw(render,
elts,
count);
- render->release_vertices(render,
- hw_verts,
- translate->key.output_stride,
- vertex_count);
+ render->release_vertices(render);
}
+void draw_pt_emit_linear(struct pt_emit *emit,
+ const float (*vertex_data)[4],
+ unsigned stride,
+ unsigned count)
+{
+ struct draw_context *draw = emit->draw;
+ struct translate *translate = emit->translate;
+ struct vbuf_render *render = draw->render;
+ void *hw_verts;
+
+#if 0
+ debug_printf("Linear emit\n");
+#endif
+ /* XXX: need to flush to get prim_vbuf.c to release its allocation??
+ */
+ draw_do_flush( draw, DRAW_FLUSH_BACKEND );
+
+ if (count >= UNDEFINED_VERTEX_ID)
+ goto fail;
+
+ /* XXX: and work out some way to coordinate the render primitive
+ * between vbuf.c and here...
+ */
+ if (!draw->render->set_primitive(draw->render, emit->prim))
+ goto fail;
+
+ if (!render->allocate_vertices(render,
+ (ushort)translate->key.output_stride,
+ (ushort)count))
+ goto fail;
+
+ hw_verts = render->map_vertices( render );
+ if (!hw_verts)
+ goto fail;
+
+ translate->set_buffer(translate, 0,
+ vertex_data, stride);
+
+ translate->set_buffer(translate, 1,
+ &draw->rasterizer->point_size,
+ 0);
+
+ translate->run(translate,
+ 0,
+ count,
+ hw_verts);
+
+ if (0) {
+ unsigned i;
+ for (i = 0; i < count; i++) {
+ debug_printf("\n\n%s vertex %d:\n", __FUNCTION__, i);
+ draw_dump_emitted_vertex( emit->vinfo,
+ (const uint8_t *)hw_verts +
+ translate->key.output_stride * i );
+ }
+ }
+
+ render->unmap_vertices( render, 0, count - 1 );
+
+ render->draw_arrays(render, 0, count);
+
+ render->release_vertices(render);
+
+ return;
+
+fail:
+ assert(0);
+ return;
+}
+
struct pt_emit *draw_pt_emit_create( struct draw_context *draw )
{
struct pt_emit *emit = CALLOC_STRUCT(pt_emit);
void draw_pt_emit_destroy( struct pt_emit *emit )
{
- translate_cache_destroy(emit->cache);
+ if (emit->cache)
+ translate_cache_destroy(emit->cache);
FREE(emit);
}