summaryrefslogtreecommitdiffstats
path: root/src/mesa/pipe/llvm/gallivm.cpp
diff options
context:
space:
mode:
authorZack Rusin <[email protected]>2007-11-01 14:00:25 -0400
committerZack Rusin <[email protected]>2007-11-02 07:15:18 -0400
commit45003b0bb920fe701304acb1599185f4dc92c89b (patch)
tree6de6b767e330a537a7d99ede33f0222420db72d6 /src/mesa/pipe/llvm/gallivm.cpp
parent2af2f7e419c1b6d796822a049f019afe3dfc6021 (diff)
Get fragment shaders working on top of LLVM.
Redo the entry points, get the output propagation correctly, interpolate the inputs before feeding into llvm for now.
Diffstat (limited to 'src/mesa/pipe/llvm/gallivm.cpp')
-rw-r--r--src/mesa/pipe/llvm/gallivm.cpp175
1 files changed, 164 insertions, 11 deletions
diff --git a/src/mesa/pipe/llvm/gallivm.cpp b/src/mesa/pipe/llvm/gallivm.cpp
index 6642f15498b..b5e90b037e7 100644
--- a/src/mesa/pipe/llvm/gallivm.cpp
+++ b/src/mesa/pipe/llvm/gallivm.cpp
@@ -68,12 +68,21 @@
#include <fstream>
#include <iostream>
+struct gallivm_interpolate {
+ int attrib;
+ int chan;
+ int type;
+};
+
struct gallivm_prog {
llvm::Module *module;
void *function;
int num_consts;
int id;
enum gallivm_shader_type type;
+
+ struct gallivm_interpolate interpolators[32*4]; //FIXME: this might not be enough for some shaders
+ int num_interp;
};
struct gallivm_cpu_engine {
@@ -141,12 +150,71 @@ static inline void AddStandardCompilePasses(PassManager &PM) {
PM.add(createConstantMergePass()); // Merge dup global constants
}
+static inline void
+add_interpolator(struct gallivm_prog *prog,
+ struct gallivm_interpolate *interp)
+{
+ prog->interpolators[prog->num_interp] = *interp;
+ ++prog->num_interp;
+}
static void
-translate_declaration(llvm::Module *module,
+translate_declaration(struct gallivm_prog *prog,
+ llvm::Module *module,
Storage *storage,
struct tgsi_full_declaration *decl,
struct tgsi_full_declaration *fd)
{
+ if (decl->Declaration.File == TGSI_FILE_INPUT) {
+ unsigned first, last, mask;
+ uint interp_method;
+
+ assert(decl->Declaration.Declare == TGSI_DECLARE_RANGE);
+
+ first = decl->u.DeclarationRange.First;
+ last = decl->u.DeclarationRange.Last;
+ mask = decl->Declaration.UsageMask;
+
+ /* Do not touch WPOS.xy */
+ if (first == 0) {
+ mask &= ~TGSI_WRITEMASK_XY;
+ if (mask == TGSI_WRITEMASK_NONE) {
+ first++;
+ if (first > last) {
+ return;
+ }
+ }
+ }
+
+ interp_method = decl->Interpolation.Interpolate;
+
+ if (mask == TGSI_WRITEMASK_XYZW) {
+ unsigned i, j;
+
+ for (i = first; i <= last; i++) {
+ for (j = 0; j < NUM_CHANNELS; j++) {
+ //interp( mach, i, j );
+ struct gallivm_interpolate interp;
+ interp.type = interp_method;
+ interp.attrib = i;
+ interp.chan = j;
+ add_interpolator(prog, &interp);
+ }
+ }
+ } else {
+ unsigned i, j;
+ for( j = 0; j < NUM_CHANNELS; j++ ) {
+ if( mask & (1 << j) ) {
+ for( i = first; i <= last; i++ ) {
+ struct gallivm_interpolate interp;
+ interp.type = interp_method;
+ interp.attrib = i;
+ interp.chan = j;
+ add_interpolator(prog, &interp);
+ }
+ }
+ }
+ }
+ }
}
@@ -686,7 +754,7 @@ tgsi_to_llvm(struct gallivm_prog *prog, const struct tgsi_token *tokens)
switch (parse.FullToken.Token.Type) {
case TGSI_TOKEN_TYPE_DECLARATION:
- translate_declaration(mod, &storage,
+ translate_declaration(prog, mod, &storage,
&parse.FullToken.FullDeclaration,
&fd);
break;
@@ -791,24 +859,83 @@ int gallivm_prog_exec(struct gallivm_prog *prog,
}
+
+static inline void
+constant_interpolation(float (*inputs)[16][4],
+ const struct tgsi_interp_coef *coefs,
+ unsigned attrib,
+ unsigned chan)
+{
+ unsigned i;
+
+ for (i = 0; i < QUAD_SIZE; ++i) {
+ inputs[i][attrib][chan] = coefs[attrib].a0[chan];
+ }
+}
+
+static inline void
+linear_interpolation(float (*inputs)[16][4],
+ const struct tgsi_interp_coef *coefs,
+ unsigned attrib,
+ unsigned chan)
+{
+ unsigned i;
+
+ for( i = 0; i < QUAD_SIZE; i++ ) {
+ const float x = inputs[i][0][0];
+ const float y = inputs[i][0][1];
+
+ inputs[i][attrib][chan] =
+ coefs[attrib].a0[chan] +
+ coefs[attrib].dadx[chan] * x +
+ coefs[attrib].dady[chan] * y;
+ }
+}
+
+static inline void
+perspective_interpolation(float (*inputs)[16][4],
+ const struct tgsi_interp_coef *coefs,
+ unsigned attrib,
+ unsigned chan )
+{
+ unsigned i;
+
+ for( i = 0; i < QUAD_SIZE; i++ ) {
+ const float x = inputs[i][0][0];
+ const float y = inputs[i][0][1];
+ /* WPOS.w here is really 1/w */
+ const float w = 1.0f / inputs[i][0][3];
+ assert(inputs[i][0][3] != 0.0);
+
+ inputs[i][attrib][chan] =
+ (coefs[attrib].a0[chan] +
+ coefs[attrib].dadx[chan] * x +
+ coefs[attrib].dady[chan] * y) * w;
+ }
+}
+
typedef int (*fragment_shader_runner)(float x, float y,
- float (*dests)[32][4],
- struct tgsi_interp_coef *coef,
- float (*consts)[4], int num_consts,
- struct tgsi_sampler *samplers,
- unsigned *sampler_units);
+ float (*dests)[16][4],
+ float (*inputs)[16][4],
+ int num_attribs,
+ float (*consts)[4], int num_consts,
+ struct tgsi_sampler *samplers,
+ unsigned *sampler_units);
int gallivm_fragment_shader_exec(struct gallivm_prog *prog,
- float x, float y,
- float (*dests)[32][4],
- struct tgsi_interp_coef *coef,
+ float fx, float fy,
+ float (*dests)[16][4],
+ float (*inputs)[16][4],
float (*consts)[4],
struct tgsi_sampler *samplers,
unsigned *sampler_units)
{
fragment_shader_runner runner = reinterpret_cast<fragment_shader_runner>(prog->function);
assert(runner);
- runner(x, y, dests, coef, consts, prog->num_consts, samplers, sampler_units);
+
+ runner(fx, fy, dests, inputs, prog->num_interp,
+ consts, prog->num_consts,
+ samplers, sampler_units);
return 0;
}
@@ -928,8 +1055,34 @@ 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)
+{
+ for (int i = 0; i < prog->num_interp; ++i) {
+ const gallivm_interpolate &interp = prog->interpolators[i];
+ switch (interp.type) {
+ case TGSI_INTERPOLATE_CONSTANT:
+ constant_interpolation(inputs, coef, interp.attrib, interp.chan);
+ break;
+
+ case TGSI_INTERPOLATE_LINEAR:
+ linear_interpolation(inputs, coef, interp.attrib, interp.chan);
+ break;
+
+ case TGSI_INTERPOLATE_PERSPECTIVE:
+ perspective_interpolation(inputs, coef, interp.attrib, interp.chan);
+ break;
+
+ default:
+ assert( 0 );
+ }
+ }
+}
+
#endif /* MESA_LLVM */
+