diff options
Diffstat (limited to 'src/gallium')
| -rw-r--r-- | src/gallium/auxiliary/gallivm/lp_bld_flow.c | 2 | ||||
| -rw-r--r-- | src/gallium/auxiliary/gallivm/lp_bld_flow.h | 4 | ||||
| -rw-r--r-- | src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c | 157 | 
3 files changed, 153 insertions, 10 deletions
| diff --git a/src/gallium/auxiliary/gallivm/lp_bld_flow.c b/src/gallium/auxiliary/gallivm/lp_bld_flow.c index bc83138908..c2f35419ec 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_flow.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_flow.c @@ -308,7 +308,7 @@ lp_build_flow_scope_end(struct lp_build_flow_context *flow)   * Note: this function has no dependencies on the flow code and could   * be used elsewhere.   */ -static LLVMBasicBlockRef +LLVMBasicBlockRef  lp_build_insert_new_block(LLVMBuilderRef builder, const char *name)  {     LLVMBasicBlockRef current_block; diff --git a/src/gallium/auxiliary/gallivm/lp_bld_flow.h b/src/gallium/auxiliary/gallivm/lp_bld_flow.h index 4c225a0d4f..8bb22543ee 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_flow.h +++ b/src/gallium/auxiliary/gallivm/lp_bld_flow.h @@ -145,7 +145,9 @@ lp_build_else(struct lp_build_if_state *ctx);  void  lp_build_endif(struct lp_build_if_state *ctx); -               + +LLVMBasicBlockRef +lp_build_insert_new_block(LLVMBuilderRef builder, const char *name);  #endif /* !LP_BLD_FLOW_H */ diff --git a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c index fbb664d43a..085afe33de 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c @@ -95,6 +95,19 @@ struct lp_exec_mask {     int cond_stack_size;     LLVMValueRef cond_mask; +   LLVMValueRef break_stack[LP_TGSI_MAX_NESTING]; +   int break_stack_size; +   LLVMValueRef break_mask; + +   LLVMValueRef cont_stack[LP_TGSI_MAX_NESTING]; +   int cont_stack_size; +   LLVMValueRef cont_mask; + +   LLVMBasicBlockRef loop_stack[LP_TGSI_MAX_NESTING]; +   int loop_stack_size; +   LLVMBasicBlockRef loop_block; + +     LLVMValueRef exec_mask;  }; @@ -145,14 +158,33 @@ static void lp_exec_mask_init(struct lp_exec_mask *mask, struct lp_build_context     mask->bld = bld;     mask->has_mask = FALSE;     mask->cond_stack_size = 0; +   mask->loop_stack_size = 0; +   mask->break_stack_size = 0; +   mask->cont_stack_size = 0;     mask->int_vec_type = lp_build_int_vec_type(mask->bld->type);  }  static void lp_exec_mask_update(struct lp_exec_mask *mask)  { -   mask->exec_mask = mask->cond_mask; -   mask->has_mask = (mask->cond_stack_size > 0); +   if (mask->loop_stack_size) { +      /*for loops we need to update the entire mask at +       * runtime */ +      LLVMValueRef tmp; +      tmp = LLVMBuildAnd(mask->bld->builder, +                         mask->cont_mask, +                         mask->break_mask, +                         "maskcb"); +      mask->exec_mask = LLVMBuildAnd(mask->bld->builder, +                                     mask->cond_mask, +                                     tmp, +                                     "maskfull"); +   } else +      mask->exec_mask = mask->cond_mask; + + +   mask->has_mask = (mask->cond_stack_size > 0 || +                     mask->loop_stack_size > 0);  }  static void lp_exec_mask_cond_push(struct lp_exec_mask *mask, @@ -189,6 +221,102 @@ static void lp_exec_mask_cond_pop(struct lp_exec_mask *mask)     lp_exec_mask_update(mask);  } +static void lp_exec_bgnloop(struct lp_exec_mask *mask) +{ + +   if (mask->cont_stack_size == 0) +      mask->cont_mask = LLVMConstAllOnes(mask->int_vec_type); +   if (mask->cont_stack_size == 0) +      mask->break_mask = LLVMConstAllOnes(mask->int_vec_type); +   if (mask->cond_stack_size == 0) +      mask->cond_mask = LLVMConstAllOnes(mask->int_vec_type); +   mask->loop_stack[mask->loop_stack_size++] = mask->loop_block; +   mask->loop_block = lp_build_insert_new_block(mask->bld->builder, "bgnloop"); +   LLVMBuildBr(mask->bld->builder, mask->loop_block); +   LLVMPositionBuilderAtEnd(mask->bld->builder, mask->loop_block); + +   lp_exec_mask_update(mask); +} + +static void lp_exec_break(struct lp_exec_mask *mask) +{ +   LLVMValueRef exec_mask = LLVMBuildNot(mask->bld->builder, +                                         mask->exec_mask, +                                         "break"); + +   mask->break_stack[mask->break_stack_size++] = mask->break_mask; +   if (mask->break_stack_size > 1) { +      mask->break_mask = LLVMBuildAnd(mask->bld->builder, +                                      mask->break_mask, +                                      exec_mask, "break_full"); +   } else +      mask->break_mask = exec_mask; + +   lp_exec_mask_update(mask); +} + +static void lp_exec_continue(struct lp_exec_mask *mask) +{ +   LLVMValueRef exec_mask = LLVMBuildNot(mask->bld->builder, +                                         mask->exec_mask, +                                         ""); + +   mask->cont_stack[mask->cont_stack_size++] = mask->cont_mask; +   if (mask->cont_stack_size > 1) { +      mask->cont_mask = LLVMBuildAnd(mask->bld->builder, +                                     mask->cont_mask, +                                     exec_mask, ""); +   } else +      mask->cont_mask = exec_mask; + +   lp_exec_mask_update(mask); +} + + +static void lp_exec_endloop(struct lp_exec_mask *mask) +{ +   LLVMBasicBlockRef endloop; +   LLVMValueRef i1cond; + +   { /* convert our soa vector into i1 */ +      int i; +      LLVMValueRef packed = 0; +      for (i = 0; i < mask->bld->type.length; ++i) { +         LLVMValueRef component = LLVMBuildExtractElement( +            mask->bld->builder, +            mask->break_mask, +            LLVMConstInt(LLVMInt32Type(), i, 0), ""); +         if (packed) +            packed = LLVMBuildOr(mask->bld->builder, +                                 packed, component, ""); +         else +            packed = component; +      } +      i1cond = LLVMBuildICmp(mask->bld->builder, LLVMIntNE, +                             packed, +                             LLVMConstNull(LLVMTypeOf(packed)), +                             ""); +   } + +   endloop = lp_build_insert_new_block(mask->bld->builder, "endloop"); + +   LLVMBuildCondBr(mask->bld->builder, +                   i1cond, endloop, mask->loop_block); + +   LLVMPositionBuilderAtEnd(mask->bld->builder, endloop); + +   mask->loop_block = mask->loop_stack[--mask->loop_stack_size]; +   /* pop the break mask */ +   if (mask->cont_stack_size) { +      mask->cont_mask = mask->cont_stack[--mask->cont_stack_size]; +   } +   if (mask->break_stack_size) { +      mask->break_mask = mask->cont_stack[--mask->break_stack_size]; +   } + +   lp_exec_mask_update(mask); +} +  static void lp_exec_mask_store(struct lp_exec_mask *mask,                                 LLVMValueRef val,                                 LLVMValueRef dst) @@ -1363,10 +1491,9 @@ emit_instruction(     case TGSI_OPCODE_TXP:        emit_tex( bld, inst, FALSE, TRUE, dst0 );        break; -       +     case TGSI_OPCODE_BRK: -      /* FIXME */ -      return 0; +      lp_exec_break(&bld->exec_mask);        break;     case TGSI_OPCODE_IF: @@ -1380,6 +1507,10 @@ emit_instruction(        return 0;        break; +   case TGSI_OPCODE_BGNLOOP: +      lp_exec_bgnloop(&bld->exec_mask); +      break; +     case TGSI_OPCODE_REP:        /* deprecated */        assert(0); @@ -1400,6 +1531,10 @@ emit_instruction(        return 0;        break; +   case TGSI_OPCODE_ENDLOOP: +      lp_exec_endloop(&bld->exec_mask); +      break; +     case TGSI_OPCODE_ENDREP:        /* deprecated */        assert(0); @@ -1499,8 +1634,7 @@ emit_instruction(        break;     case TGSI_OPCODE_CONT: -      /* FIXME */ -      return 0; +      lp_exec_continue(&bld->exec_mask);        break;     case TGSI_OPCODE_EMIT: @@ -1603,7 +1737,14 @@ lp_build_tgsi_soa(LLVMBuilderRef builder,           assert( 0 );        }     } - +   if (0) { +      LLVMBasicBlockRef block = LLVMGetInsertBlock(builder); +      LLVMValueRef function = LLVMGetBasicBlockParent(block); +      debug_printf("11111111111111111111111111111 \n"); +      tgsi_dump(tokens, 0); +      LLVMDumpValue(function); +      debug_printf("2222222222222222222222222222 \n"); +   }     tgsi_parse_free( &parse );  } | 
