summaryrefslogtreecommitdiffstats
path: root/src/gallium/auxiliary/draw/draw_llvm.c
diff options
context:
space:
mode:
authorDave Airlie <[email protected]>2012-03-03 17:35:43 +0000
committerDave Airlie <[email protected]>2012-03-06 09:37:33 +0000
commitef3e26c2e43a000d5e5e6b673324b0ebdc918207 (patch)
treed019d347c7be506b4416593af51ee1c5ee887732 /src/gallium/auxiliary/draw/draw_llvm.c
parent9c465a95ac612b346759d35fd58a9edbb79eef67 (diff)
draw/llvm: add clip distance support
This add clipdistance support like the non-llvm draw paths, if we have a clip distance we compare with it instead of doing the dot4. We also have to put the have_clipvertex bit into the emitted vertex header. Fixes vs-clip-distance-all-planes-enabled, vs-clip-distance-const-reject, vs-clip-distance-enables, vs-clip-distance-implicitly-sized, vs-clip-distance-in-param, vs-clip-distance-uint-index. Signed-off-by: Dave Airlie <[email protected]> Reviewed-by: Brian Paul <[email protected]>
Diffstat (limited to 'src/gallium/auxiliary/draw/draw_llvm.c')
-rw-r--r--src/gallium/auxiliary/draw/draw_llvm.c123
1 files changed, 77 insertions, 46 deletions
diff --git a/src/gallium/auxiliary/draw/draw_llvm.c b/src/gallium/auxiliary/draw/draw_llvm.c
index d2b6799cea5..620d6dc8de3 100644
--- a/src/gallium/auxiliary/draw/draw_llvm.c
+++ b/src/gallium/auxiliary/draw/draw_llvm.c
@@ -720,7 +720,7 @@ store_aos(struct gallivm_state *gallivm,
LLVMValueRef io_ptr,
LLVMValueRef index,
LLVMValueRef value,
- LLVMValueRef clipmask)
+ LLVMValueRef clipmask, boolean have_clipdist)
{
LLVMBuilderRef builder = gallivm->builder;
LLVMValueRef id_ptr = draw_jit_header_id(gallivm, io_ptr);
@@ -737,8 +737,10 @@ store_aos(struct gallivm_state *gallivm,
* code here. See struct vertex_header in draw_private.h.
*/
assert(DRAW_TOTAL_CLIP_PLANES==14);
- /* initialize vertex id:16 = 0xffff, pad:1 = 0, edgeflag:1 = 1 */
+ /* initialize vertex id:16 = 0xffff, have_clipdist:1 = 0, edgeflag:1 = 1 */
vertex_id_pad_edgeflag = (0xffff << 16) | (1 << DRAW_TOTAL_CLIP_PLANES);
+ if (have_clipdist)
+ vertex_id_pad_edgeflag |= 1 << (DRAW_TOTAL_CLIP_PLANES+1);
val = lp_build_const_int32(gallivm, vertex_id_pad_edgeflag);
/* OR with the clipmask */
val = LLVMBuildOr(builder, val, clipmask, "");
@@ -802,7 +804,8 @@ store_aos_array(struct gallivm_state *gallivm,
LLVMValueRef aos[TGSI_NUM_CHANNELS],
int attrib,
int num_outputs,
- LLVMValueRef clipmask)
+ LLVMValueRef clipmask,
+ boolean have_clipdist)
{
LLVMBuilderRef builder = gallivm->builder;
LLVMValueRef attr_index = lp_build_const_int32(gallivm, attrib);
@@ -838,10 +841,10 @@ store_aos_array(struct gallivm_state *gallivm,
io_ptr, ind0, ind1, ind2, ind3, clipmask0, clipmask1, clipmask2, clipmask3);
#endif
/* store for each of the 4 vertices */
- store_aos(gallivm, io0_ptr, attr_index, aos[0], clipmask0);
- store_aos(gallivm, io1_ptr, attr_index, aos[1], clipmask1);
- store_aos(gallivm, io2_ptr, attr_index, aos[2], clipmask2);
- store_aos(gallivm, io3_ptr, attr_index, aos[3], clipmask3);
+ store_aos(gallivm, io0_ptr, attr_index, aos[0], clipmask0, have_clipdist);
+ store_aos(gallivm, io1_ptr, attr_index, aos[1], clipmask1, have_clipdist);
+ store_aos(gallivm, io2_ptr, attr_index, aos[2], clipmask2, have_clipdist);
+ store_aos(gallivm, io3_ptr, attr_index, aos[3], clipmask3, have_clipdist);
}
@@ -851,7 +854,7 @@ convert_to_aos(struct gallivm_state *gallivm,
LLVMValueRef (*outputs)[TGSI_NUM_CHANNELS],
LLVMValueRef clipmask,
int num_outputs,
- int max_vertices)
+ int max_vertices, boolean have_clipdist)
{
LLVMBuilderRef builder = gallivm->builder;
unsigned chan, attrib;
@@ -882,7 +885,7 @@ convert_to_aos(struct gallivm_state *gallivm,
aos,
attrib,
num_outputs,
- clipmask);
+ clipmask, have_clipdist);
}
#if DEBUG_STORE
lp_build_printf(builder, " # storing end\n");
@@ -1049,7 +1052,8 @@ generate_clipmask(struct draw_llvm *llvm,
boolean clip_user,
boolean clip_halfz,
unsigned ucp_enable,
- LLVMValueRef context_ptr)
+ LLVMValueRef context_ptr,
+ boolean *have_clipdist)
{
struct gallivm_state *gallivm = llvm->gallivm;
LLVMBuilderRef builder = gallivm->builder;
@@ -1062,6 +1066,15 @@ generate_clipmask(struct draw_llvm *llvm,
struct lp_type f32_type = lp_type_float_vec(32);
const unsigned pos = draw_current_shader_position_output(llvm->draw);
const unsigned cv = draw_current_shader_clipvertex_output(llvm->draw);
+ int num_written_clipdistance = llvm->draw->vs.vertex_shader->info.num_written_clipdistance;
+ bool have_cd = false;
+ unsigned cd[2];
+
+ cd[0] = draw_current_shader_clipdistance_output(llvm->draw, 0);
+ cd[1] = draw_current_shader_clipdistance_output(llvm->draw, 1);
+
+ if (cd[0] != pos || cd[1] != pos)
+ have_cd = true;
mask = lp_build_const_int_vec(gallivm, lp_type_int_vec(32), 0);
temp = lp_build_const_int_vec(gallivm, lp_type_int_vec(32), 0);
@@ -1150,40 +1163,57 @@ generate_clipmask(struct draw_llvm *llvm,
ucp_enable &= ~(1 << plane_idx);
plane_idx += 6;
- indices[0] = lp_build_const_int32(gallivm, 0);
- indices[1] = lp_build_const_int32(gallivm, plane_idx);
-
- indices[2] = lp_build_const_int32(gallivm, 0);
- plane_ptr = LLVMBuildGEP(builder, planes_ptr, indices, 3, "");
- plane1 = LLVMBuildLoad(builder, plane_ptr, "plane_x");
- planes = vec4f_from_scalar(gallivm, plane1, "plane4_x");
- sum = LLVMBuildFMul(builder, planes, cv_x, "");
-
- indices[2] = lp_build_const_int32(gallivm, 1);
- plane_ptr = LLVMBuildGEP(builder, planes_ptr, indices, 3, "");
- plane1 = LLVMBuildLoad(builder, plane_ptr, "plane_y");
- planes = vec4f_from_scalar(gallivm, plane1, "plane4_y");
- test = LLVMBuildFMul(builder, planes, cv_y, "");
- sum = LLVMBuildFAdd(builder, sum, test, "");
-
- indices[2] = lp_build_const_int32(gallivm, 2);
- plane_ptr = LLVMBuildGEP(builder, planes_ptr, indices, 3, "");
- plane1 = LLVMBuildLoad(builder, plane_ptr, "plane_z");
- planes = vec4f_from_scalar(gallivm, plane1, "plane4_z");
- test = LLVMBuildFMul(builder, planes, cv_z, "");
- sum = LLVMBuildFAdd(builder, sum, test, "");
-
- indices[2] = lp_build_const_int32(gallivm, 3);
- plane_ptr = LLVMBuildGEP(builder, planes_ptr, indices, 3, "");
- plane1 = LLVMBuildLoad(builder, plane_ptr, "plane_w");
- planes = vec4f_from_scalar(gallivm, plane1, "plane4_w");
- test = LLVMBuildFMul(builder, planes, cv_w, "");
- sum = LLVMBuildFAdd(builder, sum, test, "");
-
- test = lp_build_compare(gallivm, f32_type, PIPE_FUNC_GREATER, zero, sum);
- temp = lp_build_const_int_vec(gallivm, lp_type_int_vec(32), 1 << plane_idx);
- test = LLVMBuildAnd(builder, test, temp, "");
- mask = LLVMBuildOr(builder, mask, test, "");
+ if (have_cd && num_written_clipdistance) {
+ LLVMValueRef clipdist;
+ int i;
+ i = plane_idx - 6;
+
+ *have_clipdist = TRUE;
+ if (i < 4) {
+ clipdist = LLVMBuildLoad(builder, outputs[cd[0]][i], "");
+ } else {
+ clipdist = LLVMBuildLoad(builder, outputs[cd[1]][i-4], "");
+ }
+ test = lp_build_compare(gallivm, f32_type, PIPE_FUNC_GREATER, zero, clipdist);
+ temp = lp_build_const_int_vec(gallivm, lp_type_int_vec(32), 1 << plane_idx);
+ test = LLVMBuildAnd(builder, test, temp, "");
+ mask = LLVMBuildOr(builder, mask, test, "");
+ } else {
+ indices[0] = lp_build_const_int32(gallivm, 0);
+ indices[1] = lp_build_const_int32(gallivm, plane_idx);
+
+ indices[2] = lp_build_const_int32(gallivm, 0);
+ plane_ptr = LLVMBuildGEP(builder, planes_ptr, indices, 3, "");
+ plane1 = LLVMBuildLoad(builder, plane_ptr, "plane_x");
+ planes = vec4f_from_scalar(gallivm, plane1, "plane4_x");
+ sum = LLVMBuildFMul(builder, planes, cv_x, "");
+
+ indices[2] = lp_build_const_int32(gallivm, 1);
+ plane_ptr = LLVMBuildGEP(builder, planes_ptr, indices, 3, "");
+ plane1 = LLVMBuildLoad(builder, plane_ptr, "plane_y");
+ planes = vec4f_from_scalar(gallivm, plane1, "plane4_y");
+ test = LLVMBuildFMul(builder, planes, cv_y, "");
+ sum = LLVMBuildFAdd(builder, sum, test, "");
+
+ indices[2] = lp_build_const_int32(gallivm, 2);
+ plane_ptr = LLVMBuildGEP(builder, planes_ptr, indices, 3, "");
+ plane1 = LLVMBuildLoad(builder, plane_ptr, "plane_z");
+ planes = vec4f_from_scalar(gallivm, plane1, "plane4_z");
+ test = LLVMBuildFMul(builder, planes, cv_z, "");
+ sum = LLVMBuildFAdd(builder, sum, test, "");
+
+ indices[2] = lp_build_const_int32(gallivm, 3);
+ plane_ptr = LLVMBuildGEP(builder, planes_ptr, indices, 3, "");
+ plane1 = LLVMBuildLoad(builder, plane_ptr, "plane_w");
+ planes = vec4f_from_scalar(gallivm, plane1, "plane4_w");
+ test = LLVMBuildFMul(builder, planes, cv_w, "");
+ sum = LLVMBuildFAdd(builder, sum, test, "");
+
+ test = lp_build_compare(gallivm, f32_type, PIPE_FUNC_GREATER, zero, sum);
+ temp = lp_build_const_int_vec(gallivm, lp_type_int_vec(32), 1 << plane_idx);
+ test = LLVMBuildAnd(builder, test, temp, "");
+ mask = LLVMBuildOr(builder, mask, test, "");
+ }
}
}
return mask;
@@ -1252,6 +1282,7 @@ draw_llvm_generate(struct draw_llvm *llvm, struct draw_llvm_variant *variant,
LLVMValueRef variant_func;
const unsigned pos = draw_current_shader_position_output(llvm->draw);
const unsigned cv = draw_current_shader_clipvertex_output(llvm->draw);
+ boolean have_clipdist = FALSE;
arg_types[0] = get_context_ptr_type(llvm); /* context */
arg_types[1] = get_vertex_header_ptr_type(llvm); /* vertex_header */
@@ -1417,7 +1448,7 @@ draw_llvm_generate(struct draw_llvm *llvm, struct draw_llvm_variant *variant,
variant->key.clip_user,
variant->key.clip_halfz,
variant->key.ucp_enable,
- context_ptr);
+ context_ptr, &have_clipdist);
/* return clipping boolean value for function */
clipmask_bool(gallivm, clipmask, ret_ptr);
}
@@ -1435,7 +1466,7 @@ draw_llvm_generate(struct draw_llvm *llvm, struct draw_llvm_variant *variant,
* and transformed positions in data
*/
convert_to_aos(gallivm, io, outputs, clipmask,
- vs_info->num_outputs, max_vertices);
+ vs_info->num_outputs, max_vertices, have_clipdist);
}
lp_build_loop_end_cond(&lp_loop, end, step, LLVMIntUGE);