summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorZack Rusin <[email protected]>2008-02-05 03:09:24 -0500
committerZack Rusin <[email protected]>2008-02-10 23:07:18 -0500
commit137edf75335910c9f15daacaf0ce3f4cbd43080c (patch)
treeeccb17691b781cd88bed0c607966be27ef848fbd
parent7d69090e272d0d429f0ef7a733cebe1363383447 (diff)
rewrite the way cpu engine is handled
-rw-r--r--src/mesa/pipe/draw/draw_vertex_shader.c9
-rw-r--r--src/mesa/pipe/llvm/Makefile1
-rw-r--r--src/mesa/pipe/llvm/gallivm.cpp134
-rw-r--r--src/mesa/pipe/llvm/gallivm.h37
-rw-r--r--src/mesa/pipe/llvm/gallivm_cpu.cpp204
5 files changed, 227 insertions, 158 deletions
diff --git a/src/mesa/pipe/draw/draw_vertex_shader.c b/src/mesa/pipe/draw/draw_vertex_shader.c
index 9567283ff5c..574ac670572 100644
--- a/src/mesa/pipe/draw/draw_vertex_shader.c
+++ b/src/mesa/pipe/draw/draw_vertex_shader.c
@@ -116,11 +116,10 @@ run_vertex_program(struct draw_context *draw,
#ifdef MESA_LLVM
if (1) {
struct gallivm_prog *prog = draw->vertex_shader->llvm_prog;
- gallivm_prog_exec(prog,
- machine->Inputs,
- machine->Outputs,
- machine->Consts,
- 12, 12, 12);
+ gallivm_cpu_vs_exec(prog,
+ machine->Inputs,
+ machine->Outputs,
+ machine->Consts);
} else
#elif defined(__i386__) || defined(__386__)
if (draw->use_sse) {
diff --git a/src/mesa/pipe/llvm/Makefile b/src/mesa/pipe/llvm/Makefile
index 10ff7aacae8..b333661c6f8 100644
--- a/src/mesa/pipe/llvm/Makefile
+++ b/src/mesa/pipe/llvm/Makefile
@@ -7,6 +7,7 @@ LIBNAME = gallivm
GALLIVM_SOURCES = \
gallivm.cpp \
+ gallivm_cpu.cpp \
instructions.cpp \
loweringpass.cpp \
tgsitollvm.cpp \
diff --git a/src/mesa/pipe/llvm/gallivm.cpp b/src/mesa/pipe/llvm/gallivm.cpp
index cf9b0f64067..cb9a88f0b86 100644
--- a/src/mesa/pipe/llvm/gallivm.cpp
+++ b/src/mesa/pipe/llvm/gallivm.cpp
@@ -70,10 +70,6 @@
#include <fstream>
#include <iostream>
-struct gallivm_cpu_engine {
- llvm::ExecutionEngine *engine;
-};
-
static int GLOBAL_ID = 0;
using namespace llvm;
@@ -145,38 +141,6 @@ void gallivm_prog_delete(struct gallivm_prog *prog)
free(prog);
}
-typedef void (*vertex_shader_runner)(void *ainputs,
- void *dests,
- float (*aconsts)[4],
- int num_vertices,
- int num_inputs,
- int num_attribs,
- int num_consts);
-
-
-/*!
- This function is used to execute the gallivm_prog in software. Before calling
- this function the gallivm_prog has to be JIT compiled with the gallivm_cpu_jit_compile
- function.
- */
-int gallivm_prog_exec(struct gallivm_prog *prog,
- struct tgsi_exec_vector *inputs,
- struct tgsi_exec_vector *dests,
- float (*consts)[4],
- int num_vertices,
- int num_inputs,
- int num_attribs)
-{
- vertex_shader_runner runner = reinterpret_cast<vertex_shader_runner>(prog->function);
- assert(runner);
- runner(inputs, dests, consts, num_vertices, num_inputs,
- num_attribs, prog->num_consts);
-
- return 0;
-}
-
-
-
static inline void
constant_interpolation(float (*inputs)[16][4],
const struct tgsi_interp_coef *coefs,
@@ -231,28 +195,6 @@ perspective_interpolation(float (*inputs)[16][4],
}
}
-typedef int (*fragment_shader_runner)(float x, float y,
- float (*dests)[16][4],
- float (*inputs)[16][4],
- int num_attribs,
- float (*consts)[4], int num_consts,
- struct tgsi_sampler *samplers);
-
-int gallivm_fragment_shader_exec(struct gallivm_prog *prog,
- float fx, float fy,
- float (*dests)[16][4],
- float (*inputs)[16][4],
- float (*consts)[4],
- struct tgsi_sampler *samplers)
-{
- fragment_shader_runner runner = reinterpret_cast<fragment_shader_runner>(prog->function);
- assert(runner);
-
- return runner(fx, fy, dests, inputs, prog->num_interp,
- consts, prog->num_consts,
- samplers);
-}
-
void gallivm_ir_dump(struct gallivm_ir *ir, const char *file_prefix)
{
if (!ir || !ir->module)
@@ -292,82 +234,6 @@ void gallivm_ir_dump(struct gallivm_ir *ir, const char *file_prefix)
}
-static struct gallivm_cpu_engine *CPU = 0;
-
-static inline llvm::Function *func_for_shader(struct gallivm_prog *prog)
-{
- llvm::Module *mod = prog->module;
- llvm::Function *func = 0;
-
- switch (prog->type) {
- case GALLIVM_VS:
- func = mod->getFunction("run_vertex_shader");
- break;
- case GALLIVM_FS:
- func = mod->getFunction("run_fragment_shader");
- break;
- default:
- assert(!"Unknown shader type!");
- break;
- }
- return func;
-}
-
-/*!
- This function creates a CPU based execution engine for the given gallivm_prog.
- gallivm_cpu_engine should be used as a singleton throughout the library. Before
- executing gallivm_prog_exec one needs to call gallivm_cpu_jit_compile.
- The gallivm_prog instance which is being passed to the constructor is being
- automatically JIT compiled so one shouldn't call gallivm_cpu_jit_compile
- with it again.
- */
-struct gallivm_cpu_engine * gallivm_cpu_engine_create(struct gallivm_prog *prog)
-{
- struct gallivm_cpu_engine *cpu = (struct gallivm_cpu_engine *)
- calloc(1, sizeof(struct gallivm_cpu_engine));
- llvm::Module *mod = static_cast<llvm::Module*>(prog->module);
- llvm::ExistingModuleProvider *mp = new llvm::ExistingModuleProvider(mod);
- llvm::ExecutionEngine *ee = llvm::ExecutionEngine::create(mp, false);
- ee->DisableLazyCompilation();
- cpu->engine = ee;
-
- llvm::Function *func = func_for_shader(prog);
-
- prog->function = ee->getPointerToFunction(func);
- CPU = cpu;
- return cpu;
-}
-
-
-/*!
- This function JIT compiles the given gallivm_prog with the given cpu based execution engine.
- The reference to the generated machine code entry point will be stored
- in the gallivm_prog program. After executing this function one can call gallivm_prog_exec
- in order to execute the gallivm_prog on the CPU.
- */
-void gallivm_cpu_jit_compile(struct gallivm_cpu_engine *cpu, struct gallivm_prog *prog)
-{
- llvm::Module *mod = static_cast<llvm::Module*>(prog->module);
- llvm::ExistingModuleProvider *mp = new llvm::ExistingModuleProvider(mod);
- llvm::ExecutionEngine *ee = cpu->engine;
- assert(ee);
- ee->DisableLazyCompilation();
- ee->addModuleProvider(mp);
-
- llvm::Function *func = func_for_shader(prog);
- prog->function = ee->getPointerToFunction(func);
-}
-
-void gallivm_cpu_engine_delete(struct gallivm_cpu_engine *cpu)
-{
- free(cpu);
-}
-
-struct gallivm_cpu_engine * gallivm_global_cpu_engine()
-{
- return CPU;
-}
-
void gallivm_prog_inputs_interpolate(struct gallivm_prog *prog,
float (*inputs)[16][4],
const struct tgsi_interp_coef *coef)
diff --git a/src/mesa/pipe/llvm/gallivm.h b/src/mesa/pipe/llvm/gallivm.h
index f9f5d5ee744..98eda56f81c 100644
--- a/src/mesa/pipe/llvm/gallivm.h
+++ b/src/mesa/pipe/llvm/gallivm.h
@@ -61,28 +61,16 @@ enum gallivm_vector_layout {
};
struct gallivm_ir *gallivm_ir_new(enum gallivm_shader_type type);
-void gallivm_ir_set_layout(struct gallivm_ir *prog,
- enum gallivm_vector_layout layout);
-void gallivm_ir_set_components(struct gallivm_ir *prog, int num);
-void gallivm_ir_fill_from_tgsi(struct gallivm_ir *prog,
- const struct tgsi_token *tokens);
-void gallivm_ir_delete(struct gallivm_ir *prog);
+void gallivm_ir_set_layout(struct gallivm_ir *prog,
+ enum gallivm_vector_layout layout);
+void gallivm_ir_set_components(struct gallivm_ir *prog, int num);
+void gallivm_ir_fill_from_tgsi(struct gallivm_ir *prog,
+ const struct tgsi_token *tokens);
+void gallivm_ir_delete(struct gallivm_ir *prog);
+
struct gallivm_prog *gallivm_ir_compile(struct gallivm_ir *ir);
-int gallivm_prog_exec(struct gallivm_prog *prog,
- struct tgsi_exec_vector *inputs,
- struct tgsi_exec_vector *dests,
- float (*consts)[4],
- int num_vertices,
- int num_inputs,
- int num_attribs);
-int gallivm_fragment_shader_exec(struct gallivm_prog *prog,
- float x, float y,
- float (*dests)[PIPE_MAX_SHADER_INPUTS][4],
- float (*inputs)[PIPE_MAX_SHADER_INPUTS][4],
- float (*consts)[4],
- struct tgsi_sampler *samplers);
void gallivm_prog_inputs_interpolate(struct gallivm_prog *prog,
float (*inputs)[PIPE_MAX_SHADER_INPUTS][4],
const struct tgsi_interp_coef *coefs);
@@ -91,9 +79,20 @@ void gallivm_prog_dump(struct gallivm_prog *prog, const char *file_prefix);
struct gallivm_cpu_engine *gallivm_cpu_engine_create(struct gallivm_prog *prog);
struct gallivm_cpu_engine *gallivm_global_cpu_engine();
+int gallivm_cpu_vs_exec(struct gallivm_prog *prog,
+ struct tgsi_exec_vector *inputs,
+ struct tgsi_exec_vector *dests,
+ float (*consts)[4]);
+int gallivm_cpu_fs_exec(struct gallivm_prog *prog,
+ float x, float y,
+ float (*dests)[PIPE_MAX_SHADER_INPUTS][4],
+ float (*inputs)[PIPE_MAX_SHADER_INPUTS][4],
+ float (*consts)[4],
+ struct tgsi_sampler *samplers);
void gallivm_cpu_jit_compile(struct gallivm_cpu_engine *ee, struct gallivm_prog *prog);
void gallivm_cpu_engine_delete(struct gallivm_cpu_engine *ee);
+
#endif /* MESA_LLVM */
#if defined __cplusplus
diff --git a/src/mesa/pipe/llvm/gallivm_cpu.cpp b/src/mesa/pipe/llvm/gallivm_cpu.cpp
new file mode 100644
index 00000000000..5f1268bf4f8
--- /dev/null
+++ b/src/mesa/pipe/llvm/gallivm_cpu.cpp
@@ -0,0 +1,204 @@
+/**************************************************************************
+ *
+ * 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:
+ * Zack Rusin [email protected]
+ */
+#ifdef MESA_LLVM
+
+#include "gallivm.h"
+#include "gallivm_p.h"
+
+#include "instructions.h"
+#include "loweringpass.h"
+#include "storage.h"
+#include "tgsitollvm.h"
+
+#include "pipe/p_context.h"
+#include "pipe/p_shader_tokens.h"
+
+#include "pipe/tgsi/exec/tgsi_exec.h"
+#include "pipe/tgsi/util/tgsi_dump.h"
+
+#include <llvm/Module.h>
+#include <llvm/CallingConv.h>
+#include <llvm/Constants.h>
+#include <llvm/DerivedTypes.h>
+#include <llvm/Instructions.h>
+#include <llvm/ModuleProvider.h>
+#include <llvm/Pass.h>
+#include <llvm/PassManager.h>
+#include <llvm/ParameterAttributes.h>
+#include <llvm/Support/PatternMatch.h>
+#include <llvm/ExecutionEngine/JIT.h>
+#include <llvm/ExecutionEngine/Interpreter.h>
+#include <llvm/ExecutionEngine/GenericValue.h>
+#include <llvm/Support/MemoryBuffer.h>
+#include <llvm/LinkAllPasses.h>
+#include <llvm/Analysis/Verifier.h>
+#include <llvm/Analysis/LoopPass.h>
+#include <llvm/Target/TargetData.h>
+#include <llvm/Bitcode/ReaderWriter.h>
+#include <llvm/Transforms/Utils/Cloning.h>
+
+#include <sstream>
+#include <fstream>
+#include <iostream>
+
+struct gallivm_cpu_engine {
+ llvm::ExecutionEngine *engine;
+};
+
+static struct gallivm_cpu_engine *CPU = 0;
+
+typedef int (*fragment_shader_runner)(float x, float y,
+ float (*dests)[16][4],
+ float (*inputs)[16][4],
+ int num_attribs,
+ float (*consts)[4], int num_consts,
+ struct tgsi_sampler *samplers);
+
+int gallivm_cpu_fs_exec(struct gallivm_prog *prog,
+ float fx, float fy,
+ float (*dests)[16][4],
+ float (*inputs)[16][4],
+ float (*consts)[4],
+ struct tgsi_sampler *samplers)
+{
+ fragment_shader_runner runner = reinterpret_cast<fragment_shader_runner>(prog->function);
+ assert(runner);
+
+ return runner(fx, fy, dests, inputs, prog->num_interp,
+ consts, prog->num_consts,
+ samplers);
+}
+
+static inline llvm::Function *func_for_shader(struct gallivm_prog *prog)
+{
+ llvm::Module *mod = prog->module;
+ llvm::Function *func = 0;
+
+ switch (prog->type) {
+ case GALLIVM_VS:
+ func = mod->getFunction("run_vertex_shader");
+ break;
+ case GALLIVM_FS:
+ func = mod->getFunction("run_fragment_shader");
+ break;
+ default:
+ assert(!"Unknown shader type!");
+ break;
+ }
+ return func;
+}
+
+/*!
+ This function creates a CPU based execution engine for the given gallivm_prog.
+ gallivm_cpu_engine should be used as a singleton throughout the library. Before
+ executing gallivm_prog_exec one needs to call gallivm_cpu_jit_compile.
+ The gallivm_prog instance which is being passed to the constructor is being
+ automatically JIT compiled so one shouldn't call gallivm_cpu_jit_compile
+ with it again.
+ */
+struct gallivm_cpu_engine * gallivm_cpu_engine_create(struct gallivm_prog *prog)
+{
+ struct gallivm_cpu_engine *cpu = (struct gallivm_cpu_engine *)
+ calloc(1, sizeof(struct gallivm_cpu_engine));
+ llvm::Module *mod = static_cast<llvm::Module*>(prog->module);
+ llvm::ExistingModuleProvider *mp = new llvm::ExistingModuleProvider(mod);
+ llvm::ExecutionEngine *ee = llvm::ExecutionEngine::create(mp, false);
+ ee->DisableLazyCompilation();
+ cpu->engine = ee;
+
+ llvm::Function *func = func_for_shader(prog);
+
+ prog->function = ee->getPointerToFunction(func);
+ CPU = cpu;
+ return cpu;
+}
+
+
+/*!
+ This function JIT compiles the given gallivm_prog with the given cpu based execution engine.
+ The reference to the generated machine code entry point will be stored
+ in the gallivm_prog program. After executing this function one can call gallivm_prog_exec
+ in order to execute the gallivm_prog on the CPU.
+ */
+void gallivm_cpu_jit_compile(struct gallivm_cpu_engine *cpu, struct gallivm_prog *prog)
+{
+ llvm::Module *mod = static_cast<llvm::Module*>(prog->module);
+ llvm::ExistingModuleProvider *mp = new llvm::ExistingModuleProvider(mod);
+ llvm::ExecutionEngine *ee = cpu->engine;
+ assert(ee);
+ /*FIXME : remove */
+ ee->DisableLazyCompilation();
+ ee->addModuleProvider(mp);
+
+ llvm::Function *func = func_for_shader(prog);
+ prog->function = ee->getPointerToFunction(func);
+}
+
+void gallivm_cpu_engine_delete(struct gallivm_cpu_engine *cpu)
+{
+ free(cpu);
+}
+
+struct gallivm_cpu_engine * gallivm_global_cpu_engine()
+{
+ return CPU;
+}
+
+
+typedef void (*vertex_shader_runner)(void *ainputs,
+ void *dests,
+ float (*aconsts)[4],
+ int num_vertices,
+ int num_inputs,
+ int num_attribs,
+ int num_consts);
+
+
+/*!
+ This function is used to execute the gallivm_prog in software. Before calling
+ this function the gallivm_prog has to be JIT compiled with the gallivm_cpu_jit_compile
+ function.
+ */
+int gallivm_cpu_vs_exec(struct gallivm_prog *prog,
+ struct tgsi_exec_vector *inputs,
+ struct tgsi_exec_vector *dests,
+ float (*consts)[4])
+{
+ vertex_shader_runner runner = reinterpret_cast<vertex_shader_runner>(prog->function);
+ assert(runner);
+ /*FIXME*/
+ runner(inputs, dests, consts, 4, 4, 4, prog->num_consts);
+
+ return 0;
+}
+
+#endif