Skip to content

Commit

Permalink
Support spirv with capability linkage
Browse files Browse the repository at this point in the history
Spirv with capability linkage does not have entry function, so it is required to create
dummy entry function of compute shader stage for this spirv.
  • Loading branch information
jiaolu committed Jan 4, 2021
1 parent f2de341 commit f780462
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 14 deletions.
46 changes: 32 additions & 14 deletions llpc/translator/lib/SPIRV/SPIRVReader.cpp
Expand Up @@ -6136,34 +6136,37 @@ bool SPIRVToLLVM::translate(ExecutionModel entryExecModel, const char *entryName

// Find the targeted entry-point in this translation
auto entryPoint = m_bm->getEntryPoint(entryExecModel, entryName);
if (!entryPoint)
return false;

m_entryTarget = m_bm->get<SPIRVFunction>(entryPoint->getTargetId());
if (!m_entryTarget)
if (!entryPoint && !m_bm->hasCapability(CapabilityLinkage))
return false;

m_entryTarget = (entryPoint != nullptr) ? m_bm->get<SPIRVFunction>(entryPoint->getTargetId()) : nullptr;

m_execModule = entryExecModel;
m_fpControlFlags.U32All = 0;
static_assert(SPIRVTW_8Bit == (8 >> 3), "Unexpected value!");
static_assert(SPIRVTW_16Bit == (16 >> 3), "Unexpected value!");
static_assert(SPIRVTW_32Bit == (32 >> 3), "Unexpected value!");
static_assert(SPIRVTW_64Bit == (64 >> 3), "Unexpected value!");

if (auto em = m_entryTarget->getExecutionMode(ExecutionModeDenormPreserve))
m_fpControlFlags.DenormPreserve = em->getLiterals()[0] >> 3;
if (m_entryTarget) {
if (auto em = m_entryTarget->getExecutionMode(ExecutionModeDenormPreserve))
m_fpControlFlags.DenormPreserve = em->getLiterals()[0] >> 3;

if (auto em = m_entryTarget->getExecutionMode(ExecutionModeDenormFlushToZero))
m_fpControlFlags.DenormFlushToZero = em->getLiterals()[0] >> 3;
if (auto em = m_entryTarget->getExecutionMode(ExecutionModeDenormFlushToZero))
m_fpControlFlags.DenormFlushToZero = em->getLiterals()[0] >> 3;

if (auto em = m_entryTarget->getExecutionMode(ExecutionModeSignedZeroInfNanPreserve))
m_fpControlFlags.SignedZeroInfNanPreserve = em->getLiterals()[0] >> 3;
if (auto em = m_entryTarget->getExecutionMode(ExecutionModeSignedZeroInfNanPreserve))
m_fpControlFlags.SignedZeroInfNanPreserve = em->getLiterals()[0] >> 3;

if (auto em = m_entryTarget->getExecutionMode(ExecutionModeRoundingModeRTE))
m_fpControlFlags.RoundingModeRTE = em->getLiterals()[0] >> 3;
if (auto em = m_entryTarget->getExecutionMode(ExecutionModeRoundingModeRTE))
m_fpControlFlags.RoundingModeRTE = em->getLiterals()[0] >> 3;

if (auto em = m_entryTarget->getExecutionMode(ExecutionModeRoundingModeRTZ))
m_fpControlFlags.RoundingModeRTZ = em->getLiterals()[0] >> 3;
if (auto em = m_entryTarget->getExecutionMode(ExecutionModeRoundingModeRTZ))
m_fpControlFlags.RoundingModeRTZ = em->getLiterals()[0] >> 3;
} else {
createLibraryEntryFunc();
}

// Determine any denormal overrides to be applied.
Vkgc::DenormalMode fp32DenormalMode =
Expand Down Expand Up @@ -8121,6 +8124,21 @@ llvm::GlobalValue::LinkageTypes SPIRVToLLVM::transLinkageType(const SPIRVValue *
}
}

llvm::Function *SPIRVToLLVM::createLibraryEntryFunc() {
auto builder = getBuilder();
FunctionType *funcTy = FunctionType::get(builder->getVoidTy(), {}, false);
auto func = Function::Create(funcTy, GlobalValue::ExternalLinkage, "libraryEntry", m_m);
BasicBlock *entryBlock = BasicBlock::Create(*m_context, "", func);
builder->SetInsertPoint(entryBlock);
builder->CreateRetVoid();
std::vector<Metadata *> execModelMDs;
execModelMDs.push_back(ConstantAsMetadata::get(ConstantInt::get(builder->getInt32Ty(), ExecutionModelGLCompute)));
auto execModelMdNode = MDNode::get(*m_context, execModelMDs);
func->addMetadata(gSPIRVMD::ExecutionModel, *execModelMdNode);
func->setDLLStorageClass(GlobalValue::DLLExportStorageClass);
return func;
}

} // namespace SPIRV

bool llvm::readSpirv(Builder *builder, const ShaderModuleUsage *shaderInfo, const PipelineShaderOptions *shaderOptions,
Expand Down
2 changes: 2 additions & 0 deletions llpc/translator/lib/SPIRV/SPIRVReader.h
Expand Up @@ -308,6 +308,8 @@ class SPIRVToLLVM {

Value *ConvertingSamplerSelectLadderHelper(Value *result, Value *convertingSamplerIdx,
std::function<Value *(Value *)> createImageOp);

Function* createLibraryEntryFunc();
}; // class SPIRVToLLVM

} // namespace SPIRV
Expand Down

0 comments on commit f780462

Please sign in to comment.