<commit_before>//===-- AlphaTargetMachine.cpp - Define TargetMachine for Alpha -----------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
//
//===----------------------------------------------------------------------===//

#include "Alpha.h"
#include "AlphaJITInfo.h"
#include "AlphaTargetAsmInfo.h"
#include "AlphaTargetMachine.h"
#include "llvm/Module.h"
#include "llvm/PassManager.h"
#include "llvm/Target/TargetMachineRegistry.h"
#include "llvm/Support/FormattedStream.h"

using namespace llvm;

// Register the targets
extern Target TheAlphaTarget;
static RegisterTarget<AlphaTargetMachine> X(TheAlphaTarget, "alpha",
                                            "Alpha [experimental]");

// No assembler printer by default
AlphaTargetMachine::AsmPrinterCtorFn AlphaTargetMachine::AsmPrinterCtor = 0;

// Force static initialization.
extern "C" void LLVMInitializeAlphaTarget() { }

const TargetAsmInfo *AlphaTargetMachine::createTargetAsmInfo() const {
  return new AlphaTargetAsmInfo(*this);
}

AlphaTargetMachine::AlphaTargetMachine(const Target &T, const Module &M,
                                       const std::string &FS)
  : LLVMTargetMachine(T),
    DataLayout("e-f128:128:128"),
    FrameInfo(TargetFrameInfo::StackGrowsDown, 16, 0),
    JITInfo(*this),
    Subtarget(M, FS),
    TLInfo(*this) {
  setRelocationModel(Reloc::PIC_);
}

//===----------------------------------------------------------------------===//
// Pass Pipeline Configuration
//===----------------------------------------------------------------------===//

bool AlphaTargetMachine::addInstSelector(PassManagerBase &PM,
                                         CodeGenOpt::Level OptLevel) {
  PM.add(createAlphaISelDag(*this));
  return false;
}
bool AlphaTargetMachine::addPreEmitPass(PassManagerBase &PM,
                                        CodeGenOpt::Level OptLevel) {
  // Must run branch selection immediately preceding the asm printer
  PM.add(createAlphaBranchSelectionPass());
  return false;
}
bool AlphaTargetMachine::addAssemblyEmitter(PassManagerBase &PM,
                                            CodeGenOpt::Level OptLevel,
                                            bool Verbose,
                                            formatted_raw_ostream &Out) {
  PM.add(createAlphaLLRPPass(*this));
  // Output assembly language.
  assert(AsmPrinterCtor && "AsmPrinter was not linked in");
  if (AsmPrinterCtor)
    PM.add(AsmPrinterCtor(Out, *this, Verbose));
  return false;
}
bool AlphaTargetMachine::addCodeEmitter(PassManagerBase &PM,
                                        CodeGenOpt::Level OptLevel,
                                        bool DumpAsm, MachineCodeEmitter &MCE) {
  PM.add(createAlphaCodeEmitterPass(*this, MCE));
  if (DumpAsm) {
    assert(AsmPrinterCtor && "AsmPrinter was not linked in");
    if (AsmPrinterCtor)
      PM.add(AsmPrinterCtor(ferrs(), *this, true));
  }
  return false;
}
bool AlphaTargetMachine::addCodeEmitter(PassManagerBase &PM,
                                        CodeGenOpt::Level OptLevel,
                                        bool DumpAsm, JITCodeEmitter &JCE) {
  PM.add(createAlphaJITCodeEmitterPass(*this, JCE));
  if (DumpAsm) {
    assert(AsmPrinterCtor && "AsmPrinter was not linked in");
    if (AsmPrinterCtor)
      PM.add(AsmPrinterCtor(ferrs(), *this, true));
  }
  return false;
}
bool AlphaTargetMachine::addCodeEmitter(PassManagerBase &PM,
                                        CodeGenOpt::Level OptLevel,
                                        bool DumpAsm, ObjectCodeEmitter &OCE) {
  PM.add(createAlphaObjectCodeEmitterPass(*this, OCE));
  if (DumpAsm) {
    assert(AsmPrinterCtor && "AsmPrinter was not linked in");
    if (AsmPrinterCtor)
      PM.add(AsmPrinterCtor(ferrs(), *this, true));
  }
  return false;
}
bool AlphaTargetMachine::addSimpleCodeEmitter(PassManagerBase &PM,
                                              CodeGenOpt::Level OptLevel,
                                              bool DumpAsm,
                                              MachineCodeEmitter &MCE) {
  return addCodeEmitter(PM, OptLevel, DumpAsm, MCE);
}
bool AlphaTargetMachine::addSimpleCodeEmitter(PassManagerBase &PM,
                                              CodeGenOpt::Level OptLevel,
                                              bool DumpAsm,
                                              JITCodeEmitter &JCE) {
  return addCodeEmitter(PM, OptLevel, DumpAsm, JCE);
}
bool AlphaTargetMachine::addSimpleCodeEmitter(PassManagerBase &PM,
                                              CodeGenOpt::Level OptLevel,
                                              bool DumpAsm,
                                              ObjectCodeEmitter &OCE) {
  return addCodeEmitter(PM, OptLevel, DumpAsm, OCE);
}

<commit_msg>move createAlphaLLRPPass out of addAssemblyEmitter to make Alpha more like other targets.<commit_after>//===-- AlphaTargetMachine.cpp - Define TargetMachine for Alpha -----------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
//
//===----------------------------------------------------------------------===//

#include "Alpha.h"
#include "AlphaJITInfo.h"
#include "AlphaTargetAsmInfo.h"
#include "AlphaTargetMachine.h"
#include "llvm/Module.h"
#include "llvm/PassManager.h"
#include "llvm/Target/TargetMachineRegistry.h"
#include "llvm/Support/FormattedStream.h"

using namespace llvm;

// Register the targets
extern Target TheAlphaTarget;
static RegisterTarget<AlphaTargetMachine> X(TheAlphaTarget, "alpha",
                                            "Alpha [experimental]");

// No assembler printer by default
AlphaTargetMachine::AsmPrinterCtorFn AlphaTargetMachine::AsmPrinterCtor = 0;

// Force static initialization.
extern "C" void LLVMInitializeAlphaTarget() { }

const TargetAsmInfo *AlphaTargetMachine::createTargetAsmInfo() const {
  return new AlphaTargetAsmInfo(*this);
}

AlphaTargetMachine::AlphaTargetMachine(const Target &T, const Module &M,
                                       const std::string &FS)
  : LLVMTargetMachine(T),
    DataLayout("e-f128:128:128"),
    FrameInfo(TargetFrameInfo::StackGrowsDown, 16, 0),
    JITInfo(*this),
    Subtarget(M, FS),
    TLInfo(*this) {
  setRelocationModel(Reloc::PIC_);
}

//===----------------------------------------------------------------------===//
// Pass Pipeline Configuration
//===----------------------------------------------------------------------===//

bool AlphaTargetMachine::addInstSelector(PassManagerBase &PM,
                                         CodeGenOpt::Level OptLevel) {
  PM.add(createAlphaISelDag(*this));
  return false;
}
bool AlphaTargetMachine::addPreEmitPass(PassManagerBase &PM,
                                        CodeGenOpt::Level OptLevel) {
  // Must run branch selection immediately preceding the asm printer
  PM.add(createAlphaBranchSelectionPass());
  PM.add(createAlphaLLRPPass(*this));
  return false;
}
bool AlphaTargetMachine::addAssemblyEmitter(PassManagerBase &PM,
                                            CodeGenOpt::Level OptLevel,
                                            bool Verbose,
                                            formatted_raw_ostream &Out) {
  // Output assembly language.
  assert(AsmPrinterCtor && "AsmPrinter was not linked in");
  if (AsmPrinterCtor)
    PM.add(AsmPrinterCtor(Out, *this, Verbose));
  return false;
}
bool AlphaTargetMachine::addCodeEmitter(PassManagerBase &PM,
                                        CodeGenOpt::Level OptLevel,
                                        bool DumpAsm, MachineCodeEmitter &MCE) {
  PM.add(createAlphaCodeEmitterPass(*this, MCE));
  if (DumpAsm) {
    assert(AsmPrinterCtor && "AsmPrinter was not linked in");
    if (AsmPrinterCtor)
      PM.add(AsmPrinterCtor(ferrs(), *this, true));
  }
  return false;
}
bool AlphaTargetMachine::addCodeEmitter(PassManagerBase &PM,
                                        CodeGenOpt::Level OptLevel,
                                        bool DumpAsm, JITCodeEmitter &JCE) {
  PM.add(createAlphaJITCodeEmitterPass(*this, JCE));
  if (DumpAsm) {
    assert(AsmPrinterCtor && "AsmPrinter was not linked in");
    if (AsmPrinterCtor)
      PM.add(AsmPrinterCtor(ferrs(), *this, true));
  }
  return false;
}
bool AlphaTargetMachine::addCodeEmitter(PassManagerBase &PM,
                                        CodeGenOpt::Level OptLevel,
                                        bool DumpAsm, ObjectCodeEmitter &OCE) {
  PM.add(createAlphaObjectCodeEmitterPass(*this, OCE));
  if (DumpAsm) {
    assert(AsmPrinterCtor && "AsmPrinter was not linked in");
    if (AsmPrinterCtor)
      PM.add(AsmPrinterCtor(ferrs(), *this, true));
  }
  return false;
}
bool AlphaTargetMachine::addSimpleCodeEmitter(PassManagerBase &PM,
                                              CodeGenOpt::Level OptLevel,
                                              bool DumpAsm,
                                              MachineCodeEmitter &MCE) {
  return addCodeEmitter(PM, OptLevel, DumpAsm, MCE);
}
bool AlphaTargetMachine::addSimpleCodeEmitter(PassManagerBase &PM,
                                              CodeGenOpt::Level OptLevel,
                                              bool DumpAsm,
                                              JITCodeEmitter &JCE) {
  return addCodeEmitter(PM, OptLevel, DumpAsm, JCE);
}
bool AlphaTargetMachine::addSimpleCodeEmitter(PassManagerBase &PM,
                                              CodeGenOpt::Level OptLevel,
                                              bool DumpAsm,
                                              ObjectCodeEmitter &OCE) {
  return addCodeEmitter(PM, OptLevel, DumpAsm, OCE);
}

<|endoftext|>


<commit_before>//===- PowerPCInstrInfo.cpp - PowerPC Instruction Information ---*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file contains the PowerPC implementation of the TargetInstrInfo class.
//
//===----------------------------------------------------------------------===//

#include "PowerPCInstrInfo.h"
#include "PowerPC.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "PowerPCGenInstrInfo.inc"
#include <iostream>
using namespace llvm;

PowerPCInstrInfo::PowerPCInstrInfo()
  : TargetInstrInfo(PowerPCInsts, sizeof(PowerPCInsts)/sizeof(PowerPCInsts[0])){
}

bool PowerPCInstrInfo::isMoveInstr(const MachineInstr& MI,
                               unsigned& sourceReg,
                               unsigned& destReg) const {
  MachineOpCode oc = MI.getOpcode();
  if (oc == PPC32::OR) {
      assert(MI.getNumOperands() == 3 &&
             MI.getOperand(0).isRegister() &&
             MI.getOperand(1).isRegister() &&
             MI.getOperand(2).isRegister() &&
             "invalid register-register int move instruction");
      if (MI.getOperand(1).getReg() == MI.getOperand(2).getReg()) {
        sourceReg = MI.getOperand(1).getReg();
        destReg = MI.getOperand(0).getReg();
        return true;
      }
  }
  else if (oc == PPC32::FMR) {
      assert(MI.getNumOperands() == 2 &&
             MI.getOperand(0).isRegister() &&
             MI.getOperand(1).isRegister() &&
             "invalid register-register fp move instruction");
      sourceReg = MI.getOperand(1).getReg();
      destReg = MI.getOperand(0).getReg();
      return true;
  }
  return false;
}
<commit_msg>Fix code formatting<commit_after>//===- PowerPCInstrInfo.cpp - PowerPC Instruction Information ---*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file contains the PowerPC implementation of the TargetInstrInfo class.
//
//===----------------------------------------------------------------------===//

