summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/gallium/drivers/llvmpipe/Makefile2
-rw-r--r--src/gallium/drivers/llvmpipe/SConscript2
-rw-r--r--src/gallium/drivers/llvmpipe/lp_context.c18
-rw-r--r--src/gallium/drivers/llvmpipe/lp_context.h15
-rw-r--r--src/gallium/drivers/llvmpipe/lp_draw_arrays.c2
-rw-r--r--src/gallium/drivers/llvmpipe/lp_prim_vbuf.c559
-rw-r--r--src/gallium/drivers/llvmpipe/lp_prim_vbuf.h38
-rw-r--r--src/gallium/drivers/llvmpipe/lp_setup.c111
-rw-r--r--src/gallium/drivers/llvmpipe/lp_setup.h34
-rw-r--r--src/gallium/drivers/llvmpipe/lp_setup_context.h29
-rw-r--r--src/gallium/drivers/llvmpipe/lp_setup_vbuf.c520
-rw-r--r--src/gallium/drivers/llvmpipe/lp_state_derived.c223
-rw-r--r--src/gallium/drivers/llvmpipe/lp_state_fs.c3
13 files changed, 698 insertions, 858 deletions
diff --git a/src/gallium/drivers/llvmpipe/Makefile b/src/gallium/drivers/llvmpipe/Makefile
index 345326e33d7..6ec97046e15 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 f0b71ef3eee..ae4303bd24f 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 06aa0325403..0457ccc8a94 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 17c6939ff5b..b796148457e 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 b879b5e755e..91fcbc01c6d 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 925e6f8b3bd..00000000000
--- 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 0676e2f42ac..00000000000
--- 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 e361e5df63a..e2b21aed473 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 5c606e86afc..a6120fcbe40 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 f6604a8034a..d2278a46e66 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 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 00000000000..5cd4f354fd6
--- /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 a18efcc0e0f..ab827045ed6 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;
-
- 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
diff --git a/src/gallium/drivers/llvmpipe/lp_state_fs.c b/src/gallium/drivers/llvmpipe/lp_state_fs.c
index 7ed727dbbce..3ad58415e39 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);
}