diff options
Diffstat (limited to 'src/mesa')
-rw-r--r-- | src/mesa/pipe/draw/draw_vertex_shader_llvm.c | 74 | ||||
-rw-r--r-- | src/mesa/pipe/llvm/llvmtgsi.cpp | 53 | ||||
-rw-r--r-- | src/mesa/pipe/llvm/tgsillvmbuilder.cpp | 134 |
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; +} |