llvmpipe: merge setup and draw vbuf submodules
authorKeith Whitwell <keithw@vmware.com>
Wed, 6 Jan 2010 16:44:43 +0000 (16:44 +0000)
committerKeith Whitwell <keithw@vmware.com>
Wed, 6 Jan 2010 16:44:43 +0000 (16:44 +0000)
The setup tiling engine is now plugged directly into the draw module
as a rendering backend.

Removed a couple of layering violations such that the setup code no
longer reaches out into the surrounding llvmpipe state or context.

13 files changed:
src/gallium/drivers/llvmpipe/Makefile
src/gallium/drivers/llvmpipe/SConscript
src/gallium/drivers/llvmpipe/lp_context.c
src/gallium/drivers/llvmpipe/lp_context.h
src/gallium/drivers/llvmpipe/lp_draw_arrays.c
src/gallium/drivers/llvmpipe/lp_prim_vbuf.c [deleted file]
src/gallium/drivers/llvmpipe/lp_prim_vbuf.h [deleted file]
src/gallium/drivers/llvmpipe/lp_setup.c
src/gallium/drivers/llvmpipe/lp_setup.h
src/gallium/drivers/llvmpipe/lp_setup_context.h
src/gallium/drivers/llvmpipe/lp_setup_vbuf.c [new file with mode: 0644]
src/gallium/drivers/llvmpipe/lp_state_derived.c
src/gallium/drivers/llvmpipe/lp_state_fs.c

index 345326e33d7b6fe0996f777a2e199b50bc27a095..6ec97046e15a4c57930dd789d310c513f5ba8c07 100644 (file)
@@ -35,13 +35,13 @@ C_SOURCES = \
        lp_fence.c \
        lp_flush.c \
        lp_jit.c \
-       lp_prim_vbuf.c \
        lp_rast.c \
        lp_rast_tri.c \
        lp_setup.c \
        lp_setup_line.c \
        lp_setup_point.c \
        lp_setup_tri.c \
+       lp_setup_vbuf.c \
        lp_query.c \
        lp_screen.c \
        lp_state_blend.c \
