llvmpipe: Isolate sampling from TGSI translation.
authorJosé Fonseca <jfonseca@vmware.com>
Tue, 25 Aug 2009 07:05:31 +0000 (08:05 +0100)
committerJosé Fonseca <jfonseca@vmware.com>
Sat, 29 Aug 2009 08:21:42 +0000 (09:21 +0100)
src/gallium/drivers/llvmpipe/lp_bld_tgsi.h
src/gallium/drivers/llvmpipe/lp_bld_tgsi_soa.c
src/gallium/drivers/llvmpipe/lp_jit.c
src/gallium/drivers/llvmpipe/lp_jit.h
src/gallium/drivers/llvmpipe/lp_state_fs.c

index d42ab99cf8214abefca495810afbbbb4a0a2f074..912db24aecb364acd7102c8673601f596451f659 100644 (file)
 
 
 struct tgsi_token;
-struct tgsi_sampler;
 union lp_type;
 struct lp_build_context;
 struct lp_build_mask_context;
 
-void PIPE_CDECL
-lp_build_tgsi_fetch_texel_soa( struct tgsi_sampler **samplers,
-                               uint32_t unit,
-                               float *store );
+
+typedef void
+(*lp_emit_fetch_texel_soa_callback)( LLVMBuilderRef builder,
+                                void *context,
+                                unsigned unit,
+                                unsigned num_coords,
+                                const LLVMValueRef *coords,
+                                LLVMValueRef lodbias,
+                                LLVMValueRef *texel);
 
 void
 lp_build_tgsi_soa(LLVMBuilderRef builder,
@@ -58,7 +62,8 @@ lp_build_tgsi_soa(LLVMBuilderRef builder,
                   const LLVMValueRef *pos,
                   const LLVMValueRef (*inputs)[4],
                   LLVMValueRef (*outputs)[4],
-                  LLVMValueRef samplers_ptr);
+                  lp_emit_fetch_texel_soa_callback emit_fetch_texel,
+                  void *emit_fetch_texel_context);
 
 
 #endif /* LP_BLD_TGSI_H */
index 1335ba862eb5c810ae8924b94064018d96d6de13..0c837188cac983311b4a1ea50900e13cf3138792 100644 (file)
@@ -87,15 +87,14 @@ struct lp_build_tgsi_soa_context
    const LLVMValueRef *pos;
    const LLVMValueRef (*inputs)[NUM_CHANNELS];
    LLVMValueRef (*outputs)[NUM_CHANNELS];
-   LLVMValueRef samplers_ptr;
+
+   lp_emit_fetch_texel_soa_callback emit_fetch_texel;
+   void *emit_fetch_texel_context;
 
    LLVMValueRef immediates[LP_MAX_IMMEDIATES][NUM_CHANNELS];
    LLVMValueRef temps[LP_MAX_TEMPS][NUM_CHANNELS];
 
    struct lp_build_mask_context *mask;
-
-   /** Coords/texels store */
-   LLVMValueRef store_ptr;
 };
 
 
@@ -236,52 +235,6 @@ emit_store(
 }
 
 
-void PIPE_CDECL
-lp_build_tgsi_fetch_texel_soa( struct tgsi_sampler **samplers,
-                               uint32_t unit,
-                               float *store )
-{
-   struct tgsi_sampler *sampler = samplers[unit];
-
-#if 0
-   uint j;
-
-   debug_printf("%s sampler: %p (%p) store: %p\n", 
-                __FUNCTION__,
-                sampler, *sampler,
-                store );
-
-   debug_printf("lodbias %f\n", store[12]);
-
-   for (j = 0; j < 4; j++)
-      debug_printf("sample %d texcoord %f %f\n", 
-                   j, 
-                   store[0+j],
-                   store[4+j]);
-#endif
-
-   {
-      float rgba[NUM_CHANNELS][QUAD_SIZE];
-      sampler->get_samples(sampler,
-                           &store[0],
-                           &store[4],
-                           &store[8],
-                           0.0f, /*store[12],  lodbias */
-                           rgba);
-      memcpy(store, rgba, sizeof rgba);
-   }
-
-#if 0
-   for (j = 0; j < 4; j++)
-      debug_printf("sample %d result %f %f %f %f\n", 
-                   j, 
-                   store[0+j],
-                   store[4+j],
-                   store[8+j],
-                   store[12+j]);
-#endif
-}
-
 /**
  * High-level instruction translators.
  */
