Merge branch 'mesa_7_6_branch'
[mesa.git] / src / gallium / auxiliary / draw / draw_pt_emit.c
index 35707af8a89375534b12c01f58e5c98c5687a149..064e16c295ca4df2e9c8dd7dbcc2fed36e849fe5 100644 (file)
@@ -25,7 +25,7 @@
  *
  **************************************************************************/
 
-#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"
@@ -40,10 +40,14 @@ struct pt_emit {
    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;
@@ -51,8 +55,18 @@ void draw_pt_emit_prepare( struct pt_emit *emit,
    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;
@@ -60,7 +74,7 @@ void draw_pt_emit_prepare( struct pt_emit *emit,
 
    /* 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.
@@ -70,11 +84,11 @@ void draw_pt_emit_prepare( struct pt_emit *emit,
       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);
@@ -100,6 +114,7 @@ void draw_pt_emit_prepare( struct pt_emit *emit,
       case EMIT_4UB:
         output_format = PIPE_FORMAT_B8G8R8A8_UNORM;
         emit_sz = 4 * sizeof(ubyte);
+         break;
       default:
         assert(0);
         output_format = PIPE_FORMAT_NONE;
@@ -120,10 +135,17 @@ void draw_pt_emit_prepare( struct pt_emit *emit,
    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;
 }
 
 
@@ -143,9 +165,27 @@ void draw_pt_emit( struct pt_emit *emit,
     */
    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;
@@ -166,17 +206,88 @@ void draw_pt_emit( struct pt_emit *emit,
                   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);
@@ -195,7 +306,8 @@ struct pt_emit *draw_pt_emit_create( struct draw_context *draw )
 
 void draw_pt_emit_destroy( struct pt_emit *emit )
 {
-   translate_cache_destroy(emit->cache);
+   if (emit->cache)
+      translate_cache_destroy(emit->cache);
 
    FREE(emit);
 }