#include "PowerPCInstrInfo.h"
#include "PowerPC.h"
#include "PowerPCGenInstrInfo.inc"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include <iostream>
using namespace llvm;

PowerPCInstrInfo::PowerPCInstrInfo()
  : TargetInstrInfo(PowerPCInsts, sizeof(PowerPCInsts)/sizeof(PowerPCInsts[0]))
{ }

bool PowerPCInstrInfo::isMoveInstr(const MachineInstr& MI,
                                   unsigned& sourceReg,
                                   unsigned& destReg) const {
  MachineOpCode oc = MI.getOpcode();
  if (oc == PPC32::OR) {
    assert(MI.getNumOperands() == 3 &&
           MI.getOperand(0).isRegister() &&
           MI.getOperand(1).isRegister() &&
           MI.getOperand(2).isRegister() &&
           "invalid register-register int move instruction");
    if (MI.getOperand(1).getReg() == MI.getOperand(2).getReg()) {
      sourceReg = MI.getOperand(1).getReg();
      destReg = MI.getOperand(0).getReg();
      return true;
    }
  } else if (oc == PPC32::FMR) {
    assert(MI.getNumOperands() == 2 &&
           MI.getOperand(0).isRegister() &&
           MI.getOperand(1).isRegister() &&
           "invalid register-register fp move instruction");
    sourceReg = MI.getOperand(1).getReg();
    destReg = MI.getOperand(0).getReg();
    return true;
  }
  return false;
}
<|endoftext|>


<commit_before>//===- SystemZInstrInfo.cpp - SystemZ Instruction Information --------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file contains the SystemZ implementation of the TargetInstrInfo class.
//
//===----------------------------------------------------------------------===//

#include "SystemZ.h"
#include "SystemZInstrInfo.h"
#include "SystemZMachineFunctionInfo.h"
#include "SystemZTargetMachine.h"
#include "SystemZGenInstrInfo.inc"
#include "llvm/Function.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/PseudoSourceValue.h"

using namespace llvm;

SystemZInstrInfo::SystemZInstrInfo(SystemZTargetMachine &tm)
  : TargetInstrInfoImpl(SystemZInsts, array_lengthof(SystemZInsts)),
    RI(tm, *this), TM(tm) {
  // Fill the spill offsets map
  static const unsigned SpillOffsTab[][2] = {
    { SystemZ::R2D,  0x10 },
    { SystemZ::R3D,  0x18 },
    { SystemZ::R4D,  0x20 },
    { SystemZ::R5D,  0x28 },
    { SystemZ::R6D,  0x30 },
    { SystemZ::R7D,  0x38 },
    { SystemZ::R8D,  0x40 },
    { SystemZ::R9D,  0x48 },
    { SystemZ::R10D, 0x50 },
    { SystemZ::R11D, 0x58 },
    { SystemZ::R12D, 0x60 },
    { SystemZ::R13D, 0x68 },
    { SystemZ::R14D, 0x70 },
    { SystemZ::R15D, 0x78 }
  };

  RegSpillOffsets.grow(SystemZ::NUM_TARGET_REGS);

  for (unsigned i = 0, e = array_lengthof(SpillOffsTab); i != e; ++i)
    RegSpillOffsets[SpillOffsTab[i][0]] = SpillOffsTab[i][1];
}

void SystemZInstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB,
                                          MachineBasicBlock::iterator MI,
                                    unsigned SrcReg, bool isKill, int FrameIdx,
                                    const TargetRegisterClass *RC) const {
  assert(0 && "Cannot store this register to stack slot!");
}

void SystemZInstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB,
                                           MachineBasicBlock::iterator MI,
                                           unsigned DestReg, int FrameIdx,
                                           const TargetRegisterClass *RC) const{
  assert(0 && "Cannot store this register to stack slot!");
}

bool SystemZInstrInfo::copyRegToReg(MachineBasicBlock &MBB,
                                    MachineBasicBlock::iterator I,
                                    unsigned DestReg, unsigned SrcReg,
                                    const TargetRegisterClass *DestRC,
                                    const TargetRegisterClass *SrcRC) const {
  DebugLoc DL = DebugLoc::getUnknownLoc();
  if (I != MBB.end()) DL = I->getDebugLoc();

  // Determine if DstRC and SrcRC have a common superclass.
  const TargetRegisterClass *CommonRC = DestRC;
  if (DestRC == SrcRC)
    /* Same regclass for source and dest */;
  else if (CommonRC->hasSuperClass(SrcRC))
    CommonRC = SrcRC;
  else if (!CommonRC->hasSubClass(SrcRC))
    CommonRC = 0;

  if (CommonRC) {
    if (CommonRC == &SystemZ::GR64RegClass ||
        CommonRC == &SystemZ::ADDR64RegClass) {
      BuildMI(MBB, I, DL, get(SystemZ::MOV64rr), DestReg).addReg(SrcReg);
    } else if (CommonRC == &SystemZ::GR32RegClass ||
               CommonRC == &SystemZ::ADDR32RegClass) {
      BuildMI(MBB, I, DL, get(SystemZ::MOV32rr), DestReg).addReg(SrcReg);
    } else if (CommonRC == &SystemZ::GR64PRegClass) {
      BuildMI(MBB, I, DL, get(SystemZ::MOV64rrP), DestReg).addReg(SrcReg);
    } else if (CommonRC == &SystemZ::GR128RegClass) {
      BuildMI(MBB, I, DL, get(SystemZ::MOV128rr), DestReg).addReg(SrcReg);
    } else {
      return false;
    }

    return true;
  }

  if ((SrcRC == &SystemZ::GR64RegClass &&
       DestRC == &SystemZ::ADDR64RegClass) ||
      (DestRC == &SystemZ::GR64RegClass &&
       SrcRC == &SystemZ::ADDR64RegClass)) {
    BuildMI(MBB, I, DL, get(SystemZ::MOV64rr), DestReg).addReg(SrcReg);
    return true;
  } else if ((SrcRC == &SystemZ::GR32RegClass &&
              DestRC == &SystemZ::ADDR32RegClass) ||
             (DestRC == &SystemZ::GR32RegClass &&
              SrcRC == &SystemZ::ADDR32RegClass)) {
    BuildMI(MBB, I, DL, get(SystemZ::MOV32rr), DestReg).addReg(SrcReg);
    return true;
  }

  return false;
}

bool
SystemZInstrInfo::isMoveInstr(const MachineInstr& MI,
                              unsigned &SrcReg, unsigned &DstReg,
                              unsigned &SrcSubIdx, unsigned &DstSubIdx) const {
  SrcSubIdx = DstSubIdx = 0; // No sub-registers yet.

  switch (MI.getOpcode()) {
  default:
    return false;
  case SystemZ::MOV32rr:
  case SystemZ::MOV64rr:
  case SystemZ::MOV64rrP:
  case SystemZ::MOV128rr:
    assert(MI.getNumOperands() >= 2 &&
           MI.getOperand(0).isReg() &&
           MI.getOperand(1).isReg() &&
           "invalid register-register move instruction");
    SrcReg = MI.getOperand(1).getReg();
    DstReg = MI.getOperand(0).getReg();
    return true;
  }
}

bool
SystemZInstrInfo::spillCalleeSavedRegisters(MachineBasicBlock &MBB,
                                           MachineBasicBlock::iterator MI,
                                const std::vector<CalleeSavedInfo> &CSI) const {
  DebugLoc DL = DebugLoc::getUnknownLoc();
  if (MI != MBB.end()) DL = MI->getDebugLoc();

  MachineFunction &MF = *MBB.getParent();
  SystemZMachineFunctionInfo *MFI = MF.getInfo<SystemZMachineFunctionInfo>();
  MFI->setCalleeSavedFrameSize(CSI.size() * 8);

  // Scan the callee-saved and find the bounds of register spill area.
  unsigned LowReg = 0, HighReg = 0, StartOffset = -1U, EndOffset = 0;
  for (unsigned i = 0, e = CSI.size(); i != e; ++i) {
    unsigned Reg = CSI[i].getReg();
    unsigned Offset = RegSpillOffsets[Reg];
    if (StartOffset > Offset) {
      LowReg = Reg; StartOffset = Offset;
    }
    if (EndOffset < Offset) {
      HighReg = Reg; EndOffset = RegSpillOffsets[Reg];
    }
  }

  // Save information for epilogue inserter.
  MFI->setLowReg(LowReg); MFI->setHighReg(HighReg);

  // Build a store instruction. Use STORE MULTIPLE instruction if there are many
  // registers to store, otherwise - just STORE.
  MachineInstrBuilder MIB =
    BuildMI(MBB, MI, DL, get((LowReg == HighReg ?
                              SystemZ::MOV64mr : SystemZ::MOV64mrm)));

  // Add store operands.
  MIB.addReg(SystemZ::R15D).addImm(StartOffset);
  if (LowReg == HighReg)
    MIB.addReg(0);
  MIB.addReg(LowReg, RegState::Kill);
  if (LowReg != HighReg)
    MIB.addReg(HighReg, RegState::Kill);

  // Do a second scan adding regs as being killed by instruction
  for (unsigned i = 0, e = CSI.size(); i != e; ++i) {
    unsigned Reg = CSI[i].getReg();
    // Add the callee-saved register as live-in. It's killed at the spill.
    MBB.addLiveIn(Reg);
    if (Reg != LowReg && Reg != HighReg)
      MIB.addReg(Reg, RegState::ImplicitKill);
  }

  return true;
}

bool
SystemZInstrInfo::restoreCalleeSavedRegisters(MachineBasicBlock &MBB,
                                             MachineBasicBlock::iterator MI,
                                const std::vector<CalleeSavedInfo> &CSI) const {
  if (CSI.empty())
    return false;

  DebugLoc DL = DebugLoc::getUnknownLoc();
  if (MI != MBB.end()) DL = MI->getDebugLoc();

  MachineFunction &MF = *MBB.getParent();
  const TargetRegisterInfo *RegInfo= MF.getTarget().getRegisterInfo();
  SystemZMachineFunctionInfo *MFI = MF.getInfo<SystemZMachineFunctionInfo>();

  unsigned LowReg = MFI->getLowReg(), HighReg = MFI->getHighReg();
  unsigned StartOffset = RegSpillOffsets[LowReg];

  // Build a load instruction. Use LOAD MULTIPLE instruction if there are many
  // registers to load, otherwise - just LOAD.
  MachineInstrBuilder MIB =
    BuildMI(MBB, MI, DL, get((LowReg == HighReg ?
                              SystemZ::MOV64rm : SystemZ::MOV64rmm)));
  // Add store operands.
  MIB.addReg(LowReg, RegState::Define);
  if (LowReg != HighReg)
    MIB.addReg(HighReg, RegState::Define);

  MIB.addReg((RegInfo->hasFP(MF) ? SystemZ::R11D : SystemZ::R15D));
  MIB.addImm(StartOffset);
  if (LowReg == HighReg)
    MIB.addReg(0);

  // Do a second scan adding regs as being defined by instruction
  for (unsigned i = 0, e = CSI.size(); i != e; ++i) {
    unsigned Reg = CSI[i].getReg();
    if (Reg != LowReg && Reg != HighReg)
      MIB.addReg(Reg, RegState::ImplicitDefine);
  }

  return true;
}

unsigned
SystemZInstrInfo::InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB,
                              MachineBasicBlock *FBB,
                            const SmallVectorImpl<MachineOperand> &Cond) const {
  // FIXME this should probably have a DebugLoc operand
  DebugLoc dl = DebugLoc::getUnknownLoc();
  // Shouldn't be a fall through.
  assert(TBB && "InsertBranch must not be told to insert a fallthrough");
  assert((Cond.size() == 1 || Cond.size() == 0) &&
         "SystemZ branch conditions have one component!");

  if (Cond.empty()) {
    // Unconditional branch?
    assert(!FBB && "Unconditional branch with multiple successors!");
    BuildMI(&MBB, dl, get(SystemZ::JMP)).addMBB(TBB);
    return 1;
  }

  // Conditional branch.
  unsigned Count = 0;
  SystemZCC::CondCodes CC = (SystemZCC::CondCodes)Cond[0].getImm();
  BuildMI(&MBB, dl, getBrCond(CC)).addMBB(TBB);
  ++Count;

  if (FBB) {
    // Two-way Conditional branch. Insert the second branch.
    BuildMI(&MBB, dl, get(SystemZ::JMP)).addMBB(FBB);
    ++Count;
  }
  return Count;
}

const TargetInstrDesc&
SystemZInstrInfo::getBrCond(SystemZCC::CondCodes CC) const {
  unsigned Opc;
  switch (CC) {
  default:
    assert(0 && "Unknown condition code!");
  case SystemZCC::E:
    Opc = SystemZ::JE;
    break;
  case SystemZCC::NE:
    Opc = SystemZ::JNE;
    break;
  case SystemZCC::H:
    Opc = SystemZ::JH;
    break;
  case SystemZCC::L:
    Opc = SystemZ::JL;
    break;
  case SystemZCC::HE:
    Opc = SystemZ::JHE;
    break;
  case SystemZCC::LE:
    Opc = SystemZ::JLE;
    break;
  }

  return get(Opc);
}
<commit_msg>Provide hooks for spilling / restoring stuff<commit_after>//===- SystemZInstrInfo.cpp - SystemZ Instruction Information --------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file contains the SystemZ implementation of the TargetInstrInfo class.
//
//===----------------------------------------------------------------------===//

#include "SystemZ.h"
#include "SystemZInstrBuilder.h"
#include "SystemZInstrInfo.h"
#include "SystemZMachineFunctionInfo.h"
#include "SystemZTargetMachine.h"
#include "SystemZGenInstrInfo.inc"
#include "llvm/Function.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/PseudoSourceValue.h"

using namespace llvm;

SystemZInstrInfo::SystemZInstrInfo(SystemZTargetMachine &tm)
  : TargetInstrInfoImpl(SystemZInsts, array_lengthof(SystemZInsts)),
    RI(tm, *this), TM(tm) {
  // Fill the spill offsets map
  static const unsigned SpillOffsTab[][2] = {
    { SystemZ::R2D,  0x10 },
    { SystemZ::R3D,  0x18 },
    { SystemZ::R4D,  0x20 },
    { SystemZ::R5D,  0x28 },
    { SystemZ::R6D,  0x30 },
    { SystemZ::R7D,  0x38 },
    { SystemZ::R8D,  0x40 },
    { SystemZ::R9D,  0x48 },
    { SystemZ::R10D, 0x50 },
    { SystemZ::R11D, 0x58 },
    { SystemZ::R12D, 0x60 },
    { SystemZ::R13D, 0x68 },
    { SystemZ::R14D, 0x70 },
    { SystemZ::R15D, 0x78 }
  };

  RegSpillOffsets.grow(SystemZ::NUM_TARGET_REGS);

  for (unsigned i = 0, e = array_lengthof(SpillOffsTab); i != e; ++i)
    RegSpillOffsets[SpillOffsTab[i][0]] = SpillOffsTab[i][1];
}

void SystemZInstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB,
                                          MachineBasicBlock::iterator MI,
                                    unsigned SrcReg, bool isKill, int FrameIdx,
                                    const TargetRegisterClass *RC) const {
  DebugLoc DL = DebugLoc::getUnknownLoc();
  if (MI != MBB.end()) DL = MI->getDebugLoc();

  unsigned Opc = 0;
  if (RC == &SystemZ::GR32RegClass ||
      RC == &SystemZ::ADDR32RegClass)
    Opc = SystemZ::MOV32mr;
  else if (RC == &SystemZ::GR64RegClass ||
           RC == &SystemZ::ADDR64RegClass) {
    Opc = SystemZ::MOV64mr;
  } else
    assert(0 && "Unsupported regclass to store");

  addFrameReference(BuildMI(MBB, MI, DL, get(Opc)), FrameIdx)
    .addReg(SrcReg, getKillRegState(isKill));
}

void SystemZInstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB,
                                           MachineBasicBlock::iterator MI,
                                           unsigned DestReg, int FrameIdx,
                                           const TargetRegisterClass *RC) const{
  DebugLoc DL = DebugLoc::getUnknownLoc();
  if (MI != MBB.end()) DL = MI->getDebugLoc();

  unsigned Opc = 0;
  if (RC == &SystemZ::GR32RegClass ||
      RC == &SystemZ::ADDR32RegClass)
    Opc = SystemZ::MOV32rm;
  else if (RC == &SystemZ::GR64RegClass ||
           RC == &SystemZ::ADDR64RegClass) {
    Opc = SystemZ::MOV64rm;
  } else
    assert(0 && "Unsupported regclass to store");

  addFrameReference(BuildMI(MBB, MI, DL, get(Opc), DestReg), FrameIdx);
}

bool SystemZInstrInfo::copyRegToReg(MachineBasicBlock &MBB,
                                    MachineBasicBlock::iterator I,
                                    unsigned DestReg, unsigned SrcReg,
                                    const TargetRegisterClass *DestRC,
                                    const TargetRegisterClass *SrcRC) const {
  DebugLoc DL = DebugLoc::getUnknownLoc();
  if (I != MBB.end()) DL = I->getDebugLoc();

  // Determine if DstRC and SrcRC have a common superclass.
  const TargetRegisterClass *CommonRC = DestRC;
  if (DestRC == SrcRC)
    /* Same regclass for source and dest */;
  else if (CommonRC->hasSuperClass(SrcRC))
    CommonRC = SrcRC;
  else if (!CommonRC->hasSubClass(SrcRC))
    CommonRC = 0;

  if (CommonRC) {
    if (CommonRC == &SystemZ::GR64RegClass ||
        CommonRC == &SystemZ::ADDR64RegClass) {
      BuildMI(MBB, I, DL, get(SystemZ::MOV64rr), DestReg).addReg(SrcReg);
    } else if (CommonRC == &SystemZ::GR32RegClass ||
               CommonRC == &SystemZ::ADDR32RegClass) {
      BuildMI(MBB, I, DL, get(SystemZ::MOV32rr), DestReg).addReg(SrcReg);
    } else if (CommonRC == &SystemZ::GR64PRegClass) {
      BuildMI(MBB, I, DL, get(SystemZ::MOV64rrP), DestReg).addReg(SrcReg);
    } else if (CommonRC == &SystemZ::GR128RegClass) {
      BuildMI(MBB, I, DL, get(SystemZ::MOV128rr), DestReg).addReg(SrcReg);
    } else {
      return false;
    }

    return true;
  }

  if ((SrcRC == &SystemZ::GR64RegClass &&
       DestRC == &SystemZ::ADDR64RegClass) ||
      (DestRC == &SystemZ::GR64RegClass &&
       SrcRC == &SystemZ::ADDR64RegClass)) {
    BuildMI(MBB, I, DL, get(SystemZ::MOV64rr), DestReg).addReg(SrcReg);
    return true;
  } else if ((SrcRC == &SystemZ::GR32RegClass &&
              DestRC == &SystemZ::ADDR32RegClass) ||
             (DestRC == &SystemZ::GR32RegClass &&
              SrcRC == &SystemZ::ADDR32RegClass)) {
    BuildMI(MBB, I, DL, get(SystemZ::MOV32rr), DestReg).addReg(SrcReg);
    return true;
  }

  return false;
}

bool
SystemZInstrInfo::isMoveInstr(const MachineInstr& MI,
                              unsigned &SrcReg, unsigned &DstReg,
                              unsigned &SrcSubIdx, unsigned &DstSubIdx) const {
  SrcSubIdx = DstSubIdx = 0; // No sub-registers yet.

  switch (MI.getOpcode()) {
  default:
    return false;
  case SystemZ::MOV32rr:
  case SystemZ::MOV64rr:
  case SystemZ::MOV64rrP:
  case SystemZ::MOV128rr:
    assert(MI.getNumOperands() >= 2 &&
           MI.getOperand(0).isReg() &&
           MI.getOperand(1).isReg() &&
           "invalid register-register move instruction");
    SrcReg = MI.getOperand(1).getReg();
    DstReg = MI.getOperand(0).getReg();
    return true;
  }
}

bool
SystemZInstrInfo::spillCalleeSavedRegisters(MachineBasicBlock &MBB,
                                           MachineBasicBlock::iterator MI,
                                const std::vector<CalleeSavedInfo> &CSI) const {
  DebugLoc DL = DebugLoc::getUnknownLoc();
  if (MI != MBB.end()) DL = MI->getDebugLoc();

  MachineFunction &MF = *MBB.getParent();
  SystemZMachineFunctionInfo *MFI = MF.getInfo<SystemZMachineFunctionInfo>();
  MFI->setCalleeSavedFrameSize(CSI.size() * 8);

  // Scan the callee-saved and find the bounds of register spill area.
  unsigned LowReg = 0, HighReg = 0, StartOffset = -1U, EndOffset = 0;
  for (unsigned i = 0, e = CSI.size(); i != e; ++i) {
    unsigned Reg = CSI[i].getReg();
    unsigned Offset = RegSpillOffsets[Reg];
    if (StartOffset > Offset) {
      LowReg = Reg; StartOffset = Offset;
    }
    if (EndOffset < Offset) {
      HighReg = Reg; EndOffset = RegSpillOffsets[Reg];
    }
  }

  // Save information for epilogue inserter.
  MFI->setLowReg(LowReg); MFI->setHighReg(HighReg);

  // Build a store instruction. Use STORE MULTIPLE instruction if there are many
  // registers to store, otherwise - just STORE.
  MachineInstrBuilder MIB =
    BuildMI(MBB, MI, DL, get((LowReg == HighReg ?
                              SystemZ::MOV64mr : SystemZ::MOV64mrm)));

  // Add store operands.
  MIB.addReg(SystemZ::R15D).addImm(StartOffset);
  if (LowReg == HighReg)
    MIB.addReg(0);
  MIB.addReg(LowReg, RegState::Kill);
  if (LowReg != HighReg)
    MIB.addReg(HighReg, RegState::Kill);

  // Do a second scan adding regs as being killed by instruction
  for (unsigned i = 0, e = CSI.size(); i != e; ++i) {
    unsigned Reg = CSI[i].getReg();
    // Add the callee-saved register as live-in. It's killed at the spill.
    MBB.addLiveIn(Reg);
    if (Reg != LowReg && Reg != HighReg)
      MIB.addReg(Reg, RegState::ImplicitKill);
  }

  return true;
}

bool
SystemZInstrInfo::restoreCalleeSavedRegisters(MachineBasicBlock &MBB,
                                             MachineBasicBlock::iterator MI,
                                const std::vector<CalleeSavedInfo> &CSI) const {
  if (CSI.empty())
    return false;

  DebugLoc DL = DebugLoc::getUnknownLoc();
  if (MI != MBB.end()) DL = MI->getDebugLoc();

  MachineFunction &MF = *MBB.getParent();
  const TargetRegisterInfo *RegInfo= MF.getTarget().getRegisterInfo();
  SystemZMachineFunctionInfo *MFI = MF.getInfo<SystemZMachineFunctionInfo>();

  unsigned LowReg = MFI->getLowReg(), HighReg = MFI->getHighReg();
  unsigned StartOffset = RegSpillOffsets[LowReg];

  // Build a load instruction. Use LOAD MULTIPLE instruction if there are many
  // registers to load, otherwise - just LOAD.
  MachineInstrBuilder MIB =
    BuildMI(MBB, MI, DL, get((LowReg == HighReg ?
                              SystemZ::MOV64rm : SystemZ::MOV64rmm)));
  // Add store operands.
  MIB.addReg(LowReg, RegState::Define);
  if (LowReg != HighReg)
    MIB.addReg(HighReg, RegState::Define);

  MIB.addReg((RegInfo->hasFP(MF) ? SystemZ::R11D : SystemZ::R15D));
  MIB.addImm(StartOffset);
  if (LowReg == HighReg)
    MIB.addReg(0);

  // Do a second scan adding regs as being defined by instruction
  for (unsigned i = 0, e = CSI.size(); i != e; ++i) {
    unsigned Reg = CSI[i].getReg();
    if (Reg != LowReg && Reg != HighReg)
      MIB.addReg(Reg, RegState::ImplicitDefine);
  }

  return true;
}

