draw llvm: various fixes for the translation code
authorZack Rusin <zackr@vmware.com>
Tue, 30 Mar 2010 16:35:40 +0000 (12:35 -0400)
committerZack Rusin <zackr@vmware.com>
Tue, 30 Mar 2010 16:35:40 +0000 (12:35 -0400)
the from translation isn't quite right yet

src/gallium/auxiliary/SConscript
src/gallium/auxiliary/draw/draw_gs.c
src/gallium/auxiliary/draw/draw_llvm.c
src/gallium/auxiliary/draw/draw_llvm.h
src/gallium/auxiliary/draw/draw_llvm_translate.c

index 76675fb..b234b2f 100644 (file)
@@ -205,7 +205,8 @@ if drawllvm:
     'gallivm/lp_bld_tgsi_soa.c',
     'gallivm/lp_bld_type.c',
     'draw/draw_llvm.c',
-    'draw/draw_pt_fetch_shade_pipeline_llvm.c'
+    'draw/draw_pt_fetch_shade_pipeline_llvm.c',
+    'draw/draw_llvm_translate.c'
     ]
 
 gallium = env.ConvenienceLibrary(
index 7069aa6..131deed 100644 (file)
@@ -342,10 +342,10 @@ void draw_geometry_shader_delete(struct draw_geometry_shader *shader)
 void draw_geometry_shader_prepare(struct draw_geometry_shader *shader,
                                   struct draw_context *draw)
 {
-    if (shader->machine->Tokens != shader->state.tokens) {
-       tgsi_exec_machine_bind_shader(shader->machine,
-                                     shader->state.tokens,
-                                     draw->gs.num_samplers,
-                                     draw->gs.samplers);
-    }
+   if (shader && shader->machine->Tokens != shader->state.tokens) {
+      tgsi_exec_machine_bind_shader(shader->machine,
+                                    shader->state.tokens,
+                                    draw->gs.num_samplers,
+                                    draw->gs.samplers);
+   }
 }
index 91fe838..aa4a310 100644 (file)
@@ -115,8 +115,8 @@ 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);
+      LLVMTypeRef buffer_ptr = LLVMPointerType(LLVMIntType(8), 0);
+      llvm->buffer_ptr_type = LLVMPointerType(buffer_ptr, 0);
    }
 }
 
@@ -221,19 +221,19 @@ generate_vs(struct draw_llvm *llvm,
 
 static void
 generate_fetch(LLVMBuilderRef builder,
-               const LLVMValueRef vbuffers_ptr,
+               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 indices = LLVMConstInt(LLVMInt64Type(), 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),
                          "");
@@ -393,7 +393,7 @@ draw_llvm_generate(struct draw_llvm *llvm)
             struct pipe_vertex_element *velem = &draw->pt.vertex_element[j];
             struct pipe_vertex_buffer *vbuf = &draw->pt.vertex_buffer[
                velem->vertex_buffer_index];
-
+            LLVMDumpValue(function);
             generate_fetch(builder, vbuffers_ptr,
                            &aos_attribs[j][i], velem, vbuf, true_index);
          }
index cbbfeec..e375008 100644 (file)
@@ -115,7 +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],
+                      const char *vbuffers[PIPE_MAX_ATTRIBS],
                       unsigned start,
                       unsigned count,
                       unsigned stride);
index 012ca3f..6cbe98c 100644 (file)
@@ -1,86 +1,23 @@
+#include "draw_private.h"
+#include "draw_context.h"
 
+#include "draw_llvm.h"
 
+#include "gallivm/lp_bld_arit.h"
+#include "gallivm/lp_bld_interp.h"
+#include "gallivm/lp_bld_struct.h"
+#include "gallivm/lp_bld_type.h"
+#include "gallivm/lp_bld_flow.h"
+#include "gallivm/lp_bld_debug.h"
+#include "gallivm/lp_bld_tgsi.h"
 
 #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
+static  LLVMValueRef
 from_64_float(LLVMBuilderRef builder, LLVMValueRef val)
 {
    LLVMValueRef bc = LLVMBuildBitCast(builder, val,
@@ -89,7 +26,7 @@ from_64_float(LLVMBuilderRef builder, LLVMValueRef val)
    return LLVMBuildFPTrunc(builder, l, LLVMFloatType(), "");
 }
 
-static INLINE LLVMValueRef
+static LLVMValueRef
 from_32_float(LLVMBuilderRef builder, LLVMValueRef val)
 {
    LLVMValueRef bc = LLVMBuildBitCast(builder, val,
@@ -154,7 +91,7 @@ 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.));
+                        LLVMConstReal(LLVMFloatType(), 255.), "");
 }
 
 static INLINE LLVMValueRef
@@ -165,7 +102,7 @@ from_16_unorm(LLVMBuilderRef builder, LLVMValueRef val)
    LLVMValueRef l = LLVMBuildLoad(builder, bc, "");
    LLVMValueRef uscaled = LLVMBuildUIToFP(builder, l, LLVMFloatType(), "");
    return LLVMBuildFDiv(builder, uscaled,
-                        LLVMConstReal(builder, 65535.));
+                        LLVMConstReal(LLVMFloatType(), 65535.), "");
 }
 
 static INLINE LLVMValueRef
@@ -177,7 +114,7 @@ from_32_unorm(LLVMBuilderRef builder, LLVMValueRef val)
    LLVMValueRef uscaled = LLVMBuildUIToFP(builder, l, LLVMFloatType(), "");
 
    return LLVMBuildFDiv(builder, uscaled,
-                        LLVMConstReal(builder, 4294967295.));
+                        LLVMConstReal(LLVMFloatType(), 4294967295.), "");
 }
 
 static INLINE LLVMValueRef
@@ -186,7 +123,7 @@ 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));
+                        LLVMConstReal(LLVMFloatType(), 127.0), "");
 }
 
 static INLINE LLVMValueRef
@@ -197,7 +134,7 @@ from_16_snorm(LLVMBuilderRef builder, LLVMValueRef val)
    LLVMValueRef l = LLVMBuildLoad(builder, bc, "");
    LLVMValueRef uscaled = LLVMBuildSIToFP(builder, l, LLVMFloatType(), "");
    return LLVMBuildFDiv(builder, uscaled,
-                        LLVMConstReal(builder, 32767.0f));
+                        LLVMConstReal(LLVMFloatType(), 32767.0f), "");
 }
 
 static INLINE LLVMValueRef
@@ -209,7 +146,7 @@ from_32_snorm(LLVMBuilderRef builder, LLVMValueRef val)
    LLVMValueRef uscaled = LLVMBuildSIToFP(builder, l, LLVMFloatType(), "");
 
    return LLVMBuildFDiv(builder, uscaled,
-                        LLVMConstReal(builder, 2147483647.0));
+                        LLVMConstReal(LLVMFloatType(), 2147483647.0), "");
 }
 
 static INLINE LLVMValueRef
@@ -221,23 +158,23 @@ from_32_fixed(LLVMBuilderRef builder, LLVMValueRef val)
    LLVMValueRef uscaled = LLVMBuildSIToFP(builder, l, LLVMFloatType(), "");
 
    return LLVMBuildFDiv(builder, uscaled,
-                        LLVMConstReal(builder, 65536.0));
+                        LLVMConstReal(LLVMFloatType(), 65536.0), "");
 }
 
-static INLINE LLVMValueRef
+static LLVMValueRef
 to_64_float(LLVMBuilderRef builder, LLVMValueRef fp)
 {
    LLVMValueRef l = LLVMBuildLoad(builder, fp, "");
    return LLVMBuildFPExt(builder, l, LLVMDoubleType(), "");
 }
 
-static INLINE LLVMValueRef
+static LLVMValueRef
 to_32_float(LLVMBuilderRef builder, LLVMValueRef fp)
 {
    return LLVMBuildLoad(builder, fp, "");
 }
 
-atic INLINE LLVMValueRef
+static INLINE LLVMValueRef
 to_8_uscaled(LLVMBuilderRef builder, LLVMValueRef fp)
 {
    LLVMValueRef l = LLVMBuildLoad(builder, fp, "");
@@ -285,7 +222,7 @@ 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.));
+                        LLVMConstReal(LLVMFloatType(), 255.), "");
 }
 
 static INLINE LLVMValueRef
@@ -294,7 +231,7 @@ 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.));
+                        LLVMConstReal(LLVMFloatType(), 65535.), "");
 }
 
 static INLINE LLVMValueRef
@@ -304,7 +241,7 @@ to_32_unorm(LLVMBuilderRef builder, LLVMValueRef fp)
    LLVMValueRef uscaled = LLVMBuildFPToUI(builder, l, LLVMIntType(32), "");
 
    return LLVMBuildFMul(builder, uscaled,
-                        LLVMConstReal(builder, 4294967295.));
+                        LLVMConstReal(LLVMFloatType(), 4294967295.), "");
 }
 
 static INLINE LLVMValueRef
@@ -312,8 +249,8 @@ 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));
+   return LLVMBuildFMul(builder, uscaled,
+                        LLVMConstReal(LLVMFloatType(), 127.0), "");
 }
 
 static INLINE LLVMValueRef
@@ -322,7 +259,7 @@ 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));
+                        LLVMConstReal(LLVMFloatType(), 32767.0f), "");
 }
 
 static INLINE LLVMValueRef
@@ -331,8 +268,8 @@ 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));
+   return LLVMBuildFMul(builder, uscaled,
+                        LLVMConstReal(LLVMFloatType(), 2147483647.0), "");
 }
 
 static INLINE LLVMValueRef
@@ -342,156 +279,176 @@ to_32_fixed(LLVMBuilderRef builder, LLVMValueRef fp)
    LLVMValueRef uscaled = LLVMBuildFPToSI(builder, l, LLVMIntType(32), "");
 
    return LLVMBuildFMul(builder, uscaled,
-                        LLVMConstReal(builder, 65536.0));
+                        LLVMConstReal(LLVMFloatType(), 65536.0), "");
+}
+
+typedef LLVMValueRef (*from_func)(LLVMBuilderRef, LLVMValueRef);
+typedef  LLVMValueRef (*to_func)(LLVMBuilderRef, LLVMValueRef);
+
+/* so that underneath can avoid function calls which are prohibited
+ * for static initialization we need this conversion */
+enum ll_type {
+   LL_Double,
+   LL_Float,
+   LL_Int32,
+   LL_Int16,
+   LL_Int8
+};
+
+static INLINE LLVMTypeRef
+ll_type_to_llvm(enum ll_type type)
+{
+   switch (type) {
+   case LL_Double:
+      return LLVMDoubleType();
+   case LL_Float:
+      return LLVMFloatType();
+   case LL_Int32:
+      return LLVMInt32Type();
+   case LL_Int16:
+      return LLVMIntType(16);
+   case LL_Int8:
+      return LLVMIntType(8);
+   }
+   return LLVMIntType(8);
+}
+
+static INLINE int
+ll_type_size(enum ll_type type)
+{
+   switch (type) {
+   case LL_Double:
+      return 8;
+   case LL_Float:
+      return 4;
+   case LL_Int32:
+      return 4;
+   case LL_Int16:
+      return 2;
+   case LL_Int8:
+      return 1;
+   }
+   return 1;
 }
 
+struct draw_llvm_translate {
+   int format;
+   from_func from;
+   to_func to;
+   enum ll_type type;
+   int num_components;
+} translates[] =
+{
+   {PIPE_FORMAT_R64_FLOAT,          from_64_float, to_64_float, LL_Double, 1},
+   {PIPE_FORMAT_R64G64_FLOAT,       from_64_float, to_64_float, LL_Double, 2},
+   {PIPE_FORMAT_R64G64B64_FLOAT,    from_64_float, to_64_float, LL_Double, 3},
+   {PIPE_FORMAT_R64G64B64A64_FLOAT, from_64_float, to_64_float, LL_Double, 4},
+   {PIPE_FORMAT_R32_FLOAT,          from_32_float, to_32_float, LL_Float, 1},
+   {PIPE_FORMAT_R32G32_FLOAT,       from_32_float, to_32_float, LL_Float, 2},
+   {PIPE_FORMAT_R32G32B32_FLOAT,    from_32_float, to_32_float, LL_Float, 3},
+   {PIPE_FORMAT_R32G32B32A32_FLOAT, from_32_float, to_32_float, LL_Float, 4},
+
+   {PIPE_FORMAT_R32_UNORM,          from_32_unorm, to_32_unorm, LL_Int32, 1},
+   {PIPE_FORMAT_R32G32_UNORM,       from_32_unorm, to_32_unorm, LL_Int32, 2},
+   {PIPE_FORMAT_R32G32B32_UNORM,    from_32_unorm, to_32_unorm, LL_Int32, 3},
+   {PIPE_FORMAT_R32G32B32A32_UNORM, from_32_unorm, to_32_unorm, LL_Int32, 4},
+
+   {PIPE_FORMAT_R32_USCALED,          from_32_uscaled, to_32_uscaled, LL_Int32, 1},
+   {PIPE_FORMAT_R32G32_USCALED,       from_32_uscaled, to_32_uscaled, LL_Int32, 2},
+   {PIPE_FORMAT_R32G32B32_USCALED,    from_32_uscaled, to_32_uscaled, LL_Int32, 3},
+   {PIPE_FORMAT_R32G32B32A32_USCALED, from_32_uscaled, to_32_uscaled, LL_Int32, 4},
+
+   {PIPE_FORMAT_R32_SNORM,          from_32_snorm, to_32_snorm, LL_Int32, 1},
+   {PIPE_FORMAT_R32G32_SNORM,       from_32_snorm, to_32_snorm, LL_Int32, 2},
+   {PIPE_FORMAT_R32G32B32_SNORM,    from_32_snorm, to_32_snorm, LL_Int32, 3},
+   {PIPE_FORMAT_R32G32B32A32_SNORM, from_32_snorm, to_32_snorm, LL_Int32, 4},
+
+   {PIPE_FORMAT_R32_SSCALED,          from_32_sscaled, to_32_sscaled, LL_Int32, 1},
+   {PIPE_FORMAT_R32G32_SSCALED,       from_32_sscaled, to_32_sscaled, LL_Int32, 2},
+   {PIPE_FORMAT_R32G32B32_SSCALED,    from_32_sscaled, to_32_sscaled, LL_Int32, 3},
+   {PIPE_FORMAT_R32G32B32A32_SSCALED, from_32_sscaled, to_32_sscaled, LL_Int32, 4},
+
+   {PIPE_FORMAT_R16_UNORM,          from_16_unorm, to_16_unorm, LL_Int16, 1},
+   {PIPE_FORMAT_R16G16_UNORM,       from_16_unorm, to_16_unorm, LL_Int16, 2},
+   {PIPE_FORMAT_R16G16B16_UNORM,    from_16_unorm, to_16_unorm, LL_Int16, 3},
+   {PIPE_FORMAT_R16G16B16A16_UNORM, from_16_unorm, to_16_unorm, LL_Int16, 4},
+
+   {PIPE_FORMAT_R16_USCALED,          from_16_uscaled, to_16_uscaled, LL_Int16, 1},
+   {PIPE_FORMAT_R16G16_USCALED,       from_16_uscaled, to_16_uscaled, LL_Int16, 2},
+   {PIPE_FORMAT_R16G16B16_USCALED,    from_16_uscaled, to_16_uscaled, LL_Int16, 3},
+   {PIPE_FORMAT_R16G16B16A16_USCALED, from_16_uscaled, to_16_uscaled, LL_Int16, 4},
+
+   {PIPE_FORMAT_R16_SNORM,          from_16_snorm, to_16_snorm, LL_Int16, 1},
+   {PIPE_FORMAT_R16G16_SNORM,       from_16_snorm, to_16_snorm, LL_Int16, 2},
+   {PIPE_FORMAT_R16G16B16_SNORM,    from_16_snorm, to_16_snorm, LL_Int16, 3},
+   {PIPE_FORMAT_R16G16B16A16_SNORM, from_16_snorm, to_16_snorm, LL_Int16, 4},
+
+   {PIPE_FORMAT_R16_SSCALED,          from_16_sscaled, to_16_sscaled, LL_Int16, 1},
+   {PIPE_FORMAT_R16G16_SSCALED,       from_16_sscaled, to_16_sscaled, LL_Int16, 2},
+   {PIPE_FORMAT_R16G16B16_SSCALED,    from_16_sscaled, to_16_sscaled, LL_Int16, 3},
+   {PIPE_FORMAT_R16G16B16A16_SSCALED, from_16_sscaled, to_16_sscaled, LL_Int16, 4},
+
+   {PIPE_FORMAT_R8_UNORM,       from_8_unorm, to_8_unorm, LL_Int8, 1},
+   {PIPE_FORMAT_R8G8_UNORM,     from_8_unorm, to_8_unorm, LL_Int8, 2},
+   {PIPE_FORMAT_R8G8B8_UNORM,   from_8_unorm, to_8_unorm, LL_Int8, 3},
+   {PIPE_FORMAT_R8G8B8A8_UNORM, from_8_unorm, to_8_unorm, LL_Int8, 4},
+
+   {PIPE_FORMAT_R8_USCALED,       from_8_uscaled, to_8_uscaled, LL_Int8, 1},
+   {PIPE_FORMAT_R8G8_USCALED,     from_8_uscaled, to_8_uscaled, LL_Int8, 2},
+   {PIPE_FORMAT_R8G8B8_USCALED,   from_8_uscaled, to_8_uscaled, LL_Int8, 3},
+   {PIPE_FORMAT_R8G8B8A8_USCALED, from_8_uscaled, to_8_uscaled, LL_Int8, 4},
+
+   {PIPE_FORMAT_R8_SNORM,       from_8_snorm, to_8_snorm, LL_Int8, 1},
+   {PIPE_FORMAT_R8G8_SNORM,     from_8_snorm, to_8_snorm, LL_Int8, 2},
+   {PIPE_FORMAT_R8G8B8_SNORM,   from_8_snorm, to_8_snorm, LL_Int8, 3},
+   {PIPE_FORMAT_R8G8B8A8_SNORM, from_8_snorm, to_8_snorm, LL_Int8, 4},
+
+   {PIPE_FORMAT_R8_SSCALED,       from_8_sscaled, to_8_sscaled, LL_Int8, 1},
+   {PIPE_FORMAT_R8G8_SSCALED,     from_8_sscaled, to_8_sscaled, LL_Int8, 2},
+   {PIPE_FORMAT_R8G8B8_SSCALED,   from_8_sscaled, to_8_sscaled, LL_Int8, 3},
+   {PIPE_FORMAT_R8G8B8A8_SSCALED, from_8_sscaled, to_8_sscaled, LL_Int8, 4},
+
+   {PIPE_FORMAT_R32_FIXED,          from_32_fixed, to_32_fixed, LL_Int32, 1},
+   {PIPE_FORMAT_R32G32_FIXED,       from_32_fixed, to_32_fixed, LL_Int32, 2},
+   {PIPE_FORMAT_R32G32B32_FIXED,    from_32_fixed, to_32_fixed, LL_Int32, 3},
+   {PIPE_FORMAT_R32G32B32A32_FIXED, from_32_fixed, to_32_fixed, LL_Int32, 4},
+
+   {PIPE_FORMAT_A8R8G8B8_UNORM, from_8_unorm, to_8_unorm, LL_Int8, 4},
+   {PIPE_FORMAT_B8G8R8A8_UNORM, from_8_unorm, to_8_unorm, LL_Int8, 4},
+};
+
+
 static LLVMValueRef
-fetch(LLVMValueRef ptr, int val_size, int nr_components,
-     LLVMValueRef res)
+fetch(LLVMBuilderRef builder,
+      LLVMValueRef ptr, int val_size, int nr_components,
+      from_func func)
 {
    int i;
    int offset = 0;
+   LLVMValueRef res = LLVMConstNull(
+      LLVMVectorType(LLVMFloatType(), 4));
 
    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);
-}
+      LLVMValueRef component;
 
-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]);
-}
+      src_tmp = LLVMBuildLoad(builder, src_tmp, "");
 
-static void
-fetch_NULL( const void *ptr, float *attrib )
-{
-   attrib[0] = 0;
-   attrib[1] = 0;
-   attrib[2] = 0;
-   attrib[3] = 1;
-}
+      /* convert src_tmp to float */
+      component = func(builder, src_tmp);
 
-static void
-emit_NULL( const float *attrib, void *ptr )
-{
-   /* do nothing is the only sensible option */
+      /* vec.comp = component */
+      res = LLVMBuildInsertElement(builder,
+                                   res,
+                                   component,
+                                   dst_index, "");
+      offset += val_size;
+   }
+   return res;
 }
 
-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},
-};
-
 
 LLVMValueRef
 draw_llvm_translate_from(LLVMBuilderRef builder,
@@ -501,8 +458,13 @@ draw_llvm_translate_from(LLVMBuilderRef builder,
    int i;
    for (i = 0; i < Elements(translates); ++i) {
       if (translates[i].format == from_format) {
-         return translates.from_func(builder, vbuffer, from_format);
+         /*LLVMTypeRef type = ll_type_to_llvm(translates[i].type);*/
+         return fetch(builder,
+                      vbuffer,
+                      ll_type_size(translates[i].type),
+                      translates[i].num_components,
+                      translates[i].from);
       }
    }
-   return LLVMGetUndef(LLVMTypeOf(vbuffer));
+   return LLVMGetUndef(LLVMVectorType(LLVMFloatType(), 4));
 }