diff options
author | Vincent Lejeune <[email protected]> | 2012-09-06 22:45:38 +0200 |
---|---|---|
committer | Vincent Lejeune <[email protected]> | 2012-09-22 18:12:11 +0200 |
commit | fb40f88338b6af23faae03ced5906add8507db26 (patch) | |
tree | 66ea066cc61a464be7bfaf835afed48f4cdb80f8 /src/gallium/drivers/radeon/R600ISelLowering.cpp | |
parent | 2988fa940e1d8a4531fddff4d554eec1e6e04474 (diff) |
radeon/llvm: support for interpolation intrinsics
Reviewed-by: Tom Stellard <[email protected]>
Diffstat (limited to 'src/gallium/drivers/radeon/R600ISelLowering.cpp')
-rw-r--r-- | src/gallium/drivers/radeon/R600ISelLowering.cpp | 88 |
1 files changed, 87 insertions, 1 deletions
diff --git a/src/gallium/drivers/radeon/R600ISelLowering.cpp b/src/gallium/drivers/radeon/R600ISelLowering.cpp index 6dded2fec37..2fc9c6708ef 100644 --- a/src/gallium/drivers/radeon/R600ISelLowering.cpp +++ b/src/gallium/drivers/radeon/R600ISelLowering.cpp @@ -44,6 +44,7 @@ R600TargetLowering::R600TargetLowering(TargetMachine &TM) : setOperationAction(ISD::INTRINSIC_VOID, MVT::Other, Custom); setOperationAction(ISD::INTRINSIC_WO_CHAIN, MVT::Other, Custom); + setOperationAction(ISD::INTRINSIC_WO_CHAIN, MVT::i1, Custom); setOperationAction(ISD::ROTL, MVT::i32, Custom); @@ -240,6 +241,29 @@ MachineBasicBlock * R600TargetLowering::EmitInstrWithCustomInserter( .addReg(AMDGPU::PREDICATE_BIT, RegState::Kill); break; } + case AMDGPU::input_perspective: + { + R600MachineFunctionInfo *MFI = MF->getInfo<R600MachineFunctionInfo>(); + + // XXX Be more fine about register reservation + for (unsigned i = 0; i < 4; i ++) { + unsigned ReservedReg = AMDGPU::R600_TReg32RegClass.getRegister(i); + MFI->ReservedRegs.push_back(ReservedReg); + } + + switch (MI->getOperand(1).getImm()) { + case 0:// Perspective + MFI->HasPerspectiveInterpolation = true; + break; + case 1:// Linear + MFI->HasLinearInterpolation = true; + break; + default: + assert(0 && "Unknow ij index"); + } + + return BB; + } } MI->eraseFromParent(); @@ -294,7 +318,48 @@ SDValue R600TargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const unsigned Reg = AMDGPU::R600_TReg32RegClass.getRegister(RegIndex); return CreateLiveInRegister(DAG, &AMDGPU::R600_TReg32RegClass, Reg, VT); } - + case AMDGPUIntrinsic::R600_load_input_perspective: { + unsigned slot = cast<ConstantSDNode>(Op.getOperand(1))->getZExtValue(); + SDValue FullVector = DAG.getNode( + AMDGPUISD::INTERP, + DL, MVT::v4f32, + DAG.getConstant(0, MVT::i32), DAG.getConstant(slot / 4 , MVT::i32)); + return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, + DL, VT, FullVector, DAG.getConstant(slot % 4, MVT::i32)); + } + case AMDGPUIntrinsic::R600_load_input_linear: { + unsigned slot = cast<ConstantSDNode>(Op.getOperand(1))->getZExtValue(); + SDValue FullVector = DAG.getNode( + AMDGPUISD::INTERP, + DL, MVT::v4f32, + DAG.getConstant(1, MVT::i32), DAG.getConstant(slot / 4 , MVT::i32)); + return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, + DL, VT, FullVector, DAG.getConstant(slot % 4, MVT::i32)); + } + case AMDGPUIntrinsic::R600_load_input_constant: { + unsigned slot = cast<ConstantSDNode>(Op.getOperand(1))->getZExtValue(); + SDValue FullVector = DAG.getNode( + AMDGPUISD::INTERP_P0, + DL, MVT::v4f32, + DAG.getConstant(slot / 4 , MVT::i32)); + return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, + DL, VT, FullVector, DAG.getConstant(slot % 4, MVT::i32)); + } + case AMDGPUIntrinsic::R600_load_input_position: { + unsigned slot = cast<ConstantSDNode>(Op.getOperand(1))->getZExtValue(); + unsigned RegIndex = AMDGPU::R600_TReg32RegClass.getRegister(slot); + SDValue Reg = CreateLiveInRegister(DAG, &AMDGPU::R600_TReg32RegClass, + RegIndex, MVT::f32); + if ((slot % 4) == 3) { + return DAG.getNode(ISD::FDIV, + DL, VT, + DAG.getConstantFP(1.0f, MVT::f32), + Reg); + } else { + return Reg; + } + } + case r600_read_ngroups_x: return LowerImplicitParameter(DAG, VT, DL, 0); case r600_read_ngroups_y: @@ -347,9 +412,30 @@ void R600TargetLowering::ReplaceNodeResults(SDNode *N, switch (N->getOpcode()) { default: return; case ISD::FP_TO_UINT: Results.push_back(LowerFPTOUINT(N->getOperand(0), DAG)); + case ISD::INTRINSIC_WO_CHAIN: + { + unsigned IntrinsicID = + cast<ConstantSDNode>(N->getOperand(0))->getZExtValue(); + if (IntrinsicID == AMDGPUIntrinsic::R600_load_input_face) { + Results.push_back(LowerInputFace(N, DAG)); + } else { + return; + } + } } } +SDValue R600TargetLowering::LowerInputFace(SDNode* Op, SelectionDAG &DAG) const +{ + unsigned slot = cast<ConstantSDNode>(Op->getOperand(1))->getZExtValue(); + unsigned RegIndex = AMDGPU::R600_TReg32RegClass.getRegister(slot); + SDValue Reg = CreateLiveInRegister(DAG, &AMDGPU::R600_TReg32RegClass, + RegIndex, MVT::f32); + return DAG.getNode(ISD::SETCC, Op->getDebugLoc(), MVT::i1, + Reg, DAG.getConstantFP(0.0f, MVT::f32), + DAG.getCondCode(ISD::SETUGT)); +} + SDValue R600TargetLowering::LowerFPTOUINT(SDValue Op, SelectionDAG &DAG) const { return DAG.getNode( |