unsigned
SystemZInstrInfo::InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB,
                              MachineBasicBlock *FBB,
                            const SmallVectorImpl<MachineOperand> &Cond) const {
  // FIXME this should probably have a DebugLoc operand
  DebugLoc dl = DebugLoc::getUnknownLoc();
  // Shouldn't be a fall through.
  assert(TBB && "InsertBranch must not be told to insert a fallthrough");
  assert((Cond.size() == 1 || Cond.size() == 0) &&
         "SystemZ branch conditions have one component!");

  if (Cond.empty()) {
    // Unconditional branch?
    assert(!FBB && "Unconditional branch with multiple successors!");
    BuildMI(&MBB, dl, get(SystemZ::JMP)).addMBB(TBB);
    return 1;
  }

  // Conditional branch.
  unsigned Count = 0;
  SystemZCC::CondCodes CC = (SystemZCC::CondCodes)Cond[0].getImm();
  BuildMI(&MBB, dl, getBrCond(CC)).addMBB(TBB);
  ++Count;

  if (FBB) {
    // Two-way Conditional branch. Insert the second branch.
    BuildMI(&MBB, dl, get(SystemZ::JMP)).addMBB(FBB);
    ++Count;
  }
  return Count;
}

const TargetInstrDesc&
SystemZInstrInfo::getBrCond(SystemZCC::CondCodes CC) const {
  unsigned Opc;
  switch (CC) {
  default:
    assert(0 && "Unknown condition code!");
  case SystemZCC::E:
    Opc = SystemZ::JE;
    break;
  case SystemZCC::NE:
    Opc = SystemZ::JNE;
    break;
  case SystemZCC::H:
    Opc = SystemZ::JH;
    break;
  case SystemZCC::L:
    Opc = SystemZ::JL;
    break;
  case SystemZCC::HE:
    Opc = SystemZ::JHE;
    break;
  case SystemZCC::LE:
    Opc = SystemZ::JLE;
    break;
  }

  return get(Opc);
}
<|endoftext|>


<commit_before>/*
 * Universe
 *
 * Copyright 2015 Lubosz Sarnecki <lubosz@gmail.com>
 *
 */

#include "Renderer.h"

#include "util.h"
#include <gli/gli.hpp>

Renderer::Renderer(int width, int height) {
    translate_z = -1.f;
    rotate_x = 0.0;
    rotate_y = 0.0;

    if (gl3wInit()) {
        fprintf(stderr, "failed to initialize gl3w\n");
        return;
    }
    if (!gl3wIsSupported(4, 5)) {
        fprintf(stderr, "OpenGL 4.5 not supported\n");
        return;
    }

    printContextInfo();
    initShaders();
    glUseProgram(shader_programm);

    glEnable(GL_VERTEX_PROGRAM_POINT_SIZE);

    GLuint tex = initTexture("media/cloud.dds");
    glBindTexture(GL_TEXTURE_2D, tex);

    GLint texLoc = glGetUniformLocation(shader_programm, "cloud");
    glUniform1i(texLoc, tex-1);

    updateModel();
    updateProjection(width, height);

    glClearColor(0.0, 0.0, 0.0, 1.0);
    glDisable(GL_DEPTH_TEST);
    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

    glBindVertexArray(vao);

    glError;
}

Renderer::~Renderer() {}

void Renderer::draw(GLuint positionVBO, GLuint colorVBO, int particleCount) {
  // render the particles from VBOs
  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

  glGenVertexArrays(1, &vao);
  glBindVertexArray(vao);
  glEnableVertexAttribArray(0);
  glBindBuffer(GL_ARRAY_BUFFER, positionVBO);
  glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, NULL);

  glEnableVertexAttribArray(1);
  glBindBuffer(GL_ARRAY_BUFFER, colorVBO);
  glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, NULL);

  glDrawArrays(GL_POINTS, 0, particleCount);
}

void Renderer::printContextInfo() {
    printf("GL_RENDERER: %s\n", glGetString(GL_RENDERER));
    printf("GL_VERSION: %s\n", glGetString(GL_VERSION));
    printf("GL_SHADING_LANGUAGE_VERSION: %s\n",
           glGetString(GL_SHADING_LANGUAGE_VERSION));
}

GLuint Renderer::initTexture(char const* Filename) {
    gli::texture Texture = gli::load(Filename);
    if (Texture.empty())
        return 0;

    gli::gl GL;
    gli::gl::format const Format = GL.translate(Texture.format());
    GLenum Target = GL.translate(Texture.target());

    GLuint TextureName = 0;
    glGenTextures(1, &TextureName);
    glBindTexture(Target, TextureName);
    glTexParameteri(Target, GL_TEXTURE_BASE_LEVEL, 0);
    glTexParameteri(Target,
                    GL_TEXTURE_MAX_LEVEL, static_cast<GLint>(Texture.levels() - 1));

    glm::tvec3<GLsizei> const Dimensions(Texture.dimensions());
    GLsizei const FaceTotal =
            static_cast<GLsizei>(Texture.layers() * Texture.faces());

    glTexStorage2D(
                Target, static_cast<GLint>(Texture.levels()), Format.Internal,
                Dimensions.x,
                Texture.target() == gli::TARGET_2D ? Dimensions.y : FaceTotal);

    for (std::size_t Layer = 0;
         Layer < Texture.layers(); ++Layer)
        for (std::size_t Face = 0;
             Face < Texture.faces(); ++Face)
            for (std::size_t Level = 0;
                 Level < Texture.levels(); ++Level) {
                glm::tvec3<GLsizei> Dimensions(Texture.dimensions(Level));

                /*
                printf("layer %ld, face %ld, level %ld, iscompressed %d\n",
                       Layer, Face, Level,
                       gli::is_compressed(Texture.format()));
                */
                if (gli::is_compressed(Texture.format()))
                    glCompressedTexSubImage2D(
                                Target, static_cast<GLint>(Level),
                                0, 0,
                                Dimensions.x,
                                Dimensions.y,
                                Format.Internal, static_cast<GLsizei>(Texture.size(Level)),
                                Texture.data(Layer, Face, Level));
                else
                    glTexSubImage2D(
                                Target, static_cast<GLint>(Level),
                                0, 0,
                                Dimensions.x,
                                Dimensions.y,
                                Format.External, Format.Type,
                                Texture.data(Layer, Face, Level));
            }
    return TextureName;
}

void Renderer::initShaders() {
    shaders.push_back(readFile("gpu/MVP.vert"));
    shaders.push_back(readFile("gpu/color.frag"));

    const char* vertex[] = {shaders[0].c_str()};
    const char* fragment[] = {shaders[1].c_str()};

    GLuint vs = glCreateShader(GL_VERTEX_SHADER);
    glShaderSource(vs, 1, vertex, NULL);
    glCompileShader(vs);
    GLuint fs = glCreateShader(GL_FRAGMENT_SHADER);
    glShaderSource(fs, 1, fragment, NULL);
    glCompileShader(fs);

    shader_programm = glCreateProgram();
    glAttachShader(shader_programm, fs);
    glAttachShader(shader_programm, vs);
    glLinkProgram(shader_programm);
}

void Renderer::rotate(float x, float y) {
    rotate_x += y * 0.2;
    rotate_y += x * 0.2;
    updateModel();
}

void Renderer::translate(float z) {
    translate_z += z * 0.1;
    updateModel();
}

void Renderer::updateModel() {
    model = glm::mat4(1.0f);
    model = glm::translate(glm::mat4(1.0f), glm::vec3(0.0f, 0.0f, translate_z));
    model = glm::rotate(model, rotate_x, glm::vec3(1.0f, 0.0f, 0.0f));
    model = glm::rotate(model, rotate_y, glm::vec3(0.0f, 1.0f, 0.0f));
    updateMVP();
}

void Renderer::updateProjection(int width, int height) {
    glViewport(0, 0, width, height);
    float aspect = static_cast<GLfloat>(width)
            / static_cast<GLfloat>(height);
    projection = glm::perspective(90.0f, aspect, 0.1f, 1000.f);
    updateMVP();
}

void Renderer::updateMVP() {
    glm::mat4 mvp = projection * model;
    GLint UniformMVP = glGetUniformLocation(shader_programm, "mvp");
    glUniformMatrix4fv(UniformMVP, 1, GL_FALSE, &mvp[0][0]);
}

void Renderer::checkGlError(const char* file, int line) {
    GLenum err(glGetError());

    while (err != GL_NO_ERROR) {
        std::string error;
        switch (err) {
            case GL_INVALID_OPERATION:
                error = "INVALID_OPERATION";
                break;
            case GL_INVALID_ENUM:
                error = "INVALID_ENUM";
                break;
            case GL_INVALID_VALUE:
                error = "INVALID_VALUE";
                break;
            case GL_OUT_OF_MEMORY:
                error = "OUT_OF_MEMORY";
                break;
            case GL_INVALID_FRAMEBUFFER_OPERATION:
                error = "INVALID_FRAMEBUFFER_OPERATION";
                break;
            default:
                error = "Unknown error";
                break;
        }
        std::cout
                << "GL ERROR: GL_"
                << error << " "
                << file << " "
                << line << "\n";
        err = glGetError();
    }
}

GLuint Renderer::createVBO(
        const void* data,
        int dataSize,
        GLenum target,
        GLenum usage) {
    GLuint id;
    glGenBuffers(1, &id);
    glBindBuffer(target, id);
    glBufferData(target, dataSize, data, usage);

    // check data size in VBO is same as input array
    // if not return 0 and delete VBO
    int bufferSize = 0;
    glGetBufferParameteriv(target, GL_BUFFER_SIZE, &bufferSize);
    if (dataSize != bufferSize) {
        glDeleteBuffers(1, &id);
        id = 0;
        std::cout << "[createVBO()] Data size is mismatch with input array\n";
    }
    glBindBuffer(target, 0);
    return id;
}
<commit_msg>make linter happy<commit_after>/*
 * Universe
 *
 * Copyright 2015 Lubosz Sarnecki <lubosz@gmail.com>
 *
 */

#include "Renderer.h"

#include "util.h"
#include <gli/gli.hpp>

Renderer::Renderer(int width, int height) {
    translate_z = -1.f;
    rotate_x = 0.0;
    rotate_y = 0.0;

    if (gl3wInit()) {
        fprintf(stderr, "failed to initialize gl3w\n");
        return;
    }
    if (!gl3wIsSupported(4, 5)) {
        fprintf(stderr, "OpenGL 4.5 not supported\n");
        return;
    }

    printContextInfo();
    initShaders();
    glUseProgram(shader_programm);

    glEnable(GL_VERTEX_PROGRAM_POINT_SIZE);

    GLuint tex = initTexture("media/cloud.dds");
    glBindTexture(GL_TEXTURE_2D, tex);

    GLint texLoc = glGetUniformLocation(shader_programm, "cloud");
    glUniform1i(texLoc, tex-1);

    updateModel();
    updateProjection(width, height);

    glClearColor(0.0, 0.0, 0.0, 1.0);
    glDisable(GL_DEPTH_TEST);
    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

    glBindVertexArray(vao);

    glError;
}

