From fe0fe37959ca89e8b82b09b50700ae2491529a08 Mon Sep 17 00:00:00 2001
From: Lu Jiao <lu.jiao@amd.com>
Date: Tue, 5 Dec 2023 16:38:07 +0800
Subject: [PATCH] Integrate the KernelEntry Function

Integrate the KernelEntry Function to the empty entry module
---
 llpc/lower/llpcSpirvProcessGpuRtLibrary.cpp        | 14 ++++++++++++++
 llpc/lower/llpcSpirvProcessGpuRtLibrary.h          |  1 +
 .../continuations/lib/LowerRaytracingPipeline.cpp  | 13 +++++++++++++
 3 files changed, 28 insertions(+)

diff --git a/llpc/lower/llpcSpirvProcessGpuRtLibrary.cpp b/llpc/lower/llpcSpirvProcessGpuRtLibrary.cpp
index b792e51f78..af744c0bf0 100644
--- a/llpc/lower/llpcSpirvProcessGpuRtLibrary.cpp
+++ b/llpc/lower/llpcSpirvProcessGpuRtLibrary.cpp
@@ -111,6 +111,7 @@ SpirvProcessGpuRtLibrary::LibraryFunctionTable::LibraryFunctionTable() {
   m_libFuncPtrs["_AmdContStackFree"] = &SpirvProcessGpuRtLibrary::createContStackFree;
   m_libFuncPtrs["_AmdContStackGetPtr"] = &SpirvProcessGpuRtLibrary::createContStackGetPtr;
   m_libFuncPtrs["_AmdContStackSetPtr"] = &SpirvProcessGpuRtLibrary::createContStackSetPtr;
+  m_libFuncPtrs["_AmdEnqueueRayGen"] = &SpirvProcessGpuRtLibrary::createEnqueueRayGen;
 }
 
 // =====================================================================================================================
@@ -752,4 +753,17 @@ void SpirvProcessGpuRtLibrary::createContStackStore(llvm::Function *func) {
   m_builder->CreateRetVoid();
 }
 
+// =====================================================================================================================
+// Fill in function to execute raygen shader with given address
+//
+// @param func : The function to create
+void SpirvProcessGpuRtLibrary::createEnqueueRayGen(llvm::Function *func) {
+  auto addr = m_builder->CreateLoad(m_builder->getInt64Ty(), func->getArg(0));
+  auto dispatchData = func->getArg(1);
+  auto funcPtr = m_builder->CreateIntToPtr(addr, m_builder->getPtrTy(SPIRAS_Global));
+  auto funcTy = FunctionType::get(m_builder->getVoidTy(), {dispatchData->getType()}, false);
+  m_builder->CreateCall(funcTy, funcPtr, {dispatchData});
+  m_builder->CreateRetVoid();
+}
+
 } // namespace Llpc
diff --git a/llpc/lower/llpcSpirvProcessGpuRtLibrary.h b/llpc/lower/llpcSpirvProcessGpuRtLibrary.h
index bd61a851ed..4bed37533f 100644
--- a/llpc/lower/llpcSpirvProcessGpuRtLibrary.h
+++ b/llpc/lower/llpcSpirvProcessGpuRtLibrary.h
@@ -92,6 +92,7 @@ class SpirvProcessGpuRtLibrary : public SpirvLower, public llvm::PassInfoMixin<S
   void createContStackSetPtr(llvm::Function *func);
   void createContStackLoad(llvm::Function *func);
   void createContStackStore(llvm::Function *func);
+  void createEnqueueRayGen(llvm::Function *func);
   llvm::Value *createGetBvhSrd(llvm::Value *expansion, llvm::Value *boxSortMode);
 };
 } // namespace Llpc
diff --git a/shared/continuations/lib/LowerRaytracingPipeline.cpp b/shared/continuations/lib/LowerRaytracingPipeline.cpp
index 137c6e4fbf..2da69259fe 100644
--- a/shared/continuations/lib/LowerRaytracingPipeline.cpp
+++ b/shared/continuations/lib/LowerRaytracingPipeline.cpp
@@ -1912,6 +1912,19 @@ LowerRaytracingPipelinePassImpl::LowerRaytracingPipelinePassImpl(
       PAQManager{Mod, MetadataState.getMaxPayloadRegisterCount()} {}
 
 bool LowerRaytracingPipelinePassImpl::run() {
+  if (Mod->empty()) {
+    auto FuncTy = FunctionType::get(Builder.getVoidTy(), {}, false);
+    // GpurtLibrary is not defined in the gpuopen
+    // Function *ConKernel = GpurtLibrary->getFunction("_cont_KernelEntry");
+    Function *ConKernel = nullptr;
+    Function *EntryFunc =
+        Function::Create(FuncTy, GlobalValue::ExternalLinkage, "main", *Mod);
+    EntryFunc->setCallingConv(CallingConv::C);
+    moveFunctionBody(*ConKernel, *EntryFunc);
+    setLgcRtShaderStage(EntryFunc, RayTracingShaderStage::RayGeneration);
+
+    return true;
+  }
   MetadataState.updateModuleMetadata();
 
   collectDriverFunctions();