Add resource link info for library profile.
This commit is contained in:
Родитель
b6e876bf39
Коммит
c1bc9d945a
|
@ -114,6 +114,7 @@ public:
|
|||
|
||||
// Resources.
|
||||
static const char kDxilResourcesMDName[];
|
||||
static const char kDxilResourcesLinkInfoMDName[];
|
||||
static const unsigned kDxilNumResourceFields = 4;
|
||||
static const unsigned kDxilResourceSRVs = 0;
|
||||
static const unsigned kDxilResourceUAVs = 1;
|
||||
|
@ -292,6 +293,13 @@ public:
|
|||
llvm::MDTuple *pCBuffers, llvm::MDTuple *pSamplers);
|
||||
void GetDxilResources(const llvm::MDOperand &MDO, const llvm::MDTuple *&pSRVs, const llvm::MDTuple *&pUAVs,
|
||||
const llvm::MDTuple *&pCBuffers, const llvm::MDTuple *&pSamplers);
|
||||
void EmitDxilResourceLinkInfoTuple(llvm::MDTuple *pSRVs, llvm::MDTuple *pUAVs,
|
||||
llvm::MDTuple *pCBuffers,
|
||||
llvm::MDTuple *pSamplers);
|
||||
void LoadDxilResourceLinkInfoTuple(const llvm::MDTuple *&pSRVs,
|
||||
const llvm::MDTuple *&pUAVs,
|
||||
const llvm::MDTuple *&pCBuffers,
|
||||
const llvm::MDTuple *&pSamplers);
|
||||
void EmitDxilResourceBase(const DxilResourceBase &R, llvm::Metadata *ppMDVals[]);
|
||||
void LoadDxilResourceBase(const llvm::MDOperand &MDO, DxilResourceBase &R);
|
||||
llvm::MDTuple *EmitDxilSRV(const DxilResource &SRV);
|
||||
|
|
|
@ -97,6 +97,11 @@ public:
|
|||
const DxilResource &GetUAV(unsigned idx) const;
|
||||
const std::vector<std::unique_ptr<DxilResource> > &GetUAVs() const;
|
||||
|
||||
void CreateResourceLinkInfo();
|
||||
struct ResourceLinkInfo;
|
||||
const ResourceLinkInfo &GetResourceLinkInfo(DXIL::ResourceClass resClass,
|
||||
unsigned rangeID) const;
|
||||
|
||||
void LoadDxilResourceBaseFromMDNode(llvm::MDNode *MD, DxilResourceBase &R);
|
||||
void LoadDxilResourceFromMDNode(llvm::MDNode *MD, DxilResource &R);
|
||||
void LoadDxilSamplerFromMDNode(llvm::MDNode *MD, DxilSampler &S);
|
||||
|
@ -330,6 +335,14 @@ public:
|
|||
float GetMaxTessellationFactor() const;
|
||||
void SetMaxTessellationFactor(float MaxTessellationFactor);
|
||||
|
||||
// Shader resource information only needed before linking.
|
||||
// Use constant as rangeID and index for resource in a library.
|
||||
// When link the library, replace these constants with real rangeID and index.
|
||||
struct ResourceLinkInfo {
|
||||
llvm::Constant *ResRangeID;
|
||||
llvm::Constant *ResIndex;
|
||||
};
|
||||
|
||||
private:
|
||||
// Signatures.
|
||||
std::unique_ptr<DxilSignature> m_InputSignature;
|
||||
|
@ -343,6 +356,12 @@ private:
|
|||
std::vector<std::unique_ptr<DxilCBuffer> > m_CBuffers;
|
||||
std::vector<std::unique_ptr<DxilSampler> > m_Samplers;
|
||||
|
||||
// Save resource link for library, when link replace it with real resource ID.
|
||||
std::vector<ResourceLinkInfo> m_SRVsLinkInfo;
|
||||
std::vector<ResourceLinkInfo> m_UAVsLinkInfo;
|
||||
std::vector<ResourceLinkInfo> m_CBuffersLinkInfo;
|
||||
std::vector<ResourceLinkInfo> m_SamplersLinkInfo;
|
||||
|
||||
// Geometry shader.
|
||||
DXIL::InputPrimitive m_InputPrimitive;
|
||||
unsigned m_MaxVertexCount;
|
||||
|
@ -389,6 +408,8 @@ private:
|
|||
// DXIL metadata serialization/deserialization.
|
||||
llvm::MDTuple *EmitDxilResources();
|
||||
void LoadDxilResources(const llvm::MDOperand &MDO);
|
||||
void EmitDxilResourcesLinkInfo();
|
||||
void LoadDxilResourcesLinkInfo();
|
||||
llvm::MDTuple *EmitDxilShaderProperties();
|
||||
void LoadDxilShaderProperties(const llvm::MDOperand &MDO);
|
||||
|
||||
|
|
|
@ -82,8 +82,12 @@ public:
|
|||
DM.GetUAVs().size() || DM.GetSRVs().size() || DM.GetSamplers().size();
|
||||
|
||||
if (hasResource) {
|
||||
AllocateDxilResources(DM);
|
||||
PatchCreateHandle(DM);
|
||||
if (!DM.GetShaderModel()->IsLib()) {
|
||||
AllocateDxilResources(DM);
|
||||
PatchCreateHandle(DM);
|
||||
} else {
|
||||
PatchCreateHandleForLib(DM);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -101,6 +105,8 @@ private:
|
|||
void AllocateDxilResources(DxilModule &DM);
|
||||
// Add lowbound to create handle range index.
|
||||
void PatchCreateHandle(DxilModule &DM);
|
||||
// Add lowbound to create handle range index for library.
|
||||
void PatchCreateHandleForLib(DxilModule &DM);
|
||||
// Switch CBuffer for SRV for TBuffers.
|
||||
void PatchTBuffers(DxilModule &DM);
|
||||
};
|
||||
|
@ -244,7 +250,8 @@ void PatchLowerBoundOfCreateHandle(CallInst *handle, DxilModule &DM) {
|
|||
|
||||
DXIL::ResourceClass ResClass =
|
||||
static_cast<DXIL::ResourceClass>(createHandle.get_resourceClass_val());
|
||||
// Not support case dynamic rangeId yet.
|
||||
// Dynamic rangeId is not supported - skip and let validation report the
|
||||
// error.
|
||||
if (!isa<ConstantInt>(createHandle.get_rangeId()))
|
||||
return;
|
||||
|
||||
|
@ -449,6 +456,51 @@ void DxilCondenseResources::PatchCreateHandle(DxilModule &DM) {
|
|||
}
|
||||
}
|
||||
|
||||
void DxilCondenseResources::PatchCreateHandleForLib(DxilModule &DM) {
|
||||
Function *createHandle = DM.GetOP()->GetOpFunc(DXIL::OpCode::CreateHandle,
|
||||
Type::getVoidTy(DM.GetCtx()));
|
||||
DM.CreateResourceLinkInfo();
|
||||
Value *zeroIndex = ConstantInt::get(Type::getInt32Ty(DM.GetCtx()), 0);
|
||||
for (User *U : createHandle->users()) {
|
||||
CallInst *handle = cast<CallInst>(U);
|
||||
DxilInst_CreateHandle createHandle(handle);
|
||||
DXASSERT_NOMSG(createHandle);
|
||||
|
||||
DXIL::ResourceClass ResClass =
|
||||
static_cast<DXIL::ResourceClass>(createHandle.get_resourceClass_val());
|
||||
// Dynamic rangeId is not supported - skip and let validation report the
|
||||
// error.
|
||||
if (!isa<ConstantInt>(createHandle.get_rangeId()))
|
||||
continue;
|
||||
|
||||
unsigned rangeId =
|
||||
cast<ConstantInt>(createHandle.get_rangeId())->getLimitedValue();
|
||||
|
||||
const DxilModule::ResourceLinkInfo &linkInfo =
|
||||
DM.GetResourceLinkInfo(ResClass, rangeId);
|
||||
|
||||
IRBuilder<> Builder(handle);
|
||||
Value *linkRangeID = Builder.CreateLoad(linkInfo.ResRangeID);
|
||||
// Update rangeID to linkinfo rangeID.
|
||||
handle->setArgOperand(DXIL::OperandIndex::kCreateHandleResIDOpIdx,
|
||||
linkRangeID);
|
||||
|
||||
Value *Index = createHandle.get_index();
|
||||
Value *linkIndex = Builder.CreateLoad(linkInfo.ResIndex);
|
||||
|
||||
if (Index == zeroIndex) {
|
||||
// Update index to linkinfo index.
|
||||
handle->setArgOperand(DXIL::OperandIndex::kCreateHandleResIndexOpIdx,
|
||||
linkIndex);
|
||||
} else {
|
||||
// Add linkinfo index to index.
|
||||
Value *newIdx = Builder.CreateAdd(Index, linkIndex);
|
||||
handle->setArgOperand(DXIL::OperandIndex::kCreateHandleResIndexOpIdx,
|
||||
newIdx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
char DxilCondenseResources::ID = 0;
|
||||
|
||||
bool llvm::AreDxilResourcesDense(llvm::Module *M, hlsl::DxilResourceBase **ppNonDense) {
|
||||
|
|
|
@ -42,6 +42,7 @@ const char DxilMDHelper::kDxilVersionMDName[] = "dx.vers
|
|||
const char DxilMDHelper::kDxilShaderModelMDName[] = "dx.shaderModel";
|
||||
const char DxilMDHelper::kDxilEntryPointsMDName[] = "dx.entryPoints";
|
||||
const char DxilMDHelper::kDxilResourcesMDName[] = "dx.resources";
|
||||
const char DxilMDHelper::kDxilResourcesLinkInfoMDName[] = "dx.resources.link.info";
|
||||
const char DxilMDHelper::kDxilTypeSystemMDName[] = "dx.typeAnnotations";
|
||||
const char DxilMDHelper::kDxilTypeSystemHelperVariablePrefix[] = "dx.typevar.";
|
||||
const char DxilMDHelper::kDxilControlFlowHintMDName[] = "dx.controlflow.hints";
|
||||
|
@ -442,6 +443,52 @@ MDTuple *DxilMDHelper::EmitDxilResourceTuple(MDTuple *pSRVs, MDTuple *pUAVs,
|
|||
return pTupleMD;
|
||||
}
|
||||
|
||||
void DxilMDHelper::EmitDxilResourceLinkInfoTuple(MDTuple *pSRVs, MDTuple *pUAVs,
|
||||
MDTuple *pCBuffers,
|
||||
MDTuple *pSamplers) {
|
||||
DXASSERT(pSRVs != nullptr || pUAVs != nullptr || pCBuffers != nullptr ||
|
||||
pSamplers != nullptr,
|
||||
"resource tuple should not be emitted if there are no resources");
|
||||
Metadata *MDVals[kDxilNumResourceFields];
|
||||
MDVals[kDxilResourceSRVs] = pSRVs;
|
||||
MDVals[kDxilResourceUAVs] = pUAVs;
|
||||
MDVals[kDxilResourceCBuffers] = pCBuffers;
|
||||
MDVals[kDxilResourceSamplers] = pSamplers;
|
||||
MDTuple *pTupleMD = MDNode::get(m_Ctx, MDVals);
|
||||
|
||||
NamedMDNode *pResourcesNamedMD =
|
||||
m_pModule->getNamedMetadata(kDxilResourcesLinkInfoMDName);
|
||||
IFTBOOL(pResourcesNamedMD == nullptr, DXC_E_INCORRECT_DXIL_METADATA);
|
||||
pResourcesNamedMD =
|
||||
m_pModule->getOrInsertNamedMetadata(kDxilResourcesLinkInfoMDName);
|
||||
pResourcesNamedMD->addOperand(pTupleMD);
|
||||
}
|
||||
|
||||
void DxilMDHelper::LoadDxilResourceLinkInfoTuple(const llvm::MDTuple *&pSRVs,
|
||||
const llvm::MDTuple *&pUAVs,
|
||||
const llvm::MDTuple *&pCBuffers,
|
||||
const llvm::MDTuple *&pSamplers) {
|
||||
NamedMDNode *pResourcesNamedMD =
|
||||
m_pModule->getNamedMetadata(kDxilResourcesLinkInfoMDName);
|
||||
if (!pResourcesNamedMD) {
|
||||
pSRVs = pUAVs = pCBuffers = pSamplers = nullptr;
|
||||
return;
|
||||
}
|
||||
|
||||
IFTBOOL(pResourcesNamedMD->getNumOperands() == 1,
|
||||
DXC_E_INCORRECT_DXIL_METADATA);
|
||||
|
||||
const MDTuple *pTupleMD = dyn_cast<MDTuple>(pResourcesNamedMD->getOperand(0));
|
||||
IFTBOOL(pTupleMD != nullptr, DXC_E_INCORRECT_DXIL_METADATA);
|
||||
IFTBOOL(pTupleMD->getNumOperands() == kDxilNumResourceFields,
|
||||
DXC_E_INCORRECT_DXIL_METADATA);
|
||||
|
||||
pSRVs = CastToTupleOrNull(pTupleMD->getOperand(kDxilResourceSRVs));
|
||||
pUAVs = CastToTupleOrNull(pTupleMD->getOperand(kDxilResourceUAVs));
|
||||
pCBuffers = CastToTupleOrNull(pTupleMD->getOperand(kDxilResourceCBuffers));
|
||||
pSamplers = CastToTupleOrNull(pTupleMD->getOperand(kDxilResourceSamplers));
|
||||
}
|
||||
|
||||
void DxilMDHelper::GetDxilResources(const MDOperand &MDO, const MDTuple *&pSRVs,
|
||||
const MDTuple *&pUAVs, const MDTuple *&pCBuffers,
|
||||
const MDTuple *&pSamplers) {
|
||||
|
|
|
@ -801,6 +801,58 @@ const vector<unique_ptr<DxilResource> > &DxilModule::GetUAVs() const {
|
|||
return m_UAVs;
|
||||
}
|
||||
|
||||
static void CreateResourceLinkConstant(Module &M, DxilResourceBase *pRes,
|
||||
std::vector<DxilModule::ResourceLinkInfo> &resLinkInfo) {
|
||||
Type *i32Ty = Type::getInt32Ty(M.getContext());
|
||||
const bool IsConstantTrue = true;
|
||||
Constant *NullInitVal = nullptr;
|
||||
GlobalVariable *rangeID = new GlobalVariable(
|
||||
M, i32Ty, IsConstantTrue, llvm::GlobalValue::ExternalLinkage, NullInitVal,
|
||||
pRes->GetGlobalName() + "_rangeID");
|
||||
GlobalVariable *index = new GlobalVariable(
|
||||
M, i32Ty, IsConstantTrue, llvm::GlobalValue::ExternalLinkage, NullInitVal,
|
||||
pRes->GetGlobalName() + "_index");
|
||||
|
||||
resLinkInfo.emplace_back(DxilModule::ResourceLinkInfo{rangeID, index});
|
||||
}
|
||||
|
||||
void DxilModule::CreateResourceLinkInfo() {
|
||||
DXASSERT(GetShaderModel()->IsLib(), "only for library profile");
|
||||
DXASSERT(m_SRVsLinkInfo.empty() && m_UAVsLinkInfo.empty() &&
|
||||
m_CBuffersLinkInfo.empty() && m_SamplersLinkInfo.empty(),
|
||||
"else resource link info was already created");
|
||||
Module &M = *m_pModule;
|
||||
for (auto &SRV : m_SRVs) {
|
||||
CreateResourceLinkConstant(M, SRV.get(), m_SRVsLinkInfo);
|
||||
}
|
||||
for (auto &UAV : m_UAVs) {
|
||||
CreateResourceLinkConstant(M, UAV.get(), m_UAVsLinkInfo);
|
||||
}
|
||||
for (auto &CBuffer : m_CBuffers) {
|
||||
CreateResourceLinkConstant(M, CBuffer.get(), m_CBuffersLinkInfo);
|
||||
}
|
||||
for (auto &Sampler : m_Samplers) {
|
||||
CreateResourceLinkConstant(M, Sampler.get(), m_SamplersLinkInfo);
|
||||
}
|
||||
}
|
||||
|
||||
const DxilModule::ResourceLinkInfo &
|
||||
DxilModule::GetResourceLinkInfo(DXIL::ResourceClass resClass,
|
||||
unsigned rangeID) const {
|
||||
switch (resClass) {
|
||||
case DXIL::ResourceClass::UAV:
|
||||
return m_UAVsLinkInfo[rangeID];
|
||||
case DXIL::ResourceClass::CBuffer:
|
||||
return m_CBuffersLinkInfo[rangeID];
|
||||
case DXIL::ResourceClass::Sampler:
|
||||
return m_SamplersLinkInfo[rangeID];
|
||||
default:
|
||||
DXASSERT(DXIL::ResourceClass::SRV == resClass,
|
||||
"else invalid resource class");
|
||||
return m_SRVsLinkInfo[rangeID];
|
||||
}
|
||||
}
|
||||
|
||||
void DxilModule::LoadDxilResourceBaseFromMDNode(MDNode *MD, DxilResourceBase &R) {
|
||||
return m_pMDHelper->LoadDxilResourceBaseFromMDNode(MD, R);
|
||||
}
|
||||
|
@ -1068,6 +1120,8 @@ void DxilModule::EmitDxilMetadata() {
|
|||
if (!m_RootSignature->IsEmpty()) {
|
||||
m_pMDHelper->EmitRootSignature(*m_RootSignature.get());
|
||||
}
|
||||
if (m_pSM->IsLib())
|
||||
EmitDxilResourcesLinkInfo();
|
||||
}
|
||||
|
||||
bool DxilModule::IsKnownNamedMetaData(llvm::NamedMDNode &Node) {
|
||||
|
@ -1104,6 +1158,9 @@ void DxilModule::LoadDxilMetadata() {
|
|||
m_pMDHelper->LoadRootSignature(*m_RootSignature.get());
|
||||
|
||||
m_pMDHelper->LoadDxilViewIdState(*m_pViewIdState.get());
|
||||
|
||||
if (loadedModule->IsLib())
|
||||
LoadDxilResourcesLinkInfo();
|
||||
}
|
||||
|
||||
MDTuple *DxilModule::EmitDxilResources() {
|
||||
|
@ -1198,6 +1255,85 @@ void DxilModule::LoadDxilResources(const llvm::MDOperand &MDO) {
|
|||
}
|
||||
}
|
||||
|
||||
static MDTuple *CreateResourcesLinkInfo(std::vector<DxilModule::ResourceLinkInfo> &LinkInfoList,
|
||||
unsigned size, LLVMContext &Ctx) {
|
||||
DXASSERT(size == LinkInfoList.size(), "link info size must match resource size");
|
||||
if (LinkInfoList.empty())
|
||||
return nullptr;
|
||||
|
||||
vector<Metadata *> MDVals;
|
||||
for (size_t i = 0; i < size; i++) {
|
||||
MDVals.emplace_back(ValueAsMetadata::get(LinkInfoList[i].ResRangeID));
|
||||
MDVals.emplace_back(ValueAsMetadata::get(LinkInfoList[i].ResIndex));
|
||||
}
|
||||
return MDNode::get(Ctx, MDVals);
|
||||
}
|
||||
|
||||
void DxilModule::EmitDxilResourcesLinkInfo() {
|
||||
// Emit SRV base records.
|
||||
MDTuple *pTupleSRVs =
|
||||
CreateResourcesLinkInfo(m_SRVsLinkInfo, m_SRVs.size(), m_Ctx);
|
||||
|
||||
// Emit UAV base records.
|
||||
MDTuple *pTupleUAVs =
|
||||
CreateResourcesLinkInfo(m_UAVsLinkInfo, m_UAVs.size(), m_Ctx);
|
||||
|
||||
// Emit CBuffer base records.
|
||||
MDTuple *pTupleCBuffers =
|
||||
CreateResourcesLinkInfo(m_CBuffersLinkInfo, m_CBuffers.size(), m_Ctx);
|
||||
|
||||
// Emit Sampler records.
|
||||
MDTuple *pTupleSamplers =
|
||||
CreateResourcesLinkInfo(m_SamplersLinkInfo, m_Samplers.size(), m_Ctx);
|
||||
|
||||
if (pTupleSRVs != nullptr || pTupleUAVs != nullptr ||
|
||||
pTupleCBuffers != nullptr || pTupleSamplers != nullptr) {
|
||||
m_pMDHelper->EmitDxilResourceLinkInfoTuple(pTupleSRVs, pTupleUAVs,
|
||||
pTupleCBuffers, pTupleSamplers);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
LoadResourcesLinkInfo(const llvm::MDTuple *pMD,
|
||||
std::vector<DxilModule::ResourceLinkInfo> &LinkInfoList,
|
||||
unsigned size, DxilMDHelper *pMDHelper) {
|
||||
if (!pMD) {
|
||||
IFTBOOL(size == 0, DXC_E_INCORRECT_DXIL_METADATA);
|
||||
return;
|
||||
}
|
||||
unsigned operandSize = pMD->getNumOperands();
|
||||
IFTBOOL(operandSize == (2 * size), DXC_E_INCORRECT_DXIL_METADATA);
|
||||
for (unsigned i = 0; i < operandSize; i += 2) {
|
||||
Constant *rangeID =
|
||||
dyn_cast<Constant>(pMDHelper->ValueMDToValue(pMD->getOperand(i)));
|
||||
Constant *index =
|
||||
dyn_cast<Constant>(pMDHelper->ValueMDToValue(pMD->getOperand(i + 1)));
|
||||
LinkInfoList.emplace_back(DxilModule::ResourceLinkInfo{rangeID, index});
|
||||
}
|
||||
}
|
||||
|
||||
void DxilModule::LoadDxilResourcesLinkInfo() {
|
||||
const llvm::MDTuple *pSRVs, *pUAVs, *pCBuffers, *pSamplers;
|
||||
m_pMDHelper->LoadDxilResourceLinkInfoTuple(pSRVs, pUAVs, pCBuffers,
|
||||
pSamplers);
|
||||
|
||||
// Load SRV base records.
|
||||
LoadResourcesLinkInfo(pSRVs, m_SRVsLinkInfo, m_SRVs.size(),
|
||||
m_pMDHelper.get());
|
||||
|
||||
// Load UAV base records.
|
||||
LoadResourcesLinkInfo(pUAVs, m_UAVsLinkInfo, m_UAVs.size(),
|
||||
m_pMDHelper.get());
|
||||
|
||||
// Load CBuffer records.
|
||||
LoadResourcesLinkInfo(pCBuffers, m_CBuffersLinkInfo, m_CBuffers.size(),
|
||||
m_pMDHelper.get());
|
||||
|
||||
// Load Sampler records.
|
||||
LoadResourcesLinkInfo(pSamplers, m_SamplersLinkInfo, m_Samplers.size(),
|
||||
m_pMDHelper.get());
|
||||
}
|
||||
|
||||
MDTuple *DxilModule::EmitDxilShaderProperties() {
|
||||
vector<Metadata *> MDVals;
|
||||
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
// RUN: %dxc -T lib_6_1 %s | FileCheck %s
|
||||
|
||||
// Make sure globals for link info exist.
|
||||
// CHECK: g_txDiffuse_rangeID
|
||||
// CHECK: g_txDiffuse_index
|
||||
// CHECK: g_samLinear_rangeID
|
||||
// CHECK: g_samLinear_index
|
||||
|
||||
// Make sure link info metadata exist.
|
||||
// CHECK: dx.resources.link.info
|
||||
// CHECK: !{i32* @g_txDiffuse_rangeID, i32* @g_txDiffuse_index}
|
||||
// CHECK: !{i32* @g_samLinear_rangeID, i32* @g_samLinear_index}
|
||||
|
||||
|
||||
Texture2D g_txDiffuse;
|
||||
SamplerState g_samLinear;
|
||||
|
||||
float4 test(float2 c : C) : SV_TARGET
|
||||
{
|
||||
float4 x = g_txDiffuse.Sample( g_samLinear, c );
|
||||
return x;
|
||||
}
|
||||
|
|
@ -501,6 +501,7 @@ public:
|
|||
TEST_METHOD(CodeGenIntrinsic5)
|
||||
TEST_METHOD(CodeGenInvalidInputOutputTypes)
|
||||
TEST_METHOD(CodeGenLegacyStruct)
|
||||
TEST_METHOD(CodeGenLibResource)
|
||||
TEST_METHOD(CodeGenLibUnusedFunc)
|
||||
TEST_METHOD(CodeGenLitInParen)
|
||||
TEST_METHOD(CodeGenLiteralShift)
|
||||
|
@ -2772,6 +2773,10 @@ TEST_F(CompilerTest, CodeGenLegacyStruct) {
|
|||
CodeGenTestCheck(L"..\\CodeGenHLSL\\legacy_struct.hlsl");
|
||||
}
|
||||
|
||||
TEST_F(CompilerTest, CodeGenLibResource) {
|
||||
CodeGenTestCheck(L"..\\CodeGenHLSL\\lib_resource.hlsl");
|
||||
}
|
||||
|
||||
TEST_F(CompilerTest, CodeGenLibUnusedFunc) {
|
||||
CodeGenTestCheck(L"..\\CodeGenHLSL\\lib_unused_func.hlsl");
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче