diff options
| -rw-r--r-- | src/gallium/drivers/llvmpipe/Makefile | 2 | ||||
| -rw-r--r-- | src/gallium/drivers/llvmpipe/SConscript | 2 | ||||
| -rw-r--r-- | src/gallium/drivers/llvmpipe/lp_context.c | 18 | ||||
| -rw-r--r-- | src/gallium/drivers/llvmpipe/lp_context.h | 15 | ||||
| -rw-r--r-- | src/gallium/drivers/llvmpipe/lp_draw_arrays.c | 2 | ||||
| -rw-r--r-- | src/gallium/drivers/llvmpipe/lp_prim_vbuf.c | 559 | ||||
| -rw-r--r-- | src/gallium/drivers/llvmpipe/lp_prim_vbuf.h | 38 | ||||
| -rw-r--r-- | src/gallium/drivers/llvmpipe/lp_setup.c | 111 | ||||
| -rw-r--r-- | src/gallium/drivers/llvmpipe/lp_setup.h | 34 | ||||
| -rw-r--r-- | src/gallium/drivers/llvmpipe/lp_setup_context.h | 27 | ||||
| -rw-r--r-- | src/gallium/drivers/llvmpipe/lp_setup_vbuf.c | 520 | ||||
| -rw-r--r-- | src/gallium/drivers/llvmpipe/lp_state_derived.c | 219 | ||||
| -rw-r--r-- | src/gallium/drivers/llvmpipe/lp_state_fs.c | 3 | 
13 files changed, 695 insertions, 855 deletions
| diff --git a/src/gallium/drivers/llvmpipe/Makefile b/src/gallium/drivers/llvmpipe/Makefile index 345326e33d..6ec97046e1 100644 --- a/src/gallium/drivers/llvmpipe/Makefile +++ b/src/gallium/drivers/llvmpipe/Makefile @@ -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 \ diff --git a/src/gallium/drivers/llvmpipe/SConscript b/src/gallium/drivers/llvmpipe/SConscript index f0b71ef3ee..ae4303bd24 100644 --- a/src/gallium/drivers/llvmpipe/SConscript +++ b/src/gallium/drivers/llvmpipe/SConscript @@ -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', diff --git a/src/gallium/drivers/llvmpipe/lp_context.c b/src/gallium/drivers/llvmpipe/lp_context.c index 06aa032540..0457ccc8a9 100644 --- a/src/gallium/drivers/llvmpipe/lp_context.c +++ b/src/gallium/drivers/llvmpipe/lp_context.c @@ -31,14 +31,12 @@   */  #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); diff --git a/src/gallium/drivers/llvmpipe/lp_context.h b/src/gallium/drivers/llvmpipe/lp_context.h index 17c6939ff5..b796148457 100644 --- a/src/gallium/drivers/llvmpipe/lp_context.h +++ b/src/gallium/drivers/llvmpipe/lp_context.h @@ -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; diff --git a/src/gallium/drivers/llvmpipe/lp_draw_arrays.c b/src/gallium/drivers/llvmpipe/lp_draw_arrays.c index b879b5e755..91fcbc01c6 100644 --- a/src/gallium/drivers/llvmpipe/lp_draw_arrays.c +++ b/src/gallium/drivers/llvmpipe/lp_draw_arrays.c @@ -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 index 925e6f8b3b..0000000000 --- a/src/gallium/drivers/llvmpipe/lp_prim_vbuf.c +++ /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 index 0676e2f42a..0000000000 --- a/src/gallium/drivers/llvmpipe/lp_prim_vbuf.h +++ /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 */ diff --git a/src/gallium/drivers/llvmpipe/lp_setup.c b/src/gallium/drivers/llvmpipe/lp_setup.c index e361e5df63..e2b21aed47 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup.c +++ b/src/gallium/drivers/llvmpipe/lp_setup.c @@ -39,19 +39,22 @@  #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); diff --git a/src/gallium/drivers/llvmpipe/lp_setup.h b/src/gallium/drivers/llvmpipe/lp_setup.h index 5c606e86af..a6120fcbe4 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup.h +++ b/src/gallium/drivers/llvmpipe/lp_setup.h @@ -28,6 +28,10 @@  #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, @@ -72,22 +77,6 @@ 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 ); diff --git a/src/gallium/drivers/llvmpipe/lp_setup_context.h b/src/gallium/drivers/llvmpipe/lp_setup_context.h index f6604a8034..d2278a46e6 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup_context.h +++ b/src/gallium/drivers/llvmpipe/lp_setup_context.h @@ -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 lp_rasterizer *rast; +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 index 0000000000..5cd4f354fd --- /dev/null +++ b/src/gallium/drivers/llvmpipe/lp_setup_vbuf.c @@ -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; +} diff --git a/src/gallium/drivers/llvmpipe/lp_state_derived.c b/src/gallium/drivers/llvmpipe/lp_state_derived.c index a18efcc0e0..ab827045ed 100644 --- a/src/gallium/drivers/llvmpipe/lp_state_derived.c +++ b/src/gallium/drivers/llvmpipe/lp_state_derived.c @@ -37,17 +37,6 @@  #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; +   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; -   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. +    * +    * 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); -      /* 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); -      /* -       * 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; +   lp_setup_set_vertex_info(llvmpipe->setup, vinfo_vbuf); -         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; -         } +/* +   llvmpipe->psize_slot = draw_find_vs_output(llvmpipe->draw, +                                              TGSI_SEMANTIC_PSIZE, 0); +*/ + +   /* 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]; + +      for (i = 0; i < lpfs->info.num_inputs; i++) { +         /* This can be precomputed, except for flatshade: +          */           switch (lpfs->info.input_semantic_name[i]) { +         case TGSI_SEMANTIC_FACE: +            inputs[i].interp = LP_INTERP_FACING; +            break;           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); +            inputs[i].interp = LP_INTERP_POSITION;              break; -           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; - -         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; - -         case TGSI_SEMANTIC_GENERIC: -         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); +            /* 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 diff --git a/src/gallium/drivers/llvmpipe/lp_state_fs.c b/src/gallium/drivers/llvmpipe/lp_state_fs.c index 7ed727dbbc..3ad58415e3 100644 --- a/src/gallium/drivers/llvmpipe/lp_state_fs.c +++ b/src/gallium/drivers/llvmpipe/lp_state_fs.c @@ -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);  } | 
