llvmpipe: Implement KIL.
authorJosé Fonseca <jfonseca@vmware.com>
Sun, 16 Aug 2009 20:01:57 +0000 (21:01 +0100)
committerJosé Fonseca <jfonseca@vmware.com>
Sat, 29 Aug 2009 08:21:33 +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_quad_fs.c
src/gallium/drivers/llvmpipe/lp_state.h
src/gallium/drivers/llvmpipe/lp_state_fs.c

index eb504622100638a2be9843a7140e31ab67ae4fe9..b61b2dc5bfdf387ea414d39801468eedfda6affb 100644 (file)
@@ -40,7 +40,7 @@ lp_build_tgsi_fetch_texel_soa( struct tgsi_sampler **samplers,
                                uint32_t unit,
                                float *store );
 
-void
+LLVMValueRef
 lp_build_tgsi_soa(LLVMBuilderRef builder,
                   const struct tgsi_token *tokens,
                   union lp_type type,
index 85c264947b4e1874047fa9689cb2ce1cb5b7dbcd..f60e79e6beb857be5e724c7eef69ed0378baa624 100644 (file)
@@ -31,6 +31,7 @@
 #include "util/u_debug.h"
 #include "util/u_math.h"
 #include "util/u_memory.h"
+#include "tgsi/tgsi_info.h"
 #include "tgsi/tgsi_parse.h"
 #include "tgsi/tgsi_util.h"
 #include "tgsi/tgsi_exec.h"
@@ -38,6 +39,7 @@
 #include "lp_bld_const.h"
 #include "lp_bld_intr.h"
 #include "lp_bld_arit.h"
+#include "lp_bld_logic.h"
 #include "lp_bld_swizzle.h"
 #include "lp_bld_tgsi.h"
 
@@ -85,6 +87,8 @@ struct lp_build_tgsi_soa_context
    LLVMValueRef immediates[LP_MAX_IMMEDIATES][NUM_CHANNELS];
    LLVMValueRef temps[LP_MAX_TEMPS][NUM_CHANNELS];
 
+   LLVMValueRef mask;
+
    /** Coords/texels store */
    LLVMValueRef store_ptr;
 };