@@ -292,28 +245,28 @@ emit_tex( struct lp_build_tgsi_soa_context *bld,
           boolean apply_lodbias,
           boolean projected)
 {
-   LLVMTypeRef vec_type = lp_build_vec_type(bld->base.type);
    const uint unit = inst->FullSrcRegisters[1].SrcRegister.Index;
    LLVMValueRef lodbias;
    LLVMValueRef oow;
-   LLVMValueRef args[3];
-   unsigned count;
+   LLVMValueRef coords[3];
+   LLVMValueRef texel[4];
+   unsigned num_coords;
    unsigned i;
 
    switch (inst->InstructionExtTexture.Texture) {
    case TGSI_TEXTURE_1D:
    case TGSI_TEXTURE_SHADOW1D:
-      count = 1;
+      num_coords = 1;
       break;
    case TGSI_TEXTURE_2D:
    case TGSI_TEXTURE_RECT:
    case TGSI_TEXTURE_SHADOW2D:
    case TGSI_TEXTURE_SHADOWRECT:
-      count = 2;
+      num_coords = 2;
       break;
    case TGSI_TEXTURE_3D:
    case TGSI_TEXTURE_CUBE:
-      count = 3;
+      num_coords = 3;
       break;
    default:
       assert(0);
@@ -325,41 +278,22 @@ emit_tex( struct lp_build_tgsi_soa_context *bld,
    else
       lodbias = bld->base.zero;
 
-   if(!bld->store_ptr)
-      bld->store_ptr = LLVMBuildArrayAlloca(bld->base.builder,
-                                            vec_type,
-                                            LLVMConstInt(LLVMInt32Type(), 4, 0),
-                                            "store");
-
    if (projected) {
       oow = emit_fetch( bld, inst, 0, 3 );
       oow = lp_build_rcp(&bld->base, oow);
    }
 
-   for (i = 0; i < count; i++) {
-      LLVMValueRef index = LLVMConstInt(LLVMInt32Type(), i, 0);
-      LLVMValueRef coord_ptr = LLVMBuildGEP(bld->base.builder, bld->store_ptr, &index, 1, "");
-      LLVMValueRef coord;
-
-      coord = emit_fetch( bld, inst, 0, i );
-
+   for (i = 0; i < num_coords; i++) {
+      coords[i] = emit_fetch( bld, inst, 0, i );
       if (projected)
-         coord = lp_build_mul(&bld->base, coord, oow);
-
-      LLVMBuildStore(bld->base.builder, coord, coord_ptr);
+         coords[i] = lp_build_mul(&bld->base, coords[i], oow);
    }
 
-   args[0] = bld->samplers_ptr;
-   args[1] = LLVMConstInt(LLVMInt32Type(), unit, 0);
-   args[2] = bld->store_ptr;
-
-   lp_build_intrinsic(bld->base.builder, "fetch_texel", LLVMVoidType(), args, 3);
+   bld->emit_fetch_texel(bld->base.builder, bld->emit_fetch_texel_context,
+                         unit, num_coords, coords, lodbias, texel);
 
    FOR_EACH_DST0_ENABLED_CHANNEL( inst, i ) {
-      LLVMValueRef index = LLVMConstInt(LLVMInt32Type(), i, 0);
-      LLVMValueRef res_ptr = LLVMBuildGEP(bld->base.builder, bld->store_ptr, &index, 1, "");
-      LLVMValueRef res = LLVMBuildLoad(bld->base.builder, res_ptr, "");
-      emit_store( bld, inst, 0, i, res );
+      emit_store( bld, inst, 0, i, texel[i] );
    }
 }
 
@@ -1353,7 +1287,8 @@ lp_build_tgsi_soa(LLVMBuilderRef builder,
                   const LLVMValueRef *pos,
                   const LLVMValueRef (*inputs)[NUM_CHANNELS],
                   LLVMValueRef (*outputs)[NUM_CHANNELS],
-                  LLVMValueRef samplers_ptr)
+                  lp_emit_fetch_texel_soa_callback emit_fetch_texel,
+                  void *emit_fetch_texel_context)
 {
    struct lp_build_tgsi_soa_context bld;
    struct tgsi_parse_context parse;
@@ -1368,7 +1303,8 @@ lp_build_tgsi_soa(LLVMBuilderRef builder,
    bld.inputs = inputs;
    bld.outputs = outputs;
    bld.consts_ptr = consts_ptr;
-   bld.samplers_ptr = samplers_ptr;
+   bld.emit_fetch_texel = emit_fetch_texel;
+   bld.emit_fetch_texel_context = emit_fetch_texel_context;
 
    tgsi_parse_init( &parse, tokens );
 
index 39c4df836334fd2312e16cc6f44e073930d3090b..d288460a1b8a2cd8f452bcd3bdf7ce3dc7d34bcb 100644 (file)
@@ -38,7 +38,6 @@
 #include "util/u_memory.h"
 #include "lp_screen.h"
 #include "lp_bld_intr.h"
-#include "lp_bld_tgsi.h" /* for lp_build_tgsi_fetch_texel_soa */
 #include "lp_jit.h"
 
 
@@ -88,7 +87,7 @@ lp_jit_init_globals(struct llvmpipe_screen *screen)
       fetch_texel = lp_declare_intrinsic(screen->module, "fetch_texel",
                                          ret_type, arg_types, Elements(arg_types));
 
-      LLVMAddGlobalMapping(screen->engine, fetch_texel, lp_build_tgsi_fetch_texel_soa);
+      LLVMAddGlobalMapping(screen->engine, fetch_texel, lp_fetch_texel_soa);
    }
 
 #ifdef DEBUG
index 33010ad5fb8d93ab3886095236f8796d06a89201..a7fb60f9f5c6e87730d16e10777ba24f09a86f1b 100644 (file)
@@ -92,6 +92,11 @@ typedef void
                     void *color,
                     void *depth);
 
+void PIPE_CDECL
+lp_fetch_texel_soa( struct tgsi_sampler **samplers,
+                    uint32_t unit,
+                    float *store );
+
 
 void
 lp_jit_screen_cleanup(struct llvmpipe_screen *screen);
index 4981432eb382592004d652bd1a148e56aecf4f3c..94170bd71616239129dab564ad079e91743ee959 100644 (file)
@@ -71,6 +71,7 @@
 #include "lp_bld_type.h"
 #include "lp_bld_const.h"
 #include "lp_bld_conv.h"
+#include "lp_bld_intr.h"
 #include "lp_bld_logic.h"
 #include "lp_bld_depth.h"
 #include "lp_bld_interp.h"
@@ -172,6 +173,107 @@ generate_depth(struct llvmpipe_context *lp,
 }
 
 
+struct build_fetch_texel_context
+{
+   LLVMValueRef context_ptr;
+
+   LLVMValueRef samplers_ptr;
+
+   /** Coords/texels store */
+   LLVMValueRef store_ptr;
+};
+
+
+void PIPE_CDECL
+lp_fetch_texel_soa( struct tgsi_sampler **samplers,
+                    uint32_t unit,
+                    float *store )
+{
+   struct tgsi_sampler *sampler = samplers[unit];
+
+#if 0
+   uint j;
+
+   debug_printf("%s sampler: %p (%p) store: %p\n",
+                __FUNCTION__,
+                sampler, *sampler,
+                store );
+
+   debug_printf("lodbias %f\n", store[12]);
+
+   for (j = 0; j < 4; j++)
+      debug_printf("sample %d texcoord %f %f\n",
+                   j,
+                   store[0+j],
+                   store[4+j]);
+#endif
+
+   {
+      float rgba[NUM_CHANNELS][QUAD_SIZE];
+      sampler->get_samples(sampler,
+                           &store[0],
+                           &store[4],
+                           &store[8],
+                           0.0f, /*store[12],  lodbias */
+                           rgba);
+      memcpy(store, rgba, sizeof rgba);
+   }
+
+#if 0
+   for (j = 0; j < 4; j++)
+      debug_printf("sample %d result %f %f %f %f\n",
+                   j,
+                   store[0+j],
+                   store[4+j],
+                   store[8+j],
+                   store[12+j]);
+#endif
+}
+
+
+static void
+emit_fetch_texel( LLVMBuilderRef builder,
+                  void *context,
+                  unsigned unit,
+                  unsigned num_coords,
+                  const LLVMValueRef *coords,
+                  LLVMValueRef lodbias,
+                  LLVMValueRef *texel)
+{
+   struct build_fetch_texel_context *bld = context;
+   LLVMTypeRef vec_type = LLVMTypeOf(coords[0]);
+   LLVMValueRef args[3];
+   unsigned i;
+
+   if(!bld->samplers_ptr)
+      bld->samplers_ptr = lp_jit_context_samplers(builder, bld->context_ptr);
+
+   if(!bld->store_ptr)
+      bld->store_ptr = LLVMBuildArrayAlloca(builder,
+                                            vec_type,
+                                            LLVMConstInt(LLVMInt32Type(), 4, 0),
+                                            "texel_store");
+
+   for (i = 0; i < num_coords; i++) {
+      LLVMValueRef index = LLVMConstInt(LLVMInt32Type(), i, 0);
+      LLVMValueRef coord_ptr = LLVMBuildGEP(builder, bld->store_ptr, &index, 1, "");
+      LLVMBuildStore(builder, coords[i], coord_ptr);
+   }
+
+   args[0] = bld->samplers_ptr;
+   args[1] = LLVMConstInt(LLVMInt32Type(), unit, 0);
+   args[2] = bld->store_ptr;
+
+   lp_build_intrinsic(builder, "fetch_texel", LLVMVoidType(), args, 3);
+
+   for (i = 0; i < NUM_CHANNELS; ++i) {
+      LLVMValueRef index = LLVMConstInt(LLVMInt32Type(), i, 0);
+      LLVMValueRef texel_ptr = LLVMBuildGEP(builder, bld->store_ptr, &index, 1, "");
+      texel[i] = LLVMBuildLoad(builder, texel_ptr, "");
+   }
+}
+
+
 /**
  * Generate the fragment shader, depth/stencil test, and alpha tests.
  */
@@ -184,6 +286,7 @@ generate_fs(struct llvmpipe_context *lp,
             LLVMValueRef context_ptr,
             unsigned i,
             const struct lp_build_interp_soa_context *interp,
+            struct build_fetch_texel_context *sampler,
             LLVMValueRef *pmask,
             LLVMValueRef *color,
             LLVMValueRef depth_ptr)
@@ -193,7 +296,6 @@ generate_fs(struct llvmpipe_context *lp,
    LLVMTypeRef vec_type;
    LLVMTypeRef int_vec_type;
    LLVMValueRef consts_ptr;
-   LLVMValueRef samplers_ptr;
    LLVMValueRef outputs[PIPE_MAX_SHADER_OUTPUTS][NUM_CHANNELS];
    LLVMValueRef z = interp->pos[2];
    struct lp_build_mask_context mask;
@@ -206,7 +308,6 @@ generate_fs(struct llvmpipe_context *lp,
    int_vec_type = lp_build_int_vec_type(type);
 
    consts_ptr = lp_jit_context_constants(builder, context_ptr);
-   samplers_ptr = lp_jit_context_samplers(builder, context_ptr);
 
    lp_build_mask_begin(&mask, builder, type, *pmask);
 
@@ -226,7 +327,7 @@ generate_fs(struct llvmpipe_context *lp,
 
    lp_build_tgsi_soa(builder, tokens, type, &mask,
                      consts_ptr, interp->pos, interp->inputs,
-                     outputs, samplers_ptr);
+                     outputs, emit_fetch_texel, sampler);
 
    for (attrib = 0; attrib < shader->info.num_outputs; ++attrib) {
       for(chan = 0; chan < NUM_CHANNELS; ++chan) {
@@ -361,6 +462,7 @@ generate_fragment(struct llvmpipe_context *lp,
    LLVMBuilderRef builder;
    LLVMValueRef x0;
    LLVMValueRef y0;
+   struct build_fetch_texel_context sampler;
    struct lp_build_interp_soa_context interp;
    LLVMValueRef fs_mask[LP_MAX_VECTOR_LENGTH];
    LLVMValueRef fs_out_color[NUM_CHANNELS][LP_MAX_VECTOR_LENGTH];
@@ -484,6 +586,9 @@ generate_fragment(struct llvmpipe_context *lp,
                             a0_ptr, dadx_ptr, dady_ptr,
                             x0, y0, 2, 0);
 
+   memset(&sampler, 0, sizeof sampler);
+   sampler.context_ptr = context_ptr;
+
    for(i = 0; i < num_fs; ++i) {
       LLVMValueRef index = LLVMConstInt(LLVMInt32Type(), i, 0);
       LLVMValueRef out_color[NUM_CHANNELS];
@@ -501,6 +606,7 @@ generate_fragment(struct llvmpipe_context *lp,
                   context_ptr,
                   i,
                   &interp,
+                  &sampler,
                   &fs_mask[i],
                   out_color,
                   depth_ptr_i);