#include "lp_bld_alpha.h"
-LLVMValueRef
+void
lp_build_alpha_test(LLVMBuilderRef builder,
const struct pipe_alpha_state *state,
union lp_type type,
- LLVMValueRef alpha,
- LLVMValueRef mask)
+ LLVMValueRef *mask,
+ LLVMValueRef alpha)
{
struct lp_build_context bld;
lp_build_name(test, "alpha_mask");
- if(mask)
- mask = LLVMBuildAnd(builder, mask, test, "");
- else
- mask = test;
+ lp_build_mask_and(builder, mask, test);
}
-
- return mask;
}
union lp_type;
-LLVMValueRef
+void
lp_build_alpha_test(LLVMBuilderRef builder,
const struct pipe_alpha_state *state,
union lp_type type,
- LLVMValueRef alpha,
- LLVMValueRef mask);
+ LLVMValueRef *mask,
+ LLVMValueRef alpha);
#endif /* !LP_BLD_ALPHA_H */
#include "lp_bld_logic.h"
+void
+lp_build_mask_and(LLVMBuilderRef builder,
+ LLVMValueRef *mask,
+ LLVMValueRef value)
+{
+ if(*mask)
+ *mask = LLVMBuildAnd(builder, *mask, value, "");
+ else
+ *mask = value;
+}
+
+
LLVMValueRef
lp_build_cmp(struct lp_build_context *bld,
unsigned func,
struct lp_build_context;
+/**
+ * Bitwise AND the mask with the given value, if a previous mask was set.
+ */
+void
+lp_build_mask_and(LLVMBuilderRef builder,
+ LLVMValueRef *mask,
+ LLVMValueRef value);
+
+
/**
* @param func is one of PIPE_FUNC_xxx
*/
uint32_t unit,
float *store );
-LLVMValueRef
+void
lp_build_tgsi_soa(LLVMBuilderRef builder,
const struct tgsi_token *tokens,
union lp_type type,
+ LLVMValueRef *mask,
LLVMValueRef *pos,
LLVMValueRef a0_ptr,
LLVMValueRef dadx_ptr,
LLVMValueRef immediates[LP_MAX_IMMEDIATES][NUM_CHANNELS];
LLVMValueRef temps[LP_MAX_TEMPS][NUM_CHANNELS];
- LLVMValueRef mask;
+ LLVMValueRef *mask;
/** Coords/texels store */
LLVMValueRef store_ptr;
mask = lp_build_cmp(&bld->base, PIPE_FUNC_GEQUAL, terms[chan_index], bld->base.zero);
- if(bld->mask)
- bld->mask = LLVMBuildAnd(bld->base.builder, bld->mask, mask, "");
- else
- bld->mask = mask;
+ lp_build_mask_and(bld->base.builder, bld->mask, mask);
}
}
}
}
}
-/**
- * Translate a TGSI vertex/fragment shader to SSE2 code.
- * Slightly different things are done for vertex vs. fragment shaders.
- *
- * \param tokens the TGSI input shader
- * \param bld the output SSE code/function
- * \param immediates buffer to place immediates, later passed to SSE bld
- * \param return 1 for success, 0 if translation failed
- */
-LLVMValueRef
+
+void
lp_build_tgsi_soa(LLVMBuilderRef builder,
const struct tgsi_token *tokens,
union lp_type type,
+ LLVMValueRef *mask,
LLVMValueRef *pos,
LLVMValueRef a0_ptr,
LLVMValueRef dadx_ptr,
/* Setup build context */
memset(&bld, 0, sizeof bld);
lp_build_context_init(&bld.base, builder, type);
+ bld.mask = mask;
bld.x = pos[0];
bld.y = pos[1];
bld.w = pos[3];
}
tgsi_parse_free( &parse );
-
- return bld.mask;
}
setup_pos_vector(builder, x, y, a0_ptr, dadx_ptr, dady_ptr, pos);
+ mask = LLVMBuildLoad(builder, mask_ptr, "");
+
memset(outputs, 0, sizeof outputs);
- mask = lp_build_tgsi_soa(builder, tokens, type,
- pos, a0_ptr, dadx_ptr, dady_ptr,
- consts_ptr, outputs, samplers_ptr);
+ lp_build_tgsi_soa(builder, tokens, type, &mask,
+ pos, a0_ptr, dadx_ptr, dady_ptr,
+ consts_ptr, outputs, samplers_ptr);
for (attrib = 0; attrib < shader->info.num_outputs; ++attrib) {
for(chan = 0; chan < NUM_CHANNELS; ++chan) {
/* Alpha test */
/* XXX: should the alpha reference value be passed separately? */
if(cbuf == 0 && chan == 3)
- mask = lp_build_alpha_test(builder, alpha, type, outputs[attrib][chan], mask);
+ lp_build_alpha_test(builder, &key->alpha, type, &mask,
+ outputs[attrib][chan]);
break;
}