diff options
author | Zack Rusin <zack@tungstengraphics.com> | 2007-10-25 11:47:25 -0400 |
---|---|---|
committer | Zack Rusin <zack@tungstengraphics.com> | 2007-10-25 11:47:25 -0400 |
commit | 4a4e6f2cabdf39e9032e3e513f9966f471454077 (patch) | |
tree | be8abacf1a2b5e71c51217fbfcca17e244c8ad24 | |
parent | 1d17cb721afaa53317614af90488a45c26e083e3 (diff) |
Implement loops
-rw-r--r-- | progs/vpglsl/for.glsl | 7 | ||||
-rw-r--r-- | src/mesa/pipe/llvm/instructions.cpp | 64 | ||||
-rw-r--r-- | src/mesa/pipe/llvm/instructions.h | 11 | ||||
-rw-r--r-- | src/mesa/pipe/llvm/llvmtgsi.cpp | 21 |
4 files changed, 98 insertions, 5 deletions
diff --git a/progs/vpglsl/for.glsl b/progs/vpglsl/for.glsl new file mode 100644 index 00000000000..45d6845dacc --- /dev/null +++ b/progs/vpglsl/for.glsl @@ -0,0 +1,7 @@ + +void main() { + gl_Position = gl_Vertex; + gl_FrontColor = vec4(0); + for (int i = 0; i < 4; ++i) + gl_FrontColor += gl_Color; +} diff --git a/src/mesa/pipe/llvm/instructions.cpp b/src/mesa/pipe/llvm/instructions.cpp index a0645c58045..5b54af87178 100644 --- a/src/mesa/pipe/llvm/instructions.cpp +++ b/src/mesa/pipe/llvm/instructions.cpp @@ -1016,3 +1016,67 @@ llvm::Value * Instructions::lerp(llvm::Value *in1, llvm::Value *in2, return add(m, mul(s, in3)); } +void Instructions::beginLoop() +{ + BasicBlock *begin = new BasicBlock(name("loop"), m_func,0); + BasicBlock *end = new BasicBlock(name("endloop"), m_func,0); + + new BranchInst(begin, m_block); + Loop loop; + loop.begin = begin; + loop.end = end; + m_block = begin; + m_loopStack.push(loop); +} + +void Instructions::endLoop() +{ + assert(!m_loopStack.empty()); + Loop loop = m_loopStack.top(); + new BranchInst(loop.begin, m_block); + loop.end->moveAfter(m_block); + m_block = loop.end; + m_loopStack.pop(); +} + +void Instructions::brk() +{ + assert(!m_loopStack.empty()); + BasicBlock *unr = new BasicBlock(name("unreachable"), m_func,0); + new BranchInst(m_loopStack.top().end, m_block); + m_block = unr; +} + +llvm::Value * Instructions::trunc(llvm::Value *in) +{ + ExtractElementInst *x = new ExtractElementInst(in, unsigned(0), + name("extractx"), + m_block); + ExtractElementInst *y = new ExtractElementInst(in, unsigned(1), + name("extracty"), + m_block); + ExtractElementInst *z = new ExtractElementInst(in, unsigned(2), + name("extractz"), + m_block); + ExtractElementInst *w = new ExtractElementInst(in, unsigned(3), + name("extractw"), + m_block); + CastInst *icastx = new FPToSIInst(x, IntegerType::get(32), + name("ftoix"), m_block); + CastInst *icasty = new FPToSIInst(y, IntegerType::get(32), + name("ftoiy"), m_block); + CastInst *icastz = new FPToSIInst(z, IntegerType::get(32), + name("ftoiz"), m_block); + CastInst *icastw = new FPToSIInst(w, IntegerType::get(32), + name("ftoiw"), m_block); + CastInst *fx = new SIToFPInst(icastx, Type::FloatTy, + name("fx"), m_block); + CastInst *fy = new SIToFPInst(icasty, Type::FloatTy, + name("fy"), m_block); + CastInst *fz = new SIToFPInst(icastz, Type::FloatTy, + name("fz"), m_block); + CastInst *fw = new SIToFPInst(icastw, Type::FloatTy, + name("fw"), m_block); + return vectorFromVals(fx, fy, fz, fw); +} + diff --git a/src/mesa/pipe/llvm/instructions.h b/src/mesa/pipe/llvm/instructions.h index b0608e1da6b..29ae168e760 100644 --- a/src/mesa/pipe/llvm/instructions.h +++ b/src/mesa/pipe/llvm/instructions.h @@ -54,13 +54,16 @@ public: llvm::Value *abs(llvm::Value *in1); llvm::Value *arl(llvm::Value *in1); llvm::Value *add(llvm::Value *in1, llvm::Value *in2); + void beginLoop(); + void brk(); llvm::Value *cross(llvm::Value *in1, llvm::Value *in2); llvm::Value *dp3(llvm::Value *in1, llvm::Value *in2); llvm::Value *dp4(llvm::Value *in1, llvm::Value *in2); llvm::Value *dph(llvm::Value *in1, llvm::Value *in2); llvm::Value *dst(llvm::Value *in1, llvm::Value *in2); - void endif(); void elseop(); + void endif(); + void endLoop(); llvm::Value *ex2(llvm::Value *in); llvm::Value *floor(llvm::Value *in); llvm::Value *frc(llvm::Value *in); @@ -81,6 +84,7 @@ public: llvm::Value *sgt(llvm::Value *in1, llvm::Value *in2); llvm::Value *slt(llvm::Value *in1, llvm::Value *in2); llvm::Value *sub(llvm::Value *in1, llvm::Value *in2); + llvm::Value *trunc(llvm::Value *in); void printVector(llvm::Value *val); private: @@ -115,6 +119,11 @@ private: llvm::Constant *m_fmtPtr; std::stack<llvm::BasicBlock*> m_ifStack; + struct Loop { + llvm::BasicBlock *begin; + llvm::BasicBlock *end; + }; + std::stack<Loop> m_loopStack; }; #endif diff --git a/src/mesa/pipe/llvm/llvmtgsi.cpp b/src/mesa/pipe/llvm/llvmtgsi.cpp index 6ff4bc22708..6eae46d3ae0 100644 --- a/src/mesa/pipe/llvm/llvmtgsi.cpp +++ b/src/mesa/pipe/llvm/llvmtgsi.cpp @@ -447,7 +447,10 @@ translate_instruction(llvm::Module *module, break; case TGSI_OPCODE_TXL: break; - case TGSI_OPCODE_BRK: + case TGSI_OPCODE_BRK: { + instr->brk(); + return; + } break; case TGSI_OPCODE_IF: { instr->ifop(inputs[0]); @@ -485,7 +488,9 @@ translate_instruction(llvm::Module *module, break; case TGSI_OPCODE_NOT: break; - case TGSI_OPCODE_TRUNC: + case TGSI_OPCODE_TRUNC: { + out = instr->trunc(inputs[0]); + } break; case TGSI_OPCODE_SHL: break; @@ -511,11 +516,19 @@ translate_instruction(llvm::Module *module, break; case TGSI_OPCODE_ENDPRIM: break; - case TGSI_OPCODE_BGNLOOP2: + case TGSI_OPCODE_BGNLOOP2: { + instr->beginLoop(); + storage->setCurrentBlock(instr->currentBlock()); + return; + } break; case TGSI_OPCODE_BGNSUB: break; - case TGSI_OPCODE_ENDLOOP2: + case TGSI_OPCODE_ENDLOOP2: { + instr->endLoop(); + storage->setCurrentBlock(instr->currentBlock()); + return; + } break; case TGSI_OPCODE_ENDSUB: break; |