From: Zack Rusin Date: Mon, 29 Mar 2010 17:19:16 +0000 (-0400) Subject: draw llvmpipe: lots of fixes for fetch/emit X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=f44af927ff90a9fe1256d8c6f4869a39a55043d3;p=mesa.git draw llvmpipe: lots of fixes for fetch/emit the values passed are still not right, but the general scheme is looking good. --- diff --git a/src/gallium/auxiliary/draw/draw_llvm.c b/src/gallium/auxiliary/draw/draw_llvm.c index 6b0ddfd064d..91fe838b8b7 100644 --- a/src/gallium/auxiliary/draw/draw_llvm.c +++ b/src/gallium/auxiliary/draw/draw_llvm.c @@ -114,6 +114,10 @@ init_globals(struct draw_llvm *llvm) llvm->context_ptr_type = LLVMPointerType(context_type, 0); } + { + LLVMTypeRef buffer_ptr = LLVMPointerType(LLVMOpaqueType(), 0); + llvm->buffer_ptr_type = LLVMArrayType(buffer_ptr, PIPE_MAX_ATTRIBS); + } } struct draw_llvm * @@ -171,6 +175,7 @@ draw_llvm_destroy(struct draw_llvm *llvm) void draw_llvm_prepare(struct draw_llvm *llvm) { + draw_llvm_generate(llvm); } @@ -194,14 +199,14 @@ fail: static void generate_vs(struct draw_llvm *llvm, LLVMBuilderRef builder, + LLVMValueRef (*outputs)[NUM_CHANNELS], + const LLVMValueRef (*inputs)[NUM_CHANNELS], LLVMValueRef context_ptr, LLVMValueRef io) { const struct tgsi_token *tokens = llvm->draw->vs.vertex_shader->state.tokens; struct lp_type vs_type = lp_type_float(32); LLVMValueRef vs_consts; - const LLVMValueRef (*inputs)[NUM_CHANNELS]; - LLVMValueRef (*outputs)[NUM_CHANNELS]; lp_build_tgsi_soa(builder, tokens, @@ -214,28 +219,129 @@ generate_vs(struct draw_llvm *llvm, NULL/*sampler*/); } +static void +generate_fetch(LLVMBuilderRef builder, + const LLVMValueRef vbuffers_ptr, + LLVMValueRef *res, + struct pipe_vertex_element *velem, + struct pipe_vertex_buffer *vbuf, + LLVMValueRef index) +{ + LLVMValueRef indices = LLVMConstInt(LLVMInt32Type(), + velem->vertex_buffer_index, 0); + LLVMValueRef vbuffer_ptr = LLVMBuildGEP(builder, vbuffers_ptr, + &indices, 1, ""); + LLVMValueRef stride = LLVMBuildMul(builder, + LLVMConstInt(LLVMInt32Type(), vbuf->stride, 0), + index, ""); + stride = LLVMBuildAdd(builder, stride, + LLVMConstInt(LLVMInt32Type(), vbuf->buffer_offset, 0), + ""); + stride = LLVMBuildAdd(builder, stride, + LLVMConstInt(LLVMInt32Type(), velem->src_offset, 0), + ""); + + vbuffer_ptr = LLVMBuildGEP(builder, vbuffer_ptr, &stride, 1, ""); + + *res = draw_llvm_translate_from(builder, vbuffer_ptr, velem->src_format); +} + +static LLVMValueRef +aos_to_soa(LLVMBuilderRef builder, + LLVMValueRef val0, + LLVMValueRef val1, + LLVMValueRef val2, + LLVMValueRef val3, + LLVMValueRef channel) +{ + LLVMValueRef ex, res; + + ex = LLVMBuildExtractElement(builder, val0, + channel, ""); + res = LLVMBuildInsertElement(builder, + LLVMConstNull(LLVMTypeOf(val0)), + ex, + LLVMConstInt(LLVMInt32Type(), 0, 0), + ""); + + ex = LLVMBuildExtractElement(builder, val1, + channel, ""); + res = LLVMBuildInsertElement(builder, + res, ex, + LLVMConstInt(LLVMInt32Type(), 1, 0), + ""); + + ex = LLVMBuildExtractElement(builder, val2, + channel, ""); + res = LLVMBuildInsertElement(builder, + res, ex, + LLVMConstInt(LLVMInt32Type(), 2, 0), + ""); + + ex = LLVMBuildExtractElement(builder, val3, + channel, ""); + res = LLVMBuildInsertElement(builder, + res, ex, + LLVMConstInt(LLVMInt32Type(), 3, 0), + ""); + + return res; +} + +static void +convert_to_soa(LLVMBuilderRef builder, + LLVMValueRef (*aos)[NUM_CHANNELS], + LLVMValueRef (*soa)[NUM_CHANNELS], + int num_attribs) +{ + int i; + + debug_assert(NUM_CHANNELS == 4); + + for (i = 0; i < num_attribs; ++i) { + LLVMValueRef val0 = aos[i][0]; + LLVMValueRef val1 = aos[i][1]; + LLVMValueRef val2 = aos[i][2]; + LLVMValueRef val3 = aos[i][3]; + + soa[i][0] = aos_to_soa(builder, val0, val1, val2, val3, + LLVMConstInt(LLVMInt32Type(), 0, 0)); + soa[i][1] = aos_to_soa(builder, val0, val1, val2, val3, + LLVMConstInt(LLVMInt32Type(), 1, 0)); + soa[i][2] = aos_to_soa(builder, val0, val1, val2, val3, + LLVMConstInt(LLVMInt32Type(), 2, 0)); + soa[i][3] = aos_to_soa(builder, val0, val1, val2, val3, + LLVMConstInt(LLVMInt32Type(), 3, 0)); + + } +} + void draw_llvm_generate(struct draw_llvm *llvm) { - LLVMTypeRef arg_types[5]; + LLVMTypeRef arg_types[6]; LLVMTypeRef func_type; LLVMValueRef context_ptr; LLVMBasicBlockRef block; LLVMBuilderRef builder; LLVMValueRef function; LLVMValueRef start, end, count, stride, step; - LLVMValueRef io_ptr; - unsigned i; + LLVMValueRef io_ptr, vbuffers_ptr; + struct draw_context *draw = llvm->draw; + unsigned i, j; unsigned chan; struct lp_build_context bld; struct lp_build_loop_state lp_loop; - struct lp_type vs_type = lp_type_float(32); + struct lp_type vs_type = lp_type_float_vec(32); + const int max_vertices = 4; + LLVMValueRef outputs[PIPE_MAX_SHADER_OUTPUTS][NUM_CHANNELS]; arg_types[0] = llvm->context_ptr_type; /* context */ arg_types[1] = llvm->vertex_header_ptr_type; /* vertex_header */ - arg_types[2] = LLVMInt32Type(); /* start */ - arg_types[3] = LLVMInt32Type(); /* count */ - arg_types[4] = LLVMInt32Type(); /* stride */ + arg_types[2] = llvm->buffer_ptr_type; /* vbuffers */ + arg_types[3] = LLVMInt32Type(); /* start */ + arg_types[4] = LLVMInt32Type(); /* count */ + arg_types[5] = LLVMInt32Type(); /* stride */ func_type = LLVMFunctionType(LLVMVoidType(), arg_types, Elements(arg_types), 0); @@ -247,12 +353,14 @@ draw_llvm_generate(struct draw_llvm *llvm) context_ptr = LLVMGetParam(function, 0); io_ptr = LLVMGetParam(function, 1); - start = LLVMGetParam(function, 2); - count = LLVMGetParam(function, 3); - stride = LLVMGetParam(function, 4); + vbuffers_ptr = LLVMGetParam(function, 2); + start = LLVMGetParam(function, 3); + count = LLVMGetParam(function, 4); + stride = LLVMGetParam(function, 5); lp_build_name(context_ptr, "context"); lp_build_name(io_ptr, "io"); + lp_build_name(vbuffers_ptr, "vbuffers"); lp_build_name(start, "start"); lp_build_name(count, "count"); lp_build_name(stride, "stride"); @@ -269,13 +377,34 @@ draw_llvm_generate(struct draw_llvm *llvm) end = lp_build_add(&bld, start, count); - step = LLVMConstInt(LLVMInt32Type(), 1, 0); + step = LLVMConstInt(LLVMInt32Type(), max_vertices, 0); lp_build_loop_begin(builder, start, &lp_loop); { + LLVMValueRef inputs[PIPE_MAX_SHADER_INPUTS][NUM_CHANNELS]; + LLVMValueRef aos_attribs[PIPE_MAX_SHADER_INPUTS][NUM_CHANNELS]; LLVMValueRef io = LLVMBuildGEP(builder, io_ptr, &lp_loop.counter, 1, ""); + for (i = 0; i < NUM_CHANNELS; ++i) { + LLVMValueRef true_index = LLVMBuildAdd( + builder, + lp_loop.counter, + LLVMConstInt(LLVMInt32Type(), i, 0), ""); + for (j = 0; j < draw->pt.nr_vertex_elements; ++j) { + struct pipe_vertex_element *velem = &draw->pt.vertex_element[j]; + struct pipe_vertex_buffer *vbuf = &draw->pt.vertex_buffer[ + velem->vertex_buffer_index]; + + generate_fetch(builder, vbuffers_ptr, + &aos_attribs[j][i], velem, vbuf, true_index); + } + } + convert_to_soa(builder, inputs, aos_attribs, + draw->pt.nr_vertex_elements); + generate_vs(llvm, builder, + outputs, + inputs, context_ptr, io); } diff --git a/src/gallium/auxiliary/draw/draw_llvm.h b/src/gallium/auxiliary/draw/draw_llvm.h index 0a1845f1fb5..cbbfeeccc56 100644 --- a/src/gallium/auxiliary/draw/draw_llvm.h +++ b/src/gallium/auxiliary/draw/draw_llvm.h @@ -78,12 +78,12 @@ struct draw_jit_context const float *gs_constants; struct draw_jit_texture textures[PIPE_MAX_SAMPLERS]; - const void *vbuffers; }; void draw_shader(struct draw_jit_context *context, struct vertex_header *io, + const void *vbuffers[PIPE_MAX_ATTRIBS], unsigned start, unsigned count, unsigned stride) @@ -115,6 +115,7 @@ draw_shader(struct draw_jit_context *context, typedef void (*draw_jit_vert_func)(struct draw_jit_context *context, struct vertex_header *io, + const void *vbuffers[PIPE_MAX_ATTRIBS], unsigned start, unsigned count, unsigned stride); @@ -134,6 +135,7 @@ struct draw_llvm { LLVMTypeRef context_ptr_type; LLVMTypeRef vertex_header_ptr_type; + LLVMTypeRef buffer_ptr_type; }; @@ -150,5 +152,9 @@ draw_llvm_prepare(struct draw_llvm *llvm); void draw_llvm_generate(struct draw_llvm *llvm); +LLVMValueRef +draw_llvm_translate_from(LLVMBuilderRef builder, + LLVMValueRef vbuffer, + enum pipe_format from_format); #endif diff --git a/src/gallium/auxiliary/draw/draw_llvm_translate.c b/src/gallium/auxiliary/draw/draw_llvm_translate.c index 588e97b29ce..012ca3f6f03 100644 --- a/src/gallium/auxiliary/draw/draw_llvm_translate.c +++ b/src/gallium/auxiliary/draw/draw_llvm_translate.c @@ -492,162 +492,17 @@ struct draw_llvm_translate { {PIPE_FORMAT_B8G8R8A8_UNORM, from_8_unorm, to_8_unorm, LLVMIntType(), 4}, }; -/** - * Fetch vertex attributes for 'count' vertices. - */ -static void PIPE_CDECL generic_run_elts( struct translate *translate, - const unsigned *elts, - unsigned count, - unsigned instance_id, - void *output_buffer ) -{ - struct translate_generic *tg = translate_generic(translate); - char *vert = output_buffer; - unsigned nr_attrs = tg->nr_attrib; - unsigned attr; - unsigned i; - - /* loop over vertex attributes (vertex shader inputs) - */ - for (i = 0; i < count; i++) { - unsigned elt = *elts++; - - for (attr = 0; attr < nr_attrs; attr++) { - float data[4]; - const char *src; - - char *dst = (vert + - tg->attrib[attr].output_offset); - - if (tg->attrib[attr].instance_divisor) { - src = tg->attrib[attr].input_ptr + - tg->attrib[attr].input_stride * - (instance_id / tg->attrib[attr].instance_divisor); - } else { - src = tg->attrib[attr].input_ptr + - tg->attrib[attr].input_stride * elt; - } - - tg->attrib[attr].fetch( src, data ); - - if (0) debug_printf("vert %d/%d attr %d: %f %f %f %f\n", - i, elt, attr, data[0], data[1], data[2], data[3]); - - tg->attrib[attr].emit( data, dst ); - } - - vert += tg->translate.key.output_stride; - } -} - - -static void PIPE_CDECL generic_run( struct translate *translate, - unsigned start, - unsigned count, - unsigned instance_id, - void *output_buffer ) +LLVMValueRef +draw_llvm_translate_from(LLVMBuilderRef builder, + LLVMValueRef vbuffer, + enum pipe_format from_format) { - struct translate_generic *tg = translate_generic(translate); - char *vert = output_buffer; - unsigned nr_attrs = tg->nr_attrib; - unsigned attr; - unsigned i; - - /* loop over vertex attributes (vertex shader inputs) - */ - for (i = 0; i < count; i++) { - unsigned elt = start + i; - - for (attr = 0; attr < nr_attrs; attr++) { - float data[4]; - - char *dst = (vert + - tg->attrib[attr].output_offset); - - if (tg->attrib[attr].type == TRANSLATE_ELEMENT_NORMAL) { - const char *src; - - if (tg->attrib[attr].instance_divisor) { - src = tg->attrib[attr].input_ptr + - tg->attrib[attr].input_stride * - (instance_id / tg->attrib[attr].instance_divisor); - } else { - src = tg->attrib[attr].input_ptr + - tg->attrib[attr].input_stride * elt; - } - - tg->attrib[attr].fetch( src, data ); - } else { - data[0] = (float)instance_id; - } - - if (0) debug_printf("vert %d attr %d: %f %f %f %f\n", - i, attr, data[0], data[1], data[2], data[3]); - - tg->attrib[attr].emit( data, dst ); - } - - vert += tg->translate.key.output_stride; - } -} - - - -static void generic_set_buffer( struct translate *translate, - unsigned buf, - const void *ptr, - unsigned stride ) -{ - struct translate_generic *tg = translate_generic(translate); - unsigned i; - - for (i = 0; i < tg->nr_attrib; i++) { - if (tg->attrib[i].buffer == buf) { - tg->attrib[i].input_ptr = ((char *)ptr + - tg->attrib[i].input_offset); - tg->attrib[i].input_stride = stride; + int i; + for (i = 0; i < Elements(translates); ++i) { + if (translates[i].format == from_format) { + return translates.from_func(builder, vbuffer, from_format); } } -} - - -static void generic_release( struct translate *translate ) -{ - /* Refcount? - */ - FREE(translate); -} - -struct translate *translate_generic_create( const struct translate_key *key ) -{ - struct translate_generic *tg = CALLOC_STRUCT(translate_generic); - unsigned i; - - if (tg == NULL) - return NULL; - - tg->translate.key = *key; - tg->translate.release = generic_release; - tg->translate.set_buffer = generic_set_buffer; - tg->translate.run_elts = generic_run_elts; - tg->translate.run = generic_run; - - for (i = 0; i < key->nr_elements; i++) { - tg->attrib[i].type = key->element[i].type; - - tg->attrib[i].fetch = get_fetch_func(key->element[i].input_format); - tg->attrib[i].buffer = key->element[i].input_buffer; - tg->attrib[i].input_offset = key->element[i].input_offset; - tg->attrib[i].instance_divisor = key->element[i].instance_divisor; - - tg->attrib[i].emit = get_emit_func(key->element[i].output_format); - tg->attrib[i].output_offset = key->element[i].output_offset; - - } - - tg->nr_attrib = key->nr_elements; - - - return &tg->translate; + return LLVMGetUndef(LLVMTypeOf(vbuffer)); } 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 ae5956333eb..38b1c4462db 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 @@ -110,8 +110,7 @@ llvm_middle_end_prepare( struct draw_pt_middle_end *middle, */ draw_pt_post_vs_prepare( fpme->post_vs, (boolean)draw->bypass_clipping, - (boolean)(draw->identity_viewport || - draw->rasterizer->bypass_vs_clip_and_viewport), + (boolean)(draw->identity_viewport), (boolean)draw->rasterizer->gl_rasterization_rules, (draw->vs.edgeflag_output ? true : false) ); @@ -242,6 +241,7 @@ static void llvm_middle_end_linear_run( struct draw_pt_middle_end *middle, fpme->llvm->jit_func( &fpme->llvm->jit_context, pipeline_verts, + draw->pt.user.vbuffer, start, count, fpme->vertex_size );