draw: move hw vertex emit to a new module
authorKeith Whitwell <keith@tungstengraphics.com>
Thu, 17 Apr 2008 13:43:40 +0000 (14:43 +0100)
committerKeith Whitwell <keith@tungstengraphics.com>
Thu, 17 Apr 2008 13:43:40 +0000 (14:43 +0100)
src/gallium/auxiliary/draw/Makefile
src/gallium/auxiliary/draw/draw_private.h
src/gallium/auxiliary/draw/draw_pt.h
src/gallium/auxiliary/draw/draw_pt_emit.c [new file with mode: 0644]
src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c

index 5ab3cfe5ce9aa4a040352da5fcb4d383a1e48a07..836e98f086ac7fc3edf744746d79646cabff7065 100644 (file)
@@ -21,6 +21,7 @@ C_SOURCES = \
        draw_pt_fetch_pipeline.c \
        draw_pt_fetch_shade_pipeline.c \
        draw_pt_pipeline.c \
+       draw_pt_emit.c \
        draw_pt_elts.c \
        draw_prim.c \
        draw_pstipple.c \
index 7953dbb7d9e251643f0c055413b6ce5fd510c303..9407217fd336894056b5c29aaa80be6cb4bff56f 100644 (file)
@@ -376,14 +376,6 @@ boolean draw_pt_arrays( struct draw_context *draw,
                         unsigned count );
 
 void draw_pt_reset_vertex_ids( struct draw_context *draw );
-void draw_pt_run_pipeline( struct draw_context *draw,
-                           unsigned prim,
-                           char *verts,
-                           unsigned vertex_stride,
-                           unsigned vertex_count,
-                           const ushort *elts,
-                           unsigned count );
-
 
 #define DRAW_FLUSH_SHADER_QUEUE              0x1 /* sized not to overflow, never raised */
 #define DRAW_FLUSH_PRIM_QUEUE                0x2
index 08afb606457f760057899742805e840610ba4108..31d18ec62be82bccc2cd4b30f5a556ecd1eafa56 100644 (file)
@@ -128,4 +128,37 @@ struct draw_pt_middle_end *draw_pt_fetch_pipeline( struct draw_context *draw );
 struct draw_pt_middle_end *draw_pt_fetch_pipeline_or_emit(struct draw_context *draw);
 
 
+/* More helpers:
+ */
+void draw_pt_run_pipeline( struct draw_context *draw,
+                           unsigned prim,
+                           char *verts,
+                           unsigned vertex_stride,
+                           unsigned vertex_count,
+                           const ushort *elts,
+                           unsigned count );
+
+
+/* HW vertex emit:
+ */
+struct pt_emit;
+
+void draw_pt_emit_prepare( struct pt_emit *emit,
+                          unsigned prim,
+                          unsigned opt );
+
+void draw_pt_emit( struct pt_emit *emit,
+                  char *verts,
+                  unsigned stride,
+                  unsigned vertex_count,
+                  const ushort *elts,
+                  unsigned count );
+
+void draw_pt_emit_destroy( struct pt_emit *emit );
+
+struct pt_emit *draw_pt_emit_create( struct draw_context *draw );
+
+
+
+
 #endif
