summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZack Rusin <zack@tungstengraphics.com>2007-10-16 13:23:43 -0400
committerZack Rusin <zack@tungstengraphics.com>2007-10-24 11:21:03 -0400
commitfa2962d14833480e154e8478e57758f18cc1442e (patch)
tree5557a56853530a428ea98de81db008af51abd8f0
parent5e0205023e8e6a08b0eb61286e15eb095f32ab3d (diff)
Draw first triangle. Start on the llvm builder.
-rw-r--r--src/mesa/pipe/draw/draw_vertex_shader_llvm.c74
-rw-r--r--src/mesa/pipe/llvm/llvmtgsi.cpp53
-rw-r--r--src/mesa/pipe/llvm/tgsillvmbuilder.cpp134
3 files changed, 237 insertions, 24 deletions
diff --git a/src/mesa/pipe/draw/draw_vertex_shader_llvm.c b/src/mesa/pipe/draw/draw_vertex_shader_llvm.c
index 97a0480b5c..2ff35ace24 100644
--- a/src/mesa/pipe/draw/draw_vertex_shader_llvm.c
+++ b/src/mesa/pipe/draw/draw_vertex_shader_llvm.c
@@ -98,6 +98,21 @@ void vertex_fetch(struct draw_context *draw,
}
}
+static INLINE unsigned
+compute_clipmask(const float *clip, const float (*plane)[4], unsigned nr)
+{
+ unsigned mask = 0;
+ unsigned i;
+
+ for (i = 0; i < nr; i++) {
+ if (dot4(clip, plane[i]) < 0)
+ mask |= (1<<i);
+ }
+
+ return mask;
+}
+
+
/**
* Called by the draw module when the vertx cache needs to be flushed.
* This involves running the vertex shader.
@@ -109,8 +124,10 @@ void draw_vertex_shader_queue_flush_llvm(struct draw_context *draw)
struct vertex_header *dests[VS_QUEUE_LENGTH];
float inputs[VS_QUEUE_LENGTH][PIPE_MAX_SHADER_INPUTS][4];
float outputs[VS_QUEUE_LENGTH][PIPE_MAX_SHADER_INPUTS][4];
- float (*consts)[4] = (float (*)[4]) draw->mapped_constants;
- struct ga_llvm_prog *prog = draw->vertex_shader->state->llvm_prog;
+ float (*consts)[4] = (float (*)[4]) draw->mapped_constants;
+ struct ga_llvm_prog *prog = (struct ga_llvm_prog *)draw->vertex_shader->state->llvm_prog;
+ const float *scale = draw->viewport.scale;
+ const float *trans = draw->viewport.translate;
fprintf(stderr, "--- XX q(%d) \n", draw->vs.queue_nr);
@@ -129,5 +146,58 @@ void draw_vertex_shader_queue_flush_llvm(struct draw_context *draw)
/* FIXME: finish conversion */
/* dests = outputs */
+ /* store machine results */
+ for (int i = 0; i < draw->vs.queue_nr; ++i) {
+ unsigned slot;
+ float x, y, z, w;
+ struct vertex_header *vOut = draw->vs.queue[i].dest;
+ float (*dests)[4] = outputs[i];
+
+ /* Handle attr[0] (position) specially:
+ *
+ * XXX: Computing the clipmask should be done in the vertex
+ * program as a set of DP4 instructions appended to the
+ * user-provided code.
+ */
+ x = vOut->clip[0] = dests[0][0];
+ y = vOut->clip[1] = dests[0][1];
+ z = vOut->clip[2] = dests[0][2];
+ w = vOut->clip[3] = dests[0][3];
+ printf("output %d: %f %f %f %f\n", 0, x, y, z, w);
+
+ vOut->clipmask = compute_clipmask(vOut->clip, draw->plane, draw->nr_planes);
+ vOut->edgeflag = 1;
+
+ /* divide by w */
+ w = 1.0f / w;
+ x *= w;
+ y *= w;
+ z *= w;
+
+ /* Viewport mapping */
+ vOut->data[0][0] = x * scale[0] + trans[0];
+ vOut->data[0][1] = y * scale[1] + trans[1];
+ vOut->data[0][2] = z * scale[2] + trans[2];
+ vOut->data[0][3] = w;
+
+ /* Remaining attributes are packed into sequential post-transform
+ * vertex attrib slots.
+ * Skip 0 since we just did it above.
+ * Subtract two because of the VERTEX_HEADER, CLIP_POS attribs.
+ */
+ for (slot = 1; slot < draw->vertex_info.num_attribs - 2; slot++) {
+ vOut->data[slot][0] = dests[slot][0];
+ vOut->data[slot][1] = dests[slot][1];
+ vOut->data[slot][2] = dests[slot][2];
+ vOut->data[slot][3] = dests[slot][3];
+
+ printf("output %d: %f %f %f %f\n", slot,
+ vOut->data[slot][0],
+ vOut->data[slot][1],
+ vOut->data[slot][2],
+ vOut->data[slot][3]);
+ }
+ } /* loop over vertices */
+
draw->vs.queue_nr = 0;
}
diff --git a/src/mesa/pipe/llvm/llvmtgsi.cpp b/src/mesa/pipe/llvm/llvmtgsi.cpp
index 4ff6281c74..375e61c0db 100644
--- a/src/mesa/pipe/llvm/llvmtgsi.cpp
+++ b/src/mesa/pipe/llvm/llvmtgsi.cpp
@@ -32,6 +32,7 @@
using namespace llvm;
#include "llvm_base_shader.cpp"
+#include "tgsillvmbuilder.cpp"
static inline void addPass(PassManager &PM, Pass *P) {
@@ -116,6 +117,7 @@ translate_immediate(llvm::Module *module,
static void
translate_instruction(llvm::Module *module,
+ VertexShaderBuilder *builder,
struct tgsi_full_instruction *inst,
struct tgsi_full_instruction *fi)
{
@@ -135,6 +137,7 @@ translate_instruction(llvm::Module *module,
case TGSI_OPCODE_LOG:
break;
case TGSI_OPCODE_MUL:
+
break;
case TGSI_OPCODE_ADD:
break;
@@ -435,6 +438,7 @@ tgsi_to_llvm(const struct tgsi_token *tokens)
tgsi_parse_init(&parse, tokens);
+ Function* func_printf = mod->getFunction("printf");
//parse.FullHeader.Processor.Processor
//parse.FullVersion.Version.MajorVersion
@@ -446,7 +450,7 @@ tgsi_to_llvm(const struct tgsi_token *tokens)
fi = tgsi_default_full_instruction();
fd = tgsi_default_full_declaration();
-
+ VertexShaderBuilder builder(label_entry, ptr_IN, ptr_CONST);
while(!tgsi_parse_end_of_tokens(&parse)) {
tgsi_parse_token(&parse);
@@ -465,7 +469,7 @@ tgsi_to_llvm(const struct tgsi_token *tokens)
break;
case TGSI_TOKEN_TYPE_INSTRUCTION:
- translate_instruction(mod,
+ translate_instruction(mod, &builder,
&parse.FullToken.FullInstruction,
&fi);
break;
@@ -475,29 +479,26 @@ tgsi_to_llvm(const struct tgsi_token *tokens)
}
}
-
- Function* func_printf = mod->getFunction("printf");
-#if 1
-
+#if 0
// Type Definitions
ArrayType* ArrayTy_0 = ArrayType::get(IntegerType::get(8), 19);
-
+
PointerType* PointerTy_1 = PointerType::get(ArrayTy_0);
-
+
VectorType* VectorTy_4 = VectorType::get(Type::FloatTy, 4);
-
+
PointerType* PointerTy_3 = PointerType::get(VectorTy_4);
-
-
+
+
VectorType* VectorTy_5 = VectorType::get(IntegerType::get(32), 4);
-
-
+
+
PointerType* PointerTy_8 = PointerType::get(IntegerType::get(8));
-
-
+
+
// Global Variable Declarations
-
+
GlobalVariable* gvar_array__str = new GlobalVariable(
/*Type=*/ArrayTy_0,
/*isConstant=*/true,
@@ -505,7 +506,7 @@ tgsi_to_llvm(const struct tgsi_token *tokens)
/*Initializer=*/0, // has initializer, specified below
/*Name=*/".str",
mod);
-
+
GlobalVariable* gvar_array__str1 = new GlobalVariable(
/*Type=*/ArrayTy_0,
/*isConstant=*/true,
@@ -513,7 +514,7 @@ tgsi_to_llvm(const struct tgsi_token *tokens)
/*Initializer=*/0, // has initializer, specified below
/*Name=*/".str1",
mod);
-
+
GlobalVariable* gvar_array__str2 = new GlobalVariable(
/*Type=*/ArrayTy_0,
/*isConstant=*/true,
@@ -521,7 +522,7 @@ tgsi_to_llvm(const struct tgsi_token *tokens)
/*Initializer=*/0, // has initializer, specified below
/*Name=*/".str2",
mod);
-
+
// Constant Definitions
Constant* const_array_9 = ConstantArray::get("const %f %f %f %f\x0A", true);
Constant* const_array_10 = ConstantArray::get("resul %f %f %f %f\x0A", true);
@@ -563,14 +564,14 @@ tgsi_to_llvm(const struct tgsi_token *tokens)
const_ptr_24_indices.push_back(const_int32_21);
const_ptr_24_indices.push_back(const_int32_21);
Constant* const_ptr_24 = ConstantExpr::getGetElementPtr(gvar_array__str2, &const_ptr_24_indices[0], const_ptr_24_indices.size() );
-
+
// Global Variable Definitions
gvar_array__str->setInitializer(const_array_9);
gvar_array__str1->setInitializer(const_array_10);
gvar_array__str2->setInitializer(const_array_11);
-
+
// Function Definitions
-
+
// Function: execute_shader (func_execute_shader)
{
// Block entry (label_entry)
@@ -725,5 +726,13 @@ int ga_llvm_prog_exec(struct ga_llvm_prog *prog,
runner(inputs, dests, consts, count, num_attribs);
std::cout << "---- END LLVM Execution "<<std::endl;
+
+ for (int i = 0; i < count; ++i) {
+ for (int j = 0; j < num_attribs; ++j) {
+ printf("OUT(%d, %d) [%f, %f, %f, %f]\n", i, j,
+ dests[i][j][0], dests[i][j][1],
+ dests[i][j][2], dests[i][j][3]);
+ }
+ }
return 0;
}
diff --git a/src/mesa/pipe/llvm/tgsillvmbuilder.cpp b/src/mesa/pipe/llvm/tgsillvmbuilder.cpp
new file mode 100644
index 0000000000..4088da11f8
--- /dev/null
+++ b/src/mesa/pipe/llvm/tgsillvmbuilder.cpp
@@ -0,0 +1,134 @@
+
+#include <map>
+
+class VertexShaderBuilder
+{
+ typedef std::map<int, llvm::LoadInst*> LoadMap;
+public:
+ VertexShaderBuilder(llvm::BasicBlock *block, llvm::Value *in, llvm::Value *consts);
+
+ llvm::ConstantInt *constantInt(int);
+ llvm::Constant *shuffleMask(int vec);
+ llvm::Value *inputElement(int idx);
+ llvm::Value *constElement(int idx);
+
+ llvm::Value *shuffleVector(llvm::Value *vec, int shuffle);
+
+
+private:
+ llvm::BasicBlock *m_block;
+ llvm::Value *m_IN;
+ llvm::Value *m_CONST;
+
+ std::map<int, llvm::ConstantInt*> m_constInts;
+ std::map<int, llvm::Constant*> m_intVecs;
+ LoadMap m_inputs;
+ LoadMap m_consts;
+
+ VectorType *m_floatVecType;
+ VectorType *m_intVecType;
+
+ Value *m_undefFloatVec;
+ Value *m_undefIntVec;
+
+ int m_shuffleId;
+};
+
+VertexShaderBuilder::VertexShaderBuilder(llvm::BasicBlock *block, llvm::Value *in, llvm::Value *consts)
+ : m_block(block), m_IN(in), m_CONST(consts)
+{
+ m_floatVecType = VectorType::get(Type::FloatTy, 4);
+ m_intVecType = VectorType::get(IntegerType::get(32), 4);
+
+ m_undefFloatVec = UndefValue::get(m_floatVecType);
+ m_undefIntVec = UndefValue::get(m_intVecType);
+
+ m_shuffleId = 0;
+}
+
+//can only build vectors with all members in the [0, 9] range
+llvm::Constant *VertexShaderBuilder::shuffleMask(int vec)
+{
+ if (m_intVecs.find(vec) != m_intVecs.end()) {
+ return m_intVecs[vec];
+ }
+ int origVec = vec;
+ Constant* const_vec = 0;
+ if (origVec == 0) {
+ const_vec = Constant::getNullValue(m_intVecType);
+ } else {
+ int x = vec / 1000; vec -= x * 1000;
+ int y = vec / 100; vec -= y * 100;
+ int z = vec / 10; vec -= z * 10;
+ int w = vec;
+ std::vector<Constant*> elems;
+ elems.push_back(constantInt(x));
+ elems.push_back(constantInt(y));
+ elems.push_back(constantInt(z));
+ elems.push_back(constantInt(w));
+ const_vec = ConstantVector::get(m_intVecType, elems);
+ }
+
+ m_intVecs[origVec] = const_vec;
+ return const_vec;
+}
+
+llvm::ConstantInt *VertexShaderBuilder::constantInt(int idx)
+{
+ if (m_constInts.find(idx) != m_constInts.end()) {
+ return m_constInts[idx];
+ }
+ ConstantInt *const_int = ConstantInt::get(APInt(32, idx));
+ m_constInts[idx] = const_int;
+ return const_int;
+}
+
+llvm::Value *VertexShaderBuilder::inputElement(int idx)
+{
+ if (m_inputs.find(idx) != m_inputs.end()) {
+ return m_inputs[idx];
+ }
+ char ptrName[13];
+ char name[9];
+ snprintf(ptrName, 13, "input_ptr%d", idx);
+ snprintf(name, 9, "input%d", idx);
+ GetElementPtrInst *getElem = new GetElementPtrInst(m_IN,
+ constantInt(idx),
+ ptrName,
+ m_block);
+ LoadInst *load = new LoadInst(getElem, name,
+ false, m_block);
+ m_inputs[idx] = load;
+ return load;
+}
+
+llvm::Value *VertexShaderBuilder::constElement(int idx)
+{
+ if (m_consts.find(idx) != m_consts.end()) {
+ return m_consts[idx];
+ }
+ char ptrName[13];
+ char name[9];
+ snprintf(ptrName, 13, "const_ptr%d", idx);
+ snprintf(name, 9, "const%d", idx);
+ GetElementPtrInst *getElem = new GetElementPtrInst(m_CONST,
+ constantInt(idx),
+ ptrName,
+ m_block);
+ LoadInst *load = new LoadInst(getElem, name,
+ false, m_block);
+ m_consts[idx] = load;
+ return load;
+}
+
+llvm::Value *VertexShaderBuilder::shuffleVector(llvm::Value *vec, int shuffle)
+{
+ Constant *mask = shuffleMask(shuffle);
+ ++m_shuffleId;
+ char name[11];
+ snprintf(name, 11, "shuffle%d", m_shuffleId);
+ ShuffleVectorInst *res =
+ new ShuffleVectorInst(vec, m_undefFloatVec, mask,
+ name, m_block);
+ return res;
+}