From 94f65d095a1365b69a041302b473e40c6ccae3c3 Mon Sep 17 00:00:00 2001 From: Hui Qi Tay Date: Tue, 28 Sep 2010 17:49:25 +0100 Subject: draw: cliptest and viewport done in a single loop in vertex shader Cliptesting now done at the end of vs in draw_llvm instead of draw_pt_post_vs. Added viewport mapping transformation and further cliptesting to vertex shader in draw_llvm.c Alternative path where vertex header setup, clip coordinates store, cliptesting and viewport mapping are done earlier in the vertex shader. Still need to hook this up properly according to the return value of "draw_llvm_shader" function. --- src/gallium/auxiliary/draw/draw_llvm.c | 314 ++++++++++++++++++++++++++++++--- src/gallium/auxiliary/draw/draw_llvm.h | 6 +- 2 files changed, 293 insertions(+), 27 deletions(-) (limited to 'src/gallium/auxiliary/draw') diff --git a/src/gallium/auxiliary/draw/draw_llvm.c b/src/gallium/auxiliary/draw/draw_llvm.c index 5154c1f3c5..36254d359c 100644 --- a/src/gallium/auxiliary/draw/draw_llvm.c +++ b/src/gallium/auxiliary/draw/draw_llvm.c @@ -31,6 +31,9 @@ #include "draw_vs.h" #include "gallivm/lp_bld_arit.h" +#include "gallivm/lp_bld_logic.h" +#include "gallivm/lp_bld_const.h" +#include "gallivm/lp_bld_swizzle.h" #include "gallivm/lp_bld_struct.h" #include "gallivm/lp_bld_type.h" #include "gallivm/lp_bld_flow.h" @@ -549,19 +552,28 @@ static void store_aos(LLVMBuilderRef builder, LLVMValueRef io_ptr, LLVMValueRef index, - LLVMValueRef value) + LLVMValueRef value, + LLVMValueRef clipmask) { LLVMValueRef id_ptr = draw_jit_header_id(builder, io_ptr); LLVMValueRef data_ptr = draw_jit_header_data(builder, io_ptr); LLVMValueRef indices[3]; + LLVMValueRef val, shift; indices[0] = LLVMConstInt(LLVMInt32Type(), 0, 0); indices[1] = index; indices[2] = LLVMConstInt(LLVMInt32Type(), 0, 0); - /* undefined vertex */ - LLVMBuildStore(builder, LLVMConstInt(LLVMInt32Type(), - 0xffff, 0), id_ptr); + /* initialize vertex id:16 = 0xffff, pad:3 = 0, edgeflag:1 = 1 */ + val = LLVMConstInt(LLVMInt32Type(), 0xffff1, 0); + shift = LLVMConstInt(LLVMInt32Type(), 12, 0); + val = LLVMBuildShl(builder, val, shift, ""); + /* add clipmask:12 */ + val = LLVMBuildOr(builder, val, clipmask, ""); + + /* store vertex header */ + LLVMBuildStore(builder, val, id_ptr); + #if DEBUG_STORE lp_build_printf(builder, " ---- %p storing attribute %d (io = %p)\n", data_ptr, index, io_ptr); @@ -616,7 +628,8 @@ store_aos_array(LLVMBuilderRef builder, LLVMValueRef io_ptr, LLVMValueRef aos[NUM_CHANNELS], int attrib, - int num_outputs) + int num_outputs, + LLVMValueRef clipmask) { LLVMValueRef attr_index = LLVMConstInt(LLVMInt32Type(), attrib, 0); LLVMValueRef ind0 = LLVMConstInt(LLVMInt32Type(), 0, 0); @@ -624,7 +637,8 @@ store_aos_array(LLVMBuilderRef builder, LLVMValueRef ind2 = LLVMConstInt(LLVMInt32Type(), 2, 0); LLVMValueRef ind3 = LLVMConstInt(LLVMInt32Type(), 3, 0); LLVMValueRef io0_ptr, io1_ptr, io2_ptr, io3_ptr; - + LLVMValueRef clipmask0, clipmask1, clipmask2, clipmask3; + debug_assert(NUM_CHANNELS == 4); io0_ptr = LLVMBuildGEP(builder, io_ptr, @@ -636,21 +650,31 @@ store_aos_array(LLVMBuilderRef builder, io3_ptr = LLVMBuildGEP(builder, io_ptr, &ind3, 1, ""); + clipmask0 = LLVMBuildExtractElement(builder, clipmask, + ind0, ""); + clipmask1 = LLVMBuildExtractElement(builder, clipmask, + ind1, ""); + clipmask2 = LLVMBuildExtractElement(builder, clipmask, + ind2, ""); + clipmask3 = LLVMBuildExtractElement(builder, clipmask, + ind3, ""); + #if DEBUG_STORE - lp_build_printf(builder, " io = %p, indexes[%d, %d, %d, %d]\n", - io_ptr, ind0, ind1, ind2, ind3); + lp_build_printf(builder, "io = %p, indexes[%d, %d, %d, %d]\n, clipmask0 = %x, clipmask1 = %x, clipmask2 = %x, clipmask3 = %x\n", + io_ptr, ind0, ind1, ind2, ind3, clipmask0, clipmask1, clipmask2, clipmask3); #endif - - store_aos(builder, io0_ptr, attr_index, aos[0]); - store_aos(builder, io1_ptr, attr_index, aos[1]); - store_aos(builder, io2_ptr, attr_index, aos[2]); - store_aos(builder, io3_ptr, attr_index, aos[3]); + /* store for each of the 4 vertices */ + store_aos(builder, io0_ptr, attr_index, aos[0], clipmask0); + store_aos(builder, io1_ptr, attr_index, aos[1], clipmask1); + store_aos(builder, io2_ptr, attr_index, aos[2], clipmask2); + store_aos(builder, io3_ptr, attr_index, aos[3], clipmask3); } static void convert_to_aos(LLVMBuilderRef builder, LLVMValueRef io, LLVMValueRef (*outputs)[NUM_CHANNELS], + LLVMValueRef clipmask, int num_outputs, int max_vertices) { @@ -679,13 +703,214 @@ convert_to_aos(LLVMBuilderRef builder, io, aos, attrib, - num_outputs); + num_outputs, + clipmask); } #if DEBUG_STORE lp_build_printf(builder, " # storing end\n"); #endif } +/* + * Stores original vertex positions in clip coordinates + * There is probably a more efficient way to do this, 4 floats at once + * rather than extracting each element one by one. + */ +static void +store_clip(LLVMBuilderRef builder, + LLVMValueRef io_ptr, + LLVMValueRef (*outputs)[NUM_CHANNELS]) +{ + LLVMValueRef out[4]; + LLVMValueRef indices[2]; + LLVMValueRef io0_ptr, io1_ptr, io2_ptr, io3_ptr; + LLVMValueRef clip_ptr0, clip_ptr1, clip_ptr2, clip_ptr3; + LLVMValueRef clip0_ptr, clip1_ptr, clip2_ptr, clip3_ptr; + LLVMValueRef out0elem, out1elem, out2elem, out3elem; + + LLVMValueRef ind0 = LLVMConstInt(LLVMInt32Type(), 0, 0); + LLVMValueRef ind1 = LLVMConstInt(LLVMInt32Type(), 1, 0); + LLVMValueRef ind2 = LLVMConstInt(LLVMInt32Type(), 2, 0); + LLVMValueRef ind3 = LLVMConstInt(LLVMInt32Type(), 3, 0); + + indices[0] = LLVMConstInt(LLVMInt32Type(), 0, 0); + indices[1] = LLVMConstInt(LLVMInt32Type(), 0, 0); + + out[0] = LLVMBuildLoad(builder, outputs[0][0], ""); /*x0 y0 z0 w0*/ + out[1] = LLVMBuildLoad(builder, outputs[0][1], ""); /*x1 y1 z1 w1*/ + out[2] = LLVMBuildLoad(builder, outputs[0][2], ""); /*x2 y2 z2 w2*/ + out[3] = LLVMBuildLoad(builder, outputs[0][3], ""); /*x3 y3 z3 w3*/ + + io0_ptr = LLVMBuildGEP(builder, io_ptr, &ind0, 1, ""); + io1_ptr = LLVMBuildGEP(builder, io_ptr, &ind1, 1, ""); + io2_ptr = LLVMBuildGEP(builder, io_ptr, &ind2, 1, ""); + io3_ptr = LLVMBuildGEP(builder, io_ptr, &ind3, 1, ""); + + clip_ptr0 = draw_jit_header_clip(builder, io0_ptr); + clip_ptr1 = draw_jit_header_clip(builder, io1_ptr); + clip_ptr2 = draw_jit_header_clip(builder, io2_ptr); + clip_ptr3 = draw_jit_header_clip(builder, io3_ptr); + + for (int i = 0; i<4; i++){ + clip0_ptr = LLVMBuildGEP(builder, clip_ptr0, + indices, 2, ""); //x1 + clip1_ptr = LLVMBuildGEP(builder, clip_ptr1, + indices, 2, ""); //y1 + clip2_ptr = LLVMBuildGEP(builder, clip_ptr2, + indices, 2, ""); //z1 + clip3_ptr = LLVMBuildGEP(builder, clip_ptr3, + indices, 2, ""); //w1 + + out0elem = LLVMBuildExtractElement(builder, out[0], + indices[1], ""); //x1 + out1elem = LLVMBuildExtractElement(builder, out[1], + indices[1], ""); //y1 + out2elem = LLVMBuildExtractElement(builder, out[2], + indices[1], ""); //z1 + out3elem = LLVMBuildExtractElement(builder, out[3], + indices[1], ""); //w1 + + LLVMBuildStore(builder, out0elem, clip0_ptr); + LLVMBuildStore(builder, out1elem, clip1_ptr); + LLVMBuildStore(builder, out2elem, clip2_ptr); + LLVMBuildStore(builder, out3elem, clip3_ptr); + + indices[1]= LLVMBuildAdd(builder, indices[1], ind1, ""); + } + +} + +/* + * Transforms the outputs for viewport mapping + */ +static void +generate_viewport(struct draw_llvm *llvm, + LLVMBuilderRef builder, + LLVMValueRef (*outputs)[NUM_CHANNELS]) +{ + int i; + const float *scaleA = llvm->draw->viewport.scale; + const float *transA = llvm->draw->viewport.translate; + struct lp_type f32_type = lp_type_float_vec(32); + LLVMValueRef out3 = LLVMBuildLoad(builder, outputs[0][3], ""); /*w0 w1 w2 w3*/ + LLVMValueRef const1 = lp_build_const_vec(f32_type, 1.0); /*1.0 1.0 1.0 1.0*/ + + /* for 1/w convention*/ + out3 = LLVMBuildFDiv(builder, const1, out3, ""); + + /* Viewport Mapping */ + for (i=0; i<4; i++){ + LLVMValueRef out = LLVMBuildLoad(builder, outputs[0][i], ""); /*x0 x1 x2 x3*/ + LLVMValueRef scale = lp_build_const_vec(f32_type, scaleA[i]); /*sx sx sx sx*/ + LLVMValueRef trans = lp_build_const_vec(f32_type, transA[i]); /*tx tx tx tx*/ + + /* divide by w */ + out = LLVMBuildMul(builder, out, out3, ""); + /* mult by scale */ + out = LLVMBuildMul(builder, out, scale, ""); + /* add translation */ + out = LLVMBuildAdd(builder, out, trans, ""); + + /* store transformed outputs */ + LLVMBuildStore(builder, out, outputs[0][i]); + } + +} + +/* + * Returns clipmask as 4xi32 bitmask for the 4 vertices + */ +static LLVMValueRef +generate_clipmask(LLVMBuilderRef builder, + LLVMValueRef (*outputs)[NUM_CHANNELS]) +{ + LLVMValueRef mask; /* stores the <4xi32> clipmasks */ + LLVMValueRef test, temp; + LLVMValueRef zero, shift; + LLVMValueRef pos_x, pos_y, pos_z, pos_w; + + struct lp_type f32_type = lp_type_float_vec(32); + + zero = lp_build_const_vec(f32_type, 0); /* 0.0f 0.0f 0.0f 0.0f */ + shift = lp_build_const_int_vec(lp_type_int_vec(32), 1); /* 1 1 1 1 */ + + /* Assuming position stored at output[0] */ + pos_x = LLVMBuildLoad(builder, outputs[0][0], ""); /*x0 x1 x2 x3*/ + pos_y = LLVMBuildLoad(builder, outputs[0][1], ""); /*y0 y1 y2 y3*/ + pos_z = LLVMBuildLoad(builder, outputs[0][2], ""); /*z0 z1 z2 z3*/ + pos_w = LLVMBuildLoad(builder, outputs[0][3], ""); /*w0 w1 w2 w3*/ + + /* Cliptest, for hardwired planes */ + /* plane 1 */ + test = lp_build_compare(builder, f32_type, PIPE_FUNC_GREATER, pos_x , pos_w); + temp = shift; + test = LLVMBuildAnd(builder, test, temp, ""); + mask = test; + + /* plane 2 */ + test = LLVMBuildFAdd(builder, pos_x, pos_w, ""); + test = lp_build_compare(builder, f32_type, PIPE_FUNC_GREATER, zero, test); + temp = LLVMBuildShl(builder, temp, shift, ""); + test = LLVMBuildAnd(builder, test, temp, ""); + mask = LLVMBuildOr(builder, mask, test, ""); + + /* plane 3 */ + test = lp_build_compare(builder, f32_type, PIPE_FUNC_GREATER, pos_y, pos_w); + temp = LLVMBuildShl(builder, temp, shift, ""); + test = LLVMBuildAnd(builder, test, temp, ""); + mask = LLVMBuildOr(builder, mask, test, ""); + + /* plane 4 */ + test = LLVMBuildFAdd(builder, pos_y, pos_w, ""); + test = lp_build_compare(builder, f32_type, PIPE_FUNC_GREATER, zero, test); + temp = LLVMBuildShl(builder, temp, shift, ""); + test = LLVMBuildAnd(builder, test, temp, ""); + mask = LLVMBuildOr(builder, mask, test, ""); + + /* plane 5 */ + test = LLVMBuildFAdd(builder, pos_z, pos_w, ""); + test = lp_build_compare(builder, f32_type, PIPE_FUNC_GREATER, zero, test); + temp = LLVMBuildShl(builder, temp, shift, ""); + test = LLVMBuildAnd(builder, test, temp, ""); + mask = LLVMBuildOr(builder, mask, test, ""); + + /* plane 6 */ + test = lp_build_compare(builder, f32_type, PIPE_FUNC_GREATER, pos_z, pos_w); + temp = LLVMBuildShl(builder, temp, shift, ""); + test = LLVMBuildAnd(builder, test, temp, ""); + mask = LLVMBuildOr(builder, mask, test, ""); + + return mask; + +} + +/* + * Returns boolean if any clipping has occurred + * Used zero/non-zero i32 value to represent boolean + */ +static void +clipmask_bool(LLVMBuilderRef builder, + LLVMValueRef clipmask, + LLVMValueRef ret_ptr) +{ + LLVMValueRef ret = LLVMBuildLoad(builder, ret_ptr, ""); + LLVMValueRef temp; + int i; + + LLVMDumpValue(clipmask); + + for (i=0; i<4; i++){ + temp = LLVMBuildExtractElement(builder, clipmask, + LLVMConstInt(LLVMInt32Type(), i, 0) , ""); + ret = LLVMBuildOr(builder, ret, temp, ""); + LLVMDumpValue(ret); + } + + LLVMBuildStore(builder, ret, ret_ptr); + LLVMDumpValue(ret_ptr); + +} + static void draw_llvm_generate(struct draw_llvm *llvm, struct draw_llvm_variant *variant) { @@ -706,6 +931,8 @@ draw_llvm_generate(struct draw_llvm *llvm, struct draw_llvm_variant *variant) void *code; struct lp_build_sampler_soa *sampler = 0; + LLVMValueRef ret, ret_ptr; + arg_types[0] = llvm->context_ptr_type; /* context */ arg_types[1] = llvm->vertex_header_ptr_type; /* vertex_header */ arg_types[2] = llvm->buffer_ptr_type; /* vbuffers */ @@ -715,7 +942,7 @@ draw_llvm_generate(struct draw_llvm *llvm, struct draw_llvm_variant *variant) arg_types[6] = llvm->vb_ptr_type; /* pipe_vertex_buffer's */ arg_types[7] = LLVMInt32Type(); /* instance_id */ - func_type = LLVMFunctionType(LLVMVoidType(), arg_types, Elements(arg_types), 0); + func_type = LLVMFunctionType(LLVMInt32Type(), arg_types, Elements(arg_types), 0); variant->function = LLVMAddFunction(llvm->module, "draw_llvm_shader", func_type); LLVMSetFunctionCallConv(variant->function, LLVMCCallConv); @@ -755,6 +982,10 @@ draw_llvm_generate(struct draw_llvm *llvm, struct draw_llvm_variant *variant) step = LLVMConstInt(LLVMInt32Type(), max_vertices, 0); + /* function will return non-zero i32 value if any clipped vertices */ + ret_ptr = lp_build_alloca(builder, LLVMInt32Type(), ""); + LLVMBuildStore(builder, LLVMConstInt(LLVMInt32Type(), 0, 0), ret_ptr); + /* code generated texture sampling */ sampler = draw_llvm_sampler_soa_create( draw_llvm_variant_key_samplers(&variant->key), @@ -769,6 +1000,7 @@ draw_llvm_generate(struct draw_llvm *llvm, struct draw_llvm_variant *variant) LLVMValueRef inputs[PIPE_MAX_SHADER_INPUTS][NUM_CHANNELS]; LLVMValueRef aos_attribs[PIPE_MAX_SHADER_INPUTS][NUM_CHANNELS] = { { 0 } }; LLVMValueRef io; + LLVMValueRef clipmask; /* holds the clipmask value */ const LLVMValueRef (*ptr_aos)[NUM_CHANNELS]; io_itr = LLVMBuildSub(builder, lp_loop.counter, start, ""); @@ -805,10 +1037,22 @@ draw_llvm_generate(struct draw_llvm *llvm, struct draw_llvm_variant *variant) context_ptr, sampler); - convert_to_aos(builder, io, outputs, + /* store original positions in clip before further manipulation */ + store_clip(builder, io, outputs); + + /* allocate clipmask, assign it integer type */ + clipmask = generate_clipmask(builder, outputs); + clipmask_bool(builder, clipmask, ret_ptr); + + /* do viewport mapping */ + generate_viewport(llvm, builder, outputs); + + /* store clipmask in vertex header and positions in data */ + convert_to_aos(builder, io, outputs, clipmask, draw->vs.vertex_shader->info.num_outputs, max_vertices); } + lp_build_loop_end_cond(builder, end, step, LLVMIntUGE, &lp_loop); sampler->destroy(sampler); @@ -818,8 +1062,9 @@ draw_llvm_generate(struct draw_llvm *llvm, struct draw_llvm_variant *variant) lp_build_intrinsic(builder, "llvm.x86.mmx.emms", LLVMVoidType(), NULL, 0); #endif - LLVMBuildRetVoid(builder); - + ret = LLVMBuildLoad(builder, ret_ptr,""); + LLVMBuildRet(builder, ret); + LLVMDisposeBuilder(builder); /* @@ -869,6 +1114,7 @@ draw_llvm_generate_elts(struct draw_llvm *llvm, struct draw_llvm_variant *varian LLVMValueRef fetch_max; void *code; struct lp_build_sampler_soa *sampler = 0; + LLVMValueRef ret, ret_ptr; arg_types[0] = llvm->context_ptr_type; /* context */ arg_types[1] = llvm->vertex_header_ptr_type; /* vertex_header */ @@ -879,10 +1125,9 @@ draw_llvm_generate_elts(struct draw_llvm *llvm, struct draw_llvm_variant *varian arg_types[6] = llvm->vb_ptr_type; /* pipe_vertex_buffer's */ arg_types[7] = LLVMInt32Type(); /* instance_id */ - func_type = LLVMFunctionType(LLVMVoidType(), arg_types, Elements(arg_types), 0); + func_type = LLVMFunctionType(LLVMInt32Type(), arg_types, Elements(arg_types), 0); - variant->function_elts = LLVMAddFunction(llvm->module, "draw_llvm_shader_elts", - func_type); + variant->function_elts = LLVMAddFunction(llvm->module, "draw_llvm_shader_elts", func_type); LLVMSetFunctionCallConv(variant->function_elts, LLVMCCallConv); for(i = 0; i < Elements(arg_types); ++i) if(LLVMGetTypeKind(arg_types[i]) == LLVMPointerTypeKind) @@ -928,11 +1173,16 @@ draw_llvm_generate_elts(struct draw_llvm *llvm, struct draw_llvm_variant *varian LLVMConstInt(LLVMInt32Type(), 1, 0), "fetch_max"); + /* function returns non-zero i32 value if any clipped vertices */ + ret_ptr = lp_build_alloca(builder, LLVMInt32Type(), ""); + LLVMBuildStore(builder, LLVMConstInt(LLVMInt32Type(), 0, 0), ret_ptr); + lp_build_loop_begin(builder, LLVMConstInt(LLVMInt32Type(), 0, 0), &lp_loop); { LLVMValueRef inputs[PIPE_MAX_SHADER_INPUTS][NUM_CHANNELS]; LLVMValueRef aos_attribs[PIPE_MAX_SHADER_INPUTS][NUM_CHANNELS] = { { 0 } }; LLVMValueRef io; + LLVMValueRef clipmask; /* holds the clipmask value */ const LLVMValueRef (*ptr_aos)[NUM_CHANNELS]; io_itr = lp_loop.counter; @@ -979,10 +1229,25 @@ draw_llvm_generate_elts(struct draw_llvm *llvm, struct draw_llvm_variant *varian context_ptr, sampler); - convert_to_aos(builder, io, outputs, + /* store original positions in clip before further manipulation */ + store_clip(builder, io, outputs); + + /* allocate clipmask, assign it integer type */ + clipmask = generate_clipmask(builder, outputs); + clipmask_bool(builder, clipmask, ret_ptr); + + /* do viewport mapping */ + generate_viewport(llvm, builder, outputs); + + /* store clipmask in vertex header, + * original positions in clip + * and transformed positions in data + */ + convert_to_aos(builder, io, outputs, clipmask, draw->vs.vertex_shader->info.num_outputs, max_vertices); } + lp_build_loop_end_cond(builder, fetch_count, step, LLVMIntUGE, &lp_loop); sampler->destroy(sampler); @@ -992,8 +1257,9 @@ draw_llvm_generate_elts(struct draw_llvm *llvm, struct draw_llvm_variant *varian lp_build_intrinsic(builder, "llvm.x86.mmx.emms", LLVMVoidType(), NULL, 0); #endif - LLVMBuildRetVoid(builder); - + ret = LLVMBuildLoad(builder, ret_ptr,""); + LLVMBuildRet(builder, ret); + LLVMDisposeBuilder(builder); /* diff --git a/src/gallium/auxiliary/draw/draw_llvm.h b/src/gallium/auxiliary/draw/draw_llvm.h index b881ef6113..1142ea51cf 100644 --- a/src/gallium/auxiliary/draw/draw_llvm.h +++ b/src/gallium/auxiliary/draw/draw_llvm.h @@ -120,7 +120,7 @@ struct draw_jit_context lp_build_struct_get_ptr(_builder, _ptr, 0, "id") #define draw_jit_header_clip(_builder, _ptr) \ - lp_build_struct_get(_builder, _ptr, 1, "clip") + lp_build_struct_get_ptr(_builder, _ptr, 1, "clip") #define draw_jit_header_data(_builder, _ptr) \ lp_build_struct_get_ptr(_builder, _ptr, 2, "data") @@ -136,7 +136,7 @@ struct draw_jit_context lp_build_struct_get(_builder, _ptr, 2, "buffer_offset") -typedef void +typedef int (*draw_jit_vert_func)(struct draw_jit_context *context, struct vertex_header *io, const char *vbuffers[PIPE_MAX_ATTRIBS], @@ -147,7 +147,7 @@ typedef void unsigned instance_id); -typedef void +typedef int (*draw_jit_vert_func_elts)(struct draw_jit_context *context, struct vertex_header *io, const char *vbuffers[PIPE_MAX_ATTRIBS], -- cgit v1.2.3 From 3744d1c7d30543520cede8a6c580f26985978953 Mon Sep 17 00:00:00 2001 From: Hui Qi Tay Date: Tue, 28 Sep 2010 17:52:14 +0100 Subject: draw: added viewport and cliptest flags Corrections in store_clip to store clip coordinates in AoS form. Viewport & cliptest flag options based on variant key. Put back draw_pt_post_vs and now 2 paths based on whether clipping occurs or not. --- src/gallium/auxiliary/draw/draw_llvm.c | 130 ++++++++++++++------- src/gallium/auxiliary/draw/draw_llvm.h | 6 +- .../draw/draw_pt_fetch_shade_pipeline_llvm.c | 12 +- 3 files changed, 98 insertions(+), 50 deletions(-) (limited to 'src/gallium/auxiliary/draw') diff --git a/src/gallium/auxiliary/draw/draw_llvm.c b/src/gallium/auxiliary/draw/draw_llvm.c index 36254d359c..940b2d7ae5 100644 --- a/src/gallium/auxiliary/draw/draw_llvm.c +++ b/src/gallium/auxiliary/draw/draw_llvm.c @@ -736,10 +736,10 @@ store_clip(LLVMBuilderRef builder, indices[0] = LLVMConstInt(LLVMInt32Type(), 0, 0); indices[1] = LLVMConstInt(LLVMInt32Type(), 0, 0); - out[0] = LLVMBuildLoad(builder, outputs[0][0], ""); /*x0 y0 z0 w0*/ - out[1] = LLVMBuildLoad(builder, outputs[0][1], ""); /*x1 y1 z1 w1*/ - out[2] = LLVMBuildLoad(builder, outputs[0][2], ""); /*x2 y2 z2 w2*/ - out[3] = LLVMBuildLoad(builder, outputs[0][3], ""); /*x3 y3 z3 w3*/ + out[0] = LLVMBuildLoad(builder, outputs[0][0], ""); /*x0 x1 x2 x3*/ + out[1] = LLVMBuildLoad(builder, outputs[0][1], ""); /*y0 y1 y2 y3*/ + out[2] = LLVMBuildLoad(builder, outputs[0][2], ""); /*z0 z1 z2 z3*/ + out[3] = LLVMBuildLoad(builder, outputs[0][3], ""); /*w0 w1 w2 w3*/ io0_ptr = LLVMBuildGEP(builder, io_ptr, &ind0, 1, ""); io1_ptr = LLVMBuildGEP(builder, io_ptr, &ind1, 1, ""); @@ -753,22 +753,22 @@ store_clip(LLVMBuilderRef builder, for (int i = 0; i<4; i++){ clip0_ptr = LLVMBuildGEP(builder, clip_ptr0, - indices, 2, ""); //x1 + indices, 2, ""); //x0 clip1_ptr = LLVMBuildGEP(builder, clip_ptr1, - indices, 2, ""); //y1 + indices, 2, ""); //x1 clip2_ptr = LLVMBuildGEP(builder, clip_ptr2, - indices, 2, ""); //z1 + indices, 2, ""); //x2 clip3_ptr = LLVMBuildGEP(builder, clip_ptr3, - indices, 2, ""); //w1 - - out0elem = LLVMBuildExtractElement(builder, out[0], - indices[1], ""); //x1 - out1elem = LLVMBuildExtractElement(builder, out[1], - indices[1], ""); //y1 - out2elem = LLVMBuildExtractElement(builder, out[2], - indices[1], ""); //z1 - out3elem = LLVMBuildExtractElement(builder, out[3], - indices[1], ""); //w1 + indices, 2, ""); //x3 + + out0elem = LLVMBuildExtractElement(builder, out[i], + ind0, ""); //x0 + out1elem = LLVMBuildExtractElement(builder, out[i], + ind1, ""); //x1 + out2elem = LLVMBuildExtractElement(builder, out[i], + ind2, ""); //x2 + out3elem = LLVMBuildExtractElement(builder, out[i], + ind3, ""); //x3 LLVMBuildStore(builder, out0elem, clip0_ptr); LLVMBuildStore(builder, out1elem, clip1_ptr); @@ -822,7 +822,9 @@ generate_viewport(struct draw_llvm *llvm, */ static LLVMValueRef generate_clipmask(LLVMBuilderRef builder, - LLVMValueRef (*outputs)[NUM_CHANNELS]) + LLVMValueRef (*outputs)[NUM_CHANNELS], + boolean disable_zclipping, + boolean enable_d3dclipping) { LLVMValueRef mask; /* stores the <4xi32> clipmasks */ LLVMValueRef test, temp; @@ -866,22 +868,31 @@ generate_clipmask(LLVMBuilderRef builder, temp = LLVMBuildShl(builder, temp, shift, ""); test = LLVMBuildAnd(builder, test, temp, ""); mask = LLVMBuildOr(builder, mask, test, ""); - - /* plane 5 */ - test = LLVMBuildFAdd(builder, pos_z, pos_w, ""); - test = lp_build_compare(builder, f32_type, PIPE_FUNC_GREATER, zero, test); - temp = LLVMBuildShl(builder, temp, shift, ""); - test = LLVMBuildAnd(builder, test, temp, ""); - mask = LLVMBuildOr(builder, mask, test, ""); - - /* plane 6 */ - test = lp_build_compare(builder, f32_type, PIPE_FUNC_GREATER, pos_z, pos_w); - temp = LLVMBuildShl(builder, temp, shift, ""); - test = LLVMBuildAnd(builder, test, temp, ""); - mask = LLVMBuildOr(builder, mask, test, ""); - + + if (!disable_zclipping){ + if (enable_d3dclipping){ + /* plane 5 */ + test = lp_build_compare(builder, f32_type, PIPE_FUNC_GREATER, zero, pos_z); + temp = LLVMBuildShl(builder, temp, shift, ""); + test = LLVMBuildAnd(builder, test, temp, ""); + mask = LLVMBuildOr(builder, mask, test, ""); + } + else{ + /* plane 5 */ + test = LLVMBuildFAdd(builder, pos_z, pos_w, ""); + test = lp_build_compare(builder, f32_type, PIPE_FUNC_GREATER, zero, test); + temp = LLVMBuildShl(builder, temp, shift, ""); + test = LLVMBuildAnd(builder, test, temp, ""); + mask = LLVMBuildOr(builder, mask, test, ""); + } + /* plane 6 */ + test = lp_build_compare(builder, f32_type, PIPE_FUNC_GREATER, pos_z, pos_w); + temp = LLVMBuildShl(builder, temp, shift, ""); + test = LLVMBuildAnd(builder, test, temp, ""); + mask = LLVMBuildOr(builder, mask, test, ""); + } + return mask; - } /* @@ -930,8 +941,9 @@ draw_llvm_generate(struct draw_llvm *llvm, struct draw_llvm_variant *variant) LLVMValueRef outputs[PIPE_MAX_SHADER_OUTPUTS][NUM_CHANNELS]; void *code; struct lp_build_sampler_soa *sampler = 0; - LLVMValueRef ret, ret_ptr; + boolean disable_cliptest = variant->key.disable_cliptest; + boolean disable_viewport = variant->key.disable_viewport; arg_types[0] = llvm->context_ptr_type; /* context */ arg_types[1] = llvm->vertex_header_ptr_type; /* vertex_header */ @@ -1040,13 +1052,23 @@ draw_llvm_generate(struct draw_llvm *llvm, struct draw_llvm_variant *variant) /* store original positions in clip before further manipulation */ store_clip(builder, io, outputs); - /* allocate clipmask, assign it integer type */ - clipmask = generate_clipmask(builder, outputs); - clipmask_bool(builder, clipmask, ret_ptr); + /* do cliptest */ + if (!disable_cliptest){ + /* allocate clipmask, assign it integer type */ + clipmask = generate_clipmask(builder, outputs, + variant->key.disable_zclipping, variant->key.enable_d3dclipping); + /* return clipping boolean value for function */ + clipmask_bool(builder, clipmask, ret_ptr); + } + else{ + clipmask = lp_build_const_int_vec(lp_type_int_vec(32), 0); + } /* do viewport mapping */ - generate_viewport(llvm, builder, outputs); - + if (!disable_viewport){ + generate_viewport(llvm, builder, outputs); + } + /* store clipmask in vertex header and positions in data */ convert_to_aos(builder, io, outputs, clipmask, draw->vs.vertex_shader->info.num_outputs, @@ -1115,6 +1137,8 @@ draw_llvm_generate_elts(struct draw_llvm *llvm, struct draw_llvm_variant *varian void *code; struct lp_build_sampler_soa *sampler = 0; LLVMValueRef ret, ret_ptr; + boolean disable_cliptest = variant->key.disable_cliptest; + boolean disable_viewport = variant->key.disable_viewport; arg_types[0] = llvm->context_ptr_type; /* context */ arg_types[1] = llvm->vertex_header_ptr_type; /* vertex_header */ @@ -1232,13 +1256,23 @@ draw_llvm_generate_elts(struct draw_llvm *llvm, struct draw_llvm_variant *varian /* store original positions in clip before further manipulation */ store_clip(builder, io, outputs); - /* allocate clipmask, assign it integer type */ - clipmask = generate_clipmask(builder, outputs); - clipmask_bool(builder, clipmask, ret_ptr); - - /* do viewport mapping */ - generate_viewport(llvm, builder, outputs); + /* do cliptest */ + if (!disable_cliptest){ + /* allocate clipmask, assign it integer type */ + clipmask = generate_clipmask(builder, outputs, + variant->key.disable_zclipping, variant->key.enable_d3dclipping); + /* return clipping boolean value for function */ + clipmask_bool(builder, clipmask, ret_ptr); + } + else{ + clipmask = lp_build_const_int_vec(lp_type_int_vec(32), 0); + } + /* do viewport mapping */ + if (!disable_viewport){ + generate_viewport(llvm, builder, outputs); + } + /* store clipmask in vertex header, * original positions in clip * and transformed positions in data @@ -1303,6 +1337,12 @@ draw_llvm_make_variant_key(struct draw_llvm *llvm, char *store) */ key->nr_vertex_elements = llvm->draw->pt.nr_vertex_elements; + /* will have to rig this up properly later */ + key->disable_cliptest = 0; + key->disable_viewport = 0; + key->disable_zclipping = 0; + key->enable_d3dclipping = 0; + /* All variants of this shader will have the same value for * nr_samplers. Not yet trying to compact away holes in the * sampler array. diff --git a/src/gallium/auxiliary/draw/draw_llvm.h b/src/gallium/auxiliary/draw/draw_llvm.h index 1142ea51cf..8ff366956c 100644 --- a/src/gallium/auxiliary/draw/draw_llvm.h +++ b/src/gallium/auxiliary/draw/draw_llvm.h @@ -160,7 +160,11 @@ typedef int struct draw_llvm_variant_key { unsigned nr_vertex_elements:16; - unsigned nr_samplers:16; + unsigned nr_samplers:12; + unsigned disable_cliptest:1; + unsigned disable_viewport:1; + unsigned disable_zclipping:1; + unsigned enable_d3dclipping:1; /* Variable number of vertex elements: */ diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline_llvm.c b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline_llvm.c index 77291e304e..dc138b980d 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline_llvm.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline_llvm.c @@ -217,6 +217,7 @@ llvm_pipeline_generic( struct draw_pt_middle_end *middle, struct draw_vertex_info gs_vert_info; struct draw_vertex_info *vert_info; unsigned opt = fpme->opt; + unsigned clipped = 0; llvm_vert_info.count = fetch_info->count; llvm_vert_info.vertex_size = fpme->vertex_size; @@ -230,7 +231,7 @@ llvm_pipeline_generic( struct draw_pt_middle_end *middle, } if (fetch_info->linear) - fpme->current_variant->jit_func( &fpme->llvm->jit_context, + clipped = fpme->current_variant->jit_func( &fpme->llvm->jit_context, llvm_vert_info.verts, (const char **)draw->pt.user.vbuffer, fetch_info->start, @@ -239,7 +240,7 @@ llvm_pipeline_generic( struct draw_pt_middle_end *middle, draw->pt.vertex_buffer, draw->instance_id); else - fpme->current_variant->jit_func_elts( &fpme->llvm->jit_context, + clipped = fpme->current_variant->jit_func_elts( &fpme->llvm->jit_context, llvm_vert_info.verts, (const char **)draw->pt.user.vbuffer, fetch_info->elts, @@ -266,6 +267,9 @@ llvm_pipeline_generic( struct draw_pt_middle_end *middle, FREE(vert_info->verts); vert_info = &gs_vert_info; prim_info = &gs_prim_info; + + clipped = draw_pt_post_vs_run( fpme->post_vs, vert_info ); + } /* stream output needs to be done before clipping */ @@ -273,11 +277,11 @@ llvm_pipeline_generic( struct draw_pt_middle_end *middle, vert_info, prim_info ); - if (draw_pt_post_vs_run( fpme->post_vs, vert_info )) { + if (clipped) { opt |= PT_PIPELINE; } - /* Do we need to run the pipeline? + /* Do we need to run the pipeline? Now will come here if clipped */ if (opt & PT_PIPELINE) { pipeline( fpme, -- cgit v1.2.3 From 25bb05fef075a87ec6e5f2a989049faff2afedd2 Mon Sep 17 00:00:00 2001 From: delphi Date: Mon, 4 Oct 2010 17:08:33 +0100 Subject: draw: added userclip planes and updated variant_key --- src/gallium/auxiliary/draw/draw_llvm.c | 138 ++++++++++++++++++++++----------- src/gallium/auxiliary/draw/draw_llvm.h | 8 +- 2 files changed, 99 insertions(+), 47 deletions(-) (limited to 'src/gallium/auxiliary/draw') diff --git a/src/gallium/auxiliary/draw/draw_llvm.c b/src/gallium/auxiliary/draw/draw_llvm.c index 940b2d7ae5..9c17e7763a 100644 --- a/src/gallium/auxiliary/draw/draw_llvm.c +++ b/src/gallium/auxiliary/draw/draw_llvm.c @@ -823,13 +823,21 @@ generate_viewport(struct draw_llvm *llvm, static LLVMValueRef generate_clipmask(LLVMBuilderRef builder, LLVMValueRef (*outputs)[NUM_CHANNELS], - boolean disable_zclipping, - boolean enable_d3dclipping) + boolean clip_xy, + boolean clip_z, + boolean clip_user, + boolean enable_d3dclipping, + struct draw_llvm *llvm) { LLVMValueRef mask; /* stores the <4xi32> clipmasks */ LLVMValueRef test, temp; LLVMValueRef zero, shift; LLVMValueRef pos_x, pos_y, pos_z, pos_w; + LLVMValueRef planes, sum; + + unsigned nr; + unsigned i; + float (*plane)[4]; struct lp_type f32_type = lp_type_float_vec(32); @@ -843,33 +851,35 @@ generate_clipmask(LLVMBuilderRef builder, pos_w = LLVMBuildLoad(builder, outputs[0][3], ""); /*w0 w1 w2 w3*/ /* Cliptest, for hardwired planes */ - /* plane 1 */ - test = lp_build_compare(builder, f32_type, PIPE_FUNC_GREATER, pos_x , pos_w); - temp = shift; - test = LLVMBuildAnd(builder, test, temp, ""); - mask = test; + if (clip_xy){ + /* plane 1 */ + test = lp_build_compare(builder, f32_type, PIPE_FUNC_GREATER, pos_x , pos_w); + temp = shift; + test = LLVMBuildAnd(builder, test, temp, ""); + mask = test; - /* plane 2 */ - test = LLVMBuildFAdd(builder, pos_x, pos_w, ""); - test = lp_build_compare(builder, f32_type, PIPE_FUNC_GREATER, zero, test); - temp = LLVMBuildShl(builder, temp, shift, ""); - test = LLVMBuildAnd(builder, test, temp, ""); - mask = LLVMBuildOr(builder, mask, test, ""); + /* plane 2 */ + test = LLVMBuildFAdd(builder, pos_x, pos_w, ""); + test = lp_build_compare(builder, f32_type, PIPE_FUNC_GREATER, zero, test); + temp = LLVMBuildShl(builder, temp, shift, ""); + test = LLVMBuildAnd(builder, test, temp, ""); + mask = LLVMBuildOr(builder, mask, test, ""); - /* plane 3 */ - test = lp_build_compare(builder, f32_type, PIPE_FUNC_GREATER, pos_y, pos_w); - temp = LLVMBuildShl(builder, temp, shift, ""); - test = LLVMBuildAnd(builder, test, temp, ""); - mask = LLVMBuildOr(builder, mask, test, ""); - - /* plane 4 */ - test = LLVMBuildFAdd(builder, pos_y, pos_w, ""); - test = lp_build_compare(builder, f32_type, PIPE_FUNC_GREATER, zero, test); - temp = LLVMBuildShl(builder, temp, shift, ""); - test = LLVMBuildAnd(builder, test, temp, ""); - mask = LLVMBuildOr(builder, mask, test, ""); - - if (!disable_zclipping){ + /* plane 3 */ + test = lp_build_compare(builder, f32_type, PIPE_FUNC_GREATER, pos_y, pos_w); + temp = LLVMBuildShl(builder, temp, shift, ""); + test = LLVMBuildAnd(builder, test, temp, ""); + mask = LLVMBuildOr(builder, mask, test, ""); + + /* plane 4 */ + test = LLVMBuildFAdd(builder, pos_y, pos_w, ""); + test = lp_build_compare(builder, f32_type, PIPE_FUNC_GREATER, zero, test); + temp = LLVMBuildShl(builder, temp, shift, ""); + test = LLVMBuildAnd(builder, test, temp, ""); + mask = LLVMBuildOr(builder, mask, test, ""); + } + + if (clip_z){ if (enable_d3dclipping){ /* plane 5 */ test = lp_build_compare(builder, f32_type, PIPE_FUNC_GREATER, zero, pos_z); @@ -892,6 +902,32 @@ generate_clipmask(LLVMBuilderRef builder, mask = LLVMBuildOr(builder, mask, test, ""); } + if (clip_user){ + /* userclip planes */ + nr = llvm->draw->nr_planes; + plane = llvm->draw->plane; + for (i = 6; i < nr; i++) { + planes = lp_build_const_vec(f32_type, plane[i][0]); + sum = LLVMBuildMul(builder, planes, pos_x, ""); + + planes = lp_build_const_vec(f32_type, plane[i][1]); + test = LLVMBuildMul(builder, planes, pos_y, ""); + sum = LLVMBuildFAdd(builder, sum, test, ""); + + planes = lp_build_const_vec(f32_type, plane[i][2]); + test = LLVMBuildMul(builder, planes, pos_z, ""); + sum = LLVMBuildFAdd(builder, sum, test, ""); + + planes = lp_build_const_vec(f32_type, plane[i][3]); + test = LLVMBuildMul(builder, planes, pos_w, ""); + sum = LLVMBuildFAdd(builder, sum, test, ""); + + test = lp_build_compare(builder, f32_type, PIPE_FUNC_GREATER, zero, sum); + temp = LLVMBuildShl(builder, temp, shift, ""); + test = LLVMBuildAnd(builder, test, temp, ""); + mask = LLVMBuildOr(builder, mask, test, ""); + } + } return mask; } @@ -942,8 +978,10 @@ draw_llvm_generate(struct draw_llvm *llvm, struct draw_llvm_variant *variant) void *code; struct lp_build_sampler_soa *sampler = 0; LLVMValueRef ret, ret_ptr; - boolean disable_cliptest = variant->key.disable_cliptest; - boolean disable_viewport = variant->key.disable_viewport; + boolean bypass_viewport = variant->key.bypass_viewport; + boolean enable_cliptest = variant->key.clip_xy || + variant->key.clip_z || + variant->key.clip_user; arg_types[0] = llvm->context_ptr_type; /* context */ arg_types[1] = llvm->vertex_header_ptr_type; /* vertex_header */ @@ -1053,10 +1091,14 @@ draw_llvm_generate(struct draw_llvm *llvm, struct draw_llvm_variant *variant) store_clip(builder, io, outputs); /* do cliptest */ - if (!disable_cliptest){ + if (enable_cliptest){ /* allocate clipmask, assign it integer type */ - clipmask = generate_clipmask(builder, outputs, - variant->key.disable_zclipping, variant->key.enable_d3dclipping); + clipmask = generate_clipmask(builder, outputs, + variant->key.clip_xy, + variant->key.clip_z, + variant->key.clip_user, + variant->key.enable_d3dclipping, + llvm); /* return clipping boolean value for function */ clipmask_bool(builder, clipmask, ret_ptr); } @@ -1065,7 +1107,7 @@ draw_llvm_generate(struct draw_llvm *llvm, struct draw_llvm_variant *variant) } /* do viewport mapping */ - if (!disable_viewport){ + if (!bypass_viewport){ generate_viewport(llvm, builder, outputs); } @@ -1137,9 +1179,11 @@ draw_llvm_generate_elts(struct draw_llvm *llvm, struct draw_llvm_variant *varian void *code; struct lp_build_sampler_soa *sampler = 0; LLVMValueRef ret, ret_ptr; - boolean disable_cliptest = variant->key.disable_cliptest; - boolean disable_viewport = variant->key.disable_viewport; - + boolean bypass_viewport = variant->key.bypass_viewport; + boolean enable_cliptest = variant->key.clip_xy || + variant->key.clip_z || + variant->key.clip_user; + arg_types[0] = llvm->context_ptr_type; /* context */ arg_types[1] = llvm->vertex_header_ptr_type; /* vertex_header */ arg_types[2] = llvm->buffer_ptr_type; /* vbuffers */ @@ -1257,10 +1301,14 @@ draw_llvm_generate_elts(struct draw_llvm *llvm, struct draw_llvm_variant *varian store_clip(builder, io, outputs); /* do cliptest */ - if (!disable_cliptest){ + if (enable_cliptest){ /* allocate clipmask, assign it integer type */ - clipmask = generate_clipmask(builder, outputs, - variant->key.disable_zclipping, variant->key.enable_d3dclipping); + clipmask = generate_clipmask(builder, outputs, + variant->key.clip_xy, + variant->key.clip_z, + variant->key.clip_user, + variant->key.enable_d3dclipping, + llvm); /* return clipping boolean value for function */ clipmask_bool(builder, clipmask, ret_ptr); } @@ -1269,7 +1317,7 @@ draw_llvm_generate_elts(struct draw_llvm *llvm, struct draw_llvm_variant *varian } /* do viewport mapping */ - if (!disable_viewport){ + if (!bypass_viewport){ generate_viewport(llvm, builder, outputs); } @@ -1338,10 +1386,12 @@ draw_llvm_make_variant_key(struct draw_llvm *llvm, char *store) key->nr_vertex_elements = llvm->draw->pt.nr_vertex_elements; /* will have to rig this up properly later */ - key->disable_cliptest = 0; - key->disable_viewport = 0; - key->disable_zclipping = 0; - key->enable_d3dclipping = 0; + key->clip_xy = llvm->draw->clip_xy; + key->clip_z = llvm->draw->clip_z; + key->clip_user = llvm->draw->clip_user; + key->bypass_viewport = llvm->draw->identity_viewport; + key->enable_d3dclipping = (boolean)!llvm->draw->rasterizer->gl_rasterization_rules; + key->need_edgeflags = (llvm->draw->vs.edgeflag_output ? TRUE : FALSE); /* All variants of this shader will have the same value for * nr_samplers. Not yet trying to compact away holes in the diff --git a/src/gallium/auxiliary/draw/draw_llvm.h b/src/gallium/auxiliary/draw/draw_llvm.h index 8ff366956c..4a4d93f33a 100644 --- a/src/gallium/auxiliary/draw/draw_llvm.h +++ b/src/gallium/auxiliary/draw/draw_llvm.h @@ -161,10 +161,12 @@ struct draw_llvm_variant_key { unsigned nr_vertex_elements:16; unsigned nr_samplers:12; - unsigned disable_cliptest:1; - unsigned disable_viewport:1; - unsigned disable_zclipping:1; + unsigned clip_xy:1; + unsigned clip_z:1; + unsigned clip_user:1; + unsigned bypass_viewport:1; unsigned enable_d3dclipping:1; + unsigned need_edgeflags:1; /* Variable number of vertex elements: */ -- cgit v1.2.3 From 08f890d4c3b8376d1840f90474f7c56329432d95 Mon Sep 17 00:00:00 2001 From: delphi Date: Sun, 10 Oct 2010 00:31:16 +0100 Subject: draw: some changes to allow for runtime changes to userclip planes --- src/gallium/auxiliary/draw/draw_context.c | 1 + src/gallium/auxiliary/draw/draw_llvm.c | 70 +++++++++++++++++----- src/gallium/auxiliary/draw/draw_llvm.h | 10 ++-- src/gallium/auxiliary/draw/draw_private.h | 3 + .../draw/draw_pt_fetch_shade_pipeline_llvm.c | 3 + 5 files changed, 67 insertions(+), 20 deletions(-) (limited to 'src/gallium/auxiliary/draw') diff --git a/src/gallium/auxiliary/draw/draw_context.c b/src/gallium/auxiliary/draw/draw_context.c index b07de76a49..c52234d8e3 100644 --- a/src/gallium/auxiliary/draw/draw_context.c +++ b/src/gallium/auxiliary/draw/draw_context.c @@ -335,6 +335,7 @@ draw_set_mapped_constant_buffer(struct draw_context *draw, case PIPE_SHADER_VERTEX: draw->pt.user.vs_constants[slot] = buffer; draw->pt.user.vs_constants_size[slot] = size; + draw->pt.user.planes = (float (*) [12][4]) &(draw->plane[0]); draw_vs_set_constants(draw, slot, buffer, size); break; case PIPE_SHADER_GEOMETRY: diff --git a/src/gallium/auxiliary/draw/draw_llvm.c b/src/gallium/auxiliary/draw/draw_llvm.c index 9c17e7763a..5f11b82bb9 100644 --- a/src/gallium/auxiliary/draw/draw_llvm.c +++ b/src/gallium/auxiliary/draw/draw_llvm.c @@ -130,12 +130,13 @@ init_globals(struct draw_llvm *llvm) /* struct draw_jit_context */ { - LLVMTypeRef elem_types[3]; + LLVMTypeRef elem_types[4]; LLVMTypeRef context_type; elem_types[0] = LLVMPointerType(LLVMFloatType(), 0); /* vs_constants */ - elem_types[1] = LLVMPointerType(LLVMFloatType(), 0); /* vs_constants */ - elem_types[2] = LLVMArrayType(texture_type, + elem_types[1] = LLVMPointerType(LLVMFloatType(), 0); /* gs_constants */ + elem_types[2] = LLVMPointerType(LLVMArrayType(LLVMArrayType(LLVMFloatType(), 4), 12), 0); /* planes */ + elem_types[3] = LLVMArrayType(texture_type, PIPE_MAX_VERTEX_SAMPLERS); /* textures */ context_type = LLVMStructType(elem_types, Elements(elem_types), 0); @@ -144,6 +145,8 @@ init_globals(struct draw_llvm *llvm) llvm->target, context_type, 0); LP_CHECK_MEMBER_OFFSET(struct draw_jit_context, gs_constants, llvm->target, context_type, 1); + LP_CHECK_MEMBER_OFFSET(struct draw_jit_context, planes, + llvm->target, context_type, 2); LP_CHECK_MEMBER_OFFSET(struct draw_jit_context, textures, llvm->target, context_type, DRAW_JIT_CTX_TEXTURES); @@ -817,6 +820,23 @@ generate_viewport(struct draw_llvm *llvm, } +/* Equivalent of _mm_set1_ps(a) + */ +static LLVMValueRef vec4f_from_scalar(LLVMBuilderRef bld, + LLVMValueRef a, + const char *name) +{ + LLVMValueRef res = LLVMGetUndef(LLVMVectorType(LLVMFloatType(), 4)); + int i; + + for(i = 0; i < 4; ++i) { + LLVMValueRef index = LLVMConstInt(LLVMInt32Type(), i, 0); + res = LLVMBuildInsertElement(bld, res, a, index, i == 3 ? name : ""); + } + + return res; +} + /* * Returns clipmask as 4xi32 bitmask for the 4 vertices */ @@ -827,17 +847,16 @@ generate_clipmask(LLVMBuilderRef builder, boolean clip_z, boolean clip_user, boolean enable_d3dclipping, - struct draw_llvm *llvm) + unsigned nr, + LLVMValueRef context_ptr) { LLVMValueRef mask; /* stores the <4xi32> clipmasks */ LLVMValueRef test, temp; LLVMValueRef zero, shift; LLVMValueRef pos_x, pos_y, pos_z, pos_w; - LLVMValueRef planes, sum; + LLVMValueRef plane1, planes, plane_ptr, sum; - unsigned nr; unsigned i; - float (*plane)[4]; struct lp_type f32_type = lp_type_float_vec(32); @@ -903,22 +922,38 @@ generate_clipmask(LLVMBuilderRef builder, } if (clip_user){ + LLVMValueRef planes_ptr = draw_jit_context_planes(builder, context_ptr); + LLVMValueRef indices[3]; + /* userclip planes */ - nr = llvm->draw->nr_planes; - plane = llvm->draw->plane; for (i = 6; i < nr; i++) { - planes = lp_build_const_vec(f32_type, plane[i][0]); + indices[0] = LLVMConstInt(LLVMInt32Type(), 0, 0); + indices[1] = LLVMConstInt(LLVMInt32Type(), i, 0); + + indices[2] = LLVMConstInt(LLVMInt32Type(), 0, 0); + plane_ptr = LLVMBuildGEP(builder, planes_ptr, indices, 3, ""); + plane1 = LLVMBuildLoad(builder, plane_ptr, "plane_x"); + planes = vec4f_from_scalar(builder, plane1, "plane4_x"); sum = LLVMBuildMul(builder, planes, pos_x, ""); - planes = lp_build_const_vec(f32_type, plane[i][1]); + indices[2] = LLVMConstInt(LLVMInt32Type(), 1, 0); + plane_ptr = LLVMBuildGEP(builder, planes_ptr, indices, 3, ""); + plane1 = LLVMBuildLoad(builder, plane_ptr, "plane_y"); + planes = vec4f_from_scalar(builder, plane1, "plane4_y"); test = LLVMBuildMul(builder, planes, pos_y, ""); sum = LLVMBuildFAdd(builder, sum, test, ""); - - planes = lp_build_const_vec(f32_type, plane[i][2]); + + indices[2] = LLVMConstInt(LLVMInt32Type(), 2, 0); + plane_ptr = LLVMBuildGEP(builder, planes_ptr, indices, 3, ""); + plane1 = LLVMBuildLoad(builder, plane_ptr, "plane_z"); + planes = vec4f_from_scalar(builder, plane1, "plane4_z"); test = LLVMBuildMul(builder, planes, pos_z, ""); sum = LLVMBuildFAdd(builder, sum, test, ""); - planes = lp_build_const_vec(f32_type, plane[i][3]); + indices[2] = LLVMConstInt(LLVMInt32Type(), 3, 0); + plane_ptr = LLVMBuildGEP(builder, planes_ptr, indices, 3, ""); + plane1 = LLVMBuildLoad(builder, plane_ptr, "plane_w"); + planes = vec4f_from_scalar(builder, plane1, "plane4_w"); test = LLVMBuildMul(builder, planes, pos_w, ""); sum = LLVMBuildFAdd(builder, sum, test, ""); @@ -1098,7 +1133,8 @@ draw_llvm_generate(struct draw_llvm *llvm, struct draw_llvm_variant *variant) variant->key.clip_z, variant->key.clip_user, variant->key.enable_d3dclipping, - llvm); + variant->key.nr_planes, + context_ptr); /* return clipping boolean value for function */ clipmask_bool(builder, clipmask, ret_ptr); } @@ -1308,7 +1344,8 @@ draw_llvm_generate_elts(struct draw_llvm *llvm, struct draw_llvm_variant *varian variant->key.clip_z, variant->key.clip_user, variant->key.enable_d3dclipping, - llvm); + variant->key.nr_planes, + context_ptr); /* return clipping boolean value for function */ clipmask_bool(builder, clipmask, ret_ptr); } @@ -1392,6 +1429,7 @@ draw_llvm_make_variant_key(struct draw_llvm *llvm, char *store) key->bypass_viewport = llvm->draw->identity_viewport; key->enable_d3dclipping = (boolean)!llvm->draw->rasterizer->gl_rasterization_rules; key->need_edgeflags = (llvm->draw->vs.edgeflag_output ? TRUE : FALSE); + key->nr_planes = llvm->draw->nr_planes; /* All variants of this shader will have the same value for * nr_samplers. Not yet trying to compact away holes in the diff --git a/src/gallium/auxiliary/draw/draw_llvm.h b/src/gallium/auxiliary/draw/draw_llvm.h index 4a4d93f33a..fc7885499e 100644 --- a/src/gallium/auxiliary/draw/draw_llvm.h +++ b/src/gallium/auxiliary/draw/draw_llvm.h @@ -97,7 +97,7 @@ struct draw_jit_context { const float *vs_constants; const float *gs_constants; - + float (*planes) [12][4]; struct draw_jit_texture textures[PIPE_MAX_VERTEX_SAMPLERS]; }; @@ -109,13 +109,14 @@ struct draw_jit_context #define draw_jit_context_gs_constants(_builder, _ptr) \ lp_build_struct_get(_builder, _ptr, 1, "gs_constants") -#define DRAW_JIT_CTX_TEXTURES 2 +#define draw_jit_context_planes(_builder, _ptr) \ + lp_build_struct_get(_builder, _ptr, 2, "planes") + +#define DRAW_JIT_CTX_TEXTURES 3 #define draw_jit_context_textures(_builder, _ptr) \ lp_build_struct_get_ptr(_builder, _ptr, DRAW_JIT_CTX_TEXTURES, "textures") - - #define draw_jit_header_id(_builder, _ptr) \ lp_build_struct_get_ptr(_builder, _ptr, 0, "id") @@ -167,6 +168,7 @@ struct draw_llvm_variant_key unsigned bypass_viewport:1; unsigned enable_d3dclipping:1; unsigned need_edgeflags:1; + unsigned nr_planes; /* Variable number of vertex elements: */ diff --git a/src/gallium/auxiliary/draw/draw_private.h b/src/gallium/auxiliary/draw/draw_private.h index d417f825a0..54163d7f9e 100644 --- a/src/gallium/auxiliary/draw/draw_private.h +++ b/src/gallium/auxiliary/draw/draw_private.h @@ -169,6 +169,9 @@ struct draw_context unsigned vs_constants_size[PIPE_MAX_CONSTANT_BUFFERS]; const void *gs_constants[PIPE_MAX_CONSTANT_BUFFERS]; unsigned gs_constants_size[PIPE_MAX_CONSTANT_BUFFERS]; + + /* pointer to planes */ + float (*planes)[12][4]; } user; boolean test_fse; /* enable FSE even though its not correct (eg for softpipe) */ diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline_llvm.c b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline_llvm.c index dc138b980d..e5b2532b50 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline_llvm.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline_llvm.c @@ -175,6 +175,9 @@ llvm_middle_end_prepare( struct draw_pt_middle_end *middle, draw->pt.user.vs_constants[0]; fpme->llvm->jit_context.gs_constants = draw->pt.user.gs_constants[0]; + fpme->llvm->jit_context.planes = + (float (*) [12][4]) draw->pt.user.planes[0]; + } -- cgit v1.2.3 From 26ff7523b69ddb377ade29296d20abfc46e69489 Mon Sep 17 00:00:00 2001 From: Hui Qi Tay Date: Thu, 14 Oct 2010 14:04:39 +0100 Subject: draw: sanitize llvm variant key Fixes recompilation, but seems to be broken with llvm 2.8. --- src/gallium/auxiliary/draw/draw_llvm.c | 1 + src/gallium/auxiliary/draw/draw_llvm.h | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) (limited to 'src/gallium/auxiliary/draw') diff --git a/src/gallium/auxiliary/draw/draw_llvm.c b/src/gallium/auxiliary/draw/draw_llvm.c index 5f11b82bb9..1c18d90743 100644 --- a/src/gallium/auxiliary/draw/draw_llvm.c +++ b/src/gallium/auxiliary/draw/draw_llvm.c @@ -1430,6 +1430,7 @@ draw_llvm_make_variant_key(struct draw_llvm *llvm, char *store) key->enable_d3dclipping = (boolean)!llvm->draw->rasterizer->gl_rasterization_rules; key->need_edgeflags = (llvm->draw->vs.edgeflag_output ? TRUE : FALSE); key->nr_planes = llvm->draw->nr_planes; + key->pad = 0; /* All variants of this shader will have the same value for * nr_samplers. Not yet trying to compact away holes in the diff --git a/src/gallium/auxiliary/draw/draw_llvm.h b/src/gallium/auxiliary/draw/draw_llvm.h index fc7885499e..def068179f 100644 --- a/src/gallium/auxiliary/draw/draw_llvm.h +++ b/src/gallium/auxiliary/draw/draw_llvm.h @@ -168,7 +168,8 @@ struct draw_llvm_variant_key unsigned bypass_viewport:1; unsigned enable_d3dclipping:1; unsigned need_edgeflags:1; - unsigned nr_planes; + unsigned nr_planes:4; + unsigned pad:26; /* Variable number of vertex elements: */ -- cgit v1.2.3 From c1d6b318661de2acdee38254d3750ed8dfc09e8b Mon Sep 17 00:00:00 2001 From: Hui Qi Tay Date: Sat, 16 Oct 2010 11:02:11 +0100 Subject: draw: corrections for w coordinate --- src/gallium/auxiliary/draw/draw_llvm.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src/gallium/auxiliary/draw') diff --git a/src/gallium/auxiliary/draw/draw_llvm.c b/src/gallium/auxiliary/draw/draw_llvm.c index 1c18d90743..7afa37ba94 100644 --- a/src/gallium/auxiliary/draw/draw_llvm.c +++ b/src/gallium/auxiliary/draw/draw_llvm.c @@ -800,9 +800,10 @@ generate_viewport(struct draw_llvm *llvm, /* for 1/w convention*/ out3 = LLVMBuildFDiv(builder, const1, out3, ""); - + LLVMBuildStore(builder, out3, outputs[0][3]); + /* Viewport Mapping */ - for (i=0; i<4; i++){ + for (i=0; i<3; i++){ LLVMValueRef out = LLVMBuildLoad(builder, outputs[0][i], ""); /*x0 x1 x2 x3*/ LLVMValueRef scale = lp_build_const_vec(f32_type, scaleA[i]); /*sx sx sx sx*/ LLVMValueRef trans = lp_build_const_vec(f32_type, transA[i]); /*tx tx tx tx*/ -- cgit v1.2.3 From b5236f3da482665567a9d53264e6203092120c31 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Sun, 17 Oct 2010 17:53:29 -0700 Subject: llvmpipe: clean up fields in draw_llvm_variant_key --- src/gallium/auxiliary/draw/draw_llvm.c | 15 +++++---------- src/gallium/auxiliary/draw/draw_llvm.h | 8 ++++---- 2 files changed, 9 insertions(+), 14 deletions(-) (limited to 'src/gallium/auxiliary/draw') diff --git a/src/gallium/auxiliary/draw/draw_llvm.c b/src/gallium/auxiliary/draw/draw_llvm.c index 7afa37ba94..ebd8b9d4ad 100644 --- a/src/gallium/auxiliary/draw/draw_llvm.c +++ b/src/gallium/auxiliary/draw/draw_llvm.c @@ -847,7 +847,7 @@ generate_clipmask(LLVMBuilderRef builder, boolean clip_xy, boolean clip_z, boolean clip_user, - boolean enable_d3dclipping, + boolean clip_halfz, unsigned nr, LLVMValueRef context_ptr) { @@ -900,7 +900,7 @@ generate_clipmask(LLVMBuilderRef builder, } if (clip_z){ - if (enable_d3dclipping){ + if (clip_halfz){ /* plane 5 */ test = lp_build_compare(builder, f32_type, PIPE_FUNC_GREATER, zero, pos_z); temp = LLVMBuildShl(builder, temp, shift, ""); @@ -980,18 +980,13 @@ clipmask_bool(LLVMBuilderRef builder, LLVMValueRef temp; int i; - LLVMDumpValue(clipmask); - for (i=0; i<4; i++){ temp = LLVMBuildExtractElement(builder, clipmask, LLVMConstInt(LLVMInt32Type(), i, 0) , ""); ret = LLVMBuildOr(builder, ret, temp, ""); - LLVMDumpValue(ret); } LLVMBuildStore(builder, ret, ret_ptr); - LLVMDumpValue(ret_ptr); - } static void @@ -1133,7 +1128,7 @@ draw_llvm_generate(struct draw_llvm *llvm, struct draw_llvm_variant *variant) variant->key.clip_xy, variant->key.clip_z, variant->key.clip_user, - variant->key.enable_d3dclipping, + variant->key.clip_halfz, variant->key.nr_planes, context_ptr); /* return clipping boolean value for function */ @@ -1344,7 +1339,7 @@ draw_llvm_generate_elts(struct draw_llvm *llvm, struct draw_llvm_variant *varian variant->key.clip_xy, variant->key.clip_z, variant->key.clip_user, - variant->key.enable_d3dclipping, + variant->key.clip_halfz, variant->key.nr_planes, context_ptr); /* return clipping boolean value for function */ @@ -1428,7 +1423,7 @@ draw_llvm_make_variant_key(struct draw_llvm *llvm, char *store) key->clip_z = llvm->draw->clip_z; key->clip_user = llvm->draw->clip_user; key->bypass_viewport = llvm->draw->identity_viewport; - key->enable_d3dclipping = (boolean)!llvm->draw->rasterizer->gl_rasterization_rules; + key->clip_halfz = !llvm->draw->rasterizer->gl_rasterization_rules; key->need_edgeflags = (llvm->draw->vs.edgeflag_output ? TRUE : FALSE); key->nr_planes = llvm->draw->nr_planes; key->pad = 0; diff --git a/src/gallium/auxiliary/draw/draw_llvm.h b/src/gallium/auxiliary/draw/draw_llvm.h index def068179f..b5b8c668d7 100644 --- a/src/gallium/auxiliary/draw/draw_llvm.h +++ b/src/gallium/auxiliary/draw/draw_llvm.h @@ -160,16 +160,16 @@ typedef int struct draw_llvm_variant_key { - unsigned nr_vertex_elements:16; - unsigned nr_samplers:12; + unsigned nr_vertex_elements:8; + unsigned nr_samplers:8; unsigned clip_xy:1; unsigned clip_z:1; unsigned clip_user:1; + unsigned clip_halfz:1; unsigned bypass_viewport:1; - unsigned enable_d3dclipping:1; unsigned need_edgeflags:1; unsigned nr_planes:4; - unsigned pad:26; + unsigned pad:6; /* Variable number of vertex elements: */ -- cgit v1.2.3 From ab2e1edd1fc6fbfd4f7d1949aa0d40cdb7142bd6 Mon Sep 17 00:00:00 2001 From: Hui Qi Tay Date: Mon, 18 Oct 2010 18:48:18 +0100 Subject: draw: corrections to allow for different cliptest cases --- src/gallium/auxiliary/draw/draw_llvm.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'src/gallium/auxiliary/draw') diff --git a/src/gallium/auxiliary/draw/draw_llvm.c b/src/gallium/auxiliary/draw/draw_llvm.c index ebd8b9d4ad..622250e7f7 100644 --- a/src/gallium/auxiliary/draw/draw_llvm.c +++ b/src/gallium/auxiliary/draw/draw_llvm.c @@ -861,9 +861,11 @@ generate_clipmask(LLVMBuilderRef builder, struct lp_type f32_type = lp_type_float_vec(32); + mask = lp_build_const_int_vec(lp_type_int_vec(32), 0); + temp = lp_build_const_int_vec(lp_type_int_vec(32), 0); zero = lp_build_const_vec(f32_type, 0); /* 0.0f 0.0f 0.0f 0.0f */ shift = lp_build_const_int_vec(lp_type_int_vec(32), 1); /* 1 1 1 1 */ - + /* Assuming position stored at output[0] */ pos_x = LLVMBuildLoad(builder, outputs[0][0], ""); /*x0 x1 x2 x3*/ pos_y = LLVMBuildLoad(builder, outputs[0][1], ""); /*y0 y1 y2 y3*/ @@ -900,10 +902,10 @@ generate_clipmask(LLVMBuilderRef builder, } if (clip_z){ + temp = lp_build_const_int_vec(lp_type_int_vec(32), 16); if (clip_halfz){ /* plane 5 */ test = lp_build_compare(builder, f32_type, PIPE_FUNC_GREATER, zero, pos_z); - temp = LLVMBuildShl(builder, temp, shift, ""); test = LLVMBuildAnd(builder, test, temp, ""); mask = LLVMBuildOr(builder, mask, test, ""); } @@ -911,7 +913,6 @@ generate_clipmask(LLVMBuilderRef builder, /* plane 5 */ test = LLVMBuildFAdd(builder, pos_z, pos_w, ""); test = lp_build_compare(builder, f32_type, PIPE_FUNC_GREATER, zero, test); - temp = LLVMBuildShl(builder, temp, shift, ""); test = LLVMBuildAnd(builder, test, temp, ""); mask = LLVMBuildOr(builder, mask, test, ""); } @@ -925,6 +926,7 @@ generate_clipmask(LLVMBuilderRef builder, if (clip_user){ LLVMValueRef planes_ptr = draw_jit_context_planes(builder, context_ptr); LLVMValueRef indices[3]; + temp = lp_build_const_int_vec(lp_type_int_vec(32), 32); /* userclip planes */ for (i = 6; i < nr; i++) { -- cgit v1.2.3