iris: Don't enable smooth points when point sprites are enabled
[mesa.git] / src / gallium / auxiliary / gallivm / lp_bld_flow.c
index a9c9c7af10c2d046fe28124b853c40b06af4d047..c522bc4f4ab30aeb6647434bb55daffda2cfc1ae 100644 (file)
@@ -131,6 +131,15 @@ lp_build_mask_check(struct lp_build_mask_context *mask)
 
    value = lp_build_mask_value(mask);
 
+   /*
+    * XXX this doesn't quite generate the most efficient code possible, if
+    * the masks are vectors which have all bits set to the same value
+    * in each element.
+    * movmskps/pmovmskb would be more efficient to get the required value
+    * into ordinary reg (certainly with 8 floats).
+    * Not sure if llvm could figure that out on its own.
+    */
+
    /* cond = (mask == 0) */
    cond = LLVMBuildICmp(builder,
                         LLVMIntEQ,
@@ -179,7 +188,7 @@ lp_build_mask_value(struct lp_build_mask_context *mask)
 /**
  * Update boolean mask with given value (bitwise AND).
  * Typically used to update the quad's pixel alive/killed mask
- * after depth testing, alpha testing, TGSI_OPCODE_KIL, etc.
+ * after depth testing, alpha testing, TGSI_OPCODE_KILL_IF, etc.
  */
 void
 lp_build_mask_update(struct lp_build_mask_context *mask,
@@ -265,6 +274,73 @@ lp_build_loop_end(struct lp_build_loop_state *state,
    lp_build_loop_end_cond(state, end, step, LLVMIntNE);
 }
 
+/**
+ * Creates a c-style for loop,
+ * contrasts lp_build_loop as this checks condition on entry
+ * e.g. for(i = start; i cmp_op end; i += step)
+ * \param state      the for loop state, initialized here
+ * \param gallivm    the gallivm state
+ * \param start      starting value of iterator
+ * \param cmp_op     comparison operator used for comparing current value with end value
+ * \param end        value used to compare against iterator
+ * \param step       value added to iterator at end of each loop
+ */
+void
+lp_build_for_loop_begin(struct lp_build_for_loop_state *state,
+                        struct gallivm_state *gallivm,
+                        LLVMValueRef start,
+                        LLVMIntPredicate cmp_op,
+                        LLVMValueRef end,
+                        LLVMValueRef step)
+{
+   LLVMBuilderRef builder = gallivm->builder;
+
+   assert(LLVMTypeOf(start) == LLVMTypeOf(end));
+   assert(LLVMTypeOf(start) == LLVMTypeOf(step));
+
+   state->begin = lp_build_insert_new_block(gallivm, "loop_begin");
+   state->step  = step;
+   state->counter_var = lp_build_alloca(gallivm, LLVMTypeOf(start), "loop_counter");
+   state->gallivm = gallivm;
+   state->cond = cmp_op;
+   state->end = end;
+
+   LLVMBuildStore(builder, start, state->counter_var);
+   LLVMBuildBr(builder, state->begin);
+
+   LLVMPositionBuilderAtEnd(builder, state->begin);
+   state->counter = LLVMBuildLoad(builder, state->counter_var, "");
+
+   state->body = lp_build_insert_new_block(gallivm, "loop_body");
+   LLVMPositionBuilderAtEnd(builder, state->body);
+}
+
+/**
+ * End the for loop.
+ */
+void
+lp_build_for_loop_end(struct lp_build_for_loop_state *state)
+{
+   LLVMValueRef next, cond;
+   LLVMBuilderRef builder = state->gallivm->builder;
+
+   next = LLVMBuildAdd(builder, state->counter, state->step, "");
+   LLVMBuildStore(builder, next, state->counter_var);
+   LLVMBuildBr(builder, state->begin);
+
+   state->exit = lp_build_insert_new_block(state->gallivm, "loop_exit");
+
+   /*
+    * We build the comparison for the begin block here,
+    * if we build it earlier the output llvm ir is not human readable
+    * as the code produced is not in the standard begin -> body -> end order.
+    */
+   LLVMPositionBuilderAtEnd(builder, state->begin);
+   cond = LLVMBuildICmp(builder, state->cond, state->counter, state->end, "");
+   LLVMBuildCondBr(builder, cond, state->body, state->exit);
+
+   LLVMPositionBuilderAtEnd(builder, state->exit);
+}
 
 
 /*
@@ -378,6 +454,26 @@ lp_build_endif(struct lp_build_if_state *ifthen)
 }
 
 
+static LLVMBuilderRef
+create_builder_at_entry(struct gallivm_state *gallivm)
+{
+   LLVMBuilderRef builder = gallivm->builder;
+   LLVMBasicBlockRef current_block = LLVMGetInsertBlock(builder);
+   LLVMValueRef function = LLVMGetBasicBlockParent(current_block);
+   LLVMBasicBlockRef first_block = LLVMGetEntryBasicBlock(function);
+   LLVMValueRef first_instr = LLVMGetFirstInstruction(first_block);
+   LLVMBuilderRef first_builder = LLVMCreateBuilderInContext(gallivm->context);
+
+   if (first_instr) {
+      LLVMPositionBuilderBefore(first_builder, first_instr);
+   } else {
+      LLVMPositionBuilderAtEnd(first_builder, first_block);
+   }
+
+   return first_builder;
+}
+
+
 /**
  * Allocate a scalar (or vector) variable.
  *
@@ -399,19 +495,9 @@ lp_build_alloca(struct gallivm_state *gallivm,
                 const char *name)
 {
    LLVMBuilderRef builder = gallivm->builder;
-   LLVMBasicBlockRef current_block = LLVMGetInsertBlock(builder);
-   LLVMValueRef function = LLVMGetBasicBlockParent(current_block);
-   LLVMBasicBlockRef first_block = LLVMGetEntryBasicBlock(function);
-   LLVMValueRef first_instr = LLVMGetFirstInstruction(first_block);
-   LLVMBuilderRef first_builder = LLVMCreateBuilderInContext(gallivm->context);
+   LLVMBuilderRef first_builder = create_builder_at_entry(gallivm);
    LLVMValueRef res;
 
-   if (first_instr) {
-      LLVMPositionBuilderBefore(first_builder, first_instr);
-   } else {
-      LLVMPositionBuilderAtEnd(first_builder, first_block);
-   }
-
    res = LLVMBuildAlloca(first_builder, type, name);
    LLVMBuildStore(builder, LLVMConstNull(type), res);
 
@@ -421,6 +507,25 @@ lp_build_alloca(struct gallivm_state *gallivm,
 }
 
 
+/**
+ * Like lp_build_alloca, but do not zero-initialize the variable.
+ */
+LLVMValueRef
+lp_build_alloca_undef(struct gallivm_state *gallivm,
+                      LLVMTypeRef type,
+                      const char *name)
+{
+   LLVMBuilderRef first_builder = create_builder_at_entry(gallivm);
+   LLVMValueRef res;
+
+   res = LLVMBuildAlloca(first_builder, type, name);
+
+   LLVMDisposeBuilder(first_builder);
+
+   return res;
+}
+
+
 /**
  * Allocate an array of scalars/vectors.
  *
@@ -441,20 +546,9 @@ lp_build_array_alloca(struct gallivm_state *gallivm,
                       LLVMValueRef count,
                       const char *name)
 {
-   LLVMBuilderRef builder = gallivm->builder;
-   LLVMBasicBlockRef current_block = LLVMGetInsertBlock(builder);
-   LLVMValueRef function = LLVMGetBasicBlockParent(current_block);
-   LLVMBasicBlockRef first_block = LLVMGetEntryBasicBlock(function);
-   LLVMValueRef first_instr = LLVMGetFirstInstruction(first_block);
-   LLVMBuilderRef first_builder = LLVMCreateBuilderInContext(gallivm->context);
+   LLVMBuilderRef first_builder = create_builder_at_entry(gallivm);
    LLVMValueRef res;
 
-   if (first_instr) {
-      LLVMPositionBuilderBefore(first_builder, first_instr);
-   } else {
-      LLVMPositionBuilderAtEnd(first_builder, first_block);
-   }
-
    res = LLVMBuildArrayAlloca(first_builder, type, count, name);
 
    LLVMDisposeBuilder(first_builder);