Renderer::~Renderer() {}

void Renderer::draw(GLuint positionVBO, GLuint colorVBO, int particleCount) {
  // render the particles from VBOs
  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

  glGenVertexArrays(1, &vao);
  glBindVertexArray(vao);
  glEnableVertexAttribArray(0);
  glBindBuffer(GL_ARRAY_BUFFER, positionVBO);
  glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, NULL);

  glEnableVertexAttribArray(1);
  glBindBuffer(GL_ARRAY_BUFFER, colorVBO);
  glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, NULL);

  glDrawArrays(GL_POINTS, 0, particleCount);
}

void Renderer::printContextInfo() {
    printf("GL_RENDERER: %s\n", glGetString(GL_RENDERER));
    printf("GL_VERSION: %s\n", glGetString(GL_VERSION));
    printf("GL_SHADING_LANGUAGE_VERSION: %s\n",
           glGetString(GL_SHADING_LANGUAGE_VERSION));
}

GLuint Renderer::initTexture(char const* Filename) {
    gli::texture Texture = gli::load(Filename);
    if (Texture.empty())
        return 0;

    gli::gl GL;
    gli::gl::format const Format = GL.translate(Texture.format());
    GLenum Target = GL.translate(Texture.target());

    GLuint TextureName = 0;
    glGenTextures(1, &TextureName);
    glBindTexture(Target, TextureName);
    glTexParameteri(Target, GL_TEXTURE_BASE_LEVEL, 0);
    glTexParameteri(Target,
        GL_TEXTURE_MAX_LEVEL, static_cast<GLint>(Texture.levels() - 1));

    glm::tvec3<GLsizei> const Dimensions(Texture.dimensions());
    GLsizei const FaceTotal =
            static_cast<GLsizei>(Texture.layers() * Texture.faces());

    glTexStorage2D(
                Target, static_cast<GLint>(Texture.levels()), Format.Internal,
                Dimensions.x,
                Texture.target() == gli::TARGET_2D ? Dimensions.y : FaceTotal);

    for (std::size_t Layer = 0;
         Layer < Texture.layers(); ++Layer)
        for (std::size_t Face = 0;
             Face < Texture.faces(); ++Face)
            for (std::size_t Level = 0;
                 Level < Texture.levels(); ++Level) {
                glm::tvec3<GLsizei> Dimensions(Texture.dimensions(Level));

                /*
                printf("layer %ld, face %ld, level %ld, iscompressed %d\n",
                       Layer, Face, Level,
                       gli::is_compressed(Texture.format()));
                */
                if (gli::is_compressed(Texture.format()))
                    glCompressedTexSubImage2D(
                                Target, static_cast<GLint>(Level),
                                0, 0,
                                Dimensions.x,
                                Dimensions.y,
                                Format.Internal,
                                static_cast<GLsizei>(Texture.size(Level)),
                                Texture.data(Layer, Face, Level));
                else
                    glTexSubImage2D(
                                Target, static_cast<GLint>(Level),
                                0, 0,
                                Dimensions.x,
                                Dimensions.y,
                                Format.External, Format.Type,
                                Texture.data(Layer, Face, Level));
            }
    return TextureName;
}

void Renderer::initShaders() {
    shaders.push_back(readFile("gpu/MVP.vert"));
    shaders.push_back(readFile("gpu/color.frag"));

    const char* vertex[] = {shaders[0].c_str()};
    const char* fragment[] = {shaders[1].c_str()};

    GLuint vs = glCreateShader(GL_VERTEX_SHADER);
    glShaderSource(vs, 1, vertex, NULL);
    glCompileShader(vs);
    GLuint fs = glCreateShader(GL_FRAGMENT_SHADER);
    glShaderSource(fs, 1, fragment, NULL);
    glCompileShader(fs);

    shader_programm = glCreateProgram();
    glAttachShader(shader_programm, fs);
    glAttachShader(shader_programm, vs);
    glLinkProgram(shader_programm);
}

void Renderer::rotate(float x, float y) {
    rotate_x += y * 0.2;
    rotate_y += x * 0.2;
    updateModel();
}

void Renderer::translate(float z) {
    translate_z += z * 0.1;
    updateModel();
}

void Renderer::updateModel() {
    model = glm::mat4(1.0f);
    model = glm::translate(glm::mat4(1.0f), glm::vec3(0.0f, 0.0f, translate_z));
    model = glm::rotate(model, rotate_x, glm::vec3(1.0f, 0.0f, 0.0f));
    model = glm::rotate(model, rotate_y, glm::vec3(0.0f, 1.0f, 0.0f));
    updateMVP();
}

void Renderer::updateProjection(int width, int height) {
    glViewport(0, 0, width, height);
    float aspect = static_cast<GLfloat>(width)
            / static_cast<GLfloat>(height);
    projection = glm::perspective(90.0f, aspect, 0.1f, 1000.f);
    updateMVP();
}

void Renderer::updateMVP() {
    glm::mat4 mvp = projection * model;
    GLint UniformMVP = glGetUniformLocation(shader_programm, "mvp");
    glUniformMatrix4fv(UniformMVP, 1, GL_FALSE, &mvp[0][0]);
}

void Renderer::checkGlError(const char* file, int line) {
    GLenum err(glGetError());

    while (err != GL_NO_ERROR) {
        std::string error;
        switch (err) {
            case GL_INVALID_OPERATION:
                error = "INVALID_OPERATION";
                break;
            case GL_INVALID_ENUM:
                error = "INVALID_ENUM";
                break;
            case GL_INVALID_VALUE:
                error = "INVALID_VALUE";
                break;
            case GL_OUT_OF_MEMORY:
                error = "OUT_OF_MEMORY";
                break;
            case GL_INVALID_FRAMEBUFFER_OPERATION:
                error = "INVALID_FRAMEBUFFER_OPERATION";
                break;
            default:
                error = "Unknown error";
                break;
        }
        std::cout
                << "GL ERROR: GL_"
                << error << " "
                << file << " "
                << line << "\n";
        err = glGetError();
    }
}

GLuint Renderer::createVBO(
        const void* data,
        int dataSize,
        GLenum target,
        GLenum usage) {
    GLuint id;
    glGenBuffers(1, &id);
    glBindBuffer(target, id);
    glBufferData(target, dataSize, data, usage);

    // check data size in VBO is same as input array
    // if not return 0 and delete VBO
    int bufferSize = 0;
    glGetBufferParameteriv(target, GL_BUFFER_SIZE, &bufferSize);
    if (dataSize != bufferSize) {
        glDeleteBuffers(1, &id);
        id = 0;
        std::cout << "[createVBO()] Data size is mismatch with input array\n";
    }
    glBindBuffer(target, 0);
    return id;
}
<|endoftext|>


<commit_before>#include "../includes/SUrlArea.hpp"
#include "../includes/SMainWindow.hpp"
#include "../includes/Actions.hpp"

SUrlArea::SUrlArea(SMainWindow * parent) :
	QProgressBar(parent),
	m_parent(parent)
{
	QHBoxLayout* layout{ new QHBoxLayout(this) };
	layout->setContentsMargins(0, 0, 0, 0);
	layout->setSpacing(0);

	m_champs->setStyleSheet("background: rgba(255, 255, 255, 0)");
	m_champs->setClearButtonEnabled(true);
	layout->addWidget(m_champs);

	setTextVisible(false);

	connect(m_champs, &QLineEdit::returnPressed, this, &SUrlArea::loadUrl);
}

void SUrlArea::setText(const QString& texte)
{
	m_champs->setText(texte);
}

void SUrlArea::loadStarted()
{
	m_parent->getActions()->refreshOrStop->setIcon(QIcon(m_parent->getActions()->themePath + "stop.png"));
	m_parent->getActions()->refreshOrStop->setText("Arrter le chargement");
	connect(m_parent->getActions()->refreshOrStop, &QAction::triggered, m_parent, &SMainWindow::stop);
}

void SUrlArea::loadInProgress(int percent)
{
	setStyleSheet("QProgressBar::chunk{background-color: rgba(0, 0, 155, 0.2)}");
	setValue(percent);
}

void SUrlArea::loadFinished(bool ok)
{
	m_parent->getActions()->refreshOrStop->setIcon(QIcon(m_parent->getActions()->themePath + "refresh.png"));
	m_parent->getActions()->refreshOrStop->setText("Rafraichir la page");
	connect(m_parent->getActions()->refreshOrStop, &QAction::triggered, m_parent, &SMainWindow::refresh);
}

void SUrlArea::loadUrl()
{
	QString url{};
	if (m_champs->text().left(7) != "http://" && m_champs->text().left(8) != "https://")
		url = "https://" + m_champs->text();
	else
		url = m_champs->text();

	m_parent->currentPage()->load(QUrl(url));
}
<commit_msg>Improve web page loading by adding http and https protocol in loading verification<commit_after>#include "../includes/SUrlArea.hpp"
#include "../includes/SMainWindow.hpp"
#include "../includes/Actions.hpp"

#include <QMessageBox>

SUrlArea::SUrlArea(SMainWindow * parent) :
	QProgressBar(parent),
	m_parent(parent)
{
	QHBoxLayout* layout{ new QHBoxLayout(this) };
	layout->setContentsMargins(0, 0, 0, 0);
	layout->setSpacing(0);

	m_champs->setStyleSheet("background: rgba(255, 255, 255, 0)");
	m_champs->setClearButtonEnabled(true);
	layout->addWidget(m_champs);

	setTextVisible(false);

	connect(m_champs, &QLineEdit::returnPressed, this, &SUrlArea::loadUrl);
}

void SUrlArea::setText(const QString& texte)
{
	m_champs->setText(texte);
}

void SUrlArea::loadStarted()
{
	m_parent->getActions()->refreshOrStop->setIcon(QIcon(m_parent->getActions()->themePath + "stop.png"));
	m_parent->getActions()->refreshOrStop->setText("Arrter le chargement");
	connect(m_parent->getActions()->refreshOrStop, &QAction::triggered, m_parent, &SMainWindow::stop);

	QString url{ m_parent->currentPage()->url().toString() };
	if ((url.left(7) != "http://" && url.left(8) != "https://" && url.left(5) != "html/") && !url.isEmpty()) {
		QMessageBox warningMsgBox{ QMessageBox::Warning, tr("Site non scuris"), tr("Attention, le site sur lequel vous entrez n'est pas scuris !"), QMessageBox::Ignore | QMessageBox::Cancel, this };

		warningMsgBox.setButtonText(QMessageBox::Ignore, tr("Continuer"));
		warningMsgBox.setButtonText(QMessageBox::Cancel, tr("Retour  la scurit"));

		if (warningMsgBox.exec() == QMessageBox::Cancel)
			m_parent->back();
	}
}

void SUrlArea::loadInProgress(int percent)
{
	setStyleSheet("QProgressBar::chunk{background-color: rgba(0, 0, 155, 0.2)}");
	setValue(percent);
}

void SUrlArea::loadFinished(bool ok)
{
	m_parent->getActions()->refreshOrStop->setIcon(QIcon(m_parent->getActions()->themePath + "refresh.png"));
	m_parent->getActions()->refreshOrStop->setText("Rafraichir la page");
	connect(m_parent->getActions()->refreshOrStop, &QAction::triggered, m_parent, &SMainWindow::refresh);
}

void SUrlArea::loadUrl()
{
	QString url{};
	if (m_champs->text().left(7) != "http://" && m_champs->text().left(8) != "https://")
		url = "https://" + m_champs->text();
	else
		url = m_champs->text();

	m_parent->currentPage()->load(QUrl(url));
}
<|endoftext|>


<commit_before>#include "InjectRadiance.h"
#include "EngineShaderFactory.hpp"
#include "ShaderManager.h"
#include "ResourceManager.h"
#include "Director.h"

