llvmpipe: Code generate the position interpolation.
authorJosé Fonseca <jfonseca@vmware.com>
Wed, 19 Aug 2009 16:58:04 +0000 (17:58 +0100)
committerJosé Fonseca <jfonseca@vmware.com>
Sat, 29 Aug 2009 08:21:35 +0000 (09:21 +0100)
src/gallium/drivers/llvmpipe/lp_bld_tgsi_soa.c
src/gallium/drivers/llvmpipe/lp_quad_fs.c
src/gallium/drivers/llvmpipe/lp_state.h
src/gallium/drivers/llvmpipe/lp_state_fs.c

index 805d9fd4b24a4d82fdcec08e9caef3029b180cbc..01328c1c48a0686f3df017f9908b08e180e4878a 100644 (file)
@@ -1353,7 +1353,7 @@ emit_declaration(
             LLVMValueRef input = bld->base.undef;
 
             if( mask & (1 << chan) ) {
-               LLVMValueRef index = LLVMConstInt(LLVMInt32Type(), attrib*NUM_CHANNELS + chan, 0);
+               LLVMValueRef index = LLVMConstInt(LLVMInt32Type(), (1 + attrib)*NUM_CHANNELS + chan, 0);
                LLVMValueRef a0;
                LLVMValueRef dadx;
                LLVMValueRef dady;
index d5c3f57a45aa14850b2cffb500c709919fc6868e..78b4e1bab6d9f37243bae6ceb611804489e119ae 100644 (file)
@@ -67,37 +67,6 @@ quad_shade_stage(struct quad_stage *qs)
 }
 
 
-static void
-setup_pos_vector(struct quad_shade_stage *qss,
-                 const struct quad_interp_coef *coef,
-                 float x, float y)
-{
-   uint chan;
-
-   /* do X */
-   qss->pos[0].f[0] = x;
-   qss->pos[0].f[1] = x + 1;
-   qss->pos[0].f[2] = x;
-   qss->pos[0].f[3] = x + 1;
-
-   /* do Y */
-   qss->pos[1].f[0] = y;
-   qss->pos[1].f[1] = y;
-   qss->pos[1].f[2] = y + 1;
-   qss->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[0][chan];
-      const float dady = coef->dady[0][chan];
-      const float a0 = coef->a0[0][chan] + dadx * x + dady * y;
-      qss->pos[chan].f[0] = a0;
-      qss->pos[chan].f[1] = a0 + dadx;
-      qss->pos[chan].f[2] = a0 + dady;
-      qss->pos[chan].f[3] = a0 + dadx + dady;
-   }
-}
-
 
 /**
  * Execute fragment shader for the four fragments in the quad.
@@ -111,12 +80,6 @@ shade_quad(struct quad_stage *qs, struct quad_header *quad)
    struct tgsi_sampler **samplers;
    unsigned chan_index;
 
-   /* Compute X, Y, Z, W vals for this quad */
-   setup_pos_vector(qss,
-                    quad->coef,
-                    (float)quad->input.x0, (float)quad->input.y0);
-
-
    constants = llvmpipe->mapped_constants[PIPE_SHADER_FRAGMENT];
    samplers = (struct tgsi_sampler **)llvmpipe->tgsi.frag_samplers_list;
 
@@ -124,10 +87,11 @@ shade_quad(struct quad_stage *qs, struct quad_header *quad)
       qss->mask[chan_index] = ~0;
 
    /* run shader */