diff --git a/src/gallium/auxiliary/draw/draw_pt_emit.c b/src/gallium/auxiliary/draw/draw_pt_emit.c
new file mode 100644 (file)
index 0000000..e9ed294
--- /dev/null
@@ -0,0 +1,208 @@
+/**************************************************************************
+ *
+ * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+#include "pipe/p_util.h"
+#include "draw/draw_context.h"
+#include "draw/draw_private.h"
+#include "draw/draw_vbuf.h"
+#include "draw/draw_vertex.h"
+#include "draw/draw_pt.h"
+#include "translate/translate.h"
+
+
+struct pt_emit {
+   struct draw_context *draw;
+
+   struct translate *translate;
+
+   unsigned pipeline_vertex_size;
+   unsigned prim;
+   unsigned opt;
+};
+
+
+void draw_pt_emit_prepare( struct pt_emit *emit,
+                          unsigned prim,
+                          unsigned opt )
+{
+   struct draw_context *draw = emit->draw;
+   const struct vertex_info *vinfo;
+   unsigned dst_offset;
+   struct translate_key hw_key;
+   unsigned i;
+   boolean ok;
+
+   ok = draw->render->set_primitive(draw->render, prim);
+   if (!ok) {
+      assert(0);
+      return;
+   }
+
+   /* Must do this after set_primitive() above:
+    */
+   vinfo = draw->render->get_vertex_info(draw->render);
+
+
+   /* In passthrough mode, need to translate from vertex shader
+    * outputs to hw vertices.
+    */
+   dst_offset = 0;
+   for (i = 0; i < vinfo->num_attribs; i++) {
+      unsigned emit_sz = 0;
+      unsigned src_buffer = 0;
+      unsigned output_format;
+      unsigned src_offset = (sizeof(struct vertex_header) + 
+                            vinfo->src_index[i] * 4 * sizeof(float) );
+
+
+         
+      switch (vinfo->emit[i]) {
+      case EMIT_4F:
+        output_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
+        emit_sz = 4 * sizeof(float);
+        break;
+      case EMIT_3F:
+        output_format = PIPE_FORMAT_R32G32B32_FLOAT;
+        emit_sz = 3 * sizeof(float);
+        break;
+      case EMIT_2F:
+        output_format = PIPE_FORMAT_R32G32_FLOAT;
+        emit_sz = 2 * sizeof(float);
+        break;
+      case EMIT_1F:
+        output_format = PIPE_FORMAT_R32_FLOAT;
+        emit_sz = 1 * sizeof(float);
+        break;
+      case EMIT_1F_PSIZE:
+        output_format = PIPE_FORMAT_R32_FLOAT;
+        emit_sz = 1 * sizeof(float);
+        src_buffer = 1;
+        src_offset = 0;
+        break;
+      case EMIT_4UB:
+        output_format = PIPE_FORMAT_B8G8R8A8_UNORM;
+        emit_sz = 4 * sizeof(ubyte);
+      default:
+        assert(0);
+        output_format = PIPE_FORMAT_NONE;
+        emit_sz = 0;
+        break;
+      }
+      
+      hw_key.element[i].input_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
+      hw_key.element[i].input_buffer = src_buffer;
+      hw_key.element[i].input_offset = src_offset;
+      hw_key.element[i].output_format = output_format;
+      hw_key.element[i].output_offset = dst_offset;
+
+      dst_offset += emit_sz;
+   }
+
+   hw_key.nr_elements = vinfo->num_attribs;
+   hw_key.output_stride = vinfo->size * 4;
+
+   /* Don't bother with caching at this stage:
+    */
+   if (!emit->translate ||
+       memcmp(&emit->translate->key, &hw_key, sizeof(hw_key)) != 0) 
+   {
+      if (emit->translate)
+        emit->translate->release(emit->translate);
+
+      emit->translate = translate_generic_create( &hw_key );
+   }
+}
+
+
+void draw_pt_emit( struct pt_emit *emit,
+                  char *verts,
+                  unsigned stride,
+                  unsigned vertex_count,
+                  const ushort *elts,
+                  unsigned count )
+{
+   struct draw_context *draw = emit->draw;
+   struct translate *translate = emit->translate;
+   struct vbuf_render *render = draw->render;
+   void *hw_verts;
+
+   /* XXX: need to flush to get prim_vbuf.c to release its allocation?? 
+    */
+   draw_do_flush( draw, DRAW_FLUSH_BACKEND );
+
+   hw_verts = render->allocate_vertices(render,
+                                       (ushort)translate->key.output_stride,
+                                       (ushort)count);
+   if (!hw_verts) {
+      assert(0);
+      return;
+   }
+
+   translate->set_buffer(translate, 
+                        0, 
+                        verts,
+                        stride );
+
+   translate->set_buffer(translate, 
+                        1, 
+                        &draw->rasterizer->point_size,
+                        0);
+
+   translate->run( translate,
+                  0, 
+                  vertex_count,
+                  hw_verts );
+
+   render->draw(render,
+               elts,
+               count);
+
+   render->release_vertices(render,
+                           hw_verts,
+                           translate->key.output_stride,
+                           vertex_count);
+}
+
+
+struct pt_emit *draw_pt_emit_create( struct draw_context *draw )
+{
+   struct pt_emit *emit = CALLOC_STRUCT(pt_emit);
+   if (!emit)
+      return NULL;
+
+   emit->draw = draw;
+
+   return emit;
+}
+
+void draw_pt_emit_destroy( struct pt_emit *emit )
+{
+   if (emit->translate) 
+      emit->translate->release( emit->translate );
+
+   FREE(emit);
+}
index cf37493eb62ce6b0253957d1fa0893251143adfa..8db9e31e2dda0c9efbfddf92ba69f7099a60b891 100644 (file)
@@ -38,7 +38,7 @@ struct fetch_pipeline_middle_end {
    struct draw_pt_middle_end base;
    struct draw_context *draw;
 
-   struct translate *translate;
+   struct pt_emit *emit;
 
    unsigned pipeline_vertex_size;
    unsigned prim;
@@ -51,98 +51,12 @@ static void fetch_pipeline_prepare( struct draw_pt_middle_end *middle,
                                    unsigned opt )
 {
    struct fetch_pipeline_middle_end *fpme = (struct fetch_pipeline_middle_end *)middle;
-   struct draw_context *draw = fpme->draw;
-   unsigned i;
-   boolean ok;
-   const struct vertex_info *vinfo;
-   unsigned dst_offset;
-   struct translate_key hw_key;
 
    fpme->prim = prim;
    fpme->opt = opt;
 
-   if (!(opt & PT_PIPELINE)) {
-      ok = draw->render->set_primitive(draw->render, prim);
-      if (!ok) {
-        assert(0);
-        return;
-      }
-
-      /* Must do this after set_primitive() above:
-       */
-      vinfo = draw->render->get_vertex_info(draw->render);
-
-
-      /* In passthrough mode, need to translate from vertex shader
-       * outputs to hw vertices.
-       */
-      dst_offset = 0;
-      for (i = 0; i < vinfo->num_attribs; i++) {
-        unsigned emit_sz = 0;
-        unsigned src_buffer = 0;
-        unsigned output_format;
-        unsigned src_offset = (sizeof(struct vertex_header) + 
-                               vinfo->src_index[i] * 4 * sizeof(float) );
-
-
-         
-        switch (vinfo->emit[i]) {
-        case EMIT_4F:
-           output_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
-           emit_sz = 4 * sizeof(float);
-           break;
-        case EMIT_3F:
-           output_format = PIPE_FORMAT_R32G32B32_FLOAT;
-           emit_sz = 3 * sizeof(float);
-           break;
-        case EMIT_2F:
-           output_format = PIPE_FORMAT_R32G32_FLOAT;
-           emit_sz = 2 * sizeof(float);
-           break;
-        case EMIT_1F:
-           output_format = PIPE_FORMAT_R32_FLOAT;
-           emit_sz = 1 * sizeof(float);
-           break;
-        case EMIT_1F_PSIZE:
-           output_format = PIPE_FORMAT_R32_FLOAT;
-           emit_sz = 1 * sizeof(float);
-           src_buffer = 1;
-           src_offset = 0;
-           break;
-        case EMIT_4UB:
-           output_format = PIPE_FORMAT_B8G8R8A8_UNORM;
-           emit_sz = 4 * sizeof(ubyte);
-        default:
-           assert(0);
-           output_format = PIPE_FORMAT_NONE;
-           emit_sz = 0;
-           break;
-        }
-      
-        hw_key.element[i].input_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
-        hw_key.element[i].input_buffer = src_buffer;
-        hw_key.element[i].input_offset = src_offset;
-        hw_key.element[i].output_format = output_format;
-        hw_key.element[i].output_offset = dst_offset;
-
-        dst_offset += emit_sz;
-      }
-
-      hw_key.nr_elements = vinfo->num_attribs;
-      hw_key.output_stride = vinfo->size * 4;
-
-      /* Don't bother with caching at this stage:
-       */
-      if (!fpme->translate ||
-         memcmp(&fpme->translate->key, &hw_key, sizeof(hw_key)) != 0) 
-      {
-        if (fpme->translate)
-           fpme->translate->release(fpme->translate);
-
-        fpme->translate = translate_generic_create( &hw_key );
-      }
-   }
-
+   if (!(opt & PT_PIPELINE)) 
+      draw_pt_emit_prepare( fpme->emit, prim, opt );
 
    //fpme->pipeline_vertex_size = sizeof(struct vertex_header) + nr * 4 * sizeof(float);
    fpme->pipeline_vertex_size = MAX_VERTEX_ALLOCATION;
@@ -194,43 +108,12 @@ static void fetch_pipeline_run( struct draw_pt_middle_end *middle,
                             draw_elts,
                             draw_count );
    } else {
-      struct translate *translate = fpme->translate;
-      void *hw_verts;
-
-      /* XXX: need to flush to get prim_vbuf.c to release its allocation?? 
-       */
-      draw_do_flush( draw, DRAW_FLUSH_BACKEND );
-
-      hw_verts = draw->render->allocate_vertices(draw->render,
-                                                 (ushort)fpme->translate->key.output_stride,
-                                                 (ushort)fetch_count);
-      if (!hw_verts) {
-         assert(0);
-         return;
-      }
-
-      translate->set_buffer(translate, 
-                           0, 
-                           pipeline_verts,
-                           fpme->pipeline_vertex_size );
-
-      translate->set_buffer(translate, 
-                           1, 
-                           &fpme->draw->rasterizer->point_size,
-                           0);
-
-      translate->run( translate,
-                     0, fetch_count,
-                     hw_verts );
-
-      draw->render->draw(draw->render,
-                         draw_elts,
-                         draw_count);
-
-      draw->render->release_vertices(draw->render,
-                                     hw_verts,
-                                     fpme->translate->key.output_stride,
-                                     fetch_count);
+      draw_pt_emit( fpme->emit,
+                   pipeline_verts,
+                   fpme->pipeline_vertex_size,
+                   fetch_count,
+                   draw_elts,
+                   draw_count );
    }
 
 
@@ -252,14 +135,26 @@ static void fetch_pipeline_destroy( struct draw_pt_middle_end *middle )
 
 struct draw_pt_middle_end *draw_pt_fetch_pipeline_or_emit( struct draw_context *draw )
 {
-   struct fetch_pipeline_middle_end *fetch_pipeline = CALLOC_STRUCT( fetch_pipeline_middle_end );
+   struct fetch_pipeline_middle_end *fpme = CALLOC_STRUCT( fetch_pipeline_middle_end );
+   if (!fpme)
+      goto fail;
+
+   fpme->base.prepare = fetch_pipeline_prepare;
+   fpme->base.run     = fetch_pipeline_run;
+   fpme->base.finish  = fetch_pipeline_finish;
+   fpme->base.destroy = fetch_pipeline_destroy;
+
+   fpme->draw = draw;
+
+   fpme->emit = draw_pt_emit_create( draw );
+   if (!fpme->emit) 
+      goto fail;
 
-   fetch_pipeline->base.prepare = fetch_pipeline_prepare;
-   fetch_pipeline->base.run     = fetch_pipeline_run;
-   fetch_pipeline->base.finish  = fetch_pipeline_finish;
-   fetch_pipeline->base.destroy = fetch_pipeline_destroy;
+   return &fpme->base;
 
-   fetch_pipeline->draw = draw;
+ fail:
+   if (fpme)
+      fetch_pipeline_destroy( &fpme->base );
 
-   return &fetch_pipeline->base;
+   return NULL;
 }