@@ -356,88 +360,39 @@ emit_kil(
    struct lp_build_tgsi_soa_context *bld,
    const struct tgsi_full_src_register *reg )
 {
-#if 0
-   unsigned uniquemask;
-   unsigned unique_count = 0;
+   LLVMValueRef terms[NUM_CHANNELS];
    unsigned chan_index;
-   unsigned i;
 
-   /* This mask stores component bits that were already tested. Note that
-    * we test if the value is less than zero, so 1.0 and 0.0 need not to be
-    * tested. */
-   uniquemask = (1 << TGSI_EXTSWIZZLE_ZERO) | (1 << TGSI_EXTSWIZZLE_ONE);
+   memset(&terms, 0, sizeof terms);
 
    FOR_EACH_CHANNEL( chan_index ) {
       unsigned swizzle;
 
-      /* unswizzle channel */
-      swizzle = tgsi_util_get_full_src_register_extswizzle(
-         reg,
-         chan_index );
+      /* Unswizzle channel */
+      swizzle = tgsi_util_get_full_src_register_extswizzle( reg, chan_index );
 
-      /* check if the component has not been already tested */
-      if( !(uniquemask & (1 << swizzle)) ) {
-         uniquemask |= 1 << swizzle;
+      /* Note that we test if the value is less than zero, so 1.0 and 0.0 need
+       * not to be tested. */
+      if(swizzle == TGSI_EXTSWIZZLE_ZERO || swizzle == TGSI_EXTSWIZZLE_ONE)
+         continue;
 
-         /* allocate register */
-         emit_fetch(
-            bld,
-            unique_count++,
-            reg,
-            chan_index );
-      }
+      /* Check if the component has not been already tested. */
+      assert(swizzle < NUM_CHANNELS);
+      if( !terms[swizzle] )
+         /* TODO: change the comparison operator instead of setting the sign */
+         terms[swizzle] =  emit_fetch(bld, reg, chan_index );
    }
 
-   x86_push(
-      bld,
-      x86_make_reg( file_REG32, reg_AX ) );
-   x86_push(
-      bld,
-      x86_make_reg( file_REG32, reg_DX ) );
-
-   for (i = 0 ; i < unique_count; i++ ) {
-      LLVMValueRef dataXMM = make_xmm(i);
-
-      sse_cmpps(
-         bld,
-         dataXMM,
-         get_temp(
-            TGSI_EXEC_TEMP_00000000_I,
-            TGSI_EXEC_TEMP_00000000_C ),
-         cc_LessThan );
+   FOR_EACH_CHANNEL( chan_index ) {
+      LLVMValueRef mask;
+
+      mask = lp_build_cmp(&bld->base, PIPE_FUNC_GEQUAL, terms[chan_index], bld->base.zero);
       
-      if( i == 0 ) {
-         sse_movmskps(
-            bld,
-            x86_make_reg( file_REG32, reg_AX ),
-            dataXMM );
-      }
-      else {
-         sse_movmskps(
-            bld,
-            x86_make_reg( file_REG32, reg_DX ),
-            dataXMM );
-         x86_or(
-            bld,
-            x86_make_reg( file_REG32, reg_AX ),
-            x86_make_reg( file_REG32, reg_DX ) );
-      }
+      if(bld->mask)
+         bld->mask = LLVMBuildAnd(bld->base.builder, bld->mask, mask, "");
+      else
+         bld->mask = mask;
    }
-
-   x86_or(
-      bld,
-      get_temp(
-         TGSI_EXEC_TEMP_KILMASK_I,
-         TGSI_EXEC_TEMP_KILMASK_C ),
-      x86_make_reg( file_REG32, reg_AX ) );
-
-   x86_pop(
-      bld,
-      x86_make_reg( file_REG32, reg_DX ) );
-   x86_pop(
-      bld,
-      x86_make_reg( file_REG32, reg_AX ) );
-#endif
 }
 
 
@@ -953,12 +908,12 @@ emit_instruction(
       emit_kilp( bld );
       return 0; /* XXX fix me */
       break;
+#endif
 
    case TGSI_OPCODE_KIL:
       /* conditional kill */
       emit_kil( bld, &inst->FullSrcRegisters[0] );
       break;
-#endif
 
    case TGSI_OPCODE_PK2H:
       return 0;
@@ -1428,7 +1383,7 @@ emit_declaration(
  * \param immediates  buffer to place immediates, later passed to SSE bld
  * \param return  1 for success, 0 if translation failed
  */
-void
+LLVMValueRef
 lp_build_tgsi_soa(LLVMBuilderRef builder,
                   const struct tgsi_token *tokens,
                   union lp_type type,
@@ -1500,5 +1455,7 @@ lp_build_tgsi_soa(LLVMBuilderRef builder,
    }
 
    tgsi_parse_free( &parse );
+
+   return bld.mask;
 }
 
index f013aa68da14862d070db51f3aa15db9e29965af..5c37fab8e6f6a9c1d8e081b59b9f26e8e96f9318 100644 (file)
@@ -56,6 +56,7 @@ struct quad_shade_stage
    union tgsi_exec_channel ALIGN16_ATTRIB pos[NUM_CHANNELS];
 
    struct tgsi_exec_vector ALIGN16_ATTRIB outputs[PIPE_MAX_ATTRIBS];
+   uint32_t ALIGN16_ATTRIB mask[NUM_CHANNELS];
 };
 
 
@@ -109,6 +110,7 @@ shade_quad(struct quad_stage *qs, struct quad_header *quad)
    struct llvmpipe_context *llvmpipe = qs->llvmpipe;
    void *constants;
    struct tgsi_sampler **samplers;
+   unsigned chan_index;
    boolean z_written;
 
    /* Compute X, Y, Z, W vals for this quad */
@@ -120,6 +122,9 @@ shade_quad(struct quad_stage *qs, struct quad_header *quad)
    constants = llvmpipe->mapped_constants[PIPE_SHADER_FRAGMENT];
    samplers = (struct tgsi_sampler **)llvmpipe->tgsi.frag_samplers_list;
 
+   for (chan_index = 0; chan_index < NUM_CHANNELS; ++chan_index)
+      qss->mask[chan_index] = ~0;
+
    /* run shader */
    llvmpipe->fs->jit_function( qss->pos,
                                quad->coef->a0,
@@ -127,14 +132,14 @@ shade_quad(struct quad_stage *qs, struct quad_header *quad)
                                quad->coef->dady,
                                constants,
                                qss->outputs,
+                               qss->mask,
                                samplers);
 
-   /* FIXME */
-#if 0
-   quad->inout.mask &= ... ;
+   for (chan_index = 0; chan_index < NUM_CHANNELS; ++chan_index)
+      if(!qss->mask[chan_index])
+         quad->inout.mask &= ~(1 << chan_index);
    if (quad->inout.mask == 0)
       return FALSE;
-#endif
 
    /* store outputs */
    z_written = FALSE;
index 52e12fcbe61ec7605dbeffd4d367366b16299a20..b4bc89ea320174d122ae11f08c3c0dded124f1a8 100644 (file)
@@ -65,6 +65,7 @@ typedef void
                      const void *dady,
                      const void *consts,
                      void *outputs,
+                     uint32_t *mask,
                      struct tgsi_sampler **samplers);
 
 /**
index 157f4eb59c9b4359c563984dc368f7e197285f87..fd93d6f9b42919576975d61c191eab3ffa48510e 100644 (file)
@@ -51,7 +51,8 @@ shader_generate(struct llvmpipe_screen *screen,
    union lp_type type;
    LLVMTypeRef elem_type;
    LLVMTypeRef vec_type;
-   LLVMTypeRef arg_types[7];
+   LLVMTypeRef int_vec_type;
+   LLVMTypeRef arg_types[8];
    LLVMTypeRef func_type;
    LLVMValueRef pos_ptr;
    LLVMValueRef a0_ptr;
@@ -59,11 +60,13 @@ shader_generate(struct llvmpipe_screen *screen,
    LLVMValueRef dady_ptr;
    LLVMValueRef consts_ptr;
    LLVMValueRef outputs_ptr;
+   LLVMValueRef mask_ptr;
    LLVMValueRef samplers_ptr;
    LLVMBasicBlockRef block;
    LLVMBuilderRef builder;
    LLVMValueRef pos[NUM_CHANNELS];
    LLVMValueRef outputs[PIPE_MAX_SHADER_OUTPUTS][NUM_CHANNELS];
+   LLVMValueRef mask;
    char name[32];
    unsigned i, j;
 
@@ -76,6 +79,7 @@ shader_generate(struct llvmpipe_screen *screen,
 
    elem_type = lp_build_elem_type(type);
    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 */
@@ -83,7 +87,8 @@ shader_generate(struct llvmpipe_screen *screen,
    arg_types[3] = LLVMPointerType(elem_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 */
+   arg_types[6] = LLVMPointerType(int_vec_type, 0);    /* mask */
+   arg_types[7] = LLVMPointerType(LLVMInt8Type(), 0);  /* samplers */
 
    func_type = LLVMFunctionType(LLVMVoidType(), arg_types, Elements(arg_types), 0);
 
@@ -98,7 +103,8 @@ shader_generate(struct llvmpipe_screen *screen,
    dady_ptr = LLVMGetParam(shader->function, 3);
    consts_ptr = LLVMGetParam(shader->function, 4);
    outputs_ptr = LLVMGetParam(shader->function, 5);
-   samplers_ptr = LLVMGetParam(shader->function, 6);
+   mask_ptr = LLVMGetParam(shader->function, 6);
+   samplers_ptr = LLVMGetParam(shader->function, 7);
 
    LLVMSetValueName(pos_ptr, "pos");
    LLVMSetValueName(a0_ptr, "a0");
@@ -106,6 +112,7 @@ shader_generate(struct llvmpipe_screen *screen,
    LLVMSetValueName(dady_ptr, "dady");
    LLVMSetValueName(consts_ptr, "consts");
    LLVMSetValueName(outputs_ptr, "outputs");
+   LLVMSetValueName(mask_ptr, "mask");
    LLVMSetValueName(samplers_ptr, "samplers");
 
    block = LLVMAppendBasicBlock(shader->function, "entry");
@@ -120,9 +127,9 @@ shader_generate(struct llvmpipe_screen *screen,
 
    memset(outputs, 0, sizeof outputs);
 
-   lp_build_tgsi_soa(builder, tokens, type,
-                     pos, a0_ptr, dadx_ptr, dady_ptr,
-                     consts_ptr, outputs, samplers_ptr);
+   mask = 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) {
@@ -134,6 +141,9 @@ shader_generate(struct llvmpipe_screen *screen,
       }
    }
 
+   if(mask)
+      LLVMBuildStore(builder, mask, mask_ptr);
+
    LLVMBuildRetVoid(builder);;
 
    LLVMDisposeBuilder(builder);