DirectXShaderCompiler/include/dxc/HLSL/HLModule.h

340 строки
13 KiB
C++

///////////////////////////////////////////////////////////////////////////////
// //
// HLModule.h //
// Copyright (C) Microsoft Corporation. All rights reserved. //
// This file is distributed under the University of Illinois Open Source //
// License. See LICENSE.TXT for details. //
// //
// HighLevel DX IR module. //
// //
///////////////////////////////////////////////////////////////////////////////
#pragma once
#include "dxc/DXIL/DxilConstants.h"
#include "dxc/DXIL/DxilFunctionProps.h"
#include "dxc/DXIL/DxilMetadataHelper.h"
#include "dxc/DXIL/DxilResourceProperties.h"
#include "dxc/DXIL/DxilSampler.h"
#include "dxc/DXIL/DxilShaderModel.h"
#include "dxc/DXIL/DxilSignature.h"
#include "dxc/DXIL/DxilSubobject.h"
#include "dxc/HLSL/HLOperations.h"
#include "dxc/HLSL/HLResource.h"
#include "dxc/Support/Global.h"
#include <memory>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <vector>
namespace llvm {
template <typename T> class ArrayRef;
class LLVMContext;
class Module;
class Function;
class Instruction;
class CallInst;
class MDTuple;
class MDNode;
class GlobalVariable;
class DIGlobalVariable;
class DebugInfoFinder;
class GetElementPtrInst;
} // namespace llvm
namespace hlsl {
class ShaderModel;
class OP;
struct HLOptions {
HLOptions()
: bDefaultRowMajor(false), bIEEEStrict(false), bAllResourcesBound(false),
bDisableOptimizations(false), PackingStrategy(0),
bUseMinPrecision(false), bDX9CompatMode(false), bFXCCompatMode(false),
bLegacyResourceReservation(false), bForceZeroStoreLifetimes(false),
unused(0) {}
uint32_t GetHLOptionsRaw() const;
void SetHLOptionsRaw(uint32_t data);
unsigned bDefaultRowMajor : 1;
unsigned bIEEEStrict : 1;
unsigned bAllResourcesBound : 1;
unsigned bDisableOptimizations : 1;
unsigned PackingStrategy : 2;
static_assert((unsigned)DXIL::PackingStrategy::Invalid < 4,
"otherwise 2 bits is not enough to store PackingStrategy");
unsigned bUseMinPrecision : 1;
unsigned bDX9CompatMode : 1;
unsigned bFXCCompatMode : 1;
unsigned bLegacyResourceReservation : 1;
unsigned bForceZeroStoreLifetimes : 1;
unsigned bResMayAlias : 1;
unsigned unused : 19;
};
typedef std::unordered_map<const llvm::Function *,
std::unique_ptr<DxilFunctionProps>>
DxilFunctionPropsMap;
/// Use this class to manipulate HLDXIR of a shader.
class HLModule {
public:
HLModule(llvm::Module *pModule);
~HLModule();
using Domain = DXIL::TessellatorDomain;
// Subsystems.
llvm::LLVMContext &GetCtx() const;
llvm::Module *GetModule() const;
OP *GetOP() const;
void SetShaderModel(const ShaderModel *pSM);
const ShaderModel *GetShaderModel() const;
void SetValidatorVersion(unsigned ValMajor, unsigned ValMinor);
void GetValidatorVersion(unsigned &ValMajor, unsigned &ValMinor) const;
void SetForceZeroStoreLifetimes(bool ForceZeroStoreLifetimes);
bool GetForceZeroStoreLifetimes() const;
// HLOptions
void SetHLOptions(HLOptions &opts);
const HLOptions &GetHLOptions() const;
// AutoBindingSpace also enables automatic binding for libraries if set.
// UINT_MAX == unset
void SetAutoBindingSpace(uint32_t Space);
uint32_t GetAutoBindingSpace() const;
// Entry function.
llvm::Function *GetEntryFunction() const;
void SetEntryFunction(llvm::Function *pEntryFunc);
const std::string &GetEntryFunctionName() const;
void SetEntryFunctionName(const std::string &name);
llvm::Function *GetPatchConstantFunction();
// Resources.
unsigned AddCBuffer(std::unique_ptr<DxilCBuffer> pCB);
DxilCBuffer &GetCBuffer(unsigned idx);
const DxilCBuffer &GetCBuffer(unsigned idx) const;
const std::vector<std::unique_ptr<DxilCBuffer>> &GetCBuffers() const;
unsigned AddSampler(std::unique_ptr<DxilSampler> pSampler);
DxilSampler &GetSampler(unsigned idx);
const DxilSampler &GetSampler(unsigned idx) const;
const std::vector<std::unique_ptr<DxilSampler>> &GetSamplers() const;
unsigned AddSRV(std::unique_ptr<HLResource> pSRV);
HLResource &GetSRV(unsigned idx);
const HLResource &GetSRV(unsigned idx) const;
const std::vector<std::unique_ptr<HLResource>> &GetSRVs() const;
unsigned AddUAV(std::unique_ptr<HLResource> pUAV);
HLResource &GetUAV(unsigned idx);
const HLResource &GetUAV(unsigned idx) const;
const std::vector<std::unique_ptr<HLResource>> &GetUAVs() const;
void RemoveGlobal(llvm::GlobalVariable *GV);
void RemoveFunction(llvm::Function *F);
// ThreadGroupSharedMemory.
typedef std::vector<llvm::GlobalVariable *>::iterator tgsm_iterator;
tgsm_iterator tgsm_begin();
tgsm_iterator tgsm_end();
void AddGroupSharedVariable(llvm::GlobalVariable *GV);
// Signatures.
std::vector<uint8_t> &GetSerializedRootSignature();
void SetSerializedRootSignature(const uint8_t *pData, unsigned size);
// DxilFunctionProps.
bool HasDxilFunctionProps(llvm::Function *F);
DxilFunctionProps &GetDxilFunctionProps(llvm::Function *F);
void AddDxilFunctionProps(llvm::Function *F,
std::unique_ptr<DxilFunctionProps> &info);
void SetPatchConstantFunctionForHS(llvm::Function *hullShaderFunc,
llvm::Function *patchConstantFunc);
bool IsGraphicsShader(llvm::Function *F); // vs,hs,ds,gs,ps
bool IsPatchConstantShader(llvm::Function *F);
bool IsComputeShader(llvm::Function *F);
bool IsNodeShader(llvm::Function *F);
// Is an entry function that uses input/output signature conventions?
// Includes: vs/hs/ds/gs/ps/cs as well as the patch constant function.
bool IsEntryThatUsesSignatures(llvm::Function *F);
// Is F an entry?
// Includes: IsEntryThatUsesSignatures and all ray tracing shaders.
bool IsEntry(llvm::Function *F);
DxilFunctionAnnotation *GetFunctionAnnotation(llvm::Function *F);
DxilFunctionAnnotation *AddFunctionAnnotation(llvm::Function *F);
// Float Denorm mode.
void SetFloat32DenormMode(const DXIL::Float32DenormMode mode);
DXIL::Float32DenormMode GetFloat32DenormMode() const;
// Default function linkage for libraries
DXIL::DefaultLinkage GetDefaultLinkage() const;
void SetDefaultLinkage(const DXIL::DefaultLinkage linkage);
// HLDXIR metadata manipulation.
/// Serialize HLDXIR in-memory form to metadata form.
void EmitHLMetadata();
/// Deserialize HLDXIR metadata form into in-memory form.
void LoadHLMetadata();
/// Delete any HLDXIR from the specified module.
static void ClearHLMetadata(llvm::Module &M);
DxilResourceBase *
AddResourceWithGlobalVariableAndProps(llvm::Constant *GV,
DxilResourceProperties &RP);
unsigned GetBindingForResourceInCB(llvm::GetElementPtrInst *CbPtr,
llvm::GlobalVariable *CbGV,
DXIL::ResourceClass RC);
// Type related methods.
static bool IsStreamOutputPtrType(llvm::Type *Ty);
static bool IsStreamOutputType(llvm::Type *Ty);
static void GetParameterRowsAndCols(llvm::Type *Ty, unsigned &rows,
unsigned &cols,
DxilParameterAnnotation &paramAnnotation);
// HL code gen.
static llvm::Function *GetHLOperationFunction(
HLOpcodeGroup group, unsigned opcode, llvm::Type *RetType,
llvm::ArrayRef<llvm::Value *> paramList, llvm::Module &M);
template <class BuilderTy>
static llvm::CallInst *
EmitHLOperationCall(BuilderTy &Builder, HLOpcodeGroup group, unsigned opcode,
llvm::Type *RetType,
llvm::ArrayRef<llvm::Value *> paramList, llvm::Module &M);
// Caller must handle conversions to bool and no-ops
static unsigned GetNumericCastOp(llvm::Type *SrcTy, bool SrcIsUnsigned,
llvm::Type *DstTy, bool DstIsUnsigned);
// Precise attribute.
// Note: Precise will be marked on alloca inst with metadata in code gen.
// But mem2reg will remove alloca inst, so need mark precise with
// function call before mem2reg.
static bool HasPreciseAttributeWithMetadata(llvm::Instruction *I);
static void MarkPreciseAttributeWithMetadata(llvm::Instruction *I);
static void ClearPreciseAttributeWithMetadata(llvm::Instruction *I);
template <class BuilderTy>
static void MarkPreciseAttributeOnValWithFunctionCall(llvm::Value *V,
BuilderTy &Builder,
llvm::Module &M);
static void MarkPreciseAttributeOnPtrWithFunctionCall(llvm::Value *Ptr,
llvm::Module &M);
static bool HasPreciseAttribute(llvm::Function *F);
// DXIL type system.
DxilTypeSystem &GetTypeSystem();
/// Emit llvm.used array to make sure that optimizations do not remove
/// unreferenced globals.
void EmitLLVMUsed();
std::vector<llvm::GlobalVariable *> &GetLLVMUsed();
// Release functions used to transfer ownership.
DxilTypeSystem *ReleaseTypeSystem();
OP *ReleaseOP();
DxilFunctionPropsMap &&ReleaseFunctionPropsMap();
llvm::DebugInfoFinder &GetOrCreateDebugInfoFinder();
// Create global variable debug info for element global variable based on the
// whole global variable.
static void CreateElementGlobalVariableDebugInfo(
llvm::GlobalVariable *GV, llvm::DebugInfoFinder &DbgInfoFinder,
llvm::GlobalVariable *EltGV, unsigned sizeInBits, unsigned alignInBits,
unsigned offsetInBits, llvm::StringRef eltName);
// Replace GV with NewGV in GlobalVariable debug info.
static void
UpdateGlobalVariableDebugInfo(llvm::GlobalVariable *GV,
llvm::DebugInfoFinder &DbgInfoFinder,
llvm::GlobalVariable *NewGV);
DxilSubobjects *GetSubobjects();
const DxilSubobjects *GetSubobjects() const;
DxilSubobjects *ReleaseSubobjects();
void ResetSubobjects(DxilSubobjects *subobjects);
// Reg binding for resource in cb.
void AddRegBinding(unsigned CbID, unsigned ConstantIdx, unsigned Srv,
unsigned Uav, unsigned Sampler);
private:
// Signatures.
std::vector<uint8_t> m_SerializedRootSignature;
// Shader resources.
std::vector<std::unique_ptr<HLResource>> m_SRVs;
std::vector<std::unique_ptr<HLResource>> m_UAVs;
std::vector<std::unique_ptr<DxilCBuffer>> m_CBuffers;
std::vector<std::unique_ptr<DxilSampler>> m_Samplers;
// ThreadGroupSharedMemory.
std::vector<llvm::GlobalVariable *> m_TGSMVariables;
// High level function info.
std::unordered_map<const llvm::Function *, std::unique_ptr<DxilFunctionProps>>
m_DxilFunctionPropsMap;
std::unordered_set<llvm::Function *> m_PatchConstantFunctions;
// Resource bindings for res in cb.
// Key = CbID << 32 | ConstantIdx. Val is reg binding.
std::unordered_map<uint64_t, unsigned> m_SrvBindingInCB;
std::unordered_map<uint64_t, unsigned> m_UavBindingInCB;
std::unordered_map<uint64_t, unsigned> m_SamplerBindingInCB;
private:
llvm::LLVMContext &m_Ctx;
llvm::Module *m_pModule;
llvm::Function *m_pEntryFunc;
std::string m_EntryName;
std::unique_ptr<DxilMDHelper> m_pMDHelper;
std::unique_ptr<llvm::DebugInfoFinder> m_pDebugInfoFinder;
const ShaderModel *m_pSM;
unsigned m_DxilMajor;
unsigned m_DxilMinor;
unsigned m_ValMajor;
unsigned m_ValMinor;
DXIL::Float32DenormMode m_Float32DenormMode;
HLOptions m_Options;
std::unique_ptr<OP> m_pOP;
size_t m_pUnused;
uint32_t m_AutoBindingSpace;
DXIL::DefaultLinkage m_DefaultLinkage;
std::unique_ptr<DxilSubobjects> m_pSubobjects;
// DXIL metadata serialization/deserialization.
llvm::MDTuple *EmitHLResources();
void LoadHLResources(const llvm::MDOperand &MDO);
llvm::MDTuple *EmitHLShaderProperties();
void LoadHLShaderProperties(const llvm::MDOperand &MDO);
llvm::MDTuple *EmitDxilShaderProperties();
// LLVM used.
std::vector<llvm::GlobalVariable *> m_LLVMUsed;
// Type annotations.
std::unique_ptr<DxilTypeSystem> m_pTypeSystem;
// Helpers.
template <typename T>
unsigned AddResource(std::vector<std::unique_ptr<T>> &Vec,
std::unique_ptr<T> pRes);
};
/// Use this class to manipulate metadata of extra metadata record properties
/// that are specific to high-level DX IR.
class HLExtraPropertyHelper : public DxilExtraPropertyHelper {
public:
HLExtraPropertyHelper(llvm::Module *pModule);
virtual ~HLExtraPropertyHelper() {}
virtual void
EmitSignatureElementProperties(const DxilSignatureElement &SE,
std::vector<llvm::Metadata *> &MDVals);
virtual void LoadSignatureElementProperties(const llvm::MDOperand &MDO,
DxilSignatureElement &SE);
};
} // namespace hlsl