using namespace Device;
using namespace Core;
using namespace Rendering;
using namespace Rendering::Shadow;
using namespace Rendering::Factory;
using namespace Rendering::Manager;
using namespace Rendering::Buffer;
using namespace Rendering::GI;
using namespace Rendering::Shader;
using namespace GPGPU::DirectCompute;
using namespace Resource;

InjectRadiance::InjectRadiance() : _shader(nullptr)
{
}

InjectRadiance::~InjectRadiance()
{
	SAFE_DELETE(_shader);
}

void InjectRadiance::Initialize(const std::string& fileName, const InitParam& param)
{
	ASSERT_COND_MSG(param.IsValid(),		"Error,  Param is invalid.");

	std::string filePath = "";
	EngineFactory pathFinder(nullptr);
	pathFinder.FetchShaderFullPath(filePath, fileName);

	ASSERT_COND_MSG(filePath.empty() == false, "Error, File path is empty!");

	ResourceManager* resourceManager = ResourceManager::SharedInstance();
	auto shaderMgr = resourceManager->GetShaderManager();

	std::vector<ShaderMacro> macros;
	{
		//  Ϲ Shadow Map ؾϱ  Ʒ ũθ ߰ش.
		macros.push_back(ShaderMacro("NEVER_USE_VSM", ""));
	}

	ID3DBlob* blob = shaderMgr->CreateBlob(filePath, "cs", "CS", false, &macros);
	_shader = new ComputeShader(ComputeShader::ThreadGroup(0, 0, 0), blob);
	ASSERT_COND_MSG(_shader->Initialize(), "can not create compute shader");

	// Setting Inputs
	{
		const Scene* curScene			= Director::SharedInstance()->GetCurrentScene();
		const ShadowRenderer* shadowMgr	= curScene->GetShadowManager();

		std::vector<ShaderForm::InputConstBuffer> inputConstBuffers;
		{
			inputConstBuffers.push_back(ShaderForm::InputConstBuffer(uint(ConstBufferBindIndex::ShadowGlobalParam),				shadowMgr->GetShadowGlobalParamConstBuffer()));
			inputConstBuffers.push_back(ShaderForm::InputConstBuffer(uint(ConstBufferBindIndex::GlobalIIllumination_InfoCB),	param.giInfoConstBuffer));
		}
		_shader->SetInputConstBuffers(inputConstBuffers);

		std::vector<ShaderForm::InputTexture> inputTextures;
		{
			inputTextures.push_back(ShaderForm::InputTexture(uint(TextureBindIndex::AnisotropicVoxelAlbedoTexture),				param.voxelization->GetAnisotropicVoxelAlbedoMapAtlas()));
			inputTextures.push_back(ShaderForm::InputTexture(uint(TextureBindIndex::AnisotropicVoxelNormalTexture),				param.voxelization->GetAnisotropicVoxelNormalMapAtlas()));
			inputTextures.push_back(ShaderForm::InputTexture(uint(TextureBindIndex::AnisotropicVoxelEmissionTexture),			param.voxelization->GetAnisotropicVoxelEmissionMapAtlas()));
		}
		_shader->SetInputTextures(inputTextures);
	}

	uint dimension = 1 << param.globalInfo->voxelDimensionPow2;

	// Setting Output
	{
		std::vector<ShaderForm::InputUnorderedAccessView> outputs;
		{
			outputs.push_back(ShaderForm::InputUnorderedAccessView(uint(UAVBindIndex::OutAnisotropicVoxelColorTexture),			param.outColorMap->GetSourceMapUAV()));
		}

		_shader->SetUAVs(outputs);
	}
}

void InjectRadiance::Dispath(const Device::DirectX* dx, const std::vector<Buffer::ConstBuffer*>& voxelizationInfoConstBuffers)
{
	ID3D11DeviceContext* context = dx->GetContext();

	for(auto iter = voxelizationInfoConstBuffers.begin(); iter != voxelizationInfoConstBuffers.end(); ++iter)
	{
		ID3D11Buffer* cb = (*iter)->GetBuffer();
		context->CSSetConstantBuffers(uint(ConstBufferBindIndex::Voxelization_InfoCB), 1, &cb);
		_shader->Dispatch(context);
	}

	//ID3D11Buffer* cb = nullptr;
	//context->CSSetConstantBuffers(uint(ConstBufferBindIndex::Voxelization_InfoCB), 1, &cb);
}

void InjectRadiance::Destroy()
{
}<commit_msg>InjectRadiance - 중복 매크로 설정 제거<commit_after>#include "InjectRadiance.h"
#include "EngineShaderFactory.hpp"
#include "ShaderManager.h"
#include "ResourceManager.h"
#include "Director.h"

using namespace Device;
using namespace Core;
using namespace Rendering;
using namespace Rendering::Shadow;
using namespace Rendering::Factory;
using namespace Rendering::Manager;
using namespace Rendering::Buffer;
using namespace Rendering::GI;
using namespace Rendering::Shader;
using namespace GPGPU::DirectCompute;
using namespace Resource;

InjectRadiance::InjectRadiance() : _shader(nullptr)
{
}

InjectRadiance::~InjectRadiance()
{
	SAFE_DELETE(_shader);
}

void InjectRadiance::Initialize(const std::string& fileName, const InitParam& param)
{
	ASSERT_COND_MSG(param.IsValid(),		"Error,  Param is invalid.");

	std::string filePath = "";
	EngineFactory pathFinder(nullptr);
	pathFinder.FetchShaderFullPath(filePath, fileName);

	ASSERT_COND_MSG(filePath.empty() == false, "Error, File path is empty!");

	ResourceManager* resourceManager = ResourceManager::SharedInstance();
	auto shaderMgr = resourceManager->GetShaderManager();

	ID3DBlob* blob = shaderMgr->CreateBlob(filePath, "cs", "CS", false, nullptr);
	_shader = new ComputeShader(ComputeShader::ThreadGroup(0, 0, 0), blob);
	ASSERT_COND_MSG(_shader->Initialize(), "can not create compute shader");

	// Setting Inputs
	{
		const Scene* curScene			= Director::SharedInstance()->GetCurrentScene();
		const ShadowRenderer* shadowMgr	= curScene->GetShadowManager();

		std::vector<ShaderForm::InputConstBuffer> inputConstBuffers;
		{
			inputConstBuffers.push_back(ShaderForm::InputConstBuffer(uint(ConstBufferBindIndex::ShadowGlobalParam),				shadowMgr->GetShadowGlobalParamConstBuffer()));
			inputConstBuffers.push_back(ShaderForm::InputConstBuffer(uint(ConstBufferBindIndex::GlobalIIllumination_InfoCB),	param.giInfoConstBuffer));
		}
		_shader->SetInputConstBuffers(inputConstBuffers);

		std::vector<ShaderForm::InputTexture> inputTextures;
		{
			inputTextures.push_back(ShaderForm::InputTexture(uint(TextureBindIndex::AnisotropicVoxelAlbedoTexture),				param.voxelization->GetAnisotropicVoxelAlbedoMapAtlas()));
			inputTextures.push_back(ShaderForm::InputTexture(uint(TextureBindIndex::AnisotropicVoxelNormalTexture),				param.voxelization->GetAnisotropicVoxelNormalMapAtlas()));
			inputTextures.push_back(ShaderForm::InputTexture(uint(TextureBindIndex::AnisotropicVoxelEmissionTexture),			param.voxelization->GetAnisotropicVoxelEmissionMapAtlas()));
		}
		_shader->SetInputTextures(inputTextures);
	}

	uint dimension = 1 << param.globalInfo->voxelDimensionPow2;

	// Setting Output
	{
		std::vector<ShaderForm::InputUnorderedAccessView> outputs;
		{
			outputs.push_back(ShaderForm::InputUnorderedAccessView(uint(UAVBindIndex::OutAnisotropicVoxelColorTexture),			param.outColorMap->GetSourceMapUAV()));
		}

		_shader->SetUAVs(outputs);
	}
}

void InjectRadiance::Dispath(const Device::DirectX* dx, const std::vector<Buffer::ConstBuffer*>& voxelizationInfoConstBuffers)
{
	ID3D11DeviceContext* context = dx->GetContext();

	for(auto iter = voxelizationInfoConstBuffers.begin(); iter != voxelizationInfoConstBuffers.end(); ++iter)
	{
		ID3D11Buffer* cb = (*iter)->GetBuffer();
		context->CSSetConstantBuffers(uint(ConstBufferBindIndex::Voxelization_InfoCB), 1, &cb);
		_shader->Dispatch(context);
	}

	//ID3D11Buffer* cb = nullptr;
	//context->CSSetConstantBuffers(uint(ConstBufferBindIndex::Voxelization_InfoCB), 1, &cb);
}

void InjectRadiance::Destroy()
{
}<|endoftext|>


<commit_before>// ScriptOp.cpp
/*
 * Copyright (c) 2010, Dan Heeks
 * This program is released under the BSD license. See the file COPYING for
 * details.
 */

#include "stdafx.h"
#include <TopoDS_Edge.hxx>
#include "ScriptOp.h"
#include "ProgramCanvas.h"
#include "Program.h"
#include "interface/HeeksObj.h"
#include "tinyxml/tinyxml.h"
#include "PythonStuff.h"
#include "MachineState.h"

#include <sstream>
#include <iomanip>

#include <BRepAdaptor_Curve.hxx>
#include <gp_Circ.hxx>
#include <BRepTools.hxx>
#include <BRep_Tool.hxx>
#include <BRepMesh.hxx>
#include <Poly_Polygon3D.hxx>

CScriptOp::CScriptOp( const CScriptOp & rhs ) : COp(rhs)
{
	m_str = rhs.m_str;
}

CScriptOp & CScriptOp::operator= ( const CScriptOp & rhs )
{
	if (this != &rhs)
	{
		COp::operator=( rhs );
		m_str = rhs.m_str;
	}

	return(*this);
}

const wxBitmap &CScriptOp::GetIcon()
{
	if(!m_active)return GetInactiveIcon();
	static wxBitmap* icon = NULL;
	if(icon == NULL)icon = new wxBitmap(wxImage(theApp.GetResFolder() + _T("/icons/scriptop.png")));
	return *icon;
}