index f0b71ef3eeeabbb6a0b5116105a0862a380d45b4..ae4303bd24ff6f9f4ba0ba9b1d773475e8d71707 100644 (file)
@@ -46,7 +46,6 @@ llvmpipe = env.ConvenienceLibrary(
                'lp_fence.c',
                'lp_flush.c',
                'lp_jit.c',
-               'lp_prim_vbuf.c',
                'lp_query.c',
                'lp_scene.c',
                'lp_scene_queue.c',
@@ -55,6 +54,7 @@ llvmpipe = env.ConvenienceLibrary(
                'lp_setup_line.c',
                'lp_setup_point.c',
                'lp_setup_tri.c',
+               'lp_setup_vbuf.c',
                'lp_state_blend.c',
                'lp_state_clip.c',
                'lp_state_derived.c',
index 06aa0325403e2bf6da40f933722a5878c5cc6130..0457ccc8a94167c4a1632ef3b69a6d755a5cf5f3 100644 (file)
  */
 
 #include "draw/draw_context.h"
-#include "draw/draw_vbuf.h"
 #include "pipe/p_defines.h"
 #include "util/u_math.h"
 #include "util/u_memory.h"
 #include "lp_clear.h"
 #include "lp_context.h"
 #include "lp_flush.h"
-#include "lp_prim_vbuf.h"
 #include "lp_state.h"
 #include "lp_surface.h"
 #include "lp_texture.h"
@@ -179,23 +177,11 @@ llvmpipe_create( struct pipe_screen *screen )
    if (debug_get_bool_option( "LP_NO_RAST", FALSE ))
       llvmpipe->no_rast = TRUE;
 
-   llvmpipe->setup = lp_setup_create( screen );
+   llvmpipe->setup = lp_setup_create( screen,
+                                      llvmpipe->draw );
    if (!llvmpipe->setup)
       goto fail;
 
-   llvmpipe->vbuf_backend = lp_create_vbuf_backend(llvmpipe);
-   if (!llvmpipe->vbuf_backend)
-      goto fail;
-
-   llvmpipe->vbuf = draw_vbuf_stage(llvmpipe->draw, llvmpipe->vbuf_backend);
-   if (!llvmpipe->vbuf)
-      goto fail;
-
-   draw_set_rasterize_stage(llvmpipe->draw, llvmpipe->vbuf);
-   draw_set_render(llvmpipe->draw, llvmpipe->vbuf_backend);
-
-
-
    /* plug in AA line/point stages */
    draw_install_aaline_stage(llvmpipe->draw, &llvmpipe->pipe);
    draw_install_aapoint_stage(llvmpipe->draw, &llvmpipe->pipe);
index 17c6939ff5b8a3ef1fd9180094bc813d5943754a..b796148457e0d01ddda494ae82f0799af1c547f2 100644 (file)
@@ -93,17 +93,6 @@ struct llvmpipe_context {
    /** Which vertex shader output slot contains point size */
    int psize_slot;
 
-   /* The reduced version of the primitive supplied by the state
-    * tracker.
-    */
-   unsigned reduced_api_prim;
-
-   /* The reduced primitive after unfilled triangles, wide-line
-    * decomposition, etc, are taken into account.  This is the
-    * primitive actually rasterized.
-    */
-   unsigned reduced_prim;
-
    /** Derived from scissor and surface bounds: */
    struct pipe_scissor_state cliprect;
 
@@ -113,10 +102,6 @@ struct llvmpipe_context {
    /** The primitive drawing context */
    struct draw_context *draw;
 
-   /** Draw module backend */
-   struct vbuf_render *vbuf_backend;
-   struct draw_stage *vbuf;
-
    unsigned tex_timestamp;
    boolean no_rast;
 
index b879b5e755e48ab899656d53cd6629a8f4f4d739..91fcbc01c6d4f7204812b8e7b2134ad9242842b5 100644 (file)
@@ -70,8 +70,6 @@ llvmpipe_draw_range_elements(struct pipe_context *pipe,
    struct draw_context *draw = lp->draw;
    unsigned i;
 
-   lp->reduced_api_prim = u_reduced_prim(mode);
-
    if (lp->dirty)
       llvmpipe_update_derived( lp );
 
diff --git a/src/gallium/drivers/llvmpipe/lp_prim_vbuf.c b/src/gallium/drivers/llvmpipe/lp_prim_vbuf.c
deleted file mode 100644 (file)
index 925e6f8..0000000
+++ /dev/null
@@ -1,559 +0,0 @@
-/**************************************************************************
- *
- * Copyright 2007 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.
- *
- **************************************************************************/
-
-/**
- * Interface between 'draw' module's output and the llvmpipe rasterizer/setup
- * code.  When the 'draw' module has finished filling a vertex buffer, the
- * draw_arrays() functions below will be called.  Loop over the vertices and
- * call the point/line/tri setup functions.
- *
- * Authors
- *  Brian Paul
- */
-
-
-#include "lp_context.h"
-#include "lp_state.h"
-#include "lp_prim_vbuf.h"
-#include "lp_setup.h"
-#include "draw/draw_context.h"
-#include "draw/draw_vbuf.h"
-#include "util/u_memory.h"
-#include "util/u_prim.h"
-
-
-#define LP_MAX_VBUF_INDEXES 1024
-#define LP_MAX_VBUF_SIZE    4096
-
-typedef const float (*cptrf4)[4];
-
-/**
- * Subclass of vbuf_render.
- */
-struct llvmpipe_vbuf_render
-{
-   struct vbuf_render base;
-   struct llvmpipe_context *llvmpipe;
-   struct setup_context *setup;
-
-   uint prim;
-   uint vertex_size;
-   uint nr_vertices;
-   uint vertex_buffer_size;
-   void *vertex_buffer;
-};
-
-
-/** cast wrapper */
-static struct llvmpipe_vbuf_render *
-llvmpipe_vbuf_render(struct vbuf_render *vbr)
-{
-   return (struct llvmpipe_vbuf_render *) vbr;
-}
-
-
-
-
-
-
-
-static const struct vertex_info *
-lp_vbuf_get_vertex_info(struct vbuf_render *vbr)
-{
-   struct llvmpipe_vbuf_render *cvbr = llvmpipe_vbuf_render(vbr);
-   return llvmpipe_get_vbuf_vertex_info(cvbr->llvmpipe);
-}
-
-
-static boolean
-lp_vbuf_allocate_vertices(struct vbuf_render *vbr,
-                          ushort vertex_size, ushort nr_vertices)
-{
-   struct llvmpipe_vbuf_render *cvbr = llvmpipe_vbuf_render(vbr);
-   unsigned size = vertex_size * nr_vertices;
-
-   if (cvbr->vertex_buffer_size < size) {
-      align_free(cvbr->vertex_buffer);
-      cvbr->vertex_buffer = align_malloc(size, 16);
-      cvbr->vertex_buffer_size = size;
-   }
-
-   cvbr->vertex_size = vertex_size;
-   cvbr->nr_vertices = nr_vertices;
-   
-   return cvbr->vertex_buffer != NULL;
-}
-
-static void
-lp_vbuf_release_vertices(struct vbuf_render *vbr)
-{
-   /* keep the old allocation for next time */
-}
-
-static void *
-lp_vbuf_map_vertices(struct vbuf_render *vbr)
-{
-   struct llvmpipe_vbuf_render *cvbr = llvmpipe_vbuf_render(vbr);
-   return cvbr->vertex_buffer;
-}
-
-static void 
-lp_vbuf_unmap_vertices(struct vbuf_render *vbr, 
-                       ushort min_index,
-                       ushort max_index )
-{
-   struct llvmpipe_vbuf_render *cvbr = llvmpipe_vbuf_render(vbr);
-   assert( cvbr->vertex_buffer_size >= (max_index+1) * cvbr->vertex_size );
-   /* do nothing */
-}
-
-
-static boolean
-lp_vbuf_set_primitive(struct vbuf_render *vbr, unsigned prim)
-{
-   struct llvmpipe_vbuf_render *cvbr = llvmpipe_vbuf_render(vbr);
-
-   llvmpipe_update_derived( cvbr->llvmpipe );
-
-   cvbr->llvmpipe->reduced_prim = u_reduced_prim(prim);
-   cvbr->prim = prim;
-   return TRUE;
-
-}
-
-
-static INLINE cptrf4 get_vert( const void *vertex_buffer,
-                               int index,
-                               int stride )
-{
-   return (cptrf4)((char *)vertex_buffer + index * stride);
-}
-
-
-/**
- * draw elements / indexed primitives
- */
-static void
-lp_vbuf_draw(struct vbuf_render *vbr, const ushort *indices, uint nr)
-{
-   struct llvmpipe_vbuf_render *cvbr = llvmpipe_vbuf_render(vbr);
-   struct llvmpipe_context *llvmpipe = cvbr->llvmpipe;
-   const unsigned stride = llvmpipe->vertex_info_vbuf.size * sizeof(float);
-   const void *vertex_buffer = cvbr->vertex_buffer;
-   struct setup_context *setup_ctx = cvbr->setup;
-   unsigned i;
-
-   switch (cvbr->prim) {
-   case PIPE_PRIM_POINTS:
-      for (i = 0; i < nr; i++) {
-         lp_setup_point( setup_ctx,
-                      get_vert(vertex_buffer, indices[i-0], stride) );
-      }
-      break;
-
-   case PIPE_PRIM_LINES:
-      for (i = 1; i < nr; i += 2) {
-         lp_setup_line( setup_ctx,
-                     get_vert(vertex_buffer, indices[i-1], stride),
-                     get_vert(vertex_buffer, indices[i-0], stride) );
-      }
-      break;
-
-   case PIPE_PRIM_LINE_STRIP:
-      for (i = 1; i < nr; i ++) {
-         lp_setup_line( setup_ctx,
-                     get_vert(vertex_buffer, indices[i-1], stride),
-                     get_vert(vertex_buffer, indices[i-0], stride) );
-      }
-      break;
-
-   case PIPE_PRIM_LINE_LOOP:
-      for (i = 1; i < nr; i ++) {
-         lp_setup_line( setup_ctx,
-                     get_vert(vertex_buffer, indices[i-1], stride),
-                     get_vert(vertex_buffer, indices[i-0], stride) );
-      }
-      if (nr) {
-         lp_setup_line( setup_ctx,
-                     get_vert(vertex_buffer, indices[nr-1], stride),
-                     get_vert(vertex_buffer, indices[0], stride) );
-      }
-      break;
-
-   case PIPE_PRIM_TRIANGLES:
-      if (llvmpipe->rasterizer->flatshade_first) {
-         for (i = 2; i < nr; i += 3) {
-            lp_setup_tri( setup_ctx,
-                       get_vert(vertex_buffer, indices[i-1], stride),
-                       get_vert(vertex_buffer, indices[i-0], stride),
-                       get_vert(vertex_buffer, indices[i-2], stride) );
-         }
-      }
-      else {
-         for (i = 2; i < nr; i += 3) {
-            lp_setup_tri( setup_ctx,
-                       get_vert(vertex_buffer, indices[i-2], stride),
-                       get_vert(vertex_buffer, indices[i-1], stride),
-                       get_vert(vertex_buffer, indices[i-0], stride) );
-         }
-      }
-      break;
-
-   case PIPE_PRIM_TRIANGLE_STRIP:
-      if (llvmpipe->rasterizer->flatshade_first) {
-         for (i = 2; i < nr; i += 1) {
-            lp_setup_tri( setup_ctx,
-                       get_vert(vertex_buffer, indices[i+(i&1)-1], stride),
-                       get_vert(vertex_buffer, indices[i-(i&1)], stride),
-                       get_vert(vertex_buffer, indices[i-2], stride) );
-         }
-      }
-      else {
-         for (i = 2; i < nr; i += 1) {
-            lp_setup_tri( setup_ctx,
-                       get_vert(vertex_buffer, indices[i+(i&1)-2], stride),
-                       get_vert(vertex_buffer, indices[i-(i&1)-1], stride),
-                       get_vert(vertex_buffer, indices[i-0], stride) );
-         }
-      }
-      break;
-
-   case PIPE_PRIM_TRIANGLE_FAN:
-      if (llvmpipe->rasterizer->flatshade_first) {
-         for (i = 2; i < nr; i += 1) {
-            lp_setup_tri( setup_ctx,
-                       get_vert(vertex_buffer, indices[i-0], stride),
-                       get_vert(vertex_buffer, indices[0], stride),
-                       get_vert(vertex_buffer, indices[i-1], stride) );
-         }
-      }
-      else {
-         for (i = 2; i < nr; i += 1) {
-            lp_setup_tri( setup_ctx,
-                       get_vert(vertex_buffer, indices[0], stride),
-                       get_vert(vertex_buffer, indices[i-1], stride),
-                       get_vert(vertex_buffer, indices[i-0], stride) );
-         }
-      }
-      break;
-
-   case PIPE_PRIM_QUADS:
-      if (llvmpipe->rasterizer->flatshade_first) {
-         for (i = 3; i < nr; i += 4) {
-            lp_setup_tri( setup_ctx,
-                       get_vert(vertex_buffer, indices[i-2], stride),
-                       get_vert(vertex_buffer, indices[i-1], stride),
-                       get_vert(vertex_buffer, indices[i-3], stride) );
-            lp_setup_tri( setup_ctx,
-                       get_vert(vertex_buffer, indices[i-1], stride),
-                       get_vert(vertex_buffer, indices[i-0], stride),
-                       get_vert(vertex_buffer, indices[i-3], stride) );
-         }
-      }
-      else {
-         for (i = 3; i < nr; i += 4) {
-            lp_setup_tri( setup_ctx,
-                       get_vert(vertex_buffer, indices[i-3], stride),
-                       get_vert(vertex_buffer, indices[i-2], stride),
-                       get_vert(vertex_buffer, indices[i-0], stride) );
-
-            lp_setup_tri( setup_ctx,
-                       get_vert(vertex_buffer, indices[i-2], stride),
-                       get_vert(vertex_buffer, indices[i-1], stride),
-                       get_vert(vertex_buffer, indices[i-0], stride) );
-         }
-      }
-      break;
-
-   case PIPE_PRIM_QUAD_STRIP:
-      if (llvmpipe->rasterizer->flatshade_first) {
-         for (i = 3; i < nr; i += 2) {
-            lp_setup_tri( setup_ctx,
-                       get_vert(vertex_buffer, indices[i-0], stride),
-                       get_vert(vertex_buffer, indices[i-1], stride),
-                       get_vert(vertex_buffer, indices[i-3], stride));
-            lp_setup_tri( setup_ctx,
-                       get_vert(vertex_buffer, indices[i-2], stride),
-                       get_vert(vertex_buffer, indices[i-0], stride),
-                       get_vert(vertex_buffer, indices[i-3], stride) );
-         }
-      }
-      else {
-         for (i = 3; i < nr; i += 2) {
-            lp_setup_tri( setup_ctx,
-                       get_vert(vertex_buffer, indices[i-3], stride),
-                       get_vert(vertex_buffer, indices[i-2], stride),
-                       get_vert(vertex_buffer, indices[i-0], stride) );
-            lp_setup_tri( setup_ctx,
-                       get_vert(vertex_buffer, indices[i-1], stride),
-                       get_vert(vertex_buffer, indices[i-3], stride),
-                       get_vert(vertex_buffer, indices[i-0], stride) );
-         }
-      }
-      break;
-
-   case PIPE_PRIM_POLYGON:
-      /* Almost same as tri fan but the _first_ vertex specifies the flat
-       * shading color.  Note that the first polygon vertex is passed as
-       * the last triangle vertex here.
-       * flatshade_first state makes no difference.
-       */
-      for (i = 2; i < nr; i += 1) {
-         lp_setup_tri( setup_ctx,
-                    get_vert(vertex_buffer, indices[i-0], stride),
-                    get_vert(vertex_buffer, indices[i-1], stride),
-                    get_vert(vertex_buffer, indices[0], stride) );
-      }
-      break;
-
-   default:
-      assert(0);
-   }
-}
-
-
-/**
- * This function is hit when the draw module is working in pass-through mode.
- * It's up to us to convert the vertex array into point/line/tri prims.
- */
-static void
-lp_vbuf_draw_arrays(struct vbuf_render *vbr, uint start, uint nr)
-{
-   struct llvmpipe_vbuf_render *cvbr = llvmpipe_vbuf_render(vbr);
-   struct llvmpipe_context *llvmpipe = cvbr->llvmpipe;
-   struct setup_context *setup_ctx = cvbr->setup;
-   const unsigned stride = llvmpipe->vertex_info_vbuf.size * sizeof(float);
-   const void *vertex_buffer =
-      (void *) get_vert(cvbr->vertex_buffer, start, stride);
-   unsigned i;
-
-   switch (cvbr->prim) {
-   case PIPE_PRIM_POINTS:
-      for (i = 0; i < nr; i++) {
-         lp_setup_point( setup_ctx,
-                      get_vert(vertex_buffer, i-0, stride) );
-      }
-      break;
-
-   case PIPE_PRIM_LINES:
-      for (i = 1; i < nr; i += 2) {
-         lp_setup_line( setup_ctx,
-                     get_vert(vertex_buffer, i-1, stride),
-                     get_vert(vertex_buffer, i-0, stride) );
-      }
-      break;
-
-   case PIPE_PRIM_LINE_STRIP:
-      for (i = 1; i < nr; i ++) {
-         lp_setup_line( setup_ctx,
-                     get_vert(vertex_buffer, i-1, stride),
-                     get_vert(vertex_buffer, i-0, stride) );
-      }
-      break;
-
-   case PIPE_PRIM_LINE_LOOP:
-      for (i = 1; i < nr; i ++) {
-         lp_setup_line( setup_ctx,
-                     get_vert(vertex_buffer, i-1, stride),
-                     get_vert(vertex_buffer, i-0, stride) );
-      }
-      if (nr) {
-         lp_setup_line( setup_ctx,
-                     get_vert(vertex_buffer, nr-1, stride),
-                     get_vert(vertex_buffer, 0, stride) );
-      }
-      break;
-
-   case PIPE_PRIM_TRIANGLES:
-      if (llvmpipe->rasterizer->flatshade_first) {
-         for (i = 2; i < nr; i += 3) {
-            lp_setup_tri( setup_ctx,
-                       get_vert(vertex_buffer, i-1, stride),
-                       get_vert(vertex_buffer, i-0, stride),
-                       get_vert(vertex_buffer, i-2, stride) );
-         }
-      }
-      else {
-         for (i = 2; i < nr; i += 3) {
-            lp_setup_tri( setup_ctx,
-                       get_vert(vertex_buffer, i-2, stride),
-                       get_vert(vertex_buffer, i-1, stride),
-                       get_vert(vertex_buffer, i-0, stride) );
-         }
-      }
-      break;
-
-   case PIPE_PRIM_TRIANGLE_STRIP:
-      if (llvmpipe->rasterizer->flatshade_first) {
-         for (i = 2; i < nr; i++) {
-            lp_setup_tri( setup_ctx,
-                       get_vert(vertex_buffer, i+(i&1)-1, stride),
-                       get_vert(vertex_buffer, i-(i&1), stride),
-                       get_vert(vertex_buffer, i-2, stride) );
-         }
-      }
-      else {
-         for (i = 2; i < nr; i++) {
-            lp_setup_tri( setup_ctx,
-                       get_vert(vertex_buffer, i+(i&1)-2, stride),
-                       get_vert(vertex_buffer, i-(i&1)-1, stride),
-                       get_vert(vertex_buffer, i-0, stride) );
-         }
-      }
-      break;
-
-   case PIPE_PRIM_TRIANGLE_FAN:
-      if (llvmpipe->rasterizer->flatshade_first) {
-         for (i = 2; i < nr; i += 1) {
-            lp_setup_tri( setup_ctx,
-                       get_vert(vertex_buffer, i-0, stride),
-                       get_vert(vertex_buffer, 0, stride),
-                       get_vert(vertex_buffer, i-1, stride) );
-         }
-      }
-      else {
-         for (i = 2; i < nr; i += 1) {
-            lp_setup_tri( setup_ctx,
-                       get_vert(vertex_buffer, 0, stride),
-                       get_vert(vertex_buffer, i-1, stride),
-                       get_vert(vertex_buffer, i-0, stride) );
-         }
-      }
-      break;
-
-   case PIPE_PRIM_QUADS:
-      if (llvmpipe->rasterizer->flatshade_first) {
-         for (i = 3; i < nr; i += 4) {
-            lp_setup_tri( setup_ctx,
-                       get_vert(vertex_buffer, i-2, stride),
-                       get_vert(vertex_buffer, i-1, stride),
-                       get_vert(vertex_buffer, i-3, stride) );
-            lp_setup_tri( setup_ctx,
-                       get_vert(vertex_buffer, i-1, stride),
-                       get_vert(vertex_buffer, i-0, stride),
-                       get_vert(vertex_buffer, i-3, stride) );
-         }
-      }
-      else {
-         for (i = 3; i < nr; i += 4) {
-            lp_setup_tri( setup_ctx,
-                       get_vert(vertex_buffer, i-3, stride),
-                       get_vert(vertex_buffer, i-2, stride),
-                       get_vert(vertex_buffer, i-0, stride) );
-            lp_setup_tri( setup_ctx,
-                       get_vert(vertex_buffer, i-2, stride),
-                       get_vert(vertex_buffer, i-1, stride),
-                       get_vert(vertex_buffer, i-0, stride) );
-         }
-      }
-      break;
-
-   case PIPE_PRIM_QUAD_STRIP:
-      if (llvmpipe->rasterizer->flatshade_first) {
-         for (i = 3; i < nr; i += 2) {
-            lp_setup_tri( setup_ctx,
-                       get_vert(vertex_buffer, i-0, stride),
-                       get_vert(vertex_buffer, i-1, stride),
-                       get_vert(vertex_buffer, i-3, stride) );
-            lp_setup_tri( setup_ctx,
-                       get_vert(vertex_buffer, i-2, stride),
-                       get_vert(vertex_buffer, i-0, stride),
-                       get_vert(vertex_buffer, i-3, stride) );
-         }
-      }
-      else {
-         for (i = 3; i < nr; i += 2) {
-            lp_setup_tri( setup_ctx,
-                       get_vert(vertex_buffer, i-3, stride),
-                       get_vert(vertex_buffer, i-2, stride),
-                       get_vert(vertex_buffer, i-0, stride) );
-            lp_setup_tri( setup_ctx,
-                       get_vert(vertex_buffer, i-1, stride),
-                       get_vert(vertex_buffer, i-3, stride),
-                       get_vert(vertex_buffer, i-0, stride) );
-         }
-      }
-      break;
-
-   case PIPE_PRIM_POLYGON:
-      /* Almost same as tri fan but the _first_ vertex specifies the flat
-       * shading color.  Note that the first polygon vertex is passed as
-       * the last triangle vertex here.
-       * flatshade_first state makes no difference.
-       */
-      for (i = 2; i < nr; i += 1) {
-         lp_setup_tri( setup_ctx,
-                    get_vert(vertex_buffer, i-1, stride),
-                    get_vert(vertex_buffer, i-0, stride),
-                    get_vert(vertex_buffer, 0, stride) );
-      }
-      break;
-
-   default:
-      assert(0);
-   }
-}
-
-
-
-static void
-lp_vbuf_destroy(struct vbuf_render *vbr)
-{
-   FREE(vbr);
-}
-
-
-/**
- * Create the post-transform vertex handler for the given context.
- */
-struct vbuf_render *
-lp_create_vbuf_backend(struct llvmpipe_context *lp)
-{
-   struct llvmpipe_vbuf_render *cvbr = CALLOC_STRUCT(llvmpipe_vbuf_render);
-
-   assert(lp->draw);
-   assert(lp->setup);
-
-
-   cvbr->base.max_indices = LP_MAX_VBUF_INDEXES;
-   cvbr->base.max_vertex_buffer_bytes = LP_MAX_VBUF_SIZE;
-
-   cvbr->base.get_vertex_info = lp_vbuf_get_vertex_info;
-   cvbr->base.allocate_vertices = lp_vbuf_allocate_vertices;
-   cvbr->base.map_vertices = lp_vbuf_map_vertices;
-   cvbr->base.unmap_vertices = lp_vbuf_unmap_vertices;
-   cvbr->base.set_primitive = lp_vbuf_set_primitive;
-   cvbr->base.draw = lp_vbuf_draw;
-   cvbr->base.draw_arrays = lp_vbuf_draw_arrays;
-   cvbr->base.release_vertices = lp_vbuf_release_vertices;
-   cvbr->base.destroy = lp_vbuf_destroy;
-
-   cvbr->llvmpipe = lp;
-   cvbr->setup = lp->setup;
-
-   return &cvbr->base;
-}
diff --git a/src/gallium/drivers/llvmpipe/lp_prim_vbuf.h b/src/gallium/drivers/llvmpipe/lp_prim_vbuf.h
deleted file mode 100644 (file)
index 0676e2f..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-/**************************************************************************
- * 
- * Copyright 2007 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.
- * 
- **************************************************************************/
-
-#ifndef LP_VBUF_H
-#define LP_VBUF_H
-
-
-struct llvmpipe_context;
-
-extern struct vbuf_render *
-lp_create_vbuf_backend(struct llvmpipe_context *llvmpipe);
-
-
-#endif /* LP_VBUF_H */
index e361e5df63aee08bb56966613f595a2edb618a4d..e2b21aed473966375f699304fa985689a424392e 100644 (file)
 #include "util/u_surface.h"
 #include "lp_scene.h"
 #include "lp_scene_queue.h"
-#include "lp_debug.h"
-#include "lp_fence.h"
-#include "lp_state.h"
 #include "lp_buffer.h"
 #include "lp_texture.h"
+#include "lp_debug.h"
+#include "lp_fence.h"
+#include "lp_rast.h"
 #include "lp_setup_context.h"
 
+#include "draw/draw_context.h"
+#include "draw/draw_vbuf.h"
+
 
 /** XXX temporary value, temporary here */
 #define MAX_SCENES 2
 
 
-static void set_state( struct setup_context *, unsigned );
+static void set_scene_state( struct setup_context *, unsigned );
 
 
 struct lp_scene *
@@ -76,7 +79,7 @@ first_triangle( struct setup_context *setup,
                 const float (*v1)[4],
                 const float (*v2)[4])
 {
-   set_state( setup, SETUP_ACTIVE );
+   set_scene_state( setup, SETUP_ACTIVE );
    lp_setup_choose_triangle( setup );
    setup->triangle( setup, v0, v1, v2 );
 }
@@ -86,7 +89,7 @@ first_line( struct setup_context *setup,
            const float (*v0)[4],
            const float (*v1)[4])
 {
-   set_state( setup, SETUP_ACTIVE );
+   set_scene_state( setup, SETUP_ACTIVE );
    lp_setup_choose_line( setup );
    setup->line( setup, v0, v1 );
 }
@@ -95,7 +98,7 @@ static void
 first_point( struct setup_context *setup,
             const float (*v0)[4])
 {
-   set_state( setup, SETUP_ACTIVE );
+   set_scene_state( setup, SETUP_ACTIVE );
    lp_setup_choose_point( setup );
    setup->point( setup, v0 );
 }
@@ -194,7 +197,7 @@ execute_clears( struct setup_context *setup )
 
 
 static void
-set_state( struct setup_context *setup,
+set_scene_state( struct setup_context *setup,
            unsigned new_state )
 {
    unsigned old_state = setup->state;
@@ -234,7 +237,7 @@ lp_setup_flush( struct setup_context *setup,
 {
    LP_DBG(DEBUG_SETUP, "%s\n", __FUNCTION__);
 
-   set_state( setup, SETUP_FLUSHED );
+   set_scene_state( setup, SETUP_FLUSHED );
 }
 
 
@@ -246,7 +249,7 @@ lp_setup_bind_framebuffer( struct setup_context *setup,
 
    LP_DBG(DEBUG_SETUP, "%s\n", __FUNCTION__);
 
-   set_state( setup, SETUP_FLUSHED );
+   set_scene_state( setup, SETUP_FLUSHED );
 
    util_copy_framebuffer_state(&setup->fb, fb);
 
@@ -302,7 +305,7 @@ lp_setup_clear( struct setup_context *setup,
        * buffers which the app or state-tracker might issue
        * separately.
        */
-      set_state( setup, SETUP_CLEARED );
+      set_scene_state( setup, SETUP_CLEARED );
 
       setup->clear.flags |= flags;
    }
@@ -321,7 +324,7 @@ lp_setup_fence( struct setup_context *setup )
 
    LP_DBG(DEBUG_SETUP, "%s rank %u\n", __FUNCTION__, rank);
 
-   set_state( setup, SETUP_ACTIVE );
+   set_scene_state( setup, SETUP_ACTIVE );
 
    /* insert the fence into all command bins */
    lp_scene_bin_everywhere( scene,
@@ -358,13 +361,13 @@ lp_setup_set_fs_inputs( struct setup_context *setup,
 }
 
 void
-lp_setup_set_fs( struct setup_context *setup,
-                 struct lp_fragment_shader *fs )
+lp_setup_set_fs_function( struct setup_context *setup,
+                          lp_jit_frag_func jit_function )
 {
-   LP_DBG(DEBUG_SETUP, "%s %p\n", __FUNCTION__, (void *) fs);
+   LP_DBG(DEBUG_SETUP, "%s %p\n", __FUNCTION__, (void *) jit_function);
    /* FIXME: reference count */
 
-   setup->fs.current.jit_function = fs ? fs->current->jit_function : NULL;
+   setup->fs.current.jit_function = jit_function;
    setup->dirty |= LP_SETUP_NEW_FS;
 }
 
@@ -406,6 +409,25 @@ lp_setup_set_blend_color( struct setup_context *setup,
    }
 }
 
+
+void 
+lp_setup_set_flatshade_first( struct setup_context *setup,
+                              boolean flatshade_first )
+{
+   setup->flatshade_first = flatshade_first;
+}
+
+
+void 
+lp_setup_set_vertex_info( struct setup_context *setup,
+                          struct vertex_info *vertex_info )
+{
+   /* XXX: just silently holding onto the pointer:
+    */
+   setup->vertex_info = vertex_info;
+}
+
+
 void
 lp_setup_set_sampler_textures( struct setup_context *setup,
                                unsigned num, struct pipe_texture **texture)
@@ -452,8 +474,8 @@ lp_setup_is_texture_referenced( struct setup_context *setup,
 }
 
 
-static INLINE void
-lp_setup_update_shader_state( struct setup_context *setup )
+void
+lp_setup_update_state( struct setup_context *setup )
 {
    struct lp_scene *scene = lp_setup_get_current_scene(setup);
 
@@ -548,36 +570,6 @@ lp_setup_update_shader_state( struct setup_context *setup )
 }
 
 
-/* Stubs for lines & points for now:
- */
-void
-lp_setup_point(struct setup_context *setup,
-                    const float (*v0)[4])
-{
-   lp_setup_update_shader_state(setup);
-   setup->point( setup, v0 );
-}
-
-void
-lp_setup_line(struct setup_context *setup,
-                   const float (*v0)[4],
-                   const float (*v1)[4])
-{
-   lp_setup_update_shader_state(setup);
-   setup->line( setup, v0, v1 );
-}
-
-void
-lp_setup_tri(struct setup_context *setup,
-             const float (*v0)[4],
-             const float (*v1)[4],
-             const float (*v2)[4])
-{
-   LP_DBG(DEBUG_SETUP, "%s\n", __FUNCTION__);
-
-   lp_setup_update_shader_state(setup);
-   setup->triangle( setup, v0, v1, v2 );
-}
 
 
 void 
@@ -602,11 +594,13 @@ lp_setup_destroy( struct setup_context *setup )
 
 
 /**
- * Create a new primitive tiling engine.  Currently also creates a
- * rasterizer to use with it.
+ * Create a new primitive tiling engine.  Plug it into the backend of
+ * the draw module.  Currently also creates a rasterizer to use with
+ * it.
  */
 struct setup_context *
-lp_setup_create( struct pipe_screen *screen )
+lp_setup_create( struct pipe_screen *screen,
+                 struct draw_context *draw )
 {
    unsigned i;
    struct setup_context *setup = CALLOC_STRUCT(setup_context);
@@ -614,6 +608,8 @@ lp_setup_create( struct pipe_screen *screen )
    if (!setup)
       return NULL;
 
+   lp_setup_init_vbuf(setup);
+
    setup->empty_scenes = lp_scene_queue_create();
    if (!setup->empty_scenes)
       goto fail;
@@ -622,6 +618,13 @@ lp_setup_create( struct pipe_screen *screen )
    if (!setup->rast) 
       goto fail;
 
+   setup->vbuf = draw_vbuf_stage(draw, &setup->base);
+   if (!setup->vbuf)
+      goto fail;
+
+   draw_set_rasterize_stage(draw, setup->vbuf);
+   draw_set_render(draw, &setup->base);
+
    /* create some empty scenes */
    for (i = 0; i < MAX_SCENES; i++) {
       struct lp_scene *scene = lp_scene_create();
@@ -637,6 +640,12 @@ lp_setup_create( struct pipe_screen *screen )
    return setup;
 
 fail:
+   if (setup->rast)
+      lp_rast_destroy( setup->rast );
+   
+   if (setup->vbuf)
+      ;
+
    if (setup->empty_scenes)
       lp_scene_queue_destroy(setup->empty_scenes);
 
index 5c606e86afcdc085aaec11a5f132d1891acc9609..a6120fcbe408df227fbe15900fc32f3be00705f7 100644 (file)
 #define LP_SETUP_H
 
 #include "pipe/p_compiler.h"
+#include "lp_jit.h"
+
+struct draw_context;
+struct vertex_info;
 
 enum lp_interp {
    LP_INTERP_CONSTANT,
@@ -58,7 +62,8 @@ struct lp_fragment_shader;
 struct lp_jit_context;
 
 struct setup_context *
-lp_setup_create( struct pipe_screen *screen );
+lp_setup_create( struct pipe_screen *screen,
+                 struct draw_context *draw );
 
 void
 lp_setup_clear(struct setup_context *setup,
@@ -71,22 +76,6 @@ struct pipe_fence_handle *
 lp_setup_fence( struct setup_context *setup );
 
 
-void
-lp_setup_tri(struct setup_context *setup,
-             const float (*v0)[4],
-             const float (*v1)[4],
-             const float (*v2)[4]);
-
-void
-lp_setup_line(struct setup_context *setup,
-              const float (*v0)[4],
-              const float (*v1)[4]);
-
-void
-lp_setup_point( struct setup_context *setup,
-                const float (*v0)[4] );
-
-
 void
 lp_setup_flush( struct setup_context *setup,
                 unsigned flags );
@@ -107,8 +96,8 @@ lp_setup_set_fs_inputs( struct setup_context *setup,
                         unsigned nr );
 
 void
-lp_setup_set_fs( struct setup_context *setup,
-                 struct lp_fragment_shader *fs );
+lp_setup_set_fs_function( struct setup_context *setup,
+                          lp_jit_frag_func jit_function );
 
 void
 lp_setup_set_fs_constants(struct setup_context *setup,
@@ -131,6 +120,13 @@ boolean
 lp_setup_is_texture_referenced( struct setup_context *setup,
                                 const struct pipe_texture *texture );
 
+void
+lp_setup_set_flatshade_first( struct setup_context *setup, 
+                              boolean flatshade_first );
+
+void
+lp_setup_set_vertex_info( struct setup_context *setup, 
+                          struct vertex_info *info );
 
 void 
 lp_setup_destroy( struct setup_context *setup );
index f6604a8034aa2896ef4d9aaf398925b980f3782f..d2278a46e664ccb3f279b49e5f06bf61ec4eac43 100644 (file)
@@ -40,6 +40,7 @@
 #include "lp_tile_soa.h"        /* for TILE_SIZE */
 #include "lp_scene.h"
 
+#include "draw/draw_vbuf.h"
 
 #define LP_SETUP_NEW_FS          0x01
 #define LP_SETUP_NEW_CONSTANTS   0x02
@@ -53,15 +54,31 @@ struct lp_scene_queue;
  * Point/line/triangle setup context.
  * Note: "stored" below indicates data which is stored in the bins,
  * not arbitrary malloc'd memory.
+ *
+ *
+ * Subclass of vbuf_render, plugged directly into the draw module as
+ * the rendering backend.
  */
-struct setup_context {
-
+struct setup_context
+{
+   struct vbuf_render base;
+
+   struct vertex_info *vertex_info;
+   uint prim;
+   uint vertex_size;
+   uint nr_vertices;
+   uint vertex_buffer_size;
+   void *vertex_buffer;
+
+   /* Final pipeline stage for draw module.  Draw module should
+    * create/install this itself now.
+    */
+   struct draw_stage *vbuf;
    struct lp_rasterizer *rast;
-
-
    struct lp_scene *scene;               /**< current scene */
    struct lp_scene_queue *empty_scenes;  /**< queue of empty scenes */
 
+   boolean flatshade_first;
    boolean ccw_is_frontface;
    unsigned cullmode;
 
@@ -120,4 +137,8 @@ void lp_setup_choose_point( struct setup_context *setup );
 
 struct lp_scene *lp_setup_get_current_scene(struct setup_context *setup);
 
+void lp_setup_init_vbuf(struct setup_context *setup);
+
+void lp_setup_update_state( struct setup_context *setup );
+
 #endif
diff --git a/src/gallium/drivers/llvmpipe/lp_setup_vbuf.c b/src/gallium/drivers/llvmpipe/lp_setup_vbuf.c
new file mode 100644 (file)
index 0000000..5cd4f35
--- /dev/null
@@ -0,0 +1,520 @@
+/**************************************************************************
+ *
+ * Copyright 2007 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.
+ *
+ **************************************************************************/
+
+/**
+ * Interface between 'draw' module's output and the llvmpipe rasterizer/setup
+ * code.  When the 'draw' module has finished filling a vertex buffer, the
+ * draw_arrays() functions below will be called.  Loop over the vertices and
+ * call the point/line/tri setup functions.
+ *
+ * Authors
+ *  Brian Paul
+ */
+
+
+#include "lp_setup_context.h"
+#include "draw/draw_context.h"
+#include "draw/draw_vbuf.h"
+#include "draw/draw_vertex.h"
+#include "util/u_memory.h"
+#include "util/u_prim.h"
+
+
+#define LP_MAX_VBUF_INDEXES 1024
+#define LP_MAX_VBUF_SIZE    4096
+
+  
+
+/** cast wrapper */
+static struct setup_context *
+setup_context(struct vbuf_render *vbr)
+{
+   return (struct setup_context *) vbr;
+}
+
+
+
+static const struct vertex_info *
+lp_vbuf_get_vertex_info(struct vbuf_render *vbr)
+{
+   struct setup_context *setup = setup_context(vbr);
+   return setup->vertex_info;
+}
+
+
+static boolean
+lp_vbuf_allocate_vertices(struct vbuf_render *vbr,
+                          ushort vertex_size, ushort nr_vertices)
+{
+   struct setup_context *setup = setup_context(vbr);
+   unsigned size = vertex_size * nr_vertices;
+
+   if (setup->vertex_buffer_size < size) {
+      align_free(setup->vertex_buffer);
+      setup->vertex_buffer = align_malloc(size, 16);
+      setup->vertex_buffer_size = size;
+   }
+
+   setup->vertex_size = vertex_size;
+   setup->nr_vertices = nr_vertices;
+   
+   return setup->vertex_buffer != NULL;
+}
+
+static void
+lp_vbuf_release_vertices(struct vbuf_render *vbr)
+{
+   /* keep the old allocation for next time */
+}
+
+static void *
+lp_vbuf_map_vertices(struct vbuf_render *vbr)
+{
+   struct setup_context *setup = setup_context(vbr);
+   return setup->vertex_buffer;
+}
+
+static void 
+lp_vbuf_unmap_vertices(struct vbuf_render *vbr, 
+                       ushort min_index,
+                       ushort max_index )
+{
+   struct setup_context *setup = setup_context(vbr);
+   assert( setup->vertex_buffer_size >= (max_index+1) * setup->vertex_size );
+   /* do nothing */
+}
+
+
+static boolean
+lp_vbuf_set_primitive(struct vbuf_render *vbr, unsigned prim)
+{
+   setup_context(vbr)->prim = prim;
+   return TRUE;
+}
+
+typedef const float (*const_float4_ptr)[4];
+
+static INLINE const_float4_ptr get_vert( const void *vertex_buffer,
+                                         int index,
+                                         int stride )
+{
+   return (const_float4_ptr)((char *)vertex_buffer + index * stride);
+}
+
+/**
+ * draw elements / indexed primitives
+ */
+static void
+lp_vbuf_draw(struct vbuf_render *vbr, const ushort *indices, uint nr)
+{
+   struct setup_context *setup = setup_context(vbr);
+   const unsigned stride = setup->vertex_info->size * sizeof(float);
+   const void *vertex_buffer = setup->vertex_buffer;
+   unsigned i;
+
+   lp_setup_update_state(setup);
+
+   switch (setup->prim) {
+   case PIPE_PRIM_POINTS:
+      for (i = 0; i < nr; i++) {
+         setup->point( setup,
+                       get_vert(vertex_buffer, indices[i-0], stride) );
+      }
+      break;
+
+   case PIPE_PRIM_LINES:
+      for (i = 1; i < nr; i += 2) {
+         setup->line( setup,
+                      get_vert(vertex_buffer, indices[i-1], stride),
+                      get_vert(vertex_buffer, indices[i-0], stride) );
+      }
+      break;
+
+   case PIPE_PRIM_LINE_STRIP:
+      for (i = 1; i < nr; i ++) {
+         setup->line( setup,
+                      get_vert(vertex_buffer, indices[i-1], stride),
+                      get_vert(vertex_buffer, indices[i-0], stride) );
+      }
+      break;
+
+   case PIPE_PRIM_LINE_LOOP:
+      for (i = 1; i < nr; i ++) {
+         setup->line( setup,
+                      get_vert(vertex_buffer, indices[i-1], stride),
+                      get_vert(vertex_buffer, indices[i-0], stride) );
+      }
+      if (nr) {
+         setup->line( setup,
+                      get_vert(vertex_buffer, indices[nr-1], stride),
+                      get_vert(vertex_buffer, indices[0], stride) );
+      }
+      break;
+
+   case PIPE_PRIM_TRIANGLES:
+      if (setup->flatshade_first) {
+         for (i = 2; i < nr; i += 3) {
+            setup->triangle( setup,
+                             get_vert(vertex_buffer, indices[i-1], stride),
+                             get_vert(vertex_buffer, indices[i-0], stride),
+                             get_vert(vertex_buffer, indices[i-2], stride) );
+         }
+      }
+      else {
+         for (i = 2; i < nr; i += 3) {
+            setup->triangle( setup,
+                             get_vert(vertex_buffer, indices[i-2], stride),
+                             get_vert(vertex_buffer, indices[i-1], stride),
+                             get_vert(vertex_buffer, indices[i-0], stride) );
+         }
+      }
+      break;
+
+   case PIPE_PRIM_TRIANGLE_STRIP:
+      if (setup->flatshade_first) {
+         for (i = 2; i < nr; i += 1) {
+            setup->triangle( setup,
+                             get_vert(vertex_buffer, indices[i+(i&1)-1], stride),
+                             get_vert(vertex_buffer, indices[i-(i&1)], stride),
+                             get_vert(vertex_buffer, indices[i-2], stride) );
+         }
+      }
+      else {
+         for (i = 2; i < nr; i += 1) {
+            setup->triangle( setup,
+                             get_vert(vertex_buffer, indices[i+(i&1)-2], stride),
+                             get_vert(vertex_buffer, indices[i-(i&1)-1], stride),
+                             get_vert(vertex_buffer, indices[i-0], stride) );
+         }
+      }
+      break;
+
+   case PIPE_PRIM_TRIANGLE_FAN:
+      if (setup->flatshade_first) {
+         for (i = 2; i < nr; i += 1) {
+            setup->triangle( setup,
+                             get_vert(vertex_buffer, indices[i-0], stride),
+                             get_vert(vertex_buffer, indices[0], stride),
+                             get_vert(vertex_buffer, indices[i-1], stride) );
+         }
+      }
+      else {
+         for (i = 2; i < nr; i += 1) {
+            setup->triangle( setup,
+                             get_vert(vertex_buffer, indices[0], stride),
+                             get_vert(vertex_buffer, indices[i-1], stride),
+                             get_vert(vertex_buffer, indices[i-0], stride) );
+         }
+      }
+      break;
+
+   case PIPE_PRIM_QUADS:
+      if (setup->flatshade_first) {
+         for (i = 3; i < nr; i += 4) {
+            setup->triangle( setup,
+                             get_vert(vertex_buffer, indices[i-2], stride),
+                             get_vert(vertex_buffer, indices[i-1], stride),
+                             get_vert(vertex_buffer, indices[i-3], stride) );
+            setup->triangle( setup,
+                             get_vert(vertex_buffer, indices[i-1], stride),
+                             get_vert(vertex_buffer, indices[i-0], stride),
+                             get_vert(vertex_buffer, indices[i-3], stride) );
+         }
+      }
+      else {
+         for (i = 3; i < nr; i += 4) {
+            setup->triangle( setup,
+                             get_vert(vertex_buffer, indices[i-3], stride),
+                             get_vert(vertex_buffer, indices[i-2], stride),
+                             get_vert(vertex_buffer, indices[i-0], stride) );
+
+            setup->triangle( setup,
+                             get_vert(vertex_buffer, indices[i-2], stride),
+                             get_vert(vertex_buffer, indices[i-1], stride),
+                             get_vert(vertex_buffer, indices[i-0], stride) );
+         }
+      }
+      break;
+
+   case PIPE_PRIM_QUAD_STRIP:
+      if (setup->flatshade_first) {
+         for (i = 3; i < nr; i += 2) {
+            setup->triangle( setup,
+                             get_vert(vertex_buffer, indices[i-0], stride),
+                             get_vert(vertex_buffer, indices[i-1], stride),
+                             get_vert(vertex_buffer, indices[i-3], stride));
+            setup->triangle( setup,
+                             get_vert(vertex_buffer, indices[i-2], stride),
+                             get_vert(vertex_buffer, indices[i-0], stride),
+                             get_vert(vertex_buffer, indices[i-3], stride) );
+         }
+      }
+      else {
+         for (i = 3; i < nr; i += 2) {
+            setup->triangle( setup,
+                             get_vert(vertex_buffer, indices[i-3], stride),
+                             get_vert(vertex_buffer, indices[i-2], stride),
+                             get_vert(vertex_buffer, indices[i-0], stride) );
+            setup->triangle( setup,
+                             get_vert(vertex_buffer, indices[i-1], stride),
+                             get_vert(vertex_buffer, indices[i-3], stride),
+                             get_vert(vertex_buffer, indices[i-0], stride) );
+         }
+      }
+      break;
+
+   case PIPE_PRIM_POLYGON:
+      /* Almost same as tri fan but the _first_ vertex specifies the flat
+       * shading color.  Note that the first polygon vertex is passed as
+       * the last triangle vertex here.
+       * flatshade_first state makes no difference.
+       */
+      for (i = 2; i < nr; i += 1) {
+         setup->triangle( setup,
+                          get_vert(vertex_buffer, indices[i-0], stride),
+                          get_vert(vertex_buffer, indices[i-1], stride),
+                          get_vert(vertex_buffer, indices[0], stride) );
+      }
+      break;
+
+   default:
+      assert(0);
+   }
+}
+
+
+/**
+ * This function is hit when the draw module is working in pass-through mode.
+ * It's up to us to convert the vertex array into point/line/tri prims.
+ */
+static void
+lp_vbuf_draw_arrays(struct vbuf_render *vbr, uint start, uint nr)
+{
+   struct setup_context *setup = setup_context(vbr);
+   const unsigned stride = setup->vertex_info->size * sizeof(float);
+   const void *vertex_buffer =
+      (void *) get_vert(setup->vertex_buffer, start, stride);
+   unsigned i;
+
+   lp_setup_update_state(setup);
+
+   switch (setup->prim) {
+   case PIPE_PRIM_POINTS:
+      for (i = 0; i < nr; i++) {
+         setup->point( setup,
+                       get_vert(vertex_buffer, i-0, stride) );
+      }
+      break;
+
+   case PIPE_PRIM_LINES:
+      for (i = 1; i < nr; i += 2) {
+         setup->line( setup,
+                      get_vert(vertex_buffer, i-1, stride),
+                      get_vert(vertex_buffer, i-0, stride) );
+      }
+      break;
+
+   case PIPE_PRIM_LINE_STRIP:
+      for (i = 1; i < nr; i ++) {
+         setup->line( setup,
+                      get_vert(vertex_buffer, i-1, stride),
+                      get_vert(vertex_buffer, i-0, stride) );
+      }
+      break;
+
+   case PIPE_PRIM_LINE_LOOP:
+      for (i = 1; i < nr; i ++) {
+         setup->line( setup,
+                      get_vert(vertex_buffer, i-1, stride),
+                      get_vert(vertex_buffer, i-0, stride) );
+      }
+      if (nr) {
+         setup->line( setup,
+                      get_vert(vertex_buffer, nr-1, stride),
+                      get_vert(vertex_buffer, 0, stride) );
+      }
+      break;
+
+   case PIPE_PRIM_TRIANGLES:
+      if (setup->flatshade_first) {
+         for (i = 2; i < nr; i += 3) {
+            setup->triangle( setup,
+                             get_vert(vertex_buffer, i-1, stride),
+                             get_vert(vertex_buffer, i-0, stride),
+                             get_vert(vertex_buffer, i-2, stride) );
+         }
+      }
+      else {
+         for (i = 2; i < nr; i += 3) {
+            setup->triangle( setup,
+                             get_vert(vertex_buffer, i-2, stride),
+                             get_vert(vertex_buffer, i-1, stride),
+                             get_vert(vertex_buffer, i-0, stride) );
+         }
+      }
+      break;
+
+   case PIPE_PRIM_TRIANGLE_STRIP:
+      if (setup->flatshade_first) {
+         for (i = 2; i < nr; i++) {
+            setup->triangle( setup,
+                             get_vert(vertex_buffer, i+(i&1)-1, stride),
+                             get_vert(vertex_buffer, i-(i&1), stride),
+                             get_vert(vertex_buffer, i-2, stride) );
+         }
+      }
+      else {
+         for (i = 2; i < nr; i++) {
+            setup->triangle( setup,
+                             get_vert(vertex_buffer, i+(i&1)-2, stride),
+                             get_vert(vertex_buffer, i-(i&1)-1, stride),
+                             get_vert(vertex_buffer, i-0, stride) );
+         }
+      }
+      break;
+
+   case PIPE_PRIM_TRIANGLE_FAN:
+      if (setup->flatshade_first) {
+         for (i = 2; i < nr; i += 1) {
+            setup->triangle( setup,
+                             get_vert(vertex_buffer, i-0, stride),
+                             get_vert(vertex_buffer, 0, stride),
+                             get_vert(vertex_buffer, i-1, stride) );
+         }
+      }
+      else {
+         for (i = 2; i < nr; i += 1) {
+            setup->triangle( setup,
+                             get_vert(vertex_buffer, 0, stride),
+                             get_vert(vertex_buffer, i-1, stride),
+                             get_vert(vertex_buffer, i-0, stride) );
+         }
+      }
+      break;
+
+   case PIPE_PRIM_QUADS:
+      if (setup->flatshade_first) {
+         for (i = 3; i < nr; i += 4) {
+            setup->triangle( setup,
+                             get_vert(vertex_buffer, i-2, stride),
+                             get_vert(vertex_buffer, i-1, stride),
+                             get_vert(vertex_buffer, i-3, stride) );
+            setup->triangle( setup,
+                             get_vert(vertex_buffer, i-1, stride),
+                             get_vert(vertex_buffer, i-0, stride),
+                             get_vert(vertex_buffer, i-3, stride) );
+         }
+      }
+      else {
+         for (i = 3; i < nr; i += 4) {
+            setup->triangle( setup,
+                             get_vert(vertex_buffer, i-3, stride),
+                             get_vert(vertex_buffer, i-2, stride),
+                             get_vert(vertex_buffer, i-0, stride) );
+            setup->triangle( setup,
+                             get_vert(vertex_buffer, i-2, stride),
+                             get_vert(vertex_buffer, i-1, stride),
+                             get_vert(vertex_buffer, i-0, stride) );
+         }
+      }
+      break;
+
+   case PIPE_PRIM_QUAD_STRIP:
+      if (setup->flatshade_first) {
+         for (i = 3; i < nr; i += 2) {
+            setup->triangle( setup,
+                             get_vert(vertex_buffer, i-0, stride),
+                             get_vert(vertex_buffer, i-1, stride),
+                             get_vert(vertex_buffer, i-3, stride) );
+            setup->triangle( setup,
+
+                             get_vert(vertex_buffer, i-2, stride),
+                             get_vert(vertex_buffer, i-0, stride),
+                             get_vert(vertex_buffer, i-3, stride) );
+         }
+      }
+      else {
+         for (i = 3; i < nr; i += 2) {
+            setup->triangle( setup,
+                             get_vert(vertex_buffer, i-3, stride),
+                             get_vert(vertex_buffer, i-2, stride),
+                             get_vert(vertex_buffer, i-0, stride) );
+            setup->triangle( setup,
+                             get_vert(vertex_buffer, i-1, stride),
+                             get_vert(vertex_buffer, i-3, stride),
+                             get_vert(vertex_buffer, i-0, stride) );
+         }
+      }
+      break;
+
+   case PIPE_PRIM_POLYGON:
+      /* Almost same as tri fan but the _first_ vertex specifies the flat
+       * shading color.  Note that the first polygon vertex is passed as
+       * the last triangle vertex here.
+       * flatshade_first state makes no difference.
+       */
+      for (i = 2; i < nr; i += 1) {
+         setup->triangle( setup,
+                          get_vert(vertex_buffer, i-1, stride),
+                          get_vert(vertex_buffer, i-0, stride),
+                          get_vert(vertex_buffer, 0, stride) );
+      }
+      break;
+
+   default:
+      assert(0);
+   }
+}
+
+
+
+static void
+lp_vbuf_destroy(struct vbuf_render *vbr)
+{
+   lp_setup_destroy(setup_context(vbr));
+}
+
+
+/**
+ * Create the post-transform vertex handler for the given context.
+ */
+void
+lp_setup_init_vbuf(struct setup_context *setup)
+{
+   setup->base.max_indices = LP_MAX_VBUF_INDEXES;
+   setup->base.max_vertex_buffer_bytes = LP_MAX_VBUF_SIZE;
+
+   setup->base.get_vertex_info = lp_vbuf_get_vertex_info;
+   setup->base.allocate_vertices = lp_vbuf_allocate_vertices;
+   setup->base.map_vertices = lp_vbuf_map_vertices;
+   setup->base.unmap_vertices = lp_vbuf_unmap_vertices;
+   setup->base.set_primitive = lp_vbuf_set_primitive;
+   setup->base.draw = lp_vbuf_draw;
+   setup->base.draw_arrays = lp_vbuf_draw_arrays;
+   setup->base.release_vertices = lp_vbuf_release_vertices;
+   setup->base.destroy = lp_vbuf_destroy;
+}
index a18efcc0e0f98a5d47a6b67e518478f89ccf76fa..ab827045ed68f954110918d1e2d2c58a6a0b8433 100644 (file)
 #include "lp_state.h"
 
 
-/**
- * Mark the current vertex layout as "invalid".
- * We'll validate the vertex layout later, when we start to actually
- * render a point or line or tri.
- */
-static void
-invalidate_vertex_layout(struct llvmpipe_context *llvmpipe)
-{
-   llvmpipe->vertex_info.num_attribs =  0;
-}
-
 
 /**
  * The vertex info describes how to convert the post-transformed vertices
@@ -57,150 +46,95 @@ invalidate_vertex_layout(struct llvmpipe_context *llvmpipe)
  * This function validates the vertex layout and returns a pointer to a
  * vertex_info object.
  */
-struct vertex_info *
-llvmpipe_get_vertex_info(struct llvmpipe_context *llvmpipe)
+static void
+compute_vertex_info(struct llvmpipe_context *llvmpipe)
 {
-   struct vertex_info *vinfo = &llvmpipe->vertex_info;
-
-   if (vinfo->num_attribs == 0) {
-      /* compute vertex layout now */
-      const struct lp_fragment_shader *lpfs = llvmpipe->fs;
-      const enum interp_mode colorInterp
-         = llvmpipe->rasterizer->flatshade ? INTERP_CONSTANT : INTERP_LINEAR;
-      struct vertex_info *vinfo_vbuf = &llvmpipe->vertex_info_vbuf;
-      const uint num = draw_num_vs_outputs(llvmpipe->draw);
-      uint i;
-
-      /* Tell draw_vbuf to simply emit the whole post-xform vertex
-       * as-is.  No longer any need to try and emit draw vertex_header
-       * info.
-       */
-      vinfo_vbuf->num_attribs = 0;
-      for (i = 0; i < num; i++) {
-        draw_emit_vertex_attr(vinfo_vbuf, EMIT_4F, INTERP_PERSPECTIVE, i);
-      }
-      draw_compute_vertex_size(vinfo_vbuf);
+   const struct lp_fragment_shader *lpfs = llvmpipe->fs;
+   struct vertex_info *vinfo_vbuf = &llvmpipe->vertex_info_vbuf;
+   const uint num = draw_num_vs_outputs(llvmpipe->draw);
+   uint i;
+
+   /* Tell draw_vbuf to simply emit the whole post-xform vertex as-is.
+    *
+    * Not really sure if this is the best approach.
+    */
+   vinfo_vbuf->num_attribs = 0;
+   for (i = 0; i < num; i++) {
+      draw_emit_vertex_attr(vinfo_vbuf, EMIT_4F, INTERP_PERSPECTIVE, i);
+   }
+   draw_compute_vertex_size(vinfo_vbuf);
 
-      /*
-       * Loop over fragment shader inputs, searching for the matching output
-       * from the vertex shader.
-       */
-      vinfo->num_attribs = 0;
-      for (i = 0; i < lpfs->info.num_inputs; i++) {
-         int src;
-         enum interp_mode interp;
 
-         switch (lpfs->info.input_interpolate[i]) {
-         case TGSI_INTERPOLATE_CONSTANT:
-            interp = INTERP_CONSTANT;
-            break;
-         case TGSI_INTERPOLATE_LINEAR:
-            interp = INTERP_LINEAR;
-            break;
-         case TGSI_INTERPOLATE_PERSPECTIVE:
-            interp = INTERP_PERSPECTIVE;
-            break;
-         default:
-            assert(0);
-            interp = INTERP_LINEAR;
-         }
+   lp_setup_set_vertex_info(llvmpipe->setup, vinfo_vbuf);
 
-         switch (lpfs->info.input_semantic_name[i]) {
-         case TGSI_SEMANTIC_POSITION:
-            src = draw_find_vs_output(llvmpipe->draw,
-                                      TGSI_SEMANTIC_POSITION, 0);
-            draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_POS, src);
-            break;
+/*
+   llvmpipe->psize_slot = draw_find_vs_output(llvmpipe->draw,
+                                              TGSI_SEMANTIC_PSIZE, 0);
+*/
 
-         case TGSI_SEMANTIC_COLOR:
-            src = draw_find_vs_output(llvmpipe->draw, TGSI_SEMANTIC_COLOR, 
-                                 lpfs->info.input_semantic_index[i]);
-            draw_emit_vertex_attr(vinfo, EMIT_4F, colorInterp, src);
-            break;
+   /* Now match FS inputs against emitted vertex data.  It's also
+    * entirely possible to just have a fixed layout for FS input,
+    * determined by the fragment shader itself, and adjust the draw
+    * outputs to match that.
+    */
+   {
+      struct lp_shader_input inputs[PIPE_MAX_SHADER_INPUTS];
 
-         case TGSI_SEMANTIC_FOG:
-            src = draw_find_vs_output(llvmpipe->draw, TGSI_SEMANTIC_FOG, 0);
-            draw_emit_vertex_attr(vinfo, EMIT_4F, interp, src);
-            break;
+      for (i = 0; i < lpfs->info.num_inputs; i++) {
 
-         case TGSI_SEMANTIC_GENERIC:
+         /* This can be precomputed, except for flatshade:
+          */
+         switch (lpfs->info.input_semantic_name[i]) {
          case TGSI_SEMANTIC_FACE:
-            /* this includes texcoords and varying vars */
-            src = draw_find_vs_output(llvmpipe->draw, TGSI_SEMANTIC_GENERIC,
-                                      lpfs->info.input_semantic_index[i]);
-            draw_emit_vertex_attr(vinfo, EMIT_4F, interp, src);
+            inputs[i].interp = LP_INTERP_FACING;
+            break;
+         case TGSI_SEMANTIC_POSITION:
+            inputs[i].interp = LP_INTERP_POSITION;
+            break;
+         case TGSI_SEMANTIC_COLOR:
+            /* Colors are linearly interpolated in the fragment shader
+             * even when flatshading is active.  This just tells the
+             * setup module to use coefficients with ddx==0 and
+             * ddy==0.
+             */
+            if (llvmpipe->rasterizer->flatshade)
+               inputs[i].interp = LP_INTERP_CONSTANT;
+            else
+               inputs[i].interp = LP_INTERP_LINEAR;
             break;
 
          default:
-            assert(0);
-         }
-      }
-
-      llvmpipe->psize_slot = draw_find_vs_output(llvmpipe->draw,
-                                                 TGSI_SEMANTIC_PSIZE, 0);
-      if (llvmpipe->psize_slot > 0) {
-         draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_CONSTANT,
-                               llvmpipe->psize_slot);
-      }
-
-      draw_compute_vertex_size(vinfo);
-
-      {
-         struct lp_shader_input inputs[PIPE_MAX_SHADER_INPUTS];
-
-         for (i = 0; i < lpfs->info.num_inputs; i++) {
-            switch (vinfo->attrib[i].interp_mode) {
-            case INTERP_CONSTANT:
+            switch (lpfs->info.input_interpolate[i]) {
+            case TGSI_INTERPOLATE_CONSTANT:
                inputs[i].interp = LP_INTERP_CONSTANT;
                break;
-            case INTERP_LINEAR:
+            case TGSI_INTERPOLATE_LINEAR:
                inputs[i].interp = LP_INTERP_LINEAR;
                break;
-            case INTERP_PERSPECTIVE:
+            case TGSI_INTERPOLATE_PERSPECTIVE:
                inputs[i].interp = LP_INTERP_PERSPECTIVE;
                break;
-            case INTERP_POS:
-               inputs[i].interp = LP_INTERP_POSITION;
-               break;
             default:
                assert(0);
+               break;
             }
-
-            if (lpfs->info.input_semantic_name[i] == TGSI_SEMANTIC_FACE)
-               inputs[i].interp = LP_INTERP_FACING;
-
-            inputs[i].src_index = vinfo->attrib[i].src_index;
          }
 
-         lp_setup_set_fs_inputs(llvmpipe->setup, inputs, lpfs->info.num_inputs);
+         /* Search for each input in current vs output:
+          */
+         inputs[i].src_index = 
+            draw_find_vs_output(llvmpipe->draw,
+                                lpfs->info.input_semantic_name[i],
+                                lpfs->info.input_semantic_index[i]);
       }
-   }
 
-   return vinfo;
+      lp_setup_set_fs_inputs(llvmpipe->setup, 
+                             inputs,
+                             lpfs->info.num_inputs);
+   }
 }
 
 
-/**
- * Called from vbuf module.
- *
- * Note that there's actually two different vertex layouts in llvmpipe.
- *
- * The normal one is computed in llvmpipe_get_vertex_info() above and is
- * used by the point/line/tri "setup" code.
- *
- * The other one (this one) is only used by the vbuf module (which is
- * not normally used by default but used in testing).  For the vbuf module,
- * we basically want to pass-through the draw module's vertex layout as-is.
- * When the llvmpipe vbuf code begins drawing, the normal vertex layout
- * will come into play again.
- */
-struct vertex_info *
-llvmpipe_get_vbuf_vertex_info(struct llvmpipe_context *llvmpipe)
-{
-   (void) llvmpipe_get_vertex_info(llvmpipe);
-   return &llvmpipe->vertex_info_vbuf;
-}
-
 
 /**
  * Recompute cliprect from scissor bounds, scissor enable and surface size.
@@ -273,7 +207,7 @@ void llvmpipe_update_derived( struct llvmpipe_context *llvmpipe )
    if (llvmpipe->dirty & (LP_NEW_RASTERIZER |
                           LP_NEW_FS |
                           LP_NEW_VS))
-      invalidate_vertex_layout( llvmpipe );
+      compute_vertex_info( llvmpipe );
 
    if (llvmpipe->dirty & (LP_NEW_SCISSOR |
                           LP_NEW_RASTERIZER |
@@ -287,36 +221,23 @@ void llvmpipe_update_derived( struct llvmpipe_context *llvmpipe )
                           LP_NEW_TEXTURE))
       llvmpipe_update_fs( llvmpipe );
 
-   if (llvmpipe->dirty & (LP_NEW_BLEND |
-                          LP_NEW_DEPTH_STENCIL_ALPHA |
-                          LP_NEW_SAMPLER |
-                          LP_NEW_TEXTURE))
-      llvmpipe_update_fs( llvmpipe );
-
    if (llvmpipe->dirty & LP_NEW_BLEND_COLOR)
-      lp_setup_set_blend_color(llvmpipe->setup, &llvmpipe->blend_color);
+      lp_setup_set_blend_color(llvmpipe->setup,
+                               &llvmpipe->blend_color);
 
    if (llvmpipe->dirty & LP_NEW_DEPTH_STENCIL_ALPHA)
-      lp_setup_set_alpha_ref_value(llvmpipe->setup, llvmpipe->depth_stencil->alpha.ref_value);
+      lp_setup_set_alpha_ref_value(llvmpipe->setup, 
+                                   llvmpipe->depth_stencil->alpha.ref_value);
 
    if (llvmpipe->dirty & LP_NEW_CONSTANTS)
-      lp_setup_set_fs_constants(llvmpipe->setup, llvmpipe->constants[PIPE_SHADER_FRAGMENT].buffer);
+      lp_setup_set_fs_constants(llvmpipe->setup, 
+                                llvmpipe->constants[PIPE_SHADER_FRAGMENT].buffer);
 
    if (llvmpipe->dirty & LP_NEW_TEXTURE)
-      lp_setup_set_sampler_textures(llvmpipe->setup, llvmpipe->num_textures, llvmpipe->texture);
+      lp_setup_set_sampler_textures(llvmpipe->setup, 
+                                    llvmpipe->num_textures,
+                                    llvmpipe->texture);
 
    llvmpipe->dirty = 0;
 }
 
-
-#if 0
-void llvmpipe_prepare(struct lp_setup_context *setup)
-{
-   struct llvmpipe_context *lp = setup->llvmpipe;
-
-   if (lp->dirty) {
-      llvmpipe_update_derived(lp);
-   }
-
-}
-#endif
index 7ed727dbbceecb6813199e49c2a508479c0c3fcf..3ad58415e3927c8ddf7bd900a599de433363aba2 100644 (file)
@@ -891,5 +891,6 @@ llvmpipe_update_fs(struct llvmpipe_context *lp)
 
    shader->current = variant;
 
-   lp_setup_set_fs(lp->setup, shader);
+   lp_setup_set_fs_function(lp->setup, 
+                            shader->current->jit_function);
 }