diff options
author | Zack Rusin <zackr@vmware.com> | 2010-02-22 22:02:58 -0500 |
---|---|---|
committer | Zack Rusin <zackr@vmware.com> | 2010-02-22 22:02:58 -0500 |
commit | c5c5cd7132e18f4aad8e73d8ee879f8823c4c1e7 (patch) | |
tree | f36680fba5d44945075e4b6f7d4269154b3c1e7d /src/gallium/auxiliary/draw/draw_llvm_translate.c | |
parent | 902ccfcb40f21e1a5fca2f1bec1cbbabb053d8cf (diff) |
gallium/draw: initial code to properly support llvm in the draw module
code generate big chunks of the vertex pipeline in order to speed up
software vertex processing.
Diffstat (limited to 'src/gallium/auxiliary/draw/draw_llvm_translate.c')
-rw-r--r-- | src/gallium/auxiliary/draw/draw_llvm_translate.c | 653 |
1 files changed, 653 insertions, 0 deletions
diff --git a/src/gallium/auxiliary/draw/draw_llvm_translate.c b/src/gallium/auxiliary/draw/draw_llvm_translate.c new file mode 100644 index 0000000000..588e97b29c --- /dev/null +++ b/src/gallium/auxiliary/draw/draw_llvm_translate.c @@ -0,0 +1,653 @@ + + + +#include "util/u_memory.h" +#include "pipe/p_state.h" +#include "translate.h" + + +#define DRAW_DBG 0 + +typedef void (*fetch_func)(const void *ptr, float *attrib); +typedef void (*emit_func)(const float *attrib, void *ptr); + + + +struct translate_generic { + struct translate translate; + + struct { + enum translate_element_type type; + + fetch_func fetch; + unsigned buffer; + unsigned input_offset; + unsigned instance_divisor; + + emit_func emit; + unsigned output_offset; + + char *input_ptr; + unsigned input_stride; + + } attrib[PIPE_MAX_ATTRIBS]; + + unsigned nr_attrib; +}; + + +static struct translate_generic *translate_generic( struct translate *translate ) +{ + return (struct translate_generic *)translate; +} + +/** + * Fetch a float[4] vertex attribute from memory, doing format/type + * conversion as needed. + * + * This is probably needed/dupliocated elsewhere, eg format + * conversion, texture sampling etc. + */ +#define ATTRIB( NAME, SZ, TYPE, FROM, TO ) \ +static void \ +fetch_##NAME(const void *ptr, float *attrib) \ +{ \ + const float defaults[4] = { 0.0f,0.0f,0.0f,1.0f }; \ + unsigned i; \ + \ + for (i = 0; i < SZ; i++) { \ + attrib[i] = FROM(i); \ + } \ + \ + for (; i < 4; i++) { \ + attrib[i] = defaults[i]; \ + } \ +} \ + \ +static void \ +emit_##NAME(const float *attrib, void *ptr) \ +{ \ + unsigned i; \ + TYPE *out = (TYPE *)ptr; \ + \ + for (i = 0; i < SZ; i++) { \ + out[i] = TO(attrib[i]); \ + } \ +} + +{ + + return conv = instr(builder, bc, ""); +} + +static INLINE LLVMValueRef +from_64_float(LLVMBuilderRef builder, LLVMValueRef val) +{ + LLVMValueRef bc = LLVMBuildBitCast(builder, val, + LLVMDoubleType() , ""); + LLVMValueRef l = LLVMBuildLoad(builder, bc, ""); + return LLVMBuildFPTrunc(builder, l, LLVMFloatType(), ""); +} + +static INLINE LLVMValueRef +from_32_float(LLVMBuilderRef builder, LLVMValueRef val) +{ + LLVMValueRef bc = LLVMBuildBitCast(builder, val, + LLVMFloatType() , ""); + return LLVMBuildLoad(builder, bc, ""); +} + +static INLINE LLVMValueRef +from_8_uscaled(LLVMBuilderRef builder, LLVMValueRef val) +{ + LLVMValueRef l = LLVMBuildLoad(builder, val, ""); + return LLVMBuildUIToFP(builder, l, LLVMFloatType(), ""); +} + +static INLINE LLVMValueRef +from_16_uscaled(LLVMBuilderRef builder, LLVMValueRef val) +{ + LLVMValueRef bc = LLVMBuildBitCast(builder, val, + LLVMIntType(16) , ""); + LLVMValueRef l = LLVMBuildLoad(builder, bc, ""); + return LLVMBuildUIToFP(builder, l, LLVMFloatType(), ""); +} + +static INLINE LLVMValueRef +from_32_uscaled(LLVMBuilderRef builder, LLVMValueRef val) +{ + LLVMValueRef bc = LLVMBuildBitCast(builder, val, + LLVMIntType(32) , ""); + LLVMValueRef l = LLVMBuildLoad(builder, bc, ""); + return LLVMBuildUIToFP(builder, l, LLVMFloatType(), ""); +} + +static INLINE LLVMValueRef +from_8_sscaled(LLVMBuilderRef builder, LLVMValueRef val) +{ + LLVMValueRef l = LLVMBuildLoad(builder, val, ""); + return LLVMBuildSIToFP(builder, l, LLVMFloatType(), ""); +} + +static INLINE LLVMValueRef +from_16_sscaled(LLVMBuilderRef builder, LLVMValueRef val) +{ + LLVMValueRef bc = LLVMBuildBitCast(builder, val, + LLVMIntType(16) , ""); + LLVMValueRef l = LLVMBuildLoad(builder, bc, ""); + return LLVMBuildSIToFP(builder, l, LLVMFloatType(), ""); +} + +static INLINE LLVMValueRef +from_32_sscaled(LLVMBuilderRef builder, LLVMValueRef val) +{ + LLVMValueRef bc = LLVMBuildBitCast(builder, val, + LLVMIntType(32) , ""); + LLVMValueRef l = LLVMBuildLoad(builder, bc, ""); + return LLVMBuildSIToFP(builder, l, LLVMFloatType(), ""); +} + + +static INLINE LLVMValueRef +from_8_unorm(LLVMBuilderRef builder, LLVMValueRef val) +{ + LLVMValueRef l = LLVMBuildLoad(builder, val, ""); + LLVMValueRef uscaled = LLVMBuildUIToFP(builder, l, LLVMFloatType(), ""); + return LLVMBuildFDiv(builder, uscaled, + LLVMConstReal(builder, 255.)); +} + +static INLINE LLVMValueRef +from_16_unorm(LLVMBuilderRef builder, LLVMValueRef val) +{ + LLVMValueRef bc = LLVMBuildBitCast(builder, val, + LLVMIntType(16) , ""); + LLVMValueRef l = LLVMBuildLoad(builder, bc, ""); + LLVMValueRef uscaled = LLVMBuildUIToFP(builder, l, LLVMFloatType(), ""); + return LLVMBuildFDiv(builder, uscaled, + LLVMConstReal(builder, 65535.)); +} + +static INLINE LLVMValueRef +from_32_unorm(LLVMBuilderRef builder, LLVMValueRef val) +{ + LLVMValueRef bc = LLVMBuildBitCast(builder, val, + LLVMIntType(32) , ""); + LLVMValueRef l = LLVMBuildLoad(builder, bc, ""); + LLVMValueRef uscaled = LLVMBuildUIToFP(builder, l, LLVMFloatType(), ""); + + return LLVMBuildFDiv(builder, uscaled, + LLVMConstReal(builder, 4294967295.)); +} + +static INLINE LLVMValueRef +from_8_snorm(LLVMBuilderRef builder, LLVMValueRef val) +{ + LLVMValueRef l = LLVMBuildLoad(builder, val, ""); + LLVMValueRef uscaled = LLVMBuildSIToFP(builder, l, LLVMFloatType(), ""); + return LLVMBuildFDiv(builder, uscaled, + LLVMConstReal(builder, 127.0)); +} + +static INLINE LLVMValueRef +from_16_snorm(LLVMBuilderRef builder, LLVMValueRef val) +{ + LLVMValueRef bc = LLVMBuildBitCast(builder, val, + LLVMIntType(16) , ""); + LLVMValueRef l = LLVMBuildLoad(builder, bc, ""); + LLVMValueRef uscaled = LLVMBuildSIToFP(builder, l, LLVMFloatType(), ""); + return LLVMBuildFDiv(builder, uscaled, + LLVMConstReal(builder, 32767.0f)); +} + +static INLINE LLVMValueRef +from_32_snorm(LLVMBuilderRef builder, LLVMValueRef val) +{ + LLVMValueRef bc = LLVMBuildBitCast(builder, val, + LLVMIntType(32) , ""); + LLVMValueRef l = LLVMBuildLoad(builder, bc, ""); + LLVMValueRef uscaled = LLVMBuildSIToFP(builder, l, LLVMFloatType(), ""); + + return LLVMBuildFDiv(builder, uscaled, + LLVMConstReal(builder, 2147483647.0)); +} + +static INLINE LLVMValueRef +from_32_fixed(LLVMBuilderRef builder, LLVMValueRef val) +{ + LLVMValueRef bc = LLVMBuildBitCast(builder, val, + LLVMIntType(32) , ""); + LLVMValueRef l = LLVMBuildLoad(builder, bc, ""); + LLVMValueRef uscaled = LLVMBuildSIToFP(builder, l, LLVMFloatType(), ""); + + return LLVMBuildFDiv(builder, uscaled, + LLVMConstReal(builder, 65536.0)); +} + +static INLINE LLVMValueRef +to_64_float(LLVMBuilderRef builder, LLVMValueRef fp) +{ + LLVMValueRef l = LLVMBuildLoad(builder, fp, ""); + return LLVMBuildFPExt(builder, l, LLVMDoubleType(), ""); +} + +static INLINE LLVMValueRef +to_32_float(LLVMBuilderRef builder, LLVMValueRef fp) +{ + return LLVMBuildLoad(builder, fp, ""); +} + +atic INLINE LLVMValueRef +to_8_uscaled(LLVMBuilderRef builder, LLVMValueRef fp) +{ + LLVMValueRef l = LLVMBuildLoad(builder, fp, ""); + return LLVMBuildFPToUI(builder, l, LLVMIntType(8), ""); +} + +static INLINE LLVMValueRef +to_16_uscaled(LLVMBuilderRef builder, LLVMValueRef fp) +{ + LLVMValueRef l = LLVMBuildLoad(builder, fp, ""); + return LLVMBuildFPToUI(builder, l, LLVMIntType(16), ""); +} + +static INLINE LLVMValueRef +to_32_uscaled(LLVMBuilderRef builder, LLVMValueRef fp) +{ + LLVMValueRef l = LLVMBuildLoad(builder, fp, ""); + return LLVMBuildFPToUI(builder, l, LLVMIntType(32), ""); +} + +static INLINE LLVMValueRef +to_8_sscaled(LLVMBuilderRef builder, LLVMValueRef fp) +{ + LLVMValueRef l = LLVMBuildLoad(builder, fp, ""); + return LLVMBuildFPToSI(builder, l, LLVMIntType(8), ""); +} + +static INLINE LLVMValueRef +to_16_sscaled(LLVMBuilderRef builder, LLVMValueRef fp) +{ + LLVMValueRef l = LLVMBuildLoad(builder, fp, ""); + return LLVMBuildFPToSI(builder, l, LLVMIntType(16), ""); +} + +static INLINE LLVMValueRef +to_32_sscaled(LLVMBuilderRef builder, LLVMValueRef fp) +{ + LLVMValueRef l = LLVMBuildLoad(builder, fp, ""); + return LLVMBuildFPToSI(builder, l, LLVMIntType(32), ""); +} + +static INLINE LLVMValueRef +to_8_unorm(LLVMBuilderRef builder, LLVMValueRef fp) +{ + LLVMValueRef l = LLVMBuildLoad(builder, fp, ""); + LLVMValueRef uscaled = LLVMBuildFPToUI(builder, l, LLVMIntType(8), ""); + return LLVMBuildFMul(builder, uscaled, + LLVMConstReal(builder, 255.)); +} + +static INLINE LLVMValueRef +to_16_unorm(LLVMBuilderRef builder, LLVMValueRef fp) +{ + LLVMValueRef l = LLVMBuildLoad(builder, fp, ""); + LLVMValueRef uscaled = LLVMBuildFPToUI(builder, l, LLVMIntType(32), ""); + return LLVMBuildFMul(builder, uscaled, + LLVMConstReal(builder, 65535.)); +} + +static INLINE LLVMValueRef +to_32_unorm(LLVMBuilderRef builder, LLVMValueRef fp) +{ + LLVMValueRef l = LLVMBuildLoad(builder, fp, ""); + LLVMValueRef uscaled = LLVMBuildFPToUI(builder, l, LLVMIntType(32), ""); + + return LLVMBuildFMul(builder, uscaled, + LLVMConstReal(builder, 4294967295.)); +} + +static INLINE LLVMValueRef +to_8_snorm(LLVMBuilderRef builder, LLVMValueRef val) +{ + LLVMValueRef l = LLVMBuildLoad(builder, val, ""); + LLVMValueRef uscaled = LLVMBuildFPToSI(builder, l, LLVMIntType(8), ""); + return LLVMBuildFMUL(builder, uscaled, + LLVMConstReal(builder, 127.0)); +} + +static INLINE LLVMValueRef +to_16_snorm(LLVMBuilderRef builder, LLVMValueRef fp) +{ + LLVMValueRef l = LLVMBuildLoad(builder, fp, ""); + LLVMValueRef uscaled = LLVMBuildFPToSI(builder, l, LLVMIntType(16), ""); + return LLVMBuildFMul(builder, uscaled, + LLVMConstReal(builder, 32767.0f)); +} + +static INLINE LLVMValueRef +to_32_snorm(LLVMBuilderRef builder, LLVMValueRef fp) +{ + LLVMValueRef l = LLVMBuildLoad(builder, fp, ""); + LLVMValueRef uscaled = LLVMBuildFPToSI(builder, l, LLVMIntType(32), ""); + + return LLVMBuildFMUL(builder, uscaled, + LLVMConstReal(builder, 2147483647.0)); +} + +static INLINE LLVMValueRef +to_32_fixed(LLVMBuilderRef builder, LLVMValueRef fp) +{ + LLVMValueRef l = LLVMBuildLoad(builder, fp, ""); + LLVMValueRef uscaled = LLVMBuildFPToSI(builder, l, LLVMIntType(32), ""); + + return LLVMBuildFMul(builder, uscaled, + LLVMConstReal(builder, 65536.0)); +} + +static LLVMValueRef +fetch(LLVMValueRef ptr, int val_size, int nr_components, + LLVMValueRef res) +{ + int i; + int offset = 0; + + for (i = 0; i < nr_components; ++i) { + LLVMValueRef src_index = LLVMConstInt(LLVMInt32Type(), offset, 0); + LLVMValueRef dst_index = LLVMConstInt(LLVMInt32Type(), i, 0); + //getelementptr i8* ptr, i64 offset + LLVMValueRef src_tmp = LLVMBuildGEP(builder, ptr, &src_index, 1, ""); + //getelementptr float* res, i64 i + LLVMValueRef res_tmp = LLVMBuildGEP(builder, res, &dst_index, 1, ""); + //bitcast i8* src, to res_type* + //load res_type src + //convert res_type src to float + //store float src, float *dst src + offset += val_size; + } +} + + +static void +fetch_B8G8R8A8_UNORM(const void *ptr, float *attrib) +{ + attrib[2] = FROM_8_UNORM(0); + attrib[1] = FROM_8_UNORM(1); + attrib[0] = FROM_8_UNORM(2); + attrib[3] = FROM_8_UNORM(3); +} + +static void +emit_B8G8R8A8_UNORM( const float *attrib, void *ptr) +{ + ubyte *out = (ubyte *)ptr; + out[2] = TO_8_UNORM(attrib[0]); + out[1] = TO_8_UNORM(attrib[1]); + out[0] = TO_8_UNORM(attrib[2]); + out[3] = TO_8_UNORM(attrib[3]); +} + +static void +fetch_NULL( const void *ptr, float *attrib ) +{ + attrib[0] = 0; + attrib[1] = 0; + attrib[2] = 0; + attrib[3] = 1; +} + +static void +emit_NULL( const float *attrib, void *ptr ) +{ + /* do nothing is the only sensible option */ +} + +typedef LLVMValueRef (*from_func)(LLVMBuilderRef, LLVMValueRef); +typedef LLVMValueRef (*to_func)(LLVMBuilderRef, LLVMValueRef); + +struct draw_llvm_translate { + int format; + from_func from; + to_func to; + LLVMTypeRef type; + int num_components; +} translates[] = +{ + {PIPE_FORMAT_R64_FLOAT, from_64_float, to_64_float, LLVMDoubleType(), 1}, + {PIPE_FORMAT_R64G64_FLOAT, from_64_float, to_64_float, LLVMDoubleType(), 2}, + {PIPE_FORMAT_R64G64B64_FLOAT, from_64_float, to_64_float, LLVMDoubleType(), 3}, + {PIPE_FORMAT_R64G64B64A64_FLOAT, from_64_float, to_64_float, LLVMDoubleType(), 4}, + + {PIPE_FORMAT_R32_FLOAT, from_32_float, to_32_float, LLVMFloatType(), 1}, + {PIPE_FORMAT_R32G32_FLOAT, from_32_float, to_32_float, LLVMFloatType(), 2}, + {PIPE_FORMAT_R32G32B32_FLOAT, from_32_float, to_32_float, LLVMFloatType(), 3}, + {PIPE_FORMAT_R32G32B32A32_FLOAT, from_32_float, to_32_float, LLVMFloatType(), 4}, + + {PIPE_FORMAT_R32_UNORM, from_32_unorm, to_32_unorm, LLVMIntType(32), 1}, + {PIPE_FORMAT_R32G32_UNORM, from_32_unorm, to_32_unorm, LLVMIntType(32), 2}, + {PIPE_FORMAT_R32G32B32_UNORM, from_32_unorm, to_32_unorm, LLVMIntType(32), 3}, + {PIPE_FORMAT_R32G32B32A32_UNORM, from_32_unorm, to_32_unorm, LLVMIntType(32), 4}, + + {PIPE_FORMAT_R32_USCALED, from_32_uscaled, to_32_uscaled, LLVMIntType(32), 1}, + {PIPE_FORMAT_R32G32_USCALED, from_32_uscaled, to_32_uscaled, LLVMIntType(32), 2}, + {PIPE_FORMAT_R32G32B32_USCALED, from_32_uscaled, to_32_uscaled, LLVMIntType(32), 3}, + {PIPE_FORMAT_R32G32B32A32_USCALED, from_32_uscaled, to_32_uscaled, LLVMIntType(32), 4}, + + {PIPE_FORMAT_R32_SNORM, from_32_snorm, to_32_snorm, LLVMIntType(32), 1}, + {PIPE_FORMAT_R32G32_SNORM, from_32_snorm, to_32_snorm, LLVMIntType(32), 2}, + {PIPE_FORMAT_R32G32B32_SNORM, from_32_snorm, to_32_snorm, LLVMIntType(32), 3}, + {PIPE_FORMAT_R32G32B32A32_SNORM, from_32_snorm, to_32_snorm, LLVMIntType(32), 4}, + + {PIPE_FORMAT_R32_SSCALED, from_32_sscaled, to_32_sscaled, LLVMIntType(32), 1}, + {PIPE_FORMAT_R32G32_SSCALED, from_32_sscaled, to_32_sscaled, LLVMIntType(32), 2}, + {PIPE_FORMAT_R32G32B32_SSCALED, from_32_sscaled, to_32_sscaled, LLVMIntType(32), 3}, + {PIPE_FORMAT_R32G32B32A32_SSCALED, from_32_sscaled, to_32_sscaled, LLVMIntType(32), 4}, + + {PIPE_FORMAT_R16_UNORM, from_16_unorm, to_16_unorm, LLVMIntType(16), 1}, + {PIPE_FORMAT_R16G16_UNORM, from_16_unorm, to_16_unorm, LLVMIntType(16), 2}, + {PIPE_FORMAT_R16G16B16_UNORM, from_16_unorm, to_16_unorm, LLVMIntType(16), 3}, + {PIPE_FORMAT_R16G16B16A16_UNORM, from_16_unorm, to_16_unorm, LLVMIntType(16), 4}, + + {PIPE_FORMAT_R16_USCALED, from_16_uscaled, to_16_uscaled, LLVMIntType(16), 1}, + {PIPE_FORMAT_R16G16_USCALED, from_16_uscaled, to_16_uscaled, LLVMIntType(16), 2}, + {PIPE_FORMAT_R16G16B16_USCALED, from_16_uscaled, to_16_uscaled, LLVMIntType(16), 3}, + {PIPE_FORMAT_R16G16B16A16_USCALED, from_16_uscaled, to_16_uscaled, LLVMIntType(16), 4}, + + {PIPE_FORMAT_R16_SNORM, from_16_snorm, to_16_snorm, LLVMIntType(16), 1}, + {PIPE_FORMAT_R16G16_SNORM, from_16_snorm, to_16_snorm, LLVMIntType(16), 2}, + {PIPE_FORMAT_R16G16B16_SNORM, from_16_snorm, to_16_snorm, LLVMIntType(16), 3}, + {PIPE_FORMAT_R16G16B16A16_SNORM, from_16_snorm, to_16_snorm, LLVMIntType(16), 4}, + + {PIPE_FORMAT_R16_SSCALED, from_16_sscaled, to_16_sscaled, LLVMIntType(16), 1}, + {PIPE_FORMAT_R16G16_SSCALED, from_16_sscaled, to_16_sscaled, LLVMIntType(16), 2}, + {PIPE_FORMAT_R16G16B16_SSCALED, from_16_sscaled, to_16_sscaled, LLVMIntType(16), 3}, + {PIPE_FORMAT_R16G16B16A16_SSCALED, from_16_sscaled, to_16_sscaled, LLVMIntType(16), 4}, + + {PIPE_FORMAT_R8_UNORM, from_8_unorm, to_8_unorm, LLVMIntType(8), 1}, + {PIPE_FORMAT_R8G8_UNORM, from_8_unorm, to_8_unorm, LLVMIntType(8), 2}, + {PIPE_FORMAT_R8G8B8_UNORM, from_8_unorm, to_8_unorm, LLVMIntType(8), 3}, + {PIPE_FORMAT_R8G8B8A8_UNORM, from_8_unorm, to_8_unorm, LLVMIntType(8), 4}, + + {PIPE_FORMAT_R8_USCALED, from_8_uscaled, to_8_uscaled, LLVMIntType(8), 1}, + {PIPE_FORMAT_R8G8_USCALED, from_8_uscaled, to_8_uscaled, LLVMIntType(8), 2}, + {PIPE_FORMAT_R8G8B8_USCALED, from_8_uscaled, to_8_uscaled, LLVMIntType(8), 3}, + {PIPE_FORMAT_R8G8B8A8_USCALED, from_8_uscaled, to_8_uscaled, LLVMIntType(8), 4}, + + {PIPE_FORMAT_R8_SNORM, from_8_snorm, to_8_snorm, LLVMIntType(8), 1}, + {PIPE_FORMAT_R8G8_SNORM, from_8_snorm, to_8_snorm, LLVMIntType(8), 2}, + {PIPE_FORMAT_R8G8B8_SNORM, from_8_snorm, to_8_snorm, LLVMIntType(8), 3}, + {PIPE_FORMAT_R8G8B8A8_SNORM, from_8_snorm, to_8_snorm, LLVMIntType(8), 4}, + + {PIPE_FORMAT_R8_SSCALED, from_8_sscaled, to_8_sscaled, LLVMIntType(8), 1}, + {PIPE_FORMAT_R8G8_SSCALED, from_8_sscaled, to_8_sscaled, LLVMIntType(8), 2}, + {PIPE_FORMAT_R8G8B8_SSCALED, from_8_sscaled, to_8_sscaled, LLVMIntType(8), 3}, + {PIPE_FORMAT_R8G8B8A8_SSCALED, from_8_sscaled, to_8_sscaled, LLVMIntType(8), 4}, + + {PIPE_FORMAT_R32_FIXED, from_32_fixed, to_32_fixed, LLVMIntType(32), 1}, + {PIPE_FORMAT_R32G32_FIXED, from_32_fixed, to_32_fixed, LLVMIntType(32), 2}, + {PIPE_FORMAT_R32G32B32_FIXED, from_32_fixed, to_32_fixed, LLVMIntType(32), 3}, + {PIPE_FORMAT_R32G32B32A32_FIXED, from_32_fixed, to_32_fixed, LLVMIntType(32), 4}, + + {PIPE_FORMAT_A8R8G8B8_UNORM, from_8_unorm, to_8_unorm, LLVMIntType(8), 4}, + {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 ) +{ + 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; + } + } +} + + +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; +} |