-   llvmpipe->fs->jit_function( qss->pos,
-                               quad->coef->a0 + 1,
-                               quad->coef->dadx + 1,
-                               quad->coef->dady + 1,
+   llvmpipe->fs->jit_function( quad->input.x0,
+                               quad->input.y0,
+                               quad->coef->a0,
+                               quad->coef->dadx,
+                               quad->coef->dady,
                                constants,
                                qss->mask,
                                quad->output.color,
index df7fff9d38cff3bb11064a8848aac614b9d1bbee..f8b3793a59500e662899dee41e18d1479b80b34e 100644 (file)
@@ -59,7 +59,8 @@ struct vertex_info;
 
 
 typedef void
-(*lp_shader_fs_func)(const void *pos,
+(*lp_shader_fs_func)(uint32_t x,
+                     uint32_t y,
                      const void *a0,
                      const void *dadx,
                      const void *dady,
index 814ed0f1427e62830b9311213255920131eaf567..1c00c2c707ed5814c3f72dfceffe706e952f627b 100644 (file)
@@ -36,6 +36,7 @@
 #include "tgsi/tgsi_parse.h"
 #include "lp_bld_type.h"
 #include "lp_bld_tgsi.h"
+#include "lp_bld_swizzle.h"
 #include "lp_bld_debug.h"
 #include "lp_screen.h"
 #include "lp_context.h"
 #include "lp_quad.h"
 
 
+static const unsigned char quad_offset_x[4] = {0, 1, 0, 1};
+static const unsigned char quad_offset_y[4] = {0, 0, 1, 1};
+
+
+static void
+setup_pos_vector(LLVMBuilderRef builder,
+                 LLVMValueRef x,
+                 LLVMValueRef y,
+                 LLVMValueRef a0_ptr,
+                 LLVMValueRef dadx_ptr,
+                 LLVMValueRef dady_ptr,
+                 LLVMValueRef *pos)
+{
+   LLVMTypeRef int_elem_type = LLVMInt32Type();
+   LLVMTypeRef int_vec_type = LLVMVectorType(int_elem_type, QUAD_SIZE);
+   LLVMTypeRef elem_type = LLVMFloatType();
+   LLVMTypeRef vec_type = LLVMVectorType(elem_type, QUAD_SIZE);
+   LLVMValueRef x_offsets[QUAD_SIZE];
+   LLVMValueRef y_offsets[QUAD_SIZE];
+   unsigned chan;
+   unsigned i;
+
+   x = lp_build_broadcast(builder, int_vec_type, x);
+   y = lp_build_broadcast(builder, int_vec_type, y);
+
+   for(i = 0; i < QUAD_SIZE; ++i) {
+      x_offsets[i] = LLVMConstInt(int_elem_type, quad_offset_x[i], 0);
+      y_offsets[i] = LLVMConstInt(int_elem_type, quad_offset_y[i], 0);
+   }
+
+   x = LLVMBuildAdd(builder, x, LLVMConstVector(x_offsets, QUAD_SIZE), "");
+   y = LLVMBuildAdd(builder, y, LLVMConstVector(y_offsets, QUAD_SIZE), "");
+
+   x = LLVMBuildSIToFP(builder, x, vec_type, "");
+   y = LLVMBuildSIToFP(builder, y, vec_type, "");
+
+   pos[0] = x;
+   pos[1] = y;
+
+   for(chan = 2; chan < NUM_CHANNELS; ++chan) {
+      LLVMValueRef index = LLVMConstInt(LLVMInt32Type(), chan, 0);
+      LLVMValueRef a0   = LLVMBuildLoad(builder, LLVMBuildGEP(builder, a0_ptr,   &index, 1, ""), "");
+      LLVMValueRef dadx = LLVMBuildLoad(builder, LLVMBuildGEP(builder, dadx_ptr, &index, 1, ""), "");
+      LLVMValueRef dady = LLVMBuildLoad(builder, LLVMBuildGEP(builder, dady_ptr, &index, 1, ""), "");
+      LLVMValueRef res;
+      a0   = lp_build_broadcast(builder, vec_type, a0);
+      dadx = lp_build_broadcast(builder, vec_type, dadx);
+      dady = lp_build_broadcast(builder, vec_type, dady);
+      res = a0;
+      res = LLVMBuildAdd(builder, res, LLVMBuildMul(builder, dadx, x, ""), "");
+      res = LLVMBuildAdd(builder, res, LLVMBuildMul(builder, dady, y, ""), "");
+      pos[chan] = res;
+   }
+
+   for(chan = 0; chan < NUM_CHANNELS; ++chan)
+      lp_build_name(pos[chan], "pos.%c", "xyzw"[chan]);
+}
+
+
 static void
 shader_generate(struct llvmpipe_screen *screen,
                 struct lp_fragment_shader *shader)
@@ -52,9 +112,10 @@ shader_generate(struct llvmpipe_screen *screen,
    LLVMTypeRef elem_type;
    LLVMTypeRef vec_type;
    LLVMTypeRef int_vec_type;
-   LLVMTypeRef arg_types[9];
+   LLVMTypeRef arg_types[10];
    LLVMTypeRef func_type;
-   LLVMValueRef pos_ptr;
+   LLVMValueRef x;
+   LLVMValueRef y;
    LLVMValueRef a0_ptr;
    LLVMValueRef dadx_ptr;
    LLVMValueRef dady_ptr;
@@ -83,34 +144,38 @@ shader_generate(struct llvmpipe_screen *screen,
    vec_type = lp_build_vec_type(type);
    int_vec_type = lp_build_int_vec_type(type);
 
-   arg_types[0] = LLVMPointerType(vec_type, 0);        /* pos */
-   arg_types[1] = LLVMPointerType(elem_type, 0);       /* a0 */
-   arg_types[2] = LLVMPointerType(elem_type, 0);       /* dadx */
-   arg_types[3] = LLVMPointerType(elem_type, 0);       /* dady */
-   arg_types[4] = LLVMPointerType(elem_type, 0);       /* consts */
-   arg_types[5] = LLVMPointerType(int_vec_type, 0);    /* mask */
-   arg_types[6] = LLVMPointerType(vec_type, 0);        /* color */
-   arg_types[7] = LLVMPointerType(vec_type, 0);        /* depth */
-   arg_types[8] = LLVMPointerType(LLVMInt8Type(), 0);  /* samplers */
+   arg_types[0] = LLVMInt32Type();                     /* x */
+   arg_types[1] = LLVMInt32Type();                     /* y */
+   arg_types[2] = LLVMPointerType(elem_type, 0);       /* a0 */
+   arg_types[3] = LLVMPointerType(elem_type, 0);       /* dadx */
+   arg_types[4] = LLVMPointerType(elem_type, 0);       /* dady */
+   arg_types[5] = LLVMPointerType(elem_type, 0);       /* consts */
+   arg_types[6] = LLVMPointerType(int_vec_type, 0);    /* mask */
+   arg_types[7] = LLVMPointerType(vec_type, 0);        /* color */
+   arg_types[8] = LLVMPointerType(vec_type, 0);        /* depth */
+   arg_types[9] = 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);
    for(i = 0; i < Elements(arg_types); ++i)
-      LLVMAddAttribute(LLVMGetParam(shader->function, i), LLVMNoAliasAttribute);
-
-   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);
-   mask_ptr = LLVMGetParam(shader->function, 5);
-   color_ptr = LLVMGetParam(shader->function, 6);
-   depth_ptr = LLVMGetParam(shader->function, 7);
-   samplers_ptr = LLVMGetParam(shader->function, 8);
-
-   lp_build_name(pos_ptr, "pos");
+      if(LLVMGetTypeKind(arg_types[i]) == LLVMPointerTypeKind)
+         LLVMAddAttribute(LLVMGetParam(shader->function, i), LLVMNoAliasAttribute);
+
+   x            = LLVMGetParam(shader->function, 0);
+   y            = LLVMGetParam(shader->function, 1);
+   a0_ptr       = LLVMGetParam(shader->function, 2);
+   dadx_ptr     = LLVMGetParam(shader->function, 3);
+   dady_ptr     = LLVMGetParam(shader->function, 4);
+   consts_ptr   = LLVMGetParam(shader->function, 5);
+   mask_ptr     = LLVMGetParam(shader->function, 6);
+   color_ptr    = LLVMGetParam(shader->function, 7);
+   depth_ptr    = LLVMGetParam(shader->function, 8);
+   samplers_ptr = LLVMGetParam(shader->function, 9);
+
+   lp_build_name(x, "x");
+   lp_build_name(y, "y");
    lp_build_name(a0_ptr, "a0");
    lp_build_name(dadx_ptr, "dadx");
    lp_build_name(dady_ptr, "dady");
@@ -124,11 +189,7 @@ shader_generate(struct llvmpipe_screen *screen,
    builder = LLVMCreateBuilder();
    LLVMPositionBuilderAtEnd(builder, block);
 
-   for(chan = 0; chan < NUM_CHANNELS; ++chan) {
-      LLVMValueRef index = LLVMConstInt(LLVMInt32Type(), chan, 0);
-      pos[chan] = LLVMBuildLoad(builder, LLVMBuildGEP(builder, pos_ptr, &index, 1, ""), "");
-      lp_build_name(pos[chan], "pos.%c", "xyzw"[chan]);
-   }
+   setup_pos_vector(builder, x, y, a0_ptr, dadx_ptr, dady_ptr, pos);
 
    memset(outputs, 0, sizeof outputs);