/* static */ Python CScriptOp::OpenCamLibDefinition(TopoDS_Edge edge)
{
    Python python;

	BRepAdaptor_Curve curve(edge);
	switch (curve.GetType())
	{
		case GeomAbs_Line:
		{
			CNCPoint PS;
			gp_Vec VS;
			curve.D1(curve.FirstParameter(), PS, VS);
			CNCPoint PE;
			gp_Vec VE;
			curve.D1(curve.LastParameter(), PE, VE);

			python << _T("ocl.Line(ocl.Point(") << PS.X(false) << _T(",") << PS.Y(false) << _T(",") << PS.Z(false) << _T("), ")
					<< _T("ocl.Point(") << PE.X(false) << _T(",") << PE.Y(false) << _T(",") << PE.Z(false) << _T("))");
		}
		break;

		case GeomAbs_Circle:
		{
			CNCPoint PS;
			gp_Vec VS;
			curve.D1(curve.FirstParameter(), PS, VS);
			CNCPoint PE;
			gp_Vec VE;
			curve.D1(curve.LastParameter(), PE, VE);
			gp_Circ circle = curve.Circle();

            // Arc towards PE
            CNCPoint point(PE);
            CNCPoint centre( circle.Location() );
            bool l_bClockwise = (circle.Axis().Direction().Z() <= 0);

			python << _T("ocl.Arc(")
					<< _T("ocl.Point(") << PS.X(false) << _T(",") << PS.Y(false) << _T(",") << PS.Z(false) << _T("),") // Start
					<< _T("ocl.Point(") << PE.X(false) << _T(",") << PE.Y(false) << _T(",") << PE.Z(false) << _T("),") // End
					<< _T("ocl.Point(") << centre.X(false) << _T(",") << centre.Y(false) << _T(",") << centre.Z(false) << _T("),") // Centre
					<< (l_bClockwise?_T("True"):_T("False")) << _T(")"); // Direction
			break;
		}

		default:
		{
			// make lots of small lines
			gp_Pnt PS;
			gp_Vec VS;
			curve.D1(curve.FirstParameter(), PS, VS);
			gp_Pnt PE;
			gp_Vec VE;
			curve.D1(curve.LastParameter(), PE, VE);

			BRepTools::Clean(edge);
			double max_deviation_for_spline_to_arc = 0.001;
			BRepMesh::Mesh(edge, max_deviation_for_spline_to_arc);

			TopLoc_Location L;
			Handle(Poly_Polygon3D) Polyg = BRep_Tool::Polygon3D(edge, L);
			if (!Polyg.IsNull()) {
				const TColgp_Array1OfPnt& Points = Polyg->Nodes();
				Standard_Integer po;
				int i = 0;
				std::list<CNCPoint> interpolated_points;
				python << _T("ocl.Path(");
				CNCPoint previous;
				for (po = Points.Lower(); po <= Points.Upper(); po++, i++) {
					CNCPoint p = (Points.Value(po)).Transformed(L);
					interpolated_points.push_back(p);

					if (interpolated_points.size() == 1)
					{
						previous = p;
					}
					else
					{
						python << _T("ocl.Line(")
								<< _T("ocl.Point(") << previous.X(false) << _T(",") << previous.Y(false) << _T(",") << previous.Z(false) << _T(")")
								<< _T("ocl.Point(") << p.X(false) << _T(",") << p.Y(false) << _T(",") << p.Z(false) << _T(")")
								<< _T(")");
					}
				} // End for
				python << _T(")");	// End ocl.Path() definition
			} // End if - then
		}
		break;
	} // End switch

	return(python);
}

/**
	This method sorts and traverses the list of TopoDS_Edge objects arranging them into
	vectors of connected edges.  It also ensures that each edge's definition is swapped
	around so that moving from the edge's FirstParameter() to its LastParameter() correctly
	sets up the tool's location to start machining the next edge in the connected series.

	The resultant array of connected edge sequences should allow all edges in each sequence
	to be machined 'at depth'.
 */
/* static */ std::vector< std::vector<TopoDS_Edge> > CScriptOp::AggregateConnectedEdges( std::vector<TopoDS_Edge> & edges )
{
	std::vector<TopoDS_Edge> all_edges;
	std::copy( edges.begin(), edges.end(), std::inserter( all_edges, all_edges.begin() ));

	typedef std::vector<TopoDS_Edge> Series_t;
	typedef std::vector< Series_t > Chains_t;
	Chains_t chains;

/*
	while (all_edges.size() > 0)
	{
        Series_t used;
        for (Series_t::iterator itEdge = all_edges.begin(); itEdge != all_edges.end(); itEdge++)
        {
            if (used.size() == 0)
            {
                used.push_back(*itEdge);
            }
            else
            {
                // See if this edge connects with either end of the 'used' series.
                if (GetStart(
            }
        } // End for
	} // End while
*/

	return(chains);

} // End AggregateConnectedEdges() method

/**
    This method converts the list of objects into a set of nested classes that
    describe the geometry.  These classes will include definitions of these objects
    in terms of lines, arcs and points.  Any BSpline (or other) objects that are
 */
/* static */ Python CScriptOp::OpenCamLibDefinition(std::list<HeeksObj *> objects, Python object_title )
{
    Python python;

	if (objects.size() > 0)
	{
		python << _T("class ") << object_title << _T(":\n");

		python << _T("\tsketches = []\n");
		python << _T("\tpoints = []\n");
	}

    for (std::list<HeeksObj *>::iterator itObject = objects.begin(); itObject != objects.end(); itObject++)
    {
		std::vector<TopoDS_Edge> edges;
		switch ((*itObject)->GetType())
		{
		case PointType:
			double p[3];
			memset( p, 0, sizeof(p) );
			heeksCAD->VertexGetPoint( *itObject, p );
			python << _T("\tpoints.append(ocl.Point(") << p[0] << _T(",") << p[1] << _T(",") << p[2] << _T("))\n");
			break;

		case SketchType:
			if (! heeksCAD->ConvertSketchToEdges( *itObject, edges ))
			{
				Python empty;
				return(empty);
			}
			else
			{
				// The edges will already have been sorted.  We need to traverse them in order and separate
				// connected sequences of them.  As we start new connected sequences, we should check to see
				// if they connect back to their beginning and mark them as 'periodic'.
				if (edges.size() > 0)
				{
					python << _T("\tsketch_id_") << (int) (*itObject)->m_id << _T(" = ocl.Path()\n");
				}

				for (std::vector<TopoDS_Edge>::size_type offset = 0; offset < edges.size(); offset++)
				{
					python << _T("\tsketch_id_") << (int) (*itObject)->m_id << _T(".append(") << OpenCamLibDefinition(edges[offset]) << _T(")\n");
				}

				if (edges.size() > 0)
				{
					python << _T("\tsketches.append(")
							<< _T("sketch_id_") << (int) (*itObject)->m_id << _T(")\n");
				}
			} // End if - else
			break;
		} // End switch
    } // End for

    return(python);

}

Python CScriptOp::AppendTextToProgram(CMachineState *pMachineState)
{
	Python python;

	std::list<HeeksObj *> children;
	for (HeeksObj *child = GetFirstChild(); child != NULL; child = GetNextChild())
	{
	    children.push_back(child);
	}

	Python object_title;
	object_title << _T("script_op_id_") << (int) this->m_id;

	python << OpenCamLibDefinition(children, object_title);
	python << _T("\n");
	python << _T("graphics = ") << object_title << _T("()\n\n");

	python << m_str.c_str();

	if(python.Last() != _T('\n'))python.Append(_T('\n'));

	return python;
} // End AppendTextToProgram() method

ObjectCanvas* CScriptOp::GetDialog(wxWindow* parent)
{
	static TextCanvas* object_canvas = NULL;
	if(object_canvas == NULL)object_canvas = new TextCanvas(parent, &m_str);
	else
	{
		object_canvas->m_str = &m_str;
		object_canvas->SetWithObject(this);
	}
	return object_canvas;
}

HeeksObj *CScriptOp::MakeACopy(void)const
{
	return new CScriptOp(*this);
}

void CScriptOp::CopyFrom(const HeeksObj* object)
{
	if (object->GetType() == GetType())
	{
		operator=(*((CScriptOp*)object));
	}
}

bool CScriptOp::CanAddTo(HeeksObj* owner)
{
	return ((owner != NULL) && (owner->GetType() == OperationsType));
}

void CScriptOp::WriteXML(TiXmlNode *root)
{
	TiXmlElement * element = new TiXmlElement( "ScriptOp" );
	root->LinkEndChild( element );
	element->SetAttribute("script", Ttc(m_str.c_str()));

	COp::WriteBaseXML(element);
}

// static member function
HeeksObj* CScriptOp::ReadFromXMLElement(TiXmlElement* element)
{
	CScriptOp* new_object = new CScriptOp;

	new_object->m_str = wxString(Ctt(element->Attribute("script")));

	// read common parameters
	new_object->ReadBaseXML(element);

	return new_object;
}

bool CScriptOp::operator==( const CScriptOp & rhs ) const
{
	if (m_str != rhs.m_str) return(false);

	return(COp::operator==(rhs));
}
<commit_msg>Fixed bug when the ScriptOp does not contain children<commit_after>// ScriptOp.cpp
/*
 * Copyright (c) 2010, Dan Heeks
 * This program is released under the BSD license. See the file COPYING for
 * details.
 */

#include "stdafx.h"
#include <TopoDS_Edge.hxx>
#include "ScriptOp.h"
#include "ProgramCanvas.h"
#include "Program.h"
#include "interface/HeeksObj.h"
#include "tinyxml/tinyxml.h"
#include "PythonStuff.h"
#include "MachineState.h"

#include <sstream>
#include <iomanip>

#include <BRepAdaptor_Curve.hxx>
#include <gp_Circ.hxx>
#include <BRepTools.hxx>
#include <BRep_Tool.hxx>
#include <BRepMesh.hxx>
#include <Poly_Polygon3D.hxx>

CScriptOp::CScriptOp( const CScriptOp & rhs ) : COp(rhs)
{
	m_str = rhs.m_str;
}

CScriptOp & CScriptOp::operator= ( const CScriptOp & rhs )
{
	if (this != &rhs)
	{
		COp::operator=( rhs );
		m_str = rhs.m_str;
	}

	return(*this);
}

const wxBitmap &CScriptOp::GetIcon()
{
	if(!m_active)return GetInactiveIcon();
	static wxBitmap* icon = NULL;
	if(icon == NULL)icon = new wxBitmap(wxImage(theApp.GetResFolder() + _T("/icons/scriptop.png")));
	return *icon;
}

/* static */ Python CScriptOp::OpenCamLibDefinition(TopoDS_Edge edge)
{
    Python python;

	BRepAdaptor_Curve curve(edge);
	switch (curve.GetType())
	{
		case GeomAbs_Line:
		{
			CNCPoint PS;
			gp_Vec VS;
			curve.D1(curve.FirstParameter(), PS, VS);
			CNCPoint PE;
			gp_Vec VE;
			curve.D1(curve.LastParameter(), PE, VE);

			python << _T("ocl.Line(ocl.Point(") << PS.X(false) << _T(",") << PS.Y(false) << _T(",") << PS.Z(false) << _T("), ")
					<< _T("ocl.Point(") << PE.X(false) << _T(",") << PE.Y(false) << _T(",") << PE.Z(false) << _T("))");
		}
		break;

		case GeomAbs_Circle:
		{
			CNCPoint PS;
			gp_Vec VS;
			curve.D1(curve.FirstParameter(), PS, VS);
			CNCPoint PE;
			gp_Vec VE;
			curve.D1(curve.LastParameter(), PE, VE);
			gp_Circ circle = curve.Circle();

            // Arc towards PE
            CNCPoint point(PE);
            CNCPoint centre( circle.Location() );
            bool l_bClockwise = (circle.Axis().Direction().Z() <= 0);

			python << _T("ocl.Arc(")
					<< _T("ocl.Point(") << PS.X(false) << _T(",") << PS.Y(false) << _T(",") << PS.Z(false) << _T("),") // Start
					<< _T("ocl.Point(") << PE.X(false) << _T(",") << PE.Y(false) << _T(",") << PE.Z(false) << _T("),") // End
					<< _T("ocl.Point(") << centre.X(false) << _T(",") << centre.Y(false) << _T(",") << centre.Z(false) << _T("),") // Centre
					<< (l_bClockwise?_T("True"):_T("False")) << _T(")"); // Direction
			break;
		}

		default:
		{
			// make lots of small lines
			gp_Pnt PS;
			gp_Vec VS;
			curve.D1(curve.FirstParameter(), PS, VS);
			gp_Pnt PE;
			gp_Vec VE;
			curve.D1(curve.LastParameter(), PE, VE);

			BRepTools::Clean(edge);
			double max_deviation_for_spline_to_arc = 0.001;
			BRepMesh::Mesh(edge, max_deviation_for_spline_to_arc);

			TopLoc_Location L;
			Handle(Poly_Polygon3D) Polyg = BRep_Tool::Polygon3D(edge, L);
			if (!Polyg.IsNull()) {
				const TColgp_Array1OfPnt& Points = Polyg->Nodes();
				Standard_Integer po;
				int i = 0;
				std::list<CNCPoint> interpolated_points;
				python << _T("ocl.Path(");
				CNCPoint previous;
				for (po = Points.Lower(); po <= Points.Upper(); po++, i++) {
					CNCPoint p = (Points.Value(po)).Transformed(L);
					interpolated_points.push_back(p);

					if (interpolated_points.size() == 1)
					{
						previous = p;
					}
					else
					{
						python << _T("ocl.Line(")
								<< _T("ocl.Point(") << previous.X(false) << _T(",") << previous.Y(false) << _T(",") << previous.Z(false) << _T(")")
								<< _T("ocl.Point(") << p.X(false) << _T(",") << p.Y(false) << _T(",") << p.Z(false) << _T(")")
								<< _T(")");
					}
				} // End for
				python << _T(")");	// End ocl.Path() definition
			} // End if - then
		}
		break;
	} // End switch

	return(python);
}

