@@ -729,29 +729,45 @@ Value* RTBuilder::getObjRayOrig(
729729 RTBuilder::StackPointerVal* perLaneStackPtr, uint32_t dim, Value* ShaderTy,
730730 Instruction* I, bool checkInstanceLeafPtr)
731731{
732- auto * transformWorldToObject = CreateOr (
733- {
734- CreateICmpEQ (ShaderTy, getInt32 (CallableShaderTypeMD::ClosestHit)),
735- }
736- );
737- Instruction* trueTerm = nullptr ;
738- Instruction* falseTerm = nullptr ;
732+
739733 auto * IP = &*GetInsertPoint ();
740- SplitBlockAndInsertIfThenElse (transformWorldToObject, IP, &trueTerm, &falseTerm);
741734
742- SetInsertPoint (trueTerm);
735+ auto * oldBB = IP->getParent ();
736+ auto * bb = SplitBlock (oldBB, IP);
737+
738+ auto * isClosestHitBB = BasicBlock::Create (*Ctx.getLLVMContext (), VALUE_NAME (" isClosestHitBB" ), IP->getFunction (), bb);
739+ SetInsertPoint (isClosestHitBB);
740+ auto * isClosestHitBBTerm = CreateBr (bb); // we have to do this because the functions we call are going to split the block again...
741+ SetInsertPoint (isClosestHitBBTerm);
743742 auto * newI = I->clone ();
744- newI-> insertBefore (trueTerm );
745- auto * trueV = this ->TransformWorldToObject (perLaneStackPtr, dim, true , ShaderTy, newI, checkInstanceLeafPtr);
743+ Insert (newI );
744+ auto * isClosestHitV = this ->TransformWorldToObject (perLaneStackPtr, dim, true , ShaderTy, newI, checkInstanceLeafPtr);
746745 newI->eraseFromParent ();
747746
748- SetInsertPoint (falseTerm);
749- auto * falseV = getMemRayOrig (perLaneStackPtr, dim, BOTTOM_LEVEL_BVH, VALUE_NAME (" ObjRayOrig[" + Twine (dim) + " ]" ));
747+ auto * isMissBB = BasicBlock::Create (Context, VALUE_NAME (" isMissBB" ), IP->getFunction (), bb);
748+ SetInsertPoint (isMissBB);
749+ auto * isMissBBTerm = CreateBr (bb);
750+ SetInsertPoint (isMissBBTerm);
751+ auto * isMissV = getWorldRayOrig (perLaneStackPtr, dim);
752+
753+ auto * defaultBB = BasicBlock::Create (Context, VALUE_NAME (" default" ), IP->getFunction (), bb);
754+ SetInsertPoint (defaultBB);
755+ auto * defaultBBTerm = CreateBr (bb);
756+ SetInsertPoint (defaultBBTerm);
757+ auto * defaultV = getMemRayOrig (perLaneStackPtr, dim, BOTTOM_LEVEL_BVH, VALUE_NAME (" ObjRayOrig[" + Twine (dim) + " ]" ));
758+
759+ // create switch statement
760+ oldBB->getTerminator ()->eraseFromParent ();
761+ SetInsertPoint (oldBB);
762+ auto * switchI = CreateSwitch (ShaderTy, defaultBB);
763+ switchI->addCase (getInt32 (Miss), isMissBB);
764+ switchI->addCase (getInt32 (ClosestHit), isClosestHitBB);
750765
751766 SetInsertPoint (IP);
752- auto * info = CreatePHI (trueV->getType (), 2 );
753- info->addIncoming (trueV, trueTerm->getParent ());
754- info->addIncoming (falseV, falseTerm->getParent ());
767+ auto * info = CreatePHI (isClosestHitV->getType (), 3 );
768+ info->addIncoming (isClosestHitV, isClosestHitBBTerm->getParent ());
769+ info->addIncoming (isMissV, isMissBBTerm->getParent ());
770+ info->addIncoming (defaultV, defaultBBTerm->getParent ());
755771
756772 return info;
757773}
@@ -760,29 +776,45 @@ Value* RTBuilder::getObjRayDir(
760776 RTBuilder::StackPointerVal* perLaneStackPtr, uint32_t dim, Value* ShaderTy,
761777 Instruction* I, bool checkInstanceLeafPtr)
762778{
763- auto * transformWorldToObject = CreateOr (
764- {
765- CreateICmpEQ (ShaderTy, getInt32 (CallableShaderTypeMD::ClosestHit)),
766- }
767- );
768- Instruction* trueTerm = nullptr ;
769- Instruction* falseTerm = nullptr ;
779+
770780 auto * IP = &*GetInsertPoint ();
771- SplitBlockAndInsertIfThenElse (transformWorldToObject, IP, &trueTerm, &falseTerm);
772781
773- SetInsertPoint (trueTerm);
782+ auto * oldBB = IP->getParent ();
783+ auto * bb = SplitBlock (oldBB, IP);
784+
785+ auto * isClosestHitBB = BasicBlock::Create (*Ctx.getLLVMContext (), VALUE_NAME (" isClosestHitBB" ), IP->getFunction (), bb);
786+ SetInsertPoint (isClosestHitBB);
787+ auto * isClosestHitBBTerm = CreateBr (bb); // we have to do this because the functions we call are going to split the block again...
788+ SetInsertPoint (isClosestHitBBTerm);
774789 auto * newI = I->clone ();
775- newI-> insertBefore (trueTerm );
776- auto * trueV = this ->TransformWorldToObject (perLaneStackPtr, dim, false , ShaderTy, newI, checkInstanceLeafPtr);
790+ Insert (newI );
791+ auto * isClosestHitV = this ->TransformWorldToObject (perLaneStackPtr, dim, false , ShaderTy, newI, checkInstanceLeafPtr);
777792 newI->eraseFromParent ();
778793
779- SetInsertPoint (falseTerm);
780- auto * falseV = getMemRayDir (perLaneStackPtr, dim, BOTTOM_LEVEL_BVH, VALUE_NAME (" ObjRayDir[" + Twine (dim) + " ]" ));
794+ auto * isMissBB = BasicBlock::Create (Context, VALUE_NAME (" isMissBB" ), IP->getFunction (), bb);
795+ SetInsertPoint (isMissBB);
796+ auto * isMissBBTerm = CreateBr (bb);
797+ SetInsertPoint (isMissBBTerm);
798+ auto * isMissV = getWorldRayDir (perLaneStackPtr, dim);
799+
800+ auto * defaultBB = BasicBlock::Create (Context, VALUE_NAME (" default" ), IP->getFunction (), bb);
801+ SetInsertPoint (defaultBB);
802+ auto * defaultBBTerm = CreateBr (bb);
803+ SetInsertPoint (defaultBBTerm);
804+ auto * defaultV = getMemRayDir (perLaneStackPtr, dim, BOTTOM_LEVEL_BVH, VALUE_NAME (" ObjRayDir[" + Twine (dim) + " ]" ));
805+
806+ // create switch statement
807+ oldBB->getTerminator ()->eraseFromParent ();
808+ SetInsertPoint (oldBB);
809+ auto * switchI = CreateSwitch (ShaderTy, defaultBB);
810+ switchI->addCase (getInt32 (Miss), isMissBB);
811+ switchI->addCase (getInt32 (ClosestHit), isClosestHitBB);
781812
782813 SetInsertPoint (IP);
783- auto * info = CreatePHI (trueV->getType (), 2 );
784- info->addIncoming (trueV, trueTerm->getParent ());
785- info->addIncoming (falseV, falseTerm->getParent ());
814+ auto * info = CreatePHI (isClosestHitV->getType (), 3 );
815+ info->addIncoming (isClosestHitV, isClosestHitBBTerm->getParent ());
816+ info->addIncoming (isMissV, isMissBBTerm->getParent ());
817+ info->addIncoming (defaultV, defaultBBTerm->getParent ());
786818
787819 return info;
788820}
0 commit comments