llvmpipe: Eliminate non-LLVM fs execution paths.
authorJosé Fonseca <jfonseca@vmware.com>
Fri, 14 Aug 2009 09:27:32 +0000 (10:27 +0100)
committerJosé Fonseca <jfonseca@vmware.com>
Sat, 29 Aug 2009 08:21:32 +0000 (09:21 +0100)
src/gallium/drivers/llvmpipe/Makefile
src/gallium/drivers/llvmpipe/SConscript
src/gallium/drivers/llvmpipe/lp_context.c
src/gallium/drivers/llvmpipe/lp_context.h
src/gallium/drivers/llvmpipe/lp_fs.h [deleted file]
src/gallium/drivers/llvmpipe/lp_fs_exec.c [deleted file]
src/gallium/drivers/llvmpipe/lp_fs_llvm.c [deleted file]
src/gallium/drivers/llvmpipe/lp_fs_sse.c [deleted file]
src/gallium/drivers/llvmpipe/lp_quad_fs.c
src/gallium/drivers/llvmpipe/lp_state.h
src/gallium/drivers/llvmpipe/lp_state_fs.c

index 1b6cd5ed85d531a291ec78035c78f7c25bd3464e..236062a5f3e85e565e2f77be8806f911224388aa 100644 (file)
@@ -4,9 +4,6 @@ include $(TOP)/configs/current
 LIBNAME = llvmpipe
 
 C_SOURCES = \
-       lp_fs_exec.c \
-       lp_fs_sse.c \
-       lp_fs_llvm.c \
        lp_bld_arit.c \
        lp_bld_pack.c \
        lp_bld_unpack.c \