/**
	This method sorts and traverses the list of TopoDS_Edge objects arranging them into
	vectors of connected edges.  It also ensures that each edge's definition is swapped
	around so that moving from the edge's FirstParameter() to its LastParameter() correctly
	sets up the tool's location to start machining the next edge in the connected series.

	The resultant array of connected edge sequences should allow all edges in each sequence
	to be machined 'at depth'.
 */
/* static */ std::vector< std::vector<TopoDS_Edge> > CScriptOp::AggregateConnectedEdges( std::vector<TopoDS_Edge> & edges )
{
	std::vector<TopoDS_Edge> all_edges;
	std::copy( edges.begin(), edges.end(), std::inserter( all_edges, all_edges.begin() ));

	typedef std::vector<TopoDS_Edge> Series_t;
	typedef std::vector< Series_t > Chains_t;
	Chains_t chains;

/*
	while (all_edges.size() > 0)
	{
        Series_t used;
        for (Series_t::iterator itEdge = all_edges.begin(); itEdge != all_edges.end(); itEdge++)
        {
            if (used.size() == 0)
            {
                used.push_back(*itEdge);
            }
            else
            {
                // See if this edge connects with either end of the 'used' series.
                if (GetStart(
            }
        } // End for
	} // End while
*/

	return(chains);

} // End AggregateConnectedEdges() method

/**
    This method converts the list of objects into a set of nested classes that
    describe the geometry.  These classes will include definitions of these objects
    in terms of lines, arcs and points.  Any BSpline (or other) objects that are
 */
/* static */ Python CScriptOp::OpenCamLibDefinition(std::list<HeeksObj *> objects, Python object_title )
{
    Python python;

	if (objects.size() > 0)
	{
		python << _T("class ") << object_title << _T(":\n");

		python << _T("\tsketches = []\n");
		python << _T("\tpoints = []\n");
	}

    for (std::list<HeeksObj *>::iterator itObject = objects.begin(); itObject != objects.end(); itObject++)
    {
		std::vector<TopoDS_Edge> edges;
		switch ((*itObject)->GetType())
		{
		case PointType:
			double p[3];
			memset( p, 0, sizeof(p) );
			heeksCAD->VertexGetPoint( *itObject, p );
			python << _T("\tpoints.append(ocl.Point(") << p[0] << _T(",") << p[1] << _T(",") << p[2] << _T("))\n");
			break;

		case SketchType:
			if (! heeksCAD->ConvertSketchToEdges( *itObject, edges ))
			{
				Python empty;
				return(empty);
			}
			else
			{
				// The edges will already have been sorted.  We need to traverse them in order and separate
				// connected sequences of them.  As we start new connected sequences, we should check to see
				// if they connect back to their beginning and mark them as 'periodic'.
				if (edges.size() > 0)
				{
					python << _T("\tsketch_id_") << (int) (*itObject)->m_id << _T(" = ocl.Path()\n");
				}

				for (std::vector<TopoDS_Edge>::size_type offset = 0; offset < edges.size(); offset++)
				{
					python << _T("\tsketch_id_") << (int) (*itObject)->m_id << _T(".append(") << OpenCamLibDefinition(edges[offset]) << _T(")\n");
				}

				if (edges.size() > 0)
				{
					python << _T("\tsketches.append(")
							<< _T("sketch_id_") << (int) (*itObject)->m_id << _T(")\n");
				}
			} // End if - else
			break;
		} // End switch
    } // End for

    return(python);

}

Python CScriptOp::AppendTextToProgram(CMachineState *pMachineState)
{
	Python python;

	std::list<HeeksObj *> children;
	for (HeeksObj *child = GetFirstChild(); child != NULL; child = GetNextChild())
	{
	    children.push_back(child);
	}

    if (children.size() > 0)
    {
        Python object_title;
        object_title << _T("script_op_id_") << (int) this->m_id;

        python << OpenCamLibDefinition(children, object_title);
        python << _T("\n");
        python << _T("graphics = ") << object_title << _T("()\n\n");
    }

	python << m_str.c_str();

	if(python.Last() != _T('\n'))python.Append(_T('\n'));

	return python;
} // End AppendTextToProgram() method

ObjectCanvas* CScriptOp::GetDialog(wxWindow* parent)
{
	static TextCanvas* object_canvas = NULL;
	if(object_canvas == NULL)object_canvas = new TextCanvas(parent, &m_str);
	else
	{
		object_canvas->m_str = &m_str;
		object_canvas->SetWithObject(this);
	}
	return object_canvas;
}

HeeksObj *CScriptOp::MakeACopy(void)const
{
	return new CScriptOp(*this);
}

void CScriptOp::CopyFrom(const HeeksObj* object)
{
	if (object->GetType() == GetType())
	{
		operator=(*((CScriptOp*)object));
	}
}

bool CScriptOp::CanAddTo(HeeksObj* owner)
{
	return ((owner != NULL) && (owner->GetType() == OperationsType));
}

void CScriptOp::WriteXML(TiXmlNode *root)
{
	TiXmlElement * element = new TiXmlElement( "ScriptOp" );
	root->LinkEndChild( element );
	element->SetAttribute("script", Ttc(m_str.c_str()));

	COp::WriteBaseXML(element);
}

// static member function
HeeksObj* CScriptOp::ReadFromXMLElement(TiXmlElement* element)
{
	CScriptOp* new_object = new CScriptOp;

	new_object->m_str = wxString(Ctt(element->Attribute("script")));

	// read common parameters
	new_object->ReadBaseXML(element);

	return new_object;
}

bool CScriptOp::operator==( const CScriptOp & rhs ) const
{
	if (m_str != rhs.m_str) return(false);

	return(COp::operator==(rhs));
}
<|endoftext|>


<commit_before>// texture.hpp
// OpenGL texture classes

// Copyright 2015 Matthew Chandler

// 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, sublicense, 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 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 NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS 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 TEXTURE_HPP
#define TEXTURE_HPP

#include <string>
#include <memory>
#include <unordered_map>
#include <vector>

#include <glm/glm.hpp>

#include <GL/glew.h>

#include <SFML/OpenGL.hpp>
#include <SFML/System.hpp>

class Texture: public sf::NonCopyable
{
public:
    virtual ~Texture();
    virtual void bind() const = 0;
    GLuint get_id() const;

protected:
    Texture();
    virtual void set_properties() const = 0;

    GLuint _texid;
    std::string _key;
};

class Texture_2D final: public Texture
{
public:
    static std::shared_ptr<Texture_2D> create(const std::string & filename);
    static std::shared_ptr<Texture_2D> white_fallback();
    static std::shared_ptr<Texture_2D> black_fallback();
    static std::shared_ptr<Texture_2D> missing_fallback();
    static std::shared_ptr<Texture_2D> normal_map_fallback();
    void bind() const override;

private:
    Texture_2D(const std::string & filename);
    Texture_2D(const std::vector<glm::vec4> & data, const GLint width, const GLint height);
    Texture_2D(const glm::vec4 & color, const GLint width, const GLint height);
    void set_properties() const override;
};

class Texture_cubemap final: public Texture
{
public:
    static std::shared_ptr<Texture_cubemap> create(const std::string & left_fname, const std::string & right_fname,
        const std::string & back_fname, const std::string & front_fname,
        const std::string & down_fname, const std::string & up_fname);
    static std::shared_ptr<Texture_cubemap> env_fallback();
    void bind() const override;

private:
    Texture_cubemap(const std::string & left_fname, const std::string & right_fname,
        const std::string & back_fname, const std::string & front_fname,
        const std::string & down_fname, const std::string & up_fname);
    Texture_cubemap(const glm::vec4 & color, const GLint width, const GLint height);
    void set_properties() const override;

};

struct Texture_cache
{
    std::unordered_map<std::string, std::shared_ptr<Texture>> allocated_tex;

    std::shared_ptr<Texture_2D> white_fallback;
    std::shared_ptr<Texture_2D> black_fallback;
    std::shared_ptr<Texture_2D> missing_fallback;
    std::shared_ptr<Texture_2D> normal_map_fallback;

    std::shared_ptr<Texture_cubemap> env_fallback;
};

class Texture_cache_locator
{
public:
    Texture_cache_locator() = delete;
    ~Texture_cache_locator() = delete;

    static void init(std::shared_ptr<Texture_cache> cache = std::make_shared<Texture_cache>());
    static Texture_cache & get();

private:
    static std::shared_ptr<Texture_cache> _cache;
};

#endif // TEXTURE_HPP
<commit_msg>add default texture ctor<commit_after>// texture.hpp
// OpenGL texture classes

// Copyright 2015 Matthew Chandler

// 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, sublicense, 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 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 NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS 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 TEXTURE_HPP
#define TEXTURE_HPP

#include <string>
#include <memory>
#include <unordered_map>
#include <vector>

#include <glm/glm.hpp>

#include <GL/glew.h>

#include <SFML/OpenGL.hpp>
#include <SFML/System.hpp>

class Texture: public sf::NonCopyable
{
public:
    virtual ~Texture();
    virtual void bind() const = 0;
    GLuint get_id() const;

protected:
    Texture();
    virtual void set_properties() const = 0;

    GLuint _texid;
    std::string _key;
};

class Texture_2D final: public Texture
{
public:
    Texture_2D() = default;
    static std::shared_ptr<Texture_2D> create(const std::string & filename);
    static std::shared_ptr<Texture_2D> white_fallback();
    static std::shared_ptr<Texture_2D> black_fallback();
    static std::shared_ptr<Texture_2D> missing_fallback();
    static std::shared_ptr<Texture_2D> normal_map_fallback();
    void bind() const override;

private:
    explicit Texture_2D(const std::string & filename);
    Texture_2D(const std::vector<glm::vec4> & data, const GLint width, const GLint height);
    Texture_2D(const glm::vec4 & color, const GLint width, const GLint height);
    void set_properties() const override;
};

class Texture_cubemap final: public Texture
{
public:
    Texture_cubemap() = default;
    static std::shared_ptr<Texture_cubemap> create(const std::string & left_fname, const std::string & right_fname,
        const std::string & back_fname, const std::string & front_fname,
        const std::string & down_fname, const std::string & up_fname);
    static std::shared_ptr<Texture_cubemap> env_fallback();
    void bind() const override;

private:
    Texture_cubemap(const std::string & left_fname, const std::string & right_fname,
        const std::string & back_fname, const std::string & front_fname,
        const std::string & down_fname, const std::string & up_fname);
    Texture_cubemap(const glm::vec4 & color, const GLint width, const GLint height);
    void set_properties() const override;

};

struct Texture_cache
{
    std::unordered_map<std::string, std::shared_ptr<Texture>> allocated_tex;

    std::shared_ptr<Texture_2D> white_fallback;
    std::shared_ptr<Texture_2D> black_fallback;
    std::shared_ptr<Texture_2D> missing_fallback;
    std::shared_ptr<Texture_2D> normal_map_fallback;

    std::shared_ptr<Texture_cubemap> env_fallback;
};

class Texture_cache_locator
{
public:
    Texture_cache_locator() = delete;
    ~Texture_cache_locator() = delete;

    static void init(std::shared_ptr<Texture_cache> cache = std::make_shared<Texture_cache>());
    static Texture_cache & get();

private:
    static std::shared_ptr<Texture_cache> _cache;
};

#endif // TEXTURE_HPP
<|endoftext|>