llvmpipe: hook up basic gs and multiple constant buffer support
authorKeith Whitwell <keithw@vmware.com>
Fri, 28 May 2010 15:54:35 +0000 (16:54 +0100)
committerKeith Whitwell <keithw@vmware.com>
Mon, 7 Jun 2010 15:39:02 +0000 (16:39 +0100)
src/gallium/drivers/llvmpipe/SConscript
src/gallium/drivers/llvmpipe/lp_context.c
src/gallium/drivers/llvmpipe/lp_context.h
src/gallium/drivers/llvmpipe/lp_state.h
src/gallium/drivers/llvmpipe/lp_state_derived.c
src/gallium/drivers/llvmpipe/lp_state_fs.c
src/gallium/drivers/llvmpipe/lp_state_gs.c [new file with mode: 0644]
src/gallium/drivers/llvmpipe/lp_texture.c

index 2c38dc42b09f05457edf5005c571d2e9a2cbacaa..a0646692e7b67256ab9125afbaaceecb999f296e 100644 (file)
@@ -54,6 +54,7 @@ llvmpipe = env.ConvenienceLibrary(
                'lp_state_clip.c',
                'lp_state_derived.c',
                'lp_state_fs.c',
+               'lp_state_gs.c',
                'lp_state_rasterizer.c',
                'lp_state_sampler.c',
                'lp_state_surface.c',
index 32b80d3a9f633576466a2686412c5bff1720eab2..9e88a6e09f4c54c30506a41fdec99dace5a9875c 100644 (file)
@@ -48,7 +48,7 @@
 static void llvmpipe_destroy( struct pipe_context *pipe )
 {
    struct llvmpipe_context *llvmpipe = llvmpipe_context( pipe );
-   uint i;
+   uint i, j;
 
    lp_print_counters();
 
@@ -72,8 +72,8 @@ static void llvmpipe_destroy( struct pipe_context *pipe )
    }
 
    for (i = 0; i < Elements(llvmpipe->constants); i++) {
-      if (llvmpipe->constants[i]) {
-         pipe_resource_reference(&llvmpipe->constants[i], NULL);
+      for (j = 0; j < Elements(llvmpipe->constants[i]); j++) {
+         pipe_resource_reference(&llvmpipe->constants[i][j], NULL);
       }
    }
 
@@ -112,6 +112,7 @@ llvmpipe_create_context( struct pipe_screen *screen, void *priv )
    llvmpipe_init_vertex_funcs(llvmpipe);
    llvmpipe_init_fs_funcs(llvmpipe);
    llvmpipe_init_vs_funcs(llvmpipe);
+   llvmpipe_init_gs_funcs(llvmpipe);
    llvmpipe_init_rasterizer_funcs(llvmpipe);
    llvmpipe_init_context_resource_funcs( &llvmpipe->pipe );
    llvmpipe_init_surface_functions(llvmpipe);
index 689265fa30de24057558e804a58c7376aefea7f4..cb04d4a4d54fa96e07051f37b7319b906f24405b 100644 (file)
@@ -60,13 +60,14 @@ struct llvmpipe_context {
    const struct pipe_rasterizer_state *rasterizer;
    struct lp_fragment_shader *fs;
    const struct lp_vertex_shader *vs;
+   const struct lp_geometry_shader *gs;
    const struct lp_velems_state *velems;
 
    /** Other rendering state */
    struct pipe_blend_color blend_color;
    struct pipe_stencil_ref stencil_ref;
    struct pipe_clip_state clip;
-   struct pipe_resource *constants[PIPE_SHADER_TYPES];
+   struct pipe_resource *constants[PIPE_SHADER_TYPES][PIPE_MAX_CONSTANT_BUFFERS];
    struct pipe_framebuffer_state framebuffer;
    struct pipe_poly_stipple poly_stipple;
    struct pipe_scissor_state scissor;
index c268f96647351c509c0ce2f3bb8b92a0e7121b4c..3f7a85b6827318b77b67d9eeee322cd73a4f252a 100644 (file)
@@ -53,6 +53,7 @@
 #define LP_NEW_VS            0x2000
 #define LP_NEW_QUERY         0x4000
 #define LP_NEW_BLEND_COLOR   0x8000
+#define LP_NEW_GS            0x10000
 
 
 struct vertex_info;
@@ -68,6 +69,11 @@ struct lp_vertex_shader
    struct draw_vertex_shader *draw_data;
 };
 
+/** Subclass of pipe_shader_state */
+struct lp_geometry_shader {
+   struct pipe_shader_state shader;
+   struct draw_geometry_shader *draw_data;
+};
 
 /** Vertex element state */
 struct lp_velems_state
@@ -108,6 +114,9 @@ llvmpipe_init_fs_funcs(struct llvmpipe_context *llvmpipe);
 void
 llvmpipe_init_vs_funcs(struct llvmpipe_context *llvmpipe);
 
+void
+llvmpipe_init_gs_funcs(struct llvmpipe_context *llvmpipe);
+
 void
 llvmpipe_init_rasterizer_funcs(struct llvmpipe_context *llvmpipe);
 
index 9e066f5c656f62700fe958a7dc394e68dcc368b2..d20a5218d41f70157db6a04b2ede8331c07993e6 100644 (file)
@@ -186,7 +186,7 @@ void llvmpipe_update_derived( struct llvmpipe_context *llvmpipe )
 
    if (llvmpipe->dirty & LP_NEW_CONSTANTS)
       lp_setup_set_fs_constants(llvmpipe->setup, 
-                                llvmpipe->constants[PIPE_SHADER_FRAGMENT]);
+                                llvmpipe->constants[PIPE_SHADER_FRAGMENT][0]);
 
    if (llvmpipe->dirty & LP_NEW_SAMPLER_VIEW)
       lp_setup_set_fragment_sampler_views(llvmpipe->setup, 
index 6896bedf1891999aba50f5f0f05f4d62a50a3189..2619e043fdf4a87c493362acf6868f27d3636fc2 100644 (file)
@@ -1078,18 +1078,18 @@ llvmpipe_set_constant_buffer(struct pipe_context *pipe,
    const void *data = constants ? llvmpipe_resource_data(constants) : NULL;
 
    assert(shader < PIPE_SHADER_TYPES);
-   assert(index == 0);
+   assert(index < PIPE_MAX_CONSTANT_BUFFERS);
 
-   if(llvmpipe->constants[shader] == constants)
+   if(llvmpipe->constants[shader][index] == constants)
       return;
 
    draw_flush(llvmpipe->draw);
 
    /* note: reference counting */
-   pipe_resource_reference(&llvmpipe->constants[shader], constants);
+   pipe_resource_reference(&llvmpipe->constants[shader][index], constants);
 
    if(shader == PIPE_SHADER_VERTEX) {
-      draw_set_mapped_constant_buffer(llvmpipe->draw, PIPE_SHADER_VERTEX, 0,
+      draw_set_mapped_constant_buffer(llvmpipe->draw, PIPE_SHADER_VERTEX, index,
                                       data, size);
    }
 
diff --git a/src/gallium/drivers/llvmpipe/lp_state_gs.c b/src/gallium/drivers/llvmpipe/lp_state_gs.c
new file mode 100644 (file)
index 0000000..e5eeb88
--- /dev/null
@@ -0,0 +1,113 @@
+/**************************************************************************
+ * 
+ * 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.
+ * 
+ **************************************************************************/
+
+#include "lp_context.h"
+#include "lp_state.h"
+#include "lp_texture.h"
+
+#include "pipe/p_defines.h"
+#include "util/u_memory.h"
+#include "util/u_inlines.h"
+#include "draw/draw_context.h"
+#include "draw/draw_vs.h"
+#include "tgsi/tgsi_dump.h"
+#include "tgsi/tgsi_scan.h"
+#include "tgsi/tgsi_parse.h"
+
+
+static void *
+llvmpipe_create_gs_state(struct pipe_context *pipe,
+                         const struct pipe_shader_state *templ)
+{
+   struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
+   struct lp_geometry_shader *state;
+
+   state = CALLOC_STRUCT(lp_geometry_shader);
+   if (state == NULL )
+      goto fail;
+
+   /* debug */
+   if (0)
+      tgsi_dump(templ->tokens, 0);
+
+   /* copy shader tokens, the ones passed in will go away.
+    */
+   state->shader.tokens = tgsi_dup_tokens(templ->tokens);
+   if (state->shader.tokens == NULL)
+      goto fail;
+
+   state->draw_data = draw_create_geometry_shader(llvmpipe->draw, templ);
+   if (state->draw_data == NULL)
+      goto fail;
+
+   return state;
+
+fail:
+   if (state) {
+      FREE( (void *)state->shader.tokens );
+      FREE( state->draw_data );
+      FREE( state );
+   }
+   return NULL;
+}
+
+
+static void
+llvmpipe_bind_gs_state(struct pipe_context *pipe, void *gs)
+{
+   struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
+
+   llvmpipe->gs = (struct lp_geometry_shader *)gs;
+
+   draw_bind_geometry_shader(llvmpipe->draw,
+                             (llvmpipe->gs ? llvmpipe->gs->draw_data : NULL));
+
+   llvmpipe->dirty |= LP_NEW_GS;
+}
+
+
+static void
+llvmpipe_delete_gs_state(struct pipe_context *pipe, void *gs)
+{
+   struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
+
+   struct lp_geometry_shader *state =
+      (struct lp_geometry_shader *)gs;
+
+   draw_delete_geometry_shader(llvmpipe->draw,
+                               (state) ? state->draw_data : 0);
+   FREE(state);
+}
+
+
+void
+llvmpipe_init_gs_funcs(struct llvmpipe_context *llvmpipe)
+{
+   llvmpipe->pipe.create_gs_state = llvmpipe_create_gs_state;
+   llvmpipe->pipe.bind_gs_state   = llvmpipe_bind_gs_state;
+   llvmpipe->pipe.delete_gs_state = llvmpipe_delete_gs_state;
+}
index d86056ca34c6a235e37344cbdd153478db9fa9b9..0d526ead89d229abb81ca70df4c47da139d98da1 100644 (file)
@@ -219,7 +219,7 @@ llvmpipe_resource_create(struct pipe_screen *_screen,
    pipe_reference_init(&lpr->base.reference, 1);
    lpr->base.screen = &screen->base;
 
-   assert(lpr->base.bind);
+   /* assert(lpr->base.bind); */
 
    if (resource_is_texture(&lpr->base)) {
       if (lpr->base.bind & PIPE_BIND_DISPLAY_TARGET) {