index 705a8bdfd44b6269dcc6475b34b074f73d7457bb..154964bf7acfee4b7ded9e87d7cefa63977381c1 100644 (file)
@@ -7,9 +7,6 @@ env.ParseConfig('llvm-config --cppflags')
 llvmpipe = env.ConvenienceLibrary(
        target = 'llvmpipe',
        source = [
-               'lp_fs_exec.c',
-               'lp_fs_sse.c',
-               'lp_fs_llvm.c',
                'lp_bld_arit.c',
                'lp_bld_blend_aos.c',
                'lp_bld_blend_soa.c',
index a30db444d4a87d9f742994dbf7c36a8cc9b881b1..66d0cf7759227aa32bf551d4de2b6bf245b43689 100644 (file)
@@ -148,14 +148,6 @@ llvmpipe_create( struct pipe_screen *screen )
 
    util_init_math();
 
-#ifdef PIPE_ARCH_X86
-   llvmpipe->use_sse = !debug_get_bool_option( "GALLIUM_NOSSE", FALSE );
-#else
-   llvmpipe->use_sse = FALSE;
-#endif
-
-   llvmpipe->dump_fs = debug_get_bool_option( "GALLIUM_DUMP_FS", FALSE );
-
    llvmpipe->pipe.winsys = screen->winsys;
    llvmpipe->pipe.screen = screen;
    llvmpipe->pipe.destroy = llvmpipe_destroy;
index 7ac83c1e7c154f4b0c53a827645d9f9ba33088fe..6cda5e602f18cc69656b6552aade55a6d25d0aa2 100644 (file)
@@ -57,7 +57,7 @@ struct llvmpipe_context {
    const struct pipe_sampler_state *sampler[PIPE_MAX_SAMPLERS];
    const struct pipe_depth_stencil_alpha_state *depth_stencil;
    const struct pipe_rasterizer_state *rasterizer;
-   const struct lp_fragment_shader *fs;
+   struct lp_fragment_shader *fs;
    const struct lp_vertex_shader *vs;
 
    /** Other rendering state */
@@ -145,8 +145,6 @@ struct llvmpipe_context {
    unsigned tex_timestamp;
    struct llvmpipe_tex_tile_cache *tex_cache[PIPE_MAX_SAMPLERS];
 
-   unsigned use_sse : 1;
-   unsigned dump_fs : 1;
    unsigned no_rast : 1;
 };
 
diff --git a/src/gallium/drivers/llvmpipe/lp_fs.h b/src/gallium/drivers/llvmpipe/lp_fs.h
deleted file mode 100644 (file)
index 505e211..0000000
+++ /dev/null
@@ -1,54 +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.
- * 
- **************************************************************************/
-
-/* Authors:  Keith Whitwell <keith@tungstengraphics.com>
- */
-
-#ifndef LP_FS_H
-#define LP_FS_H
-
-struct lp_fragment_shader *
-llvmpipe_create_fs_exec(struct llvmpipe_context *llvmpipe,
-                      const struct pipe_shader_state *templ);
-
-struct lp_fragment_shader *
-llvmpipe_create_fs_sse(struct llvmpipe_context *llvmpipe,
-                      const struct pipe_shader_state *templ);
-
-struct lp_fragment_shader *
-llvmpipe_create_fs_llvm(struct llvmpipe_context *llvmpipe,
-                       const struct pipe_shader_state *templ);
-
-struct tgsi_interp_coef;
-struct tgsi_exec_vector;
-
-void lp_setup_pos_vector(const struct tgsi_interp_coef *coef,
-                        float x, float y,
-                        struct tgsi_exec_vector *quadpos);
-
-
-#endif
diff --git a/src/gallium/drivers/llvmpipe/lp_fs_exec.c b/src/gallium/drivers/llvmpipe/lp_fs_exec.c
deleted file mode 100644 (file)
index ea85697..0000000
+++ /dev/null
@@ -1,162 +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.
- * 
- **************************************************************************/
-
-/**
- * Execute fragment shader using the TGSI interpreter.
- */
-
-#include "lp_context.h"
-#include "lp_state.h"
-#include "lp_fs.h"
-#include "lp_quad.h"
-
-#include "pipe/p_state.h"
-#include "pipe/p_defines.h"
-#include "util/u_memory.h"
-#include "tgsi/tgsi_exec.h"
-#include "tgsi/tgsi_parse.h"
-
-
-/**
- * Subclass of lp_fragment_shader
- */
-struct lp_exec_fragment_shader
-{
-   struct lp_fragment_shader base;
-   /* No other members for now */
-};
-
-
-/** cast wrapper */
-static INLINE struct lp_exec_fragment_shader *
-lp_exec_fragment_shader(const struct lp_fragment_shader *base)
-{
-   return (struct lp_exec_fragment_shader *) base;
-}
-
-
-/**
- * Compute quad X,Y,Z,W for the four fragments in a quad.
- *
- * This should really be part of the compiled shader.
- */
-void
-lp_setup_pos_vector(const struct tgsi_interp_coef *coef,
-                   float x, float y,
-                   struct tgsi_exec_vector *quadpos)
-{
-   uint chan;
-   /* do X */
-   quadpos->xyzw[0].f[0] = x;
-   quadpos->xyzw[0].f[1] = x + 1;
-   quadpos->xyzw[0].f[2] = x;
-   quadpos->xyzw[0].f[3] = x + 1;
-
-   /* do Y */
-   quadpos->xyzw[1].f[0] = y;
-   quadpos->xyzw[1].f[1] = y;
-   quadpos->xyzw[1].f[2] = y + 1;
-   quadpos->xyzw[1].f[3] = y + 1;
-
-   /* do Z and W for all fragments in the quad */
-   for (chan = 2; chan < 4; chan++) {
-      const float dadx = coef->dadx[chan];
-      const float dady = coef->dady[chan];
-      const float a0 = coef->a0[chan] + dadx * x + dady * y;
-      quadpos->xyzw[chan].f[0] = a0;
-      quadpos->xyzw[chan].f[1] = a0 + dadx;
-      quadpos->xyzw[chan].f[2] = a0 + dady;
-      quadpos->xyzw[chan].f[3] = a0 + dadx + dady;
-   }
-}
-
-
-static void
-exec_prepare( const struct lp_fragment_shader *base,
-             struct tgsi_exec_machine *machine,
-             struct tgsi_sampler **samplers )
-{
-   /*
-    * Bind tokens/shader to the interpreter's machine state.
-    * Avoid redundant binding.
-    */
-   if (machine->Tokens != base->shader.tokens) {
-      tgsi_exec_machine_bind_shader( machine,
-                                     base->shader.tokens,
-                                     PIPE_MAX_SAMPLERS,
-                                     samplers );
-   }
-}
-
-
-/* TODO: hide the machine struct in here somewhere, remove from this
- * interface:
- */
-static unsigned 
-exec_run( const struct lp_fragment_shader *base,
-         struct tgsi_exec_machine *machine,
-         struct quad_header *quad )
-{
-   /* Compute X, Y, Z, W vals for this quad */
-   lp_setup_pos_vector(quad->posCoef, 
-                      (float)quad->input.x0, (float)quad->input.y0, 
-                      &machine->QuadPos);
-   
-   return tgsi_exec_machine_run( machine );
-}
-
-
-static void 
-exec_delete( struct lp_fragment_shader *base )
-{
-   FREE((void *) base->shader.tokens);
-   FREE(base);
-}
-
-
-struct lp_fragment_shader *
-llvmpipe_create_fs_exec(struct llvmpipe_context *llvmpipe,
-                       const struct pipe_shader_state *templ)
-{
-   struct lp_exec_fragment_shader *shader;
-
-   /* Decide whether we'll be codegenerating this shader and if so do
-    * that now.
-    */
-
-   shader = CALLOC_STRUCT(lp_exec_fragment_shader);
-   if (!shader)
-      return NULL;
-
-   /* we need to keep a local copy of the tokens */
-   shader->base.shader.tokens = tgsi_dup_tokens(templ->tokens);
-   shader->base.prepare = exec_prepare;
-   shader->base.run = exec_run;
-   shader->base.delete = exec_delete;
-
-   return &shader->base;
-}
diff --git a/src/gallium/drivers/llvmpipe/lp_fs_llvm.c b/src/gallium/drivers/llvmpipe/lp_fs_llvm.c
deleted file mode 100644 (file)
index ef1c8c3..0000000
+++ /dev/null
@@ -1,360 +0,0 @@
-/**************************************************************************
- * 
- * Copyright 2009 VMware, Inc.
- * 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.
- * 
- **************************************************************************/
-
-/**
- * Execute fragment shader using LLVM code generation.
- */
-
-
-#include "pipe/p_state.h"
-#include "pipe/p_defines.h"
-#include "util/u_memory.h"
-#include "tgsi/tgsi_parse.h"
-#include "tgsi/tgsi_exec.h"
-#include "tgsi/tgsi_dump.h"
-#include "lp_bld_type.h"
-#include "lp_bld_tgsi.h"
-#include "lp_screen.h"
-#include "lp_context.h"
-#include "lp_state.h"
-#include "lp_fs.h"
-#include "lp_quad.h"
-
-
-typedef void
-(*lp_shader_fs_func)(void *pos,
-                     void *a0,
-                     void *dadx,
-                     void *dady,
-                     void *consts,
-                     void *outputs,
-                     struct tgsi_sampler **samplers);
-
-
-/**
- * Subclass of lp_fragment_shader
- */
-struct lp_llvm_fragment_shader
-{
-   struct lp_fragment_shader base;
-
-   struct llvmpipe_screen *screen;
-
-   LLVMValueRef function;
-
-   lp_shader_fs_func jit_function;
-
-   union tgsi_exec_channel ALIGN16_ATTRIB pos[NUM_CHANNELS];
-   union tgsi_exec_channel ALIGN16_ATTRIB a0[PIPE_MAX_SHADER_INPUTS][NUM_CHANNELS];
-   union tgsi_exec_channel ALIGN16_ATTRIB dadx[PIPE_MAX_SHADER_INPUTS][NUM_CHANNELS];
-   union tgsi_exec_channel ALIGN16_ATTRIB dady[PIPE_MAX_SHADER_INPUTS][NUM_CHANNELS];
-
-   uint32_t magic;
-};
-
-
-/** cast wrapper */
-static INLINE struct lp_llvm_fragment_shader *
-lp_llvm_fragment_shader(const struct lp_fragment_shader *base)
-{
-   return (struct lp_llvm_fragment_shader *) base;
-}
-
-
-static void
-shader_generate(struct llvmpipe_screen *screen,
-                struct lp_llvm_fragment_shader *shader)
-{
-   const struct tgsi_token *tokens = shader->base.shader.tokens;
-   union lp_type type;
-   LLVMTypeRef elem_type;
-   LLVMTypeRef vec_type;
-   LLVMTypeRef arg_types[7];
-   LLVMTypeRef func_type;
-   LLVMValueRef pos_ptr;
-   LLVMValueRef a0_ptr;
-   LLVMValueRef dadx_ptr;
-   LLVMValueRef dady_ptr;
-   LLVMValueRef consts_ptr;
-   LLVMValueRef outputs_ptr;
-   LLVMValueRef samplers_ptr;
-   LLVMBasicBlockRef block;
-   LLVMBuilderRef builder;
-   LLVMValueRef pos[NUM_CHANNELS];
-   LLVMValueRef outputs[PIPE_MAX_SHADER_OUTPUTS][NUM_CHANNELS];
-   char name[32];
-   unsigned i, j;
-
-   type.value = 0;
-   type.floating = TRUE;
-   type.sign = TRUE;
-   type.norm = FALSE;
-   type.width = 32;
-   type.length = 4;
-
-   elem_type = lp_build_elem_type(type);
-   vec_type = lp_build_vec_type(type);
-
-   arg_types[0] = LLVMPointerType(vec_type, 0);        /* pos */
-   arg_types[1] = LLVMPointerType(vec_type, 0);        /* a0 */
-   arg_types[2] = LLVMPointerType(vec_type, 0);        /* dadx */
-   arg_types[3] = LLVMPointerType(vec_type, 0);        /* dady */
-   arg_types[4] = LLVMPointerType(elem_type, 0);       /* consts */
-   arg_types[5] = LLVMPointerType(vec_type, 0);        /* outputs */
-   arg_types[6] = LLVMPointerType(LLVMInt8Type(), 0);  /* samplers */
-
-   func_type = LLVMFunctionType(LLVMVoidType(), arg_types, Elements(arg_types), 0);
-
-   shader->function = LLVMAddFunction(screen->module, "shader", func_type);
-   LLVMSetFunctionCallConv(shader->function, LLVMCCallConv);
-
-   pos_ptr = LLVMGetParam(shader->function, 0);
-   a0_ptr = LLVMGetParam(shader->function, 1);
-   dadx_ptr = LLVMGetParam(shader->function, 2);
-   dady_ptr = LLVMGetParam(shader->function, 3);
-   consts_ptr = LLVMGetParam(shader->function, 4);
-   outputs_ptr = LLVMGetParam(shader->function, 5);
-   samplers_ptr = LLVMGetParam(shader->function, 6);
-
-   LLVMSetValueName(pos_ptr, "pos");
-   LLVMSetValueName(a0_ptr, "a0");
-   LLVMSetValueName(dadx_ptr, "dadx");
-   LLVMSetValueName(dady_ptr, "dady");
-   LLVMSetValueName(consts_ptr, "consts");
-   LLVMSetValueName(outputs_ptr, "outputs");
-   LLVMSetValueName(samplers_ptr, "samplers");
-
-   block = LLVMAppendBasicBlock(shader->function, "entry");
-   builder = LLVMCreateBuilder();
-   LLVMPositionBuilderAtEnd(builder, block);
-
-   for(j = 0; j < NUM_CHANNELS; ++j) {
-      LLVMValueRef index = LLVMConstInt(LLVMInt32Type(), j, 0);
-      util_snprintf(name, sizeof name, "pos.%c", "xyzw"[j]);
-      pos[j] = LLVMBuildLoad(builder, LLVMBuildGEP(builder, pos_ptr, &index, 1, ""), name);
-   }
-
-   memset(outputs, 0, sizeof outputs);
-
-   lp_build_tgsi_soa(builder, tokens, type,
-                     pos, a0_ptr, dadx_ptr, dady_ptr,
-                     consts_ptr, outputs, samplers_ptr);
-
-   for(i = 0; i < PIPE_MAX_SHADER_OUTPUTS; ++i) {
-      for(j = 0; j < NUM_CHANNELS; ++j) {
-         if(outputs[i][j]) {
-            LLVMValueRef index = LLVMConstInt(LLVMInt32Type(), i*NUM_CHANNELS + j, 0);
-            util_snprintf(name, sizeof name, "output%u.%c", i, "xyzw"[j]);
-            LLVMBuildStore(builder, outputs[i][j], LLVMBuildGEP(builder, outputs_ptr, &index, 1, name));
-         }
-      }
-   }
-
-   LLVMBuildRetVoid(builder);;
-
-   LLVMDisposeBuilder(builder);
-}
-
-
-
-static void
-fs_llvm_prepare( const struct lp_fragment_shader *base,
-               struct tgsi_exec_machine *machine,
-               struct tgsi_sampler **samplers )
-{
-   /*
-    * Bind tokens/shader to the interpreter's machine state.
-    * Avoid redundant binding.
-    */
-   if (machine->Tokens != base->shader.tokens) {
-      tgsi_exec_machine_bind_shader( machine,
-                                     base->shader.tokens,
-                                     PIPE_MAX_SAMPLERS,
-                                     samplers );
-   }
-}
-
-
-
-static void
-setup_pos_vector(struct lp_llvm_fragment_shader *shader,
-                 const struct tgsi_interp_coef *coef,
-                 float x, float y)
-{
-   uint chan;
-
-   /* do X */
-   shader->pos[0].f[0] = x;
-   shader->pos[0].f[1] = x + 1;
-   shader->pos[0].f[2] = x;
-   shader->pos[0].f[3] = x + 1;
-
-   /* do Y */
-   shader->pos[1].f[0] = y;
-   shader->pos[1].f[1] = y;
-   shader->pos[1].f[2] = y + 1;
-   shader->pos[1].f[3] = y + 1;
-
-   /* do Z and W for all fragments in the quad */
-   for (chan = 2; chan < 4; chan++) {
-      const float dadx = coef->dadx[chan];
-      const float dady = coef->dady[chan];
-      const float a0 = coef->a0[chan] + dadx * x + dady * y;
-      shader->pos[chan].f[0] = a0;
-      shader->pos[chan].f[1] = a0 + dadx;
-      shader->pos[chan].f[2] = a0 + dady;
-      shader->pos[chan].f[3] = a0 + dadx + dady;
-   }
-}
-
-
-static void
-setup_coef_vector(struct lp_llvm_fragment_shader *shader,
-                  const struct tgsi_interp_coef *coef)
-{
-   unsigned attrib, chan, i;
-
-   for (attrib = 0; attrib < PIPE_MAX_SHADER_INPUTS; ++attrib) {
-      for (chan = 0; chan < NUM_CHANNELS; ++chan) {
-         for( i = 0; i < QUAD_SIZE; ++i ) {
-            shader->a0[attrib][chan].f[i] = coef[attrib].a0[chan];
-            shader->dadx[attrib][chan].f[i] = coef[attrib].dadx[chan];
-            shader->dady[attrib][chan].f[i] = coef[attrib].dady[chan];
-         }
-      }
-   }
-}
-
-
-/* TODO: codegenerate the whole run function, skip this wrapper.
- * TODO: break dependency on tgsi_exec_machine struct
- * TODO: push Position calculation into the generated shader
- * TODO: process >1 quad at a time
- */
-static unsigned 
-fs_llvm_run( const struct lp_fragment_shader *base,
-           struct tgsi_exec_machine *machine,
-           struct quad_header *quad )
-{
-   struct lp_llvm_fragment_shader *shader = lp_llvm_fragment_shader(base);
-   unsigned mask;
-
-   /* Compute X, Y, Z, W vals for this quad */
-   setup_pos_vector(shader,
-                    quad->posCoef,
-                   (float)quad->input.x0, (float)quad->input.y0);
-
-   setup_coef_vector(shader,
-                     quad->coef);
-
-   /* init kill mask */
-   tgsi_set_kill_mask(machine, 0x0);
-   tgsi_set_exec_mask(machine, 1, 1, 1, 1);
-
-   memset(machine->Outputs, 0, sizeof machine->Outputs);
-
-   shader->jit_function( shader->pos,
-                         shader->a0, shader->dadx, shader->dady,
-                         machine->Consts,
-                         machine->Outputs,
-                         machine->Samplers);
-
-   /* FIXME */
-   mask = ~0;
-
-   return mask;
-}
-
-
-static void 
-fs_llvm_delete( struct lp_fragment_shader *base )
-{
-   struct lp_llvm_fragment_shader *shader = lp_llvm_fragment_shader(base);
-   struct llvmpipe_screen *screen = shader->screen;
-
-   if(shader->function) {
-      if(shader->jit_function)
-         LLVMFreeMachineCodeForFunction(screen->engine, shader->function);
-      LLVMDeleteFunction(shader->function);
-   }
-
-   FREE((void *) shader->base.shader.tokens);
-   FREE(shader);
-}
-
-
-struct lp_fragment_shader *
-llvmpipe_create_fs_llvm(struct llvmpipe_context *llvmpipe,
-                        const struct pipe_shader_state *templ)
-{
-   struct llvmpipe_screen *screen = llvmpipe_screen(llvmpipe->pipe.screen);
-   struct lp_llvm_fragment_shader *shader;
-   LLVMValueRef fetch_texel;
-
-   shader = CALLOC_STRUCT(lp_llvm_fragment_shader);
-   if (!shader)
-      return NULL;
-
-   /* we need to keep a local copy of the tokens */
-   shader->base.shader.tokens = tgsi_dup_tokens(templ->tokens);
-   shader->base.prepare = fs_llvm_prepare;
-   shader->base.run = fs_llvm_run;
-   shader->base.delete = fs_llvm_delete;
-
-   shader->screen = screen;
-
-   tgsi_dump(templ->tokens, 0);
-
-   shader_generate(screen, shader);
-
-   LLVMRunFunctionPassManager(screen->pass, shader->function);
-
-#if 1
-   LLVMDumpValue(shader->function);
-   debug_printf("\n");
-#endif
-
-   if(LLVMVerifyFunction(shader->function, LLVMPrintMessageAction)) {
-      LLVMDumpValue(shader->function);
-      abort();
-   }
-
-   fetch_texel = LLVMGetNamedFunction(screen->module, "fetch_texel");
-   if(fetch_texel) {
-      static boolean first_time = TRUE;
-      if(first_time) {
-         LLVMAddGlobalMapping(screen->engine, fetch_texel, lp_build_tgsi_fetch_texel_soa);
-         first_time = FALSE;
-      }
-   }
-
-   shader->jit_function = (lp_shader_fs_func)LLVMGetPointerToGlobal(screen->engine, shader->function);
-
-   return &shader->base;
-}
-
diff --git a/src/gallium/drivers/llvmpipe/lp_fs_sse.c b/src/gallium/drivers/llvmpipe/lp_fs_sse.c
deleted file mode 100644 (file)
index 61c40dd..0000000
+++ /dev/null
@@ -1,169 +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.
- * 
- **************************************************************************/
-
-/**
- * Execute fragment shader using runtime SSE code generation.
- */
-
-#include "lp_context.h"
-#include "lp_state.h"
-#include "lp_fs.h"
-#include "lp_quad.h"
-
-#include "pipe/p_state.h"
-#include "pipe/p_defines.h"
-#include "util/u_memory.h"
-#include "tgsi/tgsi_exec.h"
-#include "tgsi/tgsi_sse2.h"
-
-
-#if defined(PIPE_ARCH_X86)
-
-#include "rtasm/rtasm_x86sse.h"
-
-
-
-/**
- * Subclass of lp_fragment_shader
- */
-struct lp_sse_fragment_shader
-{
-   struct lp_fragment_shader base;
-   struct x86_function sse2_program;
-   tgsi_sse2_fs_function func;
-   float immediates[TGSI_EXEC_NUM_IMMEDIATES][4];
-};
-
-
-/** cast wrapper */
-static INLINE struct lp_sse_fragment_shader *
-lp_sse_fragment_shader(const struct lp_fragment_shader *base)
-{
-   return (struct lp_sse_fragment_shader *) base;
-}
-
-
-static void
-fs_sse_prepare( const struct lp_fragment_shader *base,
-               struct tgsi_exec_machine *machine,
-               struct tgsi_sampler **samplers )
-{
-   machine->Samplers = samplers;
-}
-
-
-/* TODO: codegenerate the whole run function, skip this wrapper.
- * TODO: break dependency on tgsi_exec_machine struct
- * TODO: push Position calculation into the generated shader
- * TODO: process >1 quad at a time
- */
-static unsigned 
-fs_sse_run( const struct lp_fragment_shader *base,
-           struct tgsi_exec_machine *machine,
-           struct quad_header *quad )
-{
-   struct lp_sse_fragment_shader *shader = lp_sse_fragment_shader(base);
-
-   /* Compute X, Y, Z, W vals for this quad -- place in temp[0] for now */
-   lp_setup_pos_vector(quad->posCoef, 
-                      (float)quad->input.x0, (float)quad->input.y0, 
-                      machine->Temps);
-
-   /* init kill mask */
-   tgsi_set_kill_mask(machine, 0x0);
-   tgsi_set_exec_mask(machine, 1, 1, 1, 1);
-
-   shader->func( machine,
-                machine->Consts,
-                 (const float (*)[4])shader->immediates,
-                machine->InterpCoefs
-                //      , &machine->QuadPos
-      );
-
-   return ~(machine->Temps[TGSI_EXEC_TEMP_KILMASK_I].xyzw[TGSI_EXEC_TEMP_KILMASK_C].u[0]);
-}
-
-
-static void 
-fs_sse_delete( struct lp_fragment_shader *base )
-{
-   struct lp_sse_fragment_shader *shader = lp_sse_fragment_shader(base);
-
-   x86_release_func( &shader->sse2_program );
-   FREE(shader);
-}
-
-
-struct lp_fragment_shader *
-llvmpipe_create_fs_sse(struct llvmpipe_context *llvmpipe,
-                      const struct pipe_shader_state *templ)
-{
-   struct lp_sse_fragment_shader *shader;
-
-   if (!llvmpipe->use_sse)
-      return NULL;
-
-   shader = CALLOC_STRUCT(lp_sse_fragment_shader);
-   if (!shader)
-      return NULL;
-
-   x86_init_func( &shader->sse2_program );
-   
-   if (!tgsi_emit_sse2( templ->tokens, &shader->sse2_program,
-                        shader->immediates, FALSE )) {
-      FREE(shader);
-      return NULL;
-   }
-
-   shader->func = (tgsi_sse2_fs_function) x86_get_func( &shader->sse2_program );
-   if (!shader->func) {
-      x86_release_func( &shader->sse2_program );
-      FREE(shader);
-      return NULL;
-   }
-
-   shader->base.shader.tokens = NULL; /* don't hold reference to templ->tokens */
-   shader->base.prepare = fs_sse_prepare;
-   shader->base.run = fs_sse_run;
-   shader->base.delete = fs_sse_delete;
-
-   return &shader->base;
-}
-
-
-#else
-
-/* Maybe put this variant in the header file.
- */
-struct lp_fragment_shader *
-llvmpipe_create_fs_sse(struct llvmpipe_context *llvmpipe,
-                      const struct pipe_shader_state *templ)
-{
-   return NULL;
-}
-
-#endif
index 1da50e493b5535d524055da59cbdf663f0736b13..338a6be80c49de9c5c86980f19a8f7eb626c046e 100644 (file)
@@ -1,8 +1,8 @@
 /**************************************************************************
  * 
+ * Copyright 2008-2009 VMware, Inc.
  * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
  * All Rights Reserved.
- * Copyright 2008 VMware, Inc.  All rights reserved.
  * 
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the
@@ -65,6 +65,114 @@ quad_shade_stage(struct quad_stage *qs)
 }
 
 
+static void
+shader_prepare( const struct lp_fragment_shader *shader,
+                struct tgsi_exec_machine *machine,
+                struct tgsi_sampler **samplers )
+{
+   /*
+    * Bind tokens/shader to the interpreter's machine state.
+    * Avoid redundant binding.
+    */
+   if (machine->Tokens != shader->base.tokens) {
+      tgsi_exec_machine_bind_shader( machine,
+                                     shader->base.tokens,
+                                     PIPE_MAX_SAMPLERS,
+                                     samplers );
+   }
+}
+
+
+
+static void
+setup_pos_vector(struct lp_fragment_shader *shader,
+                 const struct tgsi_interp_coef *coef,
+                 float x, float y)
+{
+   uint chan;
+
+   /* do X */
+   shader->pos[0].f[0] = x;
+   shader->pos[0].f[1] = x + 1;
+   shader->pos[0].f[2] = x;
+   shader->pos[0].f[3] = x + 1;
+
+   /* do Y */
+   shader->pos[1].f[0] = y;
+   shader->pos[1].f[1] = y;
+   shader->pos[1].f[2] = y + 1;
+   shader->pos[1].f[3] = y + 1;
+
+   /* do Z and W for all fragments in the quad */
+   for (chan = 2; chan < 4; chan++) {
+      const float dadx = coef->dadx[chan];
+      const float dady = coef->dady[chan];
+      const float a0 = coef->a0[chan] + dadx * x + dady * y;
+      shader->pos[chan].f[0] = a0;
+      shader->pos[chan].f[1] = a0 + dadx;
+      shader->pos[chan].f[2] = a0 + dady;
+      shader->pos[chan].f[3] = a0 + dadx + dady;
+   }
+}
+
+
+static void
+setup_coef_vector(struct lp_fragment_shader *shader,
+                  const struct tgsi_interp_coef *coef)
+{
+   unsigned attrib, chan, i;
+
+   for (attrib = 0; attrib < PIPE_MAX_SHADER_INPUTS; ++attrib) {
+      for (chan = 0; chan < NUM_CHANNELS; ++chan) {
+         for( i = 0; i < QUAD_SIZE; ++i ) {
+            shader->a0[attrib][chan].f[i] = coef[attrib].a0[chan];
+            shader->dadx[attrib][chan].f[i] = coef[attrib].dadx[chan];
+            shader->dady[attrib][chan].f[i] = coef[attrib].dady[chan];
+         }
+      }
+   }
+}
+
+
+/* TODO: codegenerate the whole run function, skip this wrapper.
+ * TODO: break dependency on tgsi_exec_machine struct
+ * TODO: push Position calculation into the generated shader
+ * TODO: process >1 quad at a time
+ */
+static unsigned
+shader_run( struct lp_fragment_shader *shader,
+            struct tgsi_exec_machine *machine,
+            struct quad_header *quad )
+{
+   unsigned mask;
+
+   /* Compute X, Y, Z, W vals for this quad */
+   setup_pos_vector(shader,
+                    quad->posCoef,
+                    (float)quad->input.x0, (float)quad->input.y0);
+
+   setup_coef_vector(shader,
+                     quad->coef);
+
+   /* init kill mask */
+   tgsi_set_kill_mask(machine, 0x0);
+   tgsi_set_exec_mask(machine, 1, 1, 1, 1);
+
+   memset(machine->Outputs, 0, sizeof machine->Outputs);
+
+   shader->jit_function( shader->pos,
+                         shader->a0, shader->dadx, shader->dady,
+                         machine->Consts,
+                         machine->Outputs,
+                         machine->Samplers);
+
+   /* FIXME */
+   mask = ~0;
+
+   return mask;
+}
+
+
 /**
  * Execute fragment shader for the four fragments in the quad.
  */
@@ -77,7 +185,7 @@ shade_quad(struct quad_stage *qs, struct quad_header *quad)
    boolean z_written;
 
    /* run shader */
-   quad->inout.mask &= llvmpipe->fs->run( llvmpipe->fs, machine, quad );
+   quad->inout.mask &= shader_run( llvmpipe->fs, machine, quad );
    if (quad->inout.mask == 0)
       return FALSE;
 
@@ -177,10 +285,9 @@ shade_begin(struct quad_stage *qs)
    struct quad_shade_stage *qss = quad_shade_stage(qs);
    struct llvmpipe_context *llvmpipe = qs->llvmpipe;
 
-   llvmpipe->fs->prepare( llvmpipe->fs, 
-                         qss->machine,
-                         (struct tgsi_sampler **)
-                             llvmpipe->tgsi.frag_samplers_list );
+   shader_prepare( llvmpipe->fs,
+                   qss->machine,
+                   (struct tgsi_sampler **)llvmpipe->tgsi.frag_samplers_list );
 
    qs->next->begin(qs->next);
 }
index 6b757a6ba71f51049bfc58c1e146c6072e8a3f36..8638732b51fc731e62f6f35116f4fc41156666dc 100644 (file)
@@ -59,29 +59,36 @@ struct tgsi_exec_machine;
 struct vertex_info;
 
 
+typedef void
+(*lp_shader_fs_func)(void *pos,
+                     void *a0,
+                     void *dadx,
+                     void *dady,
+                     void *consts,
+                     void *outputs,
+                     struct tgsi_sampler **samplers);
+
 /**
  * Subclass of pipe_shader_state (though it doesn't really need to be).
  *
  * This is starting to look an awful lot like a quad pipeline stage...
  */
-struct lp_fragment_shader {
-   struct pipe_shader_state shader;
+struct lp_fragment_shader
+{
+   struct pipe_shader_state base;
 
    struct tgsi_shader_info info;
 
-   void (*prepare)( const struct lp_fragment_shader *shader,
-                   struct tgsi_exec_machine *machine,
-                   struct tgsi_sampler **samplers);
+   struct llvmpipe_screen *screen;
 
-   /* Run the shader - this interface will get cleaned up in the
-    * future:
-    */
-   unsigned (*run)( const struct lp_fragment_shader *shader,
-                   struct tgsi_exec_machine *machine,
-                   struct quad_header *quad );
+   LLVMValueRef function;
 
+   lp_shader_fs_func jit_function;
 
-   void (*delete)( struct lp_fragment_shader * );
+   union tgsi_exec_channel ALIGN16_ATTRIB pos[NUM_CHANNELS];
+   union tgsi_exec_channel ALIGN16_ATTRIB a0[PIPE_MAX_SHADER_INPUTS][NUM_CHANNELS];
+   union tgsi_exec_channel ALIGN16_ATTRIB dadx[PIPE_MAX_SHADER_INPUTS][NUM_CHANNELS];
+   union tgsi_exec_channel ALIGN16_ATTRIB dady[PIPE_MAX_SHADER_INPUTS][NUM_CHANNELS];
 };
 
 
index 1dc0dadef68a13d883e1c5589f5540f8113ba364..e6efa426fe00fee5b138f64f11abce0bfdfe281f 100644 (file)
@@ -1,5 +1,6 @@
 /**************************************************************************
  * 
+ * Copyright 2009 VMware, Inc.
  * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
  * All Rights Reserved.
  * 
  * 
  **************************************************************************/
 
-#include "lp_context.h"
-#include "lp_state.h"
-#include "lp_fs.h"
-
 #include "pipe/p_defines.h"
 #include "util/u_memory.h"
 #include "pipe/internal/p_winsys_screen.h"
 #include "tgsi/tgsi_dump.h"
 #include "tgsi/tgsi_scan.h"
 #include "tgsi/tgsi_parse.h"
+#include "lp_bld_type.h"
+#include "lp_bld_tgsi.h"
+#include "lp_screen.h"
+#include "lp_context.h"
+#include "lp_state.h"
+#include "lp_quad.h"
+
+
+static void
+shader_generate(struct llvmpipe_screen *screen,
+                struct lp_fragment_shader *shader)
+{
+   const struct tgsi_token *tokens = shader->base.tokens;
+   union lp_type type;
+   LLVMTypeRef elem_type;
+   LLVMTypeRef vec_type;
+   LLVMTypeRef arg_types[7];
+   LLVMTypeRef func_type;
+   LLVMValueRef pos_ptr;
+   LLVMValueRef a0_ptr;
+   LLVMValueRef dadx_ptr;
+   LLVMValueRef dady_ptr;
+   LLVMValueRef consts_ptr;
+   LLVMValueRef outputs_ptr;
+   LLVMValueRef samplers_ptr;
+   LLVMBasicBlockRef block;
+   LLVMBuilderRef builder;
+   LLVMValueRef pos[NUM_CHANNELS];
+   LLVMValueRef outputs[PIPE_MAX_SHADER_OUTPUTS][NUM_CHANNELS];
+   char name[32];
+   unsigned i, j;
+
+   type.value = 0;
+   type.floating = TRUE;
+   type.sign = TRUE;
+   type.norm = FALSE;
+   type.width = 32;
+   type.length = 4;
+
+   elem_type = lp_build_elem_type(type);
+   vec_type = lp_build_vec_type(type);
+
+   arg_types[0] = LLVMPointerType(vec_type, 0);        /* pos */
+   arg_types[1] = LLVMPointerType(vec_type, 0);        /* a0 */
+   arg_types[2] = LLVMPointerType(vec_type, 0);        /* dadx */
+   arg_types[3] = LLVMPointerType(vec_type, 0);        /* dady */
+   arg_types[4] = LLVMPointerType(elem_type, 0);       /* consts */
+   arg_types[5] = LLVMPointerType(vec_type, 0);        /* outputs */
+   arg_types[6] = LLVMPointerType(LLVMInt8Type(), 0);  /* samplers */
+
+   func_type = LLVMFunctionType(LLVMVoidType(), arg_types, Elements(arg_types), 0);
+
+   shader->function = LLVMAddFunction(screen->module, "shader", func_type);
+   LLVMSetFunctionCallConv(shader->function, LLVMCCallConv);
+
+   pos_ptr = LLVMGetParam(shader->function, 0);
+   a0_ptr = LLVMGetParam(shader->function, 1);
+   dadx_ptr = LLVMGetParam(shader->function, 2);
+   dady_ptr = LLVMGetParam(shader->function, 3);
+   consts_ptr = LLVMGetParam(shader->function, 4);
+   outputs_ptr = LLVMGetParam(shader->function, 5);
+   samplers_ptr = LLVMGetParam(shader->function, 6);
+
+   LLVMSetValueName(pos_ptr, "pos");
+   LLVMSetValueName(a0_ptr, "a0");
+   LLVMSetValueName(dadx_ptr, "dadx");
+   LLVMSetValueName(dady_ptr, "dady");
+   LLVMSetValueName(consts_ptr, "consts");
+   LLVMSetValueName(outputs_ptr, "outputs");
+   LLVMSetValueName(samplers_ptr, "samplers");
+
+   block = LLVMAppendBasicBlock(shader->function, "entry");
+   builder = LLVMCreateBuilder();
+   LLVMPositionBuilderAtEnd(builder, block);
+
+   for(j = 0; j < NUM_CHANNELS; ++j) {
+      LLVMValueRef index = LLVMConstInt(LLVMInt32Type(), j, 0);
+      util_snprintf(name, sizeof name, "pos.%c", "xyzw"[j]);
+      pos[j] = LLVMBuildLoad(builder, LLVMBuildGEP(builder, pos_ptr, &index, 1, ""), name);
+   }
+
+   memset(outputs, 0, sizeof outputs);
+
+   lp_build_tgsi_soa(builder, tokens, type,
+                     pos, a0_ptr, dadx_ptr, dady_ptr,
+                     consts_ptr, outputs, samplers_ptr);
+
+   for(i = 0; i < PIPE_MAX_SHADER_OUTPUTS; ++i) {
+      for(j = 0; j < NUM_CHANNELS; ++j) {
+         if(outputs[i][j]) {
+            LLVMValueRef index = LLVMConstInt(LLVMInt32Type(), i*NUM_CHANNELS + j, 0);
+            util_snprintf(name, sizeof name, "output%u.%c", i, "xyzw"[j]);
+            LLVMBuildStore(builder, outputs[i][j], LLVMBuildGEP(builder, outputs_ptr, &index, 1, name));
+         }
+      }
+   }
+
+   LLVMBuildRetVoid(builder);;
+
+   LLVMDisposeBuilder(builder);
+}
 
 
 void *
 llvmpipe_create_fs_state(struct pipe_context *pipe,
                          const struct pipe_shader_state *templ)
 {
-   struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
-   struct lp_fragment_shader *state;
-
-   /* debug */
-   if (llvmpipe->dump_fs) 
-      tgsi_dump(templ->tokens, 0);
-
-   /* codegen */
-   state = llvmpipe_create_fs_llvm( llvmpipe, templ );
-   if (!state) {
-      state = llvmpipe_create_fs_sse( llvmpipe, templ );
-      if (!state) {
-         state = llvmpipe_create_fs_exec( llvmpipe, templ );
-      }
-   }
+   struct llvmpipe_screen *screen = llvmpipe_screen(pipe->screen);
+   struct lp_fragment_shader *shader;
+   LLVMValueRef fetch_texel;
 
-   assert(state);
+   shader = CALLOC_STRUCT(lp_fragment_shader);
+   if (!shader)
+      return NULL;
 
    /* get/save the summary info for this shader */
-   tgsi_scan_shader(templ->tokens, &state->info);
+   tgsi_scan_shader(templ->tokens, &shader->info);
 
-   return state;
+   /* we need to keep a local copy of the tokens */
+   shader->base.tokens = tgsi_dup_tokens(templ->tokens);
+
+   shader->screen = screen;
+
+#ifdef DEBUG
+   tgsi_dump(templ->tokens, 0);
+#endif
+
+   shader_generate(screen, shader);
+
+   LLVMRunFunctionPassManager(screen->pass, shader->function);
+
+#ifdef DEBUG
+   LLVMDumpValue(shader->function);
+   debug_printf("\n");
+#endif
+
+   if(LLVMVerifyFunction(shader->function, LLVMPrintMessageAction)) {
+      LLVMDumpValue(shader->function);
+      abort();
+   }
+
+   fetch_texel = LLVMGetNamedFunction(screen->module, "fetch_texel");
+   if(fetch_texel) {
+      static boolean first_time = TRUE;
+      if(first_time) {
+         LLVMAddGlobalMapping(screen->engine, fetch_texel, lp_build_tgsi_fetch_texel_soa);
+         first_time = FALSE;
+      }
+   }
+
+   shader->jit_function = (lp_shader_fs_func)LLVMGetPointerToGlobal(screen->engine, shader->function);
+
+   return shader;
 }
 
 
@@ -82,11 +204,19 @@ llvmpipe_bind_fs_state(struct pipe_context *pipe, void *fs)
 void
 llvmpipe_delete_fs_state(struct pipe_context *pipe, void *fs)
 {
-   struct lp_fragment_shader *state = fs;
+   struct lp_fragment_shader *shader = fs;
+   struct llvmpipe_screen *screen = shader->screen;
 
    assert(fs != llvmpipe_context(pipe)->fs);
    
-   state->delete( state );
+   if(shader->function) {
+      if(shader->jit_function)
+         LLVMFreeMachineCodeForFunction(screen->engine, shader->function);
+      LLVMDeleteFunction(shader->function);
+   }
+
+   FREE((void *) shader->base.tokens);
+   FREE(shader);
 }