summaryrefslogtreecommitdiff
path: root/src/gallium/drivers/llvmpipe
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/drivers/llvmpipe')
-rw-r--r--src/gallium/drivers/llvmpipe/SConscript8
-rw-r--r--src/gallium/drivers/llvmpipe/lp_bld_arit.c15
-rw-r--r--src/gallium/drivers/llvmpipe/lp_bld_logic.c48
-rw-r--r--src/gallium/drivers/llvmpipe/lp_bld_logic.h2
-rw-r--r--src/gallium/drivers/llvmpipe/lp_bld_tgsi_soa.c4
-rw-r--r--src/gallium/drivers/llvmpipe/lp_buffer.c150
-rw-r--r--src/gallium/drivers/llvmpipe/lp_buffer.h55
7 files changed, 262 insertions, 20 deletions
diff --git a/src/gallium/drivers/llvmpipe/SConscript b/src/gallium/drivers/llvmpipe/SConscript
index 6bceb84da4..5c29bdac56 100644
--- a/src/gallium/drivers/llvmpipe/SConscript
+++ b/src/gallium/drivers/llvmpipe/SConscript
@@ -2,8 +2,12 @@ Import('*')
env = env.Clone()
+env.Tool('llvm')
+if 'LLVM_VERSION' not in env:
+ print 'warning: LLVM not found: not building llvmpipe'
+ Return()
+
env.Tool('udis86')
-env.ParseConfig('llvm-config --cppflags')
llvmpipe = env.ConvenienceLibrary(
target = 'llvmpipe',
@@ -57,8 +61,6 @@ llvmpipe = env.ConvenienceLibrary(
env = env.Clone()
-env['LINK'] = env['CXX']
-env.ParseConfig('llvm-config --libs jit interpreter nativecodegen bitwriter')
env.Prepend(LIBS = [llvmpipe] + auxiliaries)
env.Program(
diff --git a/src/gallium/drivers/llvmpipe/lp_bld_arit.c b/src/gallium/drivers/llvmpipe/lp_bld_arit.c
index 710e6246d7..09a57ff33d 100644
--- a/src/gallium/drivers/llvmpipe/lp_bld_arit.c
+++ b/src/gallium/drivers/llvmpipe/lp_bld_arit.c
@@ -52,6 +52,7 @@
#include "lp_bld_type.h"
#include "lp_bld_const.h"
#include "lp_bld_intr.h"
+#include "lp_bld_logic.h"
#include "lp_bld_arit.h"
@@ -98,11 +99,8 @@ lp_build_min_simple(struct lp_build_context *bld,
if(intrinsic)
return lp_build_intrinsic_binary(bld->builder, intrinsic, lp_build_vec_type(bld->type), a, b);
- if(type.floating)
- cond = LLVMBuildFCmp(bld->builder, LLVMRealULT, a, b, "");
- else
- cond = LLVMBuildICmp(bld->builder, type.sign ? LLVMIntSLT : LLVMIntULT, a, b, "");
- return LLVMBuildSelect(bld->builder, cond, a, b, "");
+ cond = lp_build_cmp(bld, PIPE_FUNC_LESS, a, b);
+ return lp_build_select(bld, cond, a, b);
}
@@ -149,11 +147,8 @@ lp_build_max_simple(struct lp_build_context *bld,
if(intrinsic)
return lp_build_intrinsic_binary(bld->builder, intrinsic, lp_build_vec_type(bld->type), a, b);
- if(type.floating)
- cond = LLVMBuildFCmp(bld->builder, LLVMRealULT, a, b, "");
- else
- cond = LLVMBuildICmp(bld->builder, type.sign ? LLVMIntSLT : LLVMIntULT, a, b, "");
- return LLVMBuildSelect(bld->builder, cond, b, a, "");
+ cond = lp_build_cmp(bld, PIPE_FUNC_GREATER, a, b);
+ return lp_build_select(bld, cond, a, b);
}
diff --git a/src/gallium/drivers/llvmpipe/lp_bld_logic.c b/src/gallium/drivers/llvmpipe/lp_bld_logic.c
index 1e1ecf805b..8631efd6c3 100644
--- a/src/gallium/drivers/llvmpipe/lp_bld_logic.c
+++ b/src/gallium/drivers/llvmpipe/lp_bld_logic.c
@@ -33,7 +33,6 @@
*/
-#include "pipe/p_defines.h"
#include "lp_bld_type.h"
#include "lp_bld_const.h"
#include "lp_bld_intr.h"
@@ -52,6 +51,8 @@ lp_build_cmp(struct lp_build_context *bld,
LLVMValueRef zeros = LLVMConstNull(int_vec_type);
LLVMValueRef ones = LLVMConstAllOnes(int_vec_type);
LLVMValueRef cond;
+ LLVMValueRef res;
+ unsigned i;
if(func == PIPE_FUNC_NEVER)
return zeros;
@@ -68,7 +69,6 @@ lp_build_cmp(struct lp_build_context *bld,
LLVMValueRef args[3];
unsigned cc;
boolean swap;
- LLVMValueRef res;
swap = FALSE;
switch(func) {
@@ -219,7 +219,28 @@ lp_build_cmp(struct lp_build_context *bld,
assert(0);
return bld->undef;
}
+
+#if 0
+ /* XXX: Although valid IR, no LLVM target currently support this */
cond = LLVMBuildFCmp(bld->builder, op, a, b, "");
+ res = LLVMBuildSelect(bld->builder, cond, ones, zeros, "");
+#else
+ debug_printf("%s: warning: using slow element-wise vector comparison\n",
+ __FUNCTION__);
+ res = LLVMGetUndef(int_vec_type);
+ for(i = 0; i < type.length; ++i) {
+ LLVMValueRef index = LLVMConstInt(LLVMInt32Type(), i, 0);
+ cond = LLVMBuildFCmp(bld->builder, op,
+ LLVMBuildExtractElement(bld->builder, a, index, ""),
+ LLVMBuildExtractElement(bld->builder, b, index, ""),
+ "");
+ cond = LLVMBuildSelect(bld->builder, cond,
+ LLVMConstExtractElement(ones, index),
+ LLVMConstExtractElement(zeros, index),
+ "");
+ res = LLVMBuildInsertElement(bld->builder, res, cond, index, "");
+ }
+#endif
}
else {
LLVMIntPredicate op;
@@ -246,10 +267,31 @@ lp_build_cmp(struct lp_build_context *bld,
assert(0);
return bld->undef;
}
+
+#if 0
+ /* XXX: Although valid IR, no LLVM target currently support this */
cond = LLVMBuildICmp(bld->builder, op, a, b, "");
+ res = LLVMBuildSelect(bld->builder, cond, ones, zeros, "");
+#else
+ debug_printf("%s: warning: using slow element-wise vector comparison\n",
+ __FUNCTION__);
+ res = LLVMGetUndef(int_vec_type);
+ for(i = 0; i < type.length; ++i) {
+ LLVMValueRef index = LLVMConstInt(LLVMInt32Type(), i, 0);
+ cond = LLVMBuildICmp(bld->builder, op,
+ LLVMBuildExtractElement(bld->builder, a, index, ""),
+ LLVMBuildExtractElement(bld->builder, b, index, ""),
+ "");
+ cond = LLVMBuildSelect(bld->builder, cond,
+ LLVMConstExtractElement(ones, index),
+ LLVMConstExtractElement(zeros, index),
+ "");
+ res = LLVMBuildInsertElement(bld->builder, res, cond, index, "");
+ }
+#endif
}
- return LLVMBuildSelect(bld->builder, cond, ones, zeros, "");
+ return res;
}
diff --git a/src/gallium/drivers/llvmpipe/lp_bld_logic.h b/src/gallium/drivers/llvmpipe/lp_bld_logic.h
index 0989f9f207..29b9e1c45b 100644
--- a/src/gallium/drivers/llvmpipe/lp_bld_logic.h
+++ b/src/gallium/drivers/llvmpipe/lp_bld_logic.h
@@ -39,6 +39,8 @@
#include <llvm-c/Core.h>
+#include "pipe/p_defines.h" /* For PIPE_FUNC_xxx */
+
union lp_type type;
struct lp_build_context;
diff --git a/src/gallium/drivers/llvmpipe/lp_bld_tgsi_soa.c b/src/gallium/drivers/llvmpipe/lp_bld_tgsi_soa.c
index bce26607f9..d4d18febec 100644
--- a/src/gallium/drivers/llvmpipe/lp_bld_tgsi_soa.c
+++ b/src/gallium/drivers/llvmpipe/lp_bld_tgsi_soa.c
@@ -687,10 +687,6 @@ emit_instruction(
return 0;
break;
- case TGSI_OPCODE_CND0:
- return 0;
- break;
-
case TGSI_OPCODE_DP2A:
tmp0 = emit_fetch( bld, inst, 0, CHAN_X ); /* xmm0 = src[0].x */
tmp1 = emit_fetch( bld, inst, 1, CHAN_X ); /* xmm1 = src[1].x */
diff --git a/src/gallium/drivers/llvmpipe/lp_buffer.c b/src/gallium/drivers/llvmpipe/lp_buffer.c
new file mode 100644
index 0000000000..66f1f8e138
--- /dev/null
+++ b/src/gallium/drivers/llvmpipe/lp_buffer.c
@@ -0,0 +1,150 @@
+/**************************************************************************
+ *
+ * Copyright 2009 VMware, Inc.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+
+#include "util/u_memory.h"
+#include "util/u_math.h"
+
+#include "lp_winsys.h"
+#include "lp_screen.h"
+#include "lp_texture.h"
+#include "lp_buffer.h"
+
+
+static void *
+llvmpipe_buffer_map(struct pipe_screen *screen,
+ struct pipe_buffer *buf,
+ unsigned flags)
+{
+ struct llvmpipe_buffer *llvmpipe_buf = llvmpipe_buffer(buf);
+ return llvmpipe_buf->data;
+}
+
+
+static void
+llvmpipe_buffer_unmap(struct pipe_screen *screen,
+ struct pipe_buffer *buf)
+{
+}
+
+
+static void
+llvmpipe_buffer_destroy(struct pipe_buffer *buf)
+{
+ struct llvmpipe_buffer *sbuf = llvmpipe_buffer(buf);
+
+ if (!sbuf->userBuffer)
+ align_free(sbuf->data);
+
+ FREE(sbuf);
+}
+
+
+static struct pipe_buffer *
+llvmpipe_buffer_create(struct pipe_screen *screen,
+ unsigned alignment,
+ unsigned usage,
+ unsigned size)
+{
+ struct llvmpipe_buffer *buffer = CALLOC_STRUCT(llvmpipe_buffer);
+
+ pipe_reference_init(&buffer->base.reference, 1);
+ buffer->base.screen = screen;
+ buffer->base.alignment = MAX2(alignment, 16);
+ buffer->base.usage = usage;
+ buffer->base.size = size;
+
+ buffer->data = align_malloc(size, alignment);
+
+ return &buffer->base;
+}
+
+
+/**
+ * Create buffer which wraps user-space data.
+ */
+static struct pipe_buffer *
+llvmpipe_user_buffer_create(struct pipe_screen *screen,
+ void *ptr,
+ unsigned bytes)
+{
+ struct llvmpipe_buffer *buffer;
+
+ buffer = CALLOC_STRUCT(llvmpipe_buffer);
+ if(!buffer)
+ return NULL;
+
+ pipe_reference_init(&buffer->base.reference, 1);
+ buffer->base.screen = screen;
+ buffer->base.size = bytes;
+ buffer->userBuffer = TRUE;
+ buffer->data = ptr;
+
+ return &buffer->base;
+}
+
+
+static void
+llvmpipe_fence_reference(struct pipe_screen *screen,
+ struct pipe_fence_handle **ptr,
+ struct pipe_fence_handle *fence)
+{
+}
+
+
+static int
+llvmpipe_fence_signalled(struct pipe_screen *screen,
+ struct pipe_fence_handle *fence,
+ unsigned flag)
+{
+ return 0;
+}
+
+
+static int
+llvmpipe_fence_finish(struct pipe_screen *screen,
+ struct pipe_fence_handle *fence,
+ unsigned flag)
+{
+ return 0;
+}
+
+
+void
+llvmpipe_init_screen_buffer_funcs(struct pipe_screen *screen)
+{
+ screen->buffer_create = llvmpipe_buffer_create;
+ screen->user_buffer_create = llvmpipe_user_buffer_create;
+ screen->buffer_map = llvmpipe_buffer_map;
+ screen->buffer_unmap = llvmpipe_buffer_unmap;
+ screen->buffer_destroy = llvmpipe_buffer_destroy;
+
+ screen->fence_reference = llvmpipe_fence_reference;
+ screen->fence_signalled = llvmpipe_fence_signalled;
+ screen->fence_finish = llvmpipe_fence_finish;
+
+}
diff --git a/src/gallium/drivers/llvmpipe/lp_buffer.h b/src/gallium/drivers/llvmpipe/lp_buffer.h
new file mode 100644
index 0000000000..d6b8184a0b
--- /dev/null
+++ b/src/gallium/drivers/llvmpipe/lp_buffer.h
@@ -0,0 +1,55 @@
+/**************************************************************************
+ *
+ * Copyright 2009 VMware, Inc.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+#ifndef LP_BUFFER_H
+#define LP_BUFFER_H
+
+#include "pipe/p_compiler.h"
+#include "pipe/p_state.h"
+
+
+struct llvmpipe_buffer
+{
+ struct pipe_buffer base;
+ boolean userBuffer; /** Is this a user-space buffer? */
+ void *data;
+};
+
+
+/** Cast wrapper */
+static INLINE struct llvmpipe_buffer *
+llvmpipe_buffer( struct pipe_buffer *buf )
+{
+ return (struct llvmpipe_buffer *)buf;
+}
+
+
+void
+llvmpipe_init_screen_buffer_funcs(struct pipe_screen *screen);
+
+
+#endif /* LP_BUFFER_H */