RDAT: Check flags and WaveSize for min SM; fix flag detection and merging (#6207)

Add ShaderKind::Last_1_8 for shader mask
Add shader model comments before flag groupings in DxilConstants.h and DxilShaderFlags.

Add missing flag checks for min shader model in RDAT function info. Move ShaderCompatInfo computation into DxilModule, propagate callee info.

Move computation of shader model requirements based on flags into DxilModule. Finalize requirements for entry functions in AdjustMinimumShaderModelAndFlags.

Fixes for function level flag tracking:
- DerivativesInMeshAndAmpShaders: use flag to track deriv use, then adjust for entry functions.
- hasUAVs: based on resource use in function instead of global resources.
- WriteableMSAATextures: based on use in function instead of global resources.
  - Also catch cases for dynamic res from any use by looking at create/annotate handle, not just the TextureStoreSample op.
- RaytracingTier1_1: move module-level detection to CollectShaderFlagsForModule
- Marked deriv and quad ops as being supported in node.
- Fixed SampleCmpBias to be considered gradient op.
- Update RDAT definitions to dump more useful info for testing

Fixes #6218.
This commit is contained in:
Tex Riddell 2024-02-09 17:14:12 -08:00 коммит произвёл GitHub
Родитель 53b2930a1b
Коммит 9c518dbd94
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: B5690EEEBB952194
47 изменённых файлов: 3228 добавлений и 318 удалений

Просмотреть файл

@ -60,6 +60,22 @@ inline int CompareVersions(unsigned Major1, unsigned Minor1, unsigned Major2,
return 0;
}
// Utility for updating major,minor to max of current and new.
inline bool UpdateToMaxOfVersions(unsigned &major, unsigned &minor,
unsigned newMajor, unsigned newMinor) {
if (newMajor > major) {
major = newMajor;
minor = newMinor;
return true;
} else if (newMajor == major) {
if (newMinor > minor) {
minor = newMinor;
return true;
}
}
return false;
}
// Shader flags.
const unsigned kDisableOptimizations =
0x00000001; // D3D11_1_SB_GLOBAL_FLAG_SKIP_OPTIMIZATION
@ -211,7 +227,8 @@ enum class ShaderKind {
Last_1_2 = Compute,
Last_1_4 = Callable,
Last_1_7 = Amplification,
LastValid = Node,
Last_1_8 = Node,
LastValid = Last_1_8,
};
// clang-format off
@ -1862,12 +1879,22 @@ const uint64_t
0x2000;
const uint64_t ShaderFeatureInfo_WaveOps = 0x4000;
const uint64_t ShaderFeatureInfo_Int64Ops = 0x8000;
// SM 6.1+
const uint64_t ShaderFeatureInfo_ViewID = 0x10000;
const uint64_t ShaderFeatureInfo_Barycentrics = 0x20000;
// SM 6.2+
const uint64_t ShaderFeatureInfo_NativeLowPrecision = 0x40000;
// SM 6.4+
const uint64_t ShaderFeatureInfo_ShadingRate = 0x80000;
// SM 6.5+
const uint64_t ShaderFeatureInfo_Raytracing_Tier_1_1 = 0x100000;
const uint64_t ShaderFeatureInfo_SamplerFeedback = 0x200000;
// SM 6.6+
const uint64_t ShaderFeatureInfo_AtomicInt64OnTypedResource = 0x400000;
const uint64_t ShaderFeatureInfo_AtomicInt64OnGroupShared = 0x800000;
const uint64_t ShaderFeatureInfo_DerivativesInMeshAndAmpShaders = 0x1000000;
@ -1881,13 +1908,41 @@ const uint64_t ShaderFeatureInfo_AdvancedTextureOps = 0x20000000;
const uint64_t ShaderFeatureInfo_WriteableMSAATextures = 0x40000000;
// SM 6.8+
// WaveMMA slots in between two SM 6.6 feature bits.
const uint64_t ShaderFeatureInfo_WaveMMA = 0x8000000;
const uint64_t ShaderFeatureInfo_SampleCmpGradientOrBias = 0x80000000;
const uint64_t ShaderFeatureInfo_ExtendedCommandInfo = 0x100000000;
// Experimental SM 6.9+ - Reserved, not yet supported.
// WaveMMA slots in between two SM 6.6 feature bits.
const uint64_t ShaderFeatureInfo_WaveMMA = 0x8000000;
// Maximum count without rolling over into another 64-bit field is 40,
// so the last flag we can use for a feature requirement is: 0x8000000000
// This is because of the following set of flags, considered optional
// and ignored by the runtime if not recognized:
// D3D11_OPTIONAL_FEATURE_FLAGS 0x7FFFFF0000000000
const unsigned ShaderFeatureInfoCount = 33;
static_assert(ShaderFeatureInfoCount <= 40,
"ShaderFeatureInfo flags must fit within the first 40 bits; "
"after that we need to expand the FeatureInfo blob part and "
"start defining a new set of flags for ShaderFeatureInfo2.");
// OptFeatureInfo flags in higher bits of DFCC_FeatureInfo uint64_t value.
// This section is for flags that do not necessarily indicate a required
// feature, but are used to indicate something about the shader.
// Some of these flags may not actually show up in DFCC_FeatureInfo, instead
// only being used in intermediate feature info and in RDAT's FeatureInfo.
// Create flag here for any derivative use. This allows call-graph validation
// in the runtime to detect misuse of derivatives for an entry point that cannot
// support it, or to determine when the flag
// ShaderFeatureInfo_DerivativesInMeshAndAmpShaders is required.
const uint64_t OptFeatureInfo_UsesDerivatives = 0x0000010000000000ULL;
const uint64_t OptFeatureInfoShift = 40;
const unsigned OptFeatureInfoCount = 1;
static_assert(OptFeatureInfoCount <= 23,
"OptFeatureInfo flags must fit in 23 bits; after that we need to "
"expand the FeatureInfo blob part and start defining a new set "
"of flags for OptFeatureInfo2.");
// DxilSubobjectType must match D3D12_STATE_SUBOBJECT_TYPE, with
// certain values reserved, since they cannot be used from Dxil.

Просмотреть файл

@ -404,6 +404,32 @@ private:
std::unique_ptr<T> pRes);
void LoadDxilSignature(const llvm::MDTuple *pSigTuple, DxilSignature &Sig,
bool bInput);
public:
// ShaderCompatInfo tracks requirements per-function, subsequently merged into
// final entry function requirements.
struct ShaderCompatInfo {
unsigned minMajor = 6, minMinor = 0;
// 'mask' is a set of bits representing each compatible shader kind.
// Mapping is: 1 << (unsigned)DXIL::ShaderKind::<kind>.
// Starts out with all kinds valid, will be masked down based on features
// used and by known shader kinds for a particular validation version.
unsigned mask = ((unsigned)1 << (unsigned)DXIL::ShaderKind::Invalid) - 1;
ShaderFlags shaderFlags;
bool Merge(ShaderCompatInfo &other);
};
// Compute ShaderCompatInfo for all functions in module.
void ComputeShaderCompatInfo();
const ShaderCompatInfo *
GetCompatInfoForFunction(const llvm::Function *F) const;
private:
typedef std::unordered_map<const llvm::Function *, ShaderCompatInfo>
FunctionShaderCompatMap;
FunctionShaderCompatMap m_FuncToShaderCompat;
void UpdateFunctionToShaderCompat(const llvm::Function *dxilFunc);
};
} // namespace hlsl

Просмотреть файл

@ -15,6 +15,7 @@
namespace hlsl {
class DxilModule;
struct DxilFunctionProps;
}
namespace llvm {
@ -125,24 +126,29 @@ public:
void SetUAVsAtEveryStage(bool flag) { m_UAVsAtEveryStage = flag; }
bool GetUAVsAtEveryStage() const { return m_UAVsAtEveryStage; }
// SM 6.1+
void SetViewID(bool flag) { m_bViewID = flag; }
bool GetViewID() const { return m_bViewID; }
void SetBarycentrics(bool flag) { m_bBarycentrics = flag; }
bool GetBarycentrics() const { return m_bBarycentrics; }
// SM 6.2+
void SetUseNativeLowPrecision(bool flag) { m_bUseNativeLowPrecision = flag; }
bool GetUseNativeLowPrecision() const { return m_bUseNativeLowPrecision; }
// SM 6.4+
void SetShadingRate(bool flag) { m_bShadingRate = flag; }
bool GetShadingRate() const { return m_bShadingRate; }
// SM 6.5+
void SetRaytracingTier1_1(bool flag) { m_bRaytracingTier1_1 = flag; }
bool GetRaytracingTier1_1() const { return m_bRaytracingTier1_1; }
void SetSamplerFeedback(bool flag) { m_bSamplerFeedback = flag; }
bool GetSamplerFeedback() const { return m_bSamplerFeedback; }
// SM 6.6+
void SetAtomicInt64OnTypedResource(bool flag) {
m_bAtomicInt64OnTypedResource = flag;
}
@ -160,7 +166,7 @@ public:
void SetDerivativesInMeshAndAmpShaders(bool flag) {
m_bDerivativesInMeshAndAmpShaders = flag;
}
bool GetDerivativesInMeshAndAmpShaders() {
bool GetDerivativesInMeshAndAmpShaders() const {
return m_bDerivativesInMeshAndAmpShaders;
}
@ -185,6 +191,7 @@ public:
return m_bSamplerDescriptorHeapIndexing;
}
// SM 6.7+
void SetResMayNotAlias(bool flag) { m_bResMayNotAlias = flag; }
bool GetResMayNotAlias() const { return m_bResMayNotAlias; }
@ -194,9 +201,7 @@ public:
void SetWriteableMSAATextures(bool flag) { m_bWriteableMSAATextures = flag; }
bool GetWriteableMSAATextures() const { return m_bWriteableMSAATextures; }
void SetWaveMMA(bool flag) { m_bWaveMMA = flag; }
bool GetWaveMMA() const { return m_bWaveMMA; }
// SM 6.8+
void SetSampleCmpGradientOrBias(bool flag) {
m_bSampleCmpGradientOrBias = flag;
}
@ -205,7 +210,16 @@ public:
void SetExtendedCommandInfo(bool flag) { m_bExtendedCommandInfo = flag; }
bool GetExtendedCommandInfo() const { return m_bExtendedCommandInfo; }
// Experimental SM 6.9+ - Reserved, not yet supported.
void SetWaveMMA(bool flag) { m_bWaveMMA = flag; }
bool GetWaveMMA() const { return m_bWaveMMA; }
// Per-function flag
void SetUsesDerivatives(bool flag) { m_bUsesDerivatives = flag; }
bool GetUsesDerivatives() const { return m_bUsesDerivatives; }
private:
// Bit: 0
unsigned
m_bDisableOptimizations : 1; // D3D11_1_SB_GLOBAL_FLAG_SKIP_OPTIMIZATION
unsigned
@ -214,6 +228,8 @@ private:
m_bEnableDoublePrecision : 1; // D3D11_SB_GLOBAL_FLAG_ENABLE_DOUBLE_PRECISION_FLOAT_OPS
unsigned
m_bForceEarlyDepthStencil : 1; // D3D11_SB_GLOBAL_FLAG_FORCE_EARLY_DEPTH_STENCIL
// Bit: 4
unsigned
m_bEnableRawAndStructuredBuffers : 1; // D3D11_SB_GLOBAL_FLAG_ENABLE_RAW_AND_STRUCTURED_BUFFERS
unsigned
@ -221,12 +237,16 @@ private:
unsigned
m_bEnableDoubleExtensions : 1; // D3D11_1_SB_GLOBAL_FLAG_ENABLE_DOUBLE_EXTENSIONS
unsigned m_bEnableMSAD : 1; // D3D11_1_SB_GLOBAL_FLAG_ENABLE_SHADER_EXTENSIONS
// Bit: 8
unsigned m_bAllResourcesBound : 1; // D3D12_SB_GLOBAL_FLAG_ALL_RESOURCES_BOUND
unsigned
m_bViewportAndRTArrayIndex : 1; // SHADER_FEATURE_VIEWPORT_AND_RT_ARRAY_INDEX_FROM_ANY_SHADER_FEEDING_RASTERIZER
unsigned m_bInnerCoverage : 1; // SHADER_FEATURE_INNER_COVERAGE
unsigned m_bStencilRef : 1; // SHADER_FEATURE_STENCIL_REF
// Bit: 12
unsigned m_bTiledResources : 1; // SHADER_FEATURE_TILED_RESOURCES
unsigned
m_bUAVLoadAdditionalFormats : 1; // SHADER_FEATURE_TYPED_UAV_LOAD_ADDITIONAL_FORMATS
@ -235,6 +255,8 @@ private:
// SHADER_FEATURE_11_1_SHADER_EXTENSIONS
// shared with EnableMSAD
unsigned m_b64UAVs : 1; // SHADER_FEATURE_64_UAVS
// Bit: 16
unsigned m_UAVsAtEveryStage : 1; // SHADER_FEATURE_UAVS_AT_EVERY_STAGE
unsigned
m_bCSRawAndStructuredViaShader4X : 1; // SHADER_FEATURE_COMPUTE_SHADERS_PLUS_RAW_AND_STRUCTURED_BUFFERS_VIA_SHADER_4_X
@ -242,32 +264,47 @@ private:
// SHADER_FEATURE_COMPUTE_SHADERS_PLUS_RAW_AND_STRUCTURED_BUFFERS_VIA_SHADER_4_X
// is specifically about shader model 4.x.
// Bit: 18
unsigned m_bROVS : 1; // SHADER_FEATURE_ROVS
unsigned m_bWaveOps : 1; // SHADER_FEATURE_WAVE_OPS
unsigned m_bInt64Ops : 1; // SHADER_FEATURE_INT64_OPS
// Bit: 20
unsigned m_bInt64Ops : 1; // SHADER_FEATURE_INT64_OPS
// SM 6.1+
unsigned m_bViewID : 1; // SHADER_FEATURE_VIEWID
unsigned m_bBarycentrics : 1; // SHADER_FEATURE_BARYCENTRICS
// SM 6.2+
unsigned m_bUseNativeLowPrecision : 1;
// SM 6.4+
// Bit: 24
unsigned m_bShadingRate : 1; // SHADER_FEATURE_SHADINGRATE
// SM 6.5+
// Bit: 25
unsigned m_bRaytracingTier1_1 : 1; // SHADER_FEATURE_RAYTRACING_TIER_1_1
unsigned m_bSamplerFeedback : 1; // SHADER_FEATURE_SAMPLER_FEEDBACK
// SM 6.6+
// Bit: 27
unsigned
m_bAtomicInt64OnTypedResource : 1; // SHADER_FEATURE_ATOMIC_INT64_ON_TYPED_RESOURCE
unsigned
m_bAtomicInt64OnGroupShared : 1; // SHADER_FEATURE_ATOMIC_INT64_ON_GROUP_SHARED
// Bit: 29
unsigned
m_bDerivativesInMeshAndAmpShaders : 1; // SHADER_FEATURE_DERIVATIVES_IN_MESH_AND_AMPLIFICATION_SHADERS
// Bit: 30
unsigned
m_bResourceDescriptorHeapIndexing : 1; // SHADER_FEATURE_RESOURCE_DESCRIPTOR_HEAP_INDEXING
unsigned
m_bSamplerDescriptorHeapIndexing : 1; // SHADER_FEATURE_SAMPLER_DESCRIPTOR_HEAP_INDEXING
// Bit: 32
unsigned
m_bAtomicInt64OnHeapResource : 1; // SHADER_FEATURE_ATOMIC_INT64_ON_DESCRIPTOR_HEAP_RESOURCE
@ -276,18 +313,30 @@ private:
// Set if UAVs are used, unless -res-may-alias was specified.
// For modules compiled against validator version < 1.7, this flag will be
// cleared, and it must be assumed that UAV resources may alias.
// Bit: 33
unsigned m_bResMayNotAlias : 1;
// Bit: 34
unsigned m_bAdvancedTextureOps : 1; // SHADER_FEATURE_ADVANCED_TEXTURE_OPS
unsigned
m_bWriteableMSAATextures : 1; // SHADER_FEATURE_WRITEABLE_MSAA_TEXTURES
// SM 6.8+
// Experimental SM 6.9+ - Reserved, not yet supported.
// Bit: 36
unsigned m_bWaveMMA : 1; // SHADER_FEATURE_WAVE_MMA
// SM 6.8+
// Bit: 37
unsigned
m_bSampleCmpGradientOrBias : 1; // SHADER_FEATURE_SAMPLE_CMP_GRADIENT_OR_BIAS
unsigned m_bExtendedCommandInfo : 1; // SHADER_FEATURE_EXTENDED_COMMAND_INFO
uint32_t m_align1 : 25; // align to 64 bit.
// Per-function flag
// Bit: 39
unsigned m_bUsesDerivatives : 1; // SHADER_FEATURE_OPT_USES_DERIVATIVES
// (OptFeatureInfo_UsesDerivatives)
uint32_t m_align1 : 24; // align to 64 bit.
};
} // namespace hlsl

Просмотреть файл

@ -53,7 +53,9 @@ DxilPartWriter *NewRootSignatureWriter(const RootSignatureHandle &S);
DxilPartWriter *NewFeatureInfoWriter(const DxilModule &M);
DxilPartWriter *NewPSVWriter(const DxilModule &M,
uint32_t PSVVersion = UINT_MAX);
DxilPartWriter *NewRDATWriter(const DxilModule &M);
// DxilModule is non-const because it caches per-function flag computations
// used by both CollectShaderFlagsForModule and RDATWriter.
DxilPartWriter *NewRDATWriter(DxilModule &M);
DxilPartWriter *NewVersionWriter(IDxcVersionInfo *pVersionInfo);
// Store serialized ViewID data from DxilModule to PipelineStateValidation.

Просмотреть файл

@ -24,6 +24,74 @@ RDAT_ENUM_START(DxilResourceFlag, uint32_t)
RDAT_ENUM_VALUE(Atomics64Use, 1 << 4)
RDAT_ENUM_END()
RDAT_ENUM_START(DxilShaderStageFlags, uint32_t)
RDAT_ENUM_VALUE(Pixel, (1 << (uint32_t)hlsl::DXIL::ShaderKind::Pixel))
RDAT_ENUM_VALUE(Vertex, (1 << (uint32_t)hlsl::DXIL::ShaderKind::Vertex))
RDAT_ENUM_VALUE(Geometry, (1 << (uint32_t)hlsl::DXIL::ShaderKind::Geometry))
RDAT_ENUM_VALUE(Hull, (1 << (uint32_t)hlsl::DXIL::ShaderKind::Hull))
RDAT_ENUM_VALUE(Domain, (1 << (uint32_t)hlsl::DXIL::ShaderKind::Domain))
RDAT_ENUM_VALUE(Compute, (1 << (uint32_t)hlsl::DXIL::ShaderKind::Compute))
RDAT_ENUM_VALUE(Library, (1 << (uint32_t)hlsl::DXIL::ShaderKind::Library))
RDAT_ENUM_VALUE(RayGeneration, (1 << (uint32_t)hlsl::DXIL::ShaderKind::RayGeneration))
RDAT_ENUM_VALUE(Intersection, (1 << (uint32_t)hlsl::DXIL::ShaderKind::Intersection))
RDAT_ENUM_VALUE(AnyHit, (1 << (uint32_t)hlsl::DXIL::ShaderKind::AnyHit))
RDAT_ENUM_VALUE(ClosestHit, (1 << (uint32_t)hlsl::DXIL::ShaderKind::ClosestHit))
RDAT_ENUM_VALUE(Miss, (1 << (uint32_t)hlsl::DXIL::ShaderKind::Miss))
RDAT_ENUM_VALUE(Callable, (1 << (uint32_t)hlsl::DXIL::ShaderKind::Callable))
RDAT_ENUM_VALUE(Mesh, (1 << (uint32_t)hlsl::DXIL::ShaderKind::Mesh))
RDAT_ENUM_VALUE(Amplification, (1 << (uint32_t)hlsl::DXIL::ShaderKind::Amplification))
RDAT_ENUM_VALUE(Node, (1 << (uint32_t)hlsl::DXIL::ShaderKind::Node))
RDAT_ENUM_END()
// Low 32-bits of ShaderFeatureInfo from DFCC_FeatureInfo
RDAT_ENUM_START(DxilFeatureInfo1, uint32_t)
RDAT_ENUM_VALUE(Doubles, 0x0001)
RDAT_ENUM_VALUE(ComputeShadersPlusRawAndStructuredBuffersViaShader4X, 0x0002)
RDAT_ENUM_VALUE(UAVsAtEveryStage, 0x0004)
RDAT_ENUM_VALUE(_64UAVs, 0x0008)
RDAT_ENUM_VALUE(MinimumPrecision, 0x0010)
RDAT_ENUM_VALUE(_11_1_DoubleExtensions, 0x0020)
RDAT_ENUM_VALUE(_11_1_ShaderExtensions, 0x0040)
RDAT_ENUM_VALUE(LEVEL9ComparisonFiltering, 0x0080)
RDAT_ENUM_VALUE(TiledResources, 0x0100)
RDAT_ENUM_VALUE(StencilRef, 0x0200)
RDAT_ENUM_VALUE(InnerCoverage, 0x0400)
RDAT_ENUM_VALUE(TypedUAVLoadAdditionalFormats, 0x0800)
RDAT_ENUM_VALUE(ROVs, 0x1000)
RDAT_ENUM_VALUE(ViewportAndRTArrayIndexFromAnyShaderFeedingRasterizer, 0x2000)
RDAT_ENUM_VALUE(WaveOps, 0x4000)
RDAT_ENUM_VALUE(Int64Ops, 0x8000)
RDAT_ENUM_VALUE(ViewID, 0x10000)
RDAT_ENUM_VALUE(Barycentrics, 0x20000)
RDAT_ENUM_VALUE(NativeLowPrecision, 0x40000)
RDAT_ENUM_VALUE(ShadingRate, 0x80000)
RDAT_ENUM_VALUE(Raytracing_Tier_1_1, 0x100000)
RDAT_ENUM_VALUE(SamplerFeedback, 0x200000)
RDAT_ENUM_VALUE(AtomicInt64OnTypedResource, 0x400000)
RDAT_ENUM_VALUE(AtomicInt64OnGroupShared, 0x800000)
RDAT_ENUM_VALUE(DerivativesInMeshAndAmpShaders, 0x1000000)
RDAT_ENUM_VALUE(ResourceDescriptorHeapIndexing, 0x2000000)
RDAT_ENUM_VALUE(SamplerDescriptorHeapIndexing, 0x4000000)
RDAT_ENUM_VALUE(WaveMMA, 0x8000000)
RDAT_ENUM_VALUE(AtomicInt64OnHeapResource, 0x10000000)
RDAT_ENUM_VALUE(AdvancedTextureOps, 0x20000000)
RDAT_ENUM_VALUE(WriteableMSAATextures, 0x40000000)
RDAT_ENUM_VALUE(SampleCmpGradientOrBias, 0x80000000)
RDAT_ENUM_END()
// High 32-bits of ShaderFeatureInfo from DFCC_FeatureInfo
RDAT_ENUM_START(DxilFeatureInfo2, uint32_t)
RDAT_ENUM_VALUE(ExtendedCommandInfo, 0x1)
// OptFeatureInfo flags
RDAT_ENUM_VALUE(Opt_UsesDerivatives, 0x100)
#if DEF_RDAT_ENUMS == DEF_RDAT_DUMP_IMPL
static_assert(DXIL::ShaderFeatureInfoCount == 33,
"otherwise, RDAT_ENUM definition needs updating");
static_assert(DXIL::OptFeatureInfoCount == 1,
"otherwise, RDAT_ENUM definition needs updating");
#endif
RDAT_ENUM_END()
#endif // DEF_RDAT_ENUMS
#ifdef DEF_DXIL_ENUMS
@ -136,13 +204,13 @@ RDAT_STRUCT_TABLE(RuntimeDataFunctionInfo, FunctionTable)
// attribute size for closest hit and any hit
RDAT_VALUE(uint32_t, AttributeSizeInBytes)
// first 32 bits of feature flag
RDAT_VALUE(uint32_t, FeatureInfo1)
RDAT_FLAGS(uint32_t, hlsl::RDAT::DxilFeatureInfo1, FeatureInfo1)
// second 32 bits of feature flag
RDAT_VALUE(uint32_t, FeatureInfo2)
RDAT_FLAGS(uint32_t, hlsl::RDAT::DxilFeatureInfo2, FeatureInfo2)
// valid shader stage flag.
RDAT_VALUE(uint32_t, ShaderStageFlag)
RDAT_FLAGS(uint32_t, hlsl::RDAT::DxilShaderStageFlags, ShaderStageFlag)
// minimum shader target.
RDAT_VALUE(uint32_t, MinShaderTarget)
RDAT_VALUE_HEX(uint32_t, MinShaderTarget)
#if DEF_RDAT_TYPES == DEF_RDAT_TYPES_USE_HELPERS
// void SetFeatureFlags(uint64_t flags) convenience method
@ -154,10 +222,10 @@ RDAT_STRUCT_TABLE(RuntimeDataFunctionInfo, FunctionTable)
#if DEF_RDAT_TYPES == DEF_RDAT_READER_DECL
// uint64_t GetFeatureFlags() convenience method
uint64_t GetFeatureFlags();
uint64_t GetFeatureFlags() const;
#elif DEF_RDAT_TYPES == DEF_RDAT_READER_IMPL
// uint64_t GetFeatureFlags() convenience method
uint64_t RuntimeDataFunctionInfo_Reader::GetFeatureFlags() {
uint64_t RuntimeDataFunctionInfo_Reader::GetFeatureFlags() const {
return asRecord() ? (((uint64_t)asRecord()->FeatureInfo2 << 32) |
(uint64_t)asRecord()->FeatureInfo1)
: 0;

Просмотреть файл

@ -312,6 +312,8 @@
d.WriteLn(#name ": ", QuotedStringValue(name.Get(ctx)));
#define RDAT_STRING_ARRAY_REF(name) DumpStringArray(ctx, d, #name, name);
#define RDAT_VALUE(type, name) d.WriteLn(#name ": ", name);
#define RDAT_VALUE_HEX(type, name) \
d.WriteLn(#name ": ", std::hex, std::showbase, name);
#define RDAT_INDEX_ARRAY_REF(name) DumpIndexArray(ctx, d, #name, name);
#define RDAT_ENUM(sTy, eTy, name) d.DumpEnum<eTy>(#name, (eTy)name);
#define RDAT_FLAGS(sTy, eTy, name) d.DumpFlags<eTy, sTy>(#name, name);
@ -401,6 +403,9 @@
#ifndef RDAT_VALUE
#define RDAT_VALUE(type, name)
#endif
#ifndef RDAT_VALUE_HEX
#define RDAT_VALUE_HEX(type, name) RDAT_VALUE(type, name)
#endif
#ifndef RDAT_INDEX_ARRAY_REF
#define RDAT_INDEX_ARRAY_REF(name) // ref to array of uint32_t values
#endif
@ -515,6 +520,7 @@
#undef RDAT_STRING
#undef RDAT_STRING_ARRAY_REF
#undef RDAT_VALUE
#undef RDAT_VALUE_HEX
#undef RDAT_INDEX_ARRAY_REF
#undef RDAT_ENUM
#undef RDAT_FLAGS

Просмотреть файл

@ -288,11 +288,39 @@ unsigned DxilModule::GetGlobalFlags() const {
return Flags;
}
static bool RequiresRaytracingTier1_1(const DxilSubobjects *pSubobjects) {
if (!pSubobjects)
return false;
for (const auto &it : pSubobjects->GetSubobjects()) {
switch (it.second->GetKind()) {
case DXIL::SubobjectKind::RaytracingPipelineConfig1:
return true;
case DXIL::SubobjectKind::StateObjectConfig: {
uint32_t configFlags;
if (it.second->GetStateObjectConfig(configFlags) &&
((configFlags &
(unsigned)DXIL::StateObjectFlags::AllowStateObjectAdditions) != 0))
return true;
} break;
default:
break;
}
}
return false;
}
void DxilModule::CollectShaderFlagsForModule(ShaderFlags &Flags) {
for (Function &F : GetModule()->functions()) {
ShaderFlags funcFlags = ShaderFlags::CollectShaderFlags(&F, this);
Flags.CombineShaderFlags(funcFlags);
};
ComputeShaderCompatInfo();
for (auto &itInfo : m_FuncToShaderCompat)
Flags.CombineShaderFlags(itInfo.second.shaderFlags);
// Clear UsesDerivatives flag for module, making sure
// DerivativesInMeshAndAmpShaders is set for MS/AS.
if (Flags.GetUsesDerivatives()) {
Flags.SetUsesDerivatives(false);
if (m_pSM->IsMS() || m_pSM->IsAS())
Flags.SetDerivativesInMeshAndAmpShaders(true);
}
const ShaderModel *SM = GetShaderModel();
@ -322,8 +350,18 @@ void DxilModule::CollectShaderFlagsForModule(ShaderFlags &Flags) {
else
Flags.Set64UAVs(NumUAVs > kSmallUAVCount);
if (NumUAVs && !(SM->IsCS() || SM->IsPS()))
Flags.SetUAVsAtEveryStage(true);
if (DXIL::CompareVersions(m_ValMajor, m_ValMinor, 1, 8) < 0) {
// For 1.7 compatibility, set UAVsAtEveryStage if there are UAVs
// and the shader model is not CS or PS.
if (NumUAVs && !(SM->IsCS() || SM->IsPS()))
Flags.SetUAVsAtEveryStage(true);
} else {
// Starting with 1.8, UAVsAtEveryStage is only set when the shader model is
// a graphics stage where it mattered. It was unnecessary to set it for
// library profiles, or MS/AS profiles.
if (NumUAVs && (SM->IsVS() || SM->IsHS() || SM->IsDS() || SM->IsGS()))
Flags.SetUAVsAtEveryStage(true);
}
for (auto &SRV : m_SRVs) {
switch (SRV->GetKind()) {
@ -342,6 +380,10 @@ void DxilModule::CollectShaderFlagsForModule(ShaderFlags &Flags) {
bool hasCSRawAndStructuredViaShader4X =
hasRawAndStructuredBuffer && m_pSM->GetMajor() == 4 && m_pSM->IsCS();
Flags.SetCSRawAndStructuredViaShader4X(hasCSRawAndStructuredViaShader4X);
if (!Flags.GetRaytracingTier1_1()) {
Flags.SetRaytracingTier1_1(RequiresRaytracingTier1_1(GetSubobjects()));
}
}
void DxilModule::CollectShaderFlagsForModule() {
@ -2081,4 +2123,243 @@ bool DxilModule::IsPrecise(const Instruction *inst) const {
return false;
}
bool DxilModule::ShaderCompatInfo::Merge(ShaderCompatInfo &other) {
bool changed = DXIL::UpdateToMaxOfVersions(minMajor, minMinor, other.minMajor,
other.minMinor);
if ((mask & other.mask) != mask) {
mask &= other.mask;
changed = true;
}
uint64_t rawBefore = shaderFlags.GetShaderFlagsRaw();
shaderFlags.CombineShaderFlags(other.shaderFlags);
if (rawBefore != shaderFlags.GetShaderFlagsRaw())
changed = true;
return changed;
}
// Use the function properties `props` to determine the minimum shader model and
// flag requirements based on shader stage and feature usage.
// Compare that minimum required version to the values passed in with
// `minMajor` and `minMinor` and pass the maximum of those back through those
// same variables.
// Return adjusted `ShaderFlags` according to `props` set.
static ShaderFlags
AdjustMinimumShaderModelAndFlags(ShaderFlags flags,
const DxilFunctionProps *props,
unsigned &minMajor, unsigned &minMinor) {
// Adjust flags based on DxilFunctionProps and compute minimum shader model.
// Library functions use flags to capture properties that may or may not be
// used in the final shader, depending on that final shader's shader model.
// These flags will be combined up a call graph until we hit an entry,
// function, at which point, these flags and minimum shader model need to be
// adjusted.
// For instance: derivatives are allowed in CS/MS/AS in 6.6+, and for MS/AS,
// a feature bit is required. Libary functions will capture any derivative
// use into the UsesDerivatives feature bit, which is used to calculate the
// final requirements once we reach an entry function.
// Adjust things based on known shader entry point once we have one.
// This must be done after combining flags from called functions.
if (props) {
// This flag doesn't impact min shader model until we know what kind of
// entry point we have. Then, we may need to clear the flag, when it doesn't
// apply.
if (flags.GetUsesDerivatives()) {
if (props->IsCS()) {
// Always supported if SM 6.6+.
DXIL::UpdateToMaxOfVersions(minMajor, minMinor, 6, 6);
} else if (props->IsMS() || props->IsAS()) {
// Requires flag for support on SM 6.6+.
flags.SetDerivativesInMeshAndAmpShaders(true);
DXIL::UpdateToMaxOfVersions(minMajor, minMinor, 6, 6);
}
}
// If function has WaveSize, this also constrains the minimum shader model.
if (props->WaveSize.IsDefined()) {
if (props->WaveSize.IsRange())
DXIL::UpdateToMaxOfVersions(minMajor, minMinor, 6, 8);
else
DXIL::UpdateToMaxOfVersions(minMajor, minMinor, 6, 6);
}
// Adjust minimum shader model based on shader stage.
if (props->IsMS() || props->IsAS())
DXIL::UpdateToMaxOfVersions(minMajor, minMinor, 6, 5);
else if (props->IsRay())
DXIL::UpdateToMaxOfVersions(minMajor, minMinor, 6, 3);
else if (props->IsNode())
DXIL::UpdateToMaxOfVersions(minMajor, minMinor, 6, 8);
}
// Adjust minimum shader model based on flags.
if (flags.GetWaveMMA())
DXIL::UpdateToMaxOfVersions(minMajor, minMinor, 6, 9);
else if (flags.GetSampleCmpGradientOrBias() || flags.GetExtendedCommandInfo())
DXIL::UpdateToMaxOfVersions(minMajor, minMinor, 6, 8);
else if (flags.GetAdvancedTextureOps() || flags.GetWriteableMSAATextures())
DXIL::UpdateToMaxOfVersions(minMajor, minMinor, 6, 7);
else if (flags.GetAtomicInt64OnTypedResource() ||
flags.GetAtomicInt64OnGroupShared() ||
flags.GetAtomicInt64OnHeapResource() ||
flags.GetResourceDescriptorHeapIndexing() ||
flags.GetSamplerDescriptorHeapIndexing())
DXIL::UpdateToMaxOfVersions(minMajor, minMinor, 6, 6);
else if (flags.GetRaytracingTier1_1() || flags.GetSamplerFeedback())
DXIL::UpdateToMaxOfVersions(minMajor, minMinor, 6, 5);
else if (flags.GetShadingRate())
DXIL::UpdateToMaxOfVersions(minMajor, minMinor, 6, 4);
else if (flags.GetLowPrecisionPresent() && flags.GetUseNativeLowPrecision())
DXIL::UpdateToMaxOfVersions(minMajor, minMinor, 6, 2);
else if (flags.GetViewID() || flags.GetBarycentrics())
DXIL::UpdateToMaxOfVersions(minMajor, minMinor, 6, 1);
return flags;
}
void DxilModule::ComputeShaderCompatInfo() {
m_FuncToShaderCompat.clear();
bool dxil15Plus = DXIL::CompareVersions(m_ValMajor, m_ValMinor, 1, 5) >= 0;
bool dxil18Plus = DXIL::CompareVersions(m_ValMajor, m_ValMinor, 1, 8) >= 0;
bool dxil19Plus = DXIL::CompareVersions(m_ValMajor, m_ValMinor, 1, 9) >= 0;
// Initialize worklist with functions that have callers
SmallSetVector<llvm::Function *, 8> worklist;
for (auto &function : GetModule()->getFunctionList()) {
if (!function.isDeclaration()) {
// Initialize worklist with functions with callers.
// only used for validator version 1.8+
if (dxil18Plus && !function.user_empty())
worklist.insert(&function);
// Collect shader flags for function.
// Insert or lookup info
ShaderCompatInfo &info = m_FuncToShaderCompat[&function];
info.shaderFlags = ShaderFlags::CollectShaderFlags(&function, this);
} else if (!function.isIntrinsic() &&
function.getLinkage() ==
llvm::GlobalValue::LinkageTypes::ExternalLinkage &&
OP::IsDxilOpFunc(&function)) {
// update min shader model and shader stage mask per function
UpdateFunctionToShaderCompat(&function);
}
}
// Propagate ShaderCompatInfo to callers, limit to 1.8+ for compatibility
if (dxil18Plus) {
while (!worklist.empty()) {
llvm::Function *F = worklist.pop_back_val();
ShaderCompatInfo &calleeInfo = m_FuncToShaderCompat[F];
// Update callers
for (auto U : F->users()) {
if (CallInst *CI = dyn_cast<CallInst>(U)) {
llvm::Function *caller = CI->getParent()->getParent();
// Merge info, if changed and called, add to worklist so we update
// any callers of caller as well.
// Insert or lookup info
if (m_FuncToShaderCompat[caller].Merge(calleeInfo) &&
!caller->user_empty())
worklist.insert(caller);
}
}
}
}
// We must select the appropriate shader mask for the validator version,
// so we don't set any bits the validator doesn't recognize.
unsigned ValidShaderMask =
(1 << ((unsigned)DXIL::ShaderKind::LastValid + 1)) - 1;
if (!dxil15Plus) {
ValidShaderMask = (1 << ((unsigned)DXIL::ShaderKind::Last_1_4 + 1)) - 1;
} else if (!dxil18Plus) {
ValidShaderMask = (1 << ((unsigned)DXIL::ShaderKind::Last_1_7 + 1)) - 1;
} else if (!dxil19Plus) {
ValidShaderMask = (1 << ((unsigned)DXIL::ShaderKind::Last_1_8 + 1)) - 1;
}
for (auto &function : GetModule()->getFunctionList()) {
if (function.isDeclaration())
continue;
DXASSERT(m_FuncToShaderCompat.count(&function) != 0,
"otherwise, function missed earlier somehow!");
ShaderCompatInfo &info = m_FuncToShaderCompat[&function];
DXIL::ShaderKind shaderKind = DXIL::ShaderKind::Library;
const DxilFunctionProps *props = nullptr;
if (HasDxilFunctionProps(&function)) {
props = &GetDxilFunctionProps(&function);
shaderKind = props->shaderKind;
}
if (shaderKind == DXIL::ShaderKind::Library)
info.mask &= ValidShaderMask;
else
info.mask &= (1U << static_cast<unsigned>(shaderKind));
// Increase min target based on features used:
ShaderFlags &flags = info.shaderFlags;
if (dxil18Plus) {
// This handles WaveSize requirement as well.
flags = AdjustMinimumShaderModelAndFlags(flags, props, info.minMajor,
info.minMinor);
} else {
// Match prior versions that were missing some feature detection.
if (flags.GetUseNativeLowPrecision() && flags.GetLowPrecisionPresent())
DXIL::UpdateToMaxOfVersions(info.minMajor, info.minMinor, 6, 2);
else if (flags.GetBarycentrics() || flags.GetViewID())
DXIL::UpdateToMaxOfVersions(info.minMajor, info.minMinor, 6, 1);
}
}
}
void DxilModule::UpdateFunctionToShaderCompat(const llvm::Function *dxilFunc) {
const bool bWithTranslation = GetShaderModel()->IsLib();
#define SFLAG(stage) ((unsigned)1 << (unsigned)DXIL::ShaderKind::stage)
for (const llvm::User *user : dxilFunc->users()) {
if (const llvm::CallInst *CI = dyn_cast<const llvm::CallInst>(user)) {
// Find calling function
const llvm::Function *F =
cast<const llvm::Function>(CI->getParent()->getParent());
// Insert or lookup info
ShaderCompatInfo &info = m_FuncToShaderCompat[F];
unsigned major, minor, mask;
OP::GetMinShaderModelAndMask(CI, bWithTranslation, m_ValMajor, m_ValMinor,
major, minor, mask);
DXIL::UpdateToMaxOfVersions(info.minMajor, info.minMinor, major, minor);
info.mask &= mask;
} else if (const llvm::LoadInst *LI = dyn_cast<LoadInst>(user)) {
// If loading a groupshared variable, limit to CS/AS/MS/Node
if (LI->getPointerAddressSpace() == DXIL::kTGSMAddrSpace) {
const llvm::Function *F =
cast<const llvm::Function>(LI->getParent()->getParent());
// Insert or lookup info
ShaderCompatInfo &info = m_FuncToShaderCompat[F];
info.mask &=
(SFLAG(Compute) | SFLAG(Mesh) | SFLAG(Amplification) | SFLAG(Node));
}
} else if (const llvm::StoreInst *SI = dyn_cast<StoreInst>(user)) {
// If storing to a groupshared variable, limit to CS/AS/MS/Node
if (SI->getPointerAddressSpace() == DXIL::kTGSMAddrSpace) {
const llvm::Function *F =
cast<const llvm::Function>(SI->getParent()->getParent());
// Insert or lookup info
ShaderCompatInfo &info = m_FuncToShaderCompat[F];
info.mask &=
(SFLAG(Compute) | SFLAG(Mesh) | SFLAG(Amplification) | SFLAG(Node));
}
}
}
#undef SFLAG
}
const DxilModule::ShaderCompatInfo *
DxilModule::GetCompatInfoForFunction(const llvm::Function *F) const {
auto it = m_FuncToShaderCompat.find(F);
if (it != m_FuncToShaderCompat.end())
return &it->second;
return nullptr;
}
} // namespace hlsl

Просмотреть файл

@ -2857,9 +2857,9 @@ bool OP::IsDxilOpGradient(OpCode C) {
// OPCODE-GRADIENT:BEGIN
// Instructions: Sample=60, SampleBias=61, SampleCmp=64, CalculateLOD=81,
// DerivCoarseX=83, DerivCoarseY=84, DerivFineX=85, DerivFineY=86,
// WriteSamplerFeedback=174, WriteSamplerFeedbackBias=175
// WriteSamplerFeedback=174, WriteSamplerFeedbackBias=175, SampleCmpBias=255
return (60 <= op && op <= 61) || op == 64 || op == 81 ||
(83 <= op && op <= 86) || (174 <= op && op <= 175);
(83 <= op && op <= 86) || (174 <= op && op <= 175) || op == 255;
// OPCODE-GRADIENT:END
}
@ -2925,7 +2925,7 @@ void OP::GetMinShaderModelAndMask(OpCode C, bool bWithTranslation,
// Instructions: QuadReadLaneAt=122, QuadOp=123
if ((122 <= op && op <= 123)) {
mask = SFLAG(Library) | SFLAG(Compute) | SFLAG(Amplification) |
SFLAG(Mesh) | SFLAG(Pixel);
SFLAG(Mesh) | SFLAG(Pixel) | SFLAG(Node);
return;
}
// Instructions: WaveIsFirstLane=110, WaveGetLaneIndex=111,
@ -2941,15 +2941,10 @@ void OP::GetMinShaderModelAndMask(OpCode C, bool bWithTranslation,
SFLAG(Miss) | SFLAG(Callable) | SFLAG(Node);
return;
}
// Instructions: CalculateLOD=81, DerivCoarseX=83, DerivCoarseY=84,
// DerivFineX=85, DerivFineY=86
if (op == 81 || (83 <= op && op <= 86)) {
mask = SFLAG(Library) | SFLAG(Pixel) | SFLAG(Compute) |
SFLAG(Amplification) | SFLAG(Mesh);
return;
}
// Instructions: Sample=60, SampleBias=61, SampleCmp=64
if ((60 <= op && op <= 61) || op == 64) {
// Instructions: Sample=60, SampleBias=61, SampleCmp=64, CalculateLOD=81,
// DerivCoarseX=83, DerivCoarseY=84, DerivFineX=85, DerivFineY=86
if ((60 <= op && op <= 61) || op == 64 || op == 81 ||
(83 <= op && op <= 86)) {
mask = SFLAG(Library) | SFLAG(Pixel) | SFLAG(Compute) |
SFLAG(Amplification) | SFLAG(Mesh) | SFLAG(Node);
return;
@ -3170,7 +3165,7 @@ void OP::GetMinShaderModelAndMask(OpCode C, bool bWithTranslation,
minor = 7;
}
mask = SFLAG(Library) | SFLAG(Compute) | SFLAG(Amplification) |
SFLAG(Mesh) | SFLAG(Pixel);
SFLAG(Mesh) | SFLAG(Pixel) | SFLAG(Node);
return;
}
// Instructions: BarrierByMemoryType=244, BarrierByMemoryHandle=245,
@ -3230,42 +3225,42 @@ void OP::GetMinShaderModelAndMask(const llvm::CallInst *CI,
GetMinShaderModelAndMask(opcode, bWithTranslation, major, minor, mask);
unsigned op = (unsigned)opcode;
// These ops cannot indicate support for CS, AS, or MS,
// otherwise, it's saying these are guaranteed to be supported
// on the lowest shader model returned by this function
// for these shader stages. For CS, SM 6.6 is required,
// and for AS/MS, an optional feature is required.
// This also breaks compatibility for existing validators.
// We need a different mechanism to be supported in functions
// for runtime linking.
// Instructions: Sample=60, SampleBias=61, SampleCmp=64, CalculateLOD=81,
// DerivCoarseX=83, DerivCoarseY=84, DerivFineX=85, DerivFineY=86
if ((60 <= op && op <= 61) || op == 64 || op == 81 ||
(83 <= op && op <= 86)) {
mask &= ~(SFLAG(Compute) | SFLAG(Amplification) | SFLAG(Mesh));
return;
if (DXIL::CompareVersions(valMajor, valMinor, 1, 8) < 0) {
// In prior validator versions, these ops excluded CS/MS/AS from mask.
// In 1.8, we now have a mechanism to indicate derivative use with an
// independent feature bit. This allows us to fix up the min shader model
// once all bits have been marged from the call graph to the entry point.
// Instructions: Sample=60, SampleBias=61, SampleCmp=64, CalculateLOD=81,
// DerivCoarseX=83, DerivCoarseY=84, DerivFineX=85, DerivFineY=86
if ((60 <= op && op <= 61) || op == 64 || op == 81 ||
(83 <= op && op <= 86)) {
mask &= ~(SFLAG(Compute) | SFLAG(Amplification) | SFLAG(Mesh));
return;
}
}
if (DXIL::CompareVersions(valMajor, valMinor, 1, 5) < 0) {
// validator 1.4 didn't exclude wave ops in mask
if (IsDxilOpWave(opcode))
mask = ((unsigned)1 << (unsigned)DXIL::ShaderKind::Invalid) - 1;
// These shader models don't exist before 1.5
mask &= ~(SFLAG(Amplification) | SFLAG(Mesh));
mask = ((unsigned)1 << (unsigned)DXIL::ShaderKind::Mesh) - 1;
// validator 1.4 didn't have any additional rules applied:
return;
}
// Additional rules are applied manually here.
// Barrier with mode != UAVFenceGlobal requires compute, amplification, or
// mesh Instructions: Barrier=80
// Barrier with mode != UAVFenceGlobal requires compute, amplification,
// mesh, or node. Instructions: Barrier=80
if (opcode == DXIL::OpCode::Barrier) {
DxilInst_Barrier barrier(const_cast<CallInst *>(CI));
unsigned mode = barrier.get_barrierMode_val();
if (mode != (unsigned)DXIL::BarrierMode::UAVFenceGlobal) {
mask =
SFLAG(Library) | SFLAG(Compute) | SFLAG(Amplification) | SFLAG(Mesh);
// Barrier mode should be a constant, but be robust to non-constants here.
if (isa<ConstantInt>(
CI->getArgOperand(DxilInst_Barrier::arg_barrierMode))) {
DxilInst_Barrier barrier(const_cast<CallInst *>(CI));
unsigned mode = barrier.get_barrierMode_val();
if (mode != (unsigned)DXIL::BarrierMode::UAVFenceGlobal) {
mask &= SFLAG(Library) | SFLAG(Compute) | SFLAG(Amplification) |
SFLAG(Mesh) | SFLAG(Node);
}
}
return;
}

Просмотреть файл

@ -46,7 +46,7 @@ ShaderFlags::ShaderFlags()
m_bAtomicInt64OnHeapResource(false), m_bResMayNotAlias(false),
m_bAdvancedTextureOps(false), m_bWriteableMSAATextures(false),
m_bWaveMMA(false), m_bSampleCmpGradientOrBias(false),
m_bExtendedCommandInfo(false), m_align1(0) {
m_bExtendedCommandInfo(false), m_bUsesDerivatives(false), m_align1(0) {
// Silence unused field warnings
(void)m_align1;
}
@ -134,6 +134,8 @@ uint64_t ShaderFlags::GetFeatureInfo() const {
? hlsl::DXIL::ShaderFeatureInfo_ExtendedCommandInfo
: 0;
Flags |= m_bUsesDerivatives ? hlsl::DXIL::OptFeatureInfo_UsesDerivatives : 0;
return Flags;
}
@ -196,6 +198,7 @@ uint64_t ShaderFlags::GetShaderFlagsRawForCollection() {
Flags.SetWaveMMA(true);
Flags.SetSampleCmpGradientOrBias(true);
Flags.SetExtendedCommandInfo(true);
Flags.SetUsesDerivatives(true);
return Flags.GetShaderFlagsRaw();
}
@ -388,6 +391,21 @@ static bool hasSampleClamp(const CallInst *CI) {
ShaderFlags ShaderFlags::CollectShaderFlags(const Function *F,
const hlsl::DxilModule *M) {
// NOTE: This function is meant to compute shader flags for a single function,
// potentially not knowing the final shader stage for the entry that may call
// this function.
// As such, do not depend on the shader model in the module, except for
// compatibility purposes. Doing so will fail to encode flags properly for
// libraries. The real, final shader flags will be adjusted after walking
// called functions and combining flags.
// For example, the use of derivatives impacts an optional flag when used from
// a mesh or amplification shader. It also impacts the minimum shader model
// for a compute shader. We do not make assumptions about that context here.
// Instead, we simply set a new UsesDerivatives flag to indicate that
// derivatives are used, then rely on AdjustMinimumShaderModelAndFlags to set
// the final flags correctly once we've merged all called functions.
// Place module-level detection in DxilModule::CollectShaderFlagsForModule.
ShaderFlags flag;
// Module level options
flag.SetUseNativeLowPrecision(!M->GetUseMinPrecision());
@ -420,16 +438,21 @@ ShaderFlags ShaderFlags::CollectShaderFlags(const Function *F,
bool hasSamplerDescriptorHeapIndexing = false;
bool hasAtomicInt64OnHeapResource = false;
// Used to determine whether to set ResMayNotAlias flag.
bool hasUAVs = M->GetUAVs().size() > 0;
bool hasUAVsGlobally = M->GetUAVs().size() > 0;
bool hasAdvancedTextureOps = false;
bool hasWriteableMSAATextures = false;
bool hasSampleCmpGradientOrBias = false;
bool hasWaveMMA = false;
bool hasExtendedCommandInfo = false;
// UsesDerivatives is used to indicate any derivative use per-function, before
// flags are combined from called functions. Later, the flags are adjusted for
// each entry point function in AdjustMinimumShaderModelAndFlags. This will
// set DerivativesInMeshAndAmpShaders if the entry point function or shader
// model is mesh or amplification shader.
bool hasDerivatives = false;
// Try to maintain compatibility with a v1.0 validator if that's what we have.
uint32_t valMajor, valMinor;
M->GetValidatorVersion(valMajor, valMinor);
@ -444,23 +467,63 @@ ShaderFlags ShaderFlags::CollectShaderFlags(const Function *F,
bool canSetResMayNotAlias =
DXIL::CompareVersions(dxilMajor, dxilMinor, 1, 7) >= 0;
// HasLodClamp is only enabled after v1.8 validator.
bool canSetHasLodClamp = DXIL::CompareVersions(valMajor, valMinor, 1, 8) >= 0;
// Use of LodClamp requires tiled resources, but a bug in validator 1.7 and
// lower didn't recognize this. So, if validator version < 1.8, don't set
// tiled resources flag based on LodClamp.
bool canSetTiledResourcesBasedOnLodClamp =
DXIL::CompareVersions(valMajor, valMinor, 1, 8) >= 0;
// Used to determine whether to set ResMayNotAlias flag.
// Prior to validator version 1.8, we based this on global presence of UAVs.
// Now, we base it on the use of UAVs in the function.
bool hasUAVs = DXIL::CompareVersions(valMajor, valMinor, 1, 8) < 0
? hasUAVsGlobally
: false;
Type *int16Ty = Type::getInt16Ty(F->getContext());
Type *int64Ty = Type::getInt64Ty(F->getContext());
// Before validator version 1.8, we set the WriteableMSAATextures flag based
// on the presence of RWTexture2DMS[Array] resources in the module.
bool setWriteableMSAATextures_1_7 =
DXIL::CompareVersions(valMajor, valMinor, 1, 8) < 0;
bool hasWriteableMSAATextures_1_7 = false;
bool hasWriteableMSAATextures = false;
// Set up resource to binding handle map for 64-bit atomics usage
std::unordered_map<ResourceKey, DxilResource *, ResKeyHash, ResKeyEq> resMap;
for (auto &res : M->GetUAVs()) {
ResourceKey key = {(uint8_t)res->GetClass(), res->GetSpaceID(),
res->GetLowerBound(), res->GetUpperBound()};
resMap.insert({key, res.get()});
// The flag was set for this function if any RWTexture2DMS[Array] resources
// existed in the module. Now, for compatibility, we need to track this
// flag so we can set it if validator version is < 1.8.
if (res->GetKind() == DXIL::ResourceKind::Texture2DMS ||
res->GetKind() == DXIL::ResourceKind::Texture2DMSArray)
hasWriteableMSAATextures = true;
hasWriteableMSAATextures_1_7 = true;
}
auto checkUsedResourceProps = [&](DxilResourceProperties RP) {
if (hasUAVs && hasWriteableMSAATextures)
return;
if (RP.isUAV()) {
hasUAVs = true;
if (RP.getResourceKind() == DXIL::ResourceKind::Texture2DMS ||
RP.getResourceKind() == DXIL::ResourceKind::Texture2DMSArray)
hasWriteableMSAATextures = true;
}
};
auto checkUsedHandle = [&](Value *resHandle) {
if (hasUAVs && hasWriteableMSAATextures)
return;
CallInst *handleCall = FindCallToCreateHandle(resHandle);
DxilResourceProperties RP =
GetResourcePropertyFromHandleCall(M, handleCall);
checkUsedResourceProps(RP);
};
for (const BasicBlock &BB : F->getBasicBlockList()) {
for (const Instruction &I : BB.getInstList()) {
// Skip none dxil function call.
@ -618,9 +681,7 @@ ShaderFlags ShaderFlags::CollectShaderFlags(const Function *F,
case DXIL::OpCode::DerivCoarseX:
case DXIL::OpCode::DerivCoarseY:
case DXIL::OpCode::CalculateLOD: {
const ShaderModel *pSM = M->GetShaderModel();
if (pSM->IsAS() || pSM->IsMS())
hasDerivativesInMeshAndAmpShaders = true;
hasDerivatives = true;
} break;
case DXIL::OpCode::CreateHandleFromHeap: {
ConstantInt *isSamplerVal = dyn_cast<ConstantInt>(CI->getArgOperand(
@ -638,7 +699,13 @@ ShaderFlags ShaderFlags::CollectShaderFlags(const Function *F,
}
}
} break;
case DXIL::OpCode::CreateHandle:
case DXIL::OpCode::CreateHandleForLib:
case DXIL::OpCode::AnnotateHandle:
checkUsedHandle(const_cast<CallInst *>(CI));
break;
case DXIL::OpCode::TextureStoreSample:
hasWriteableMSAATextures_1_7 = true;
hasWriteableMSAATextures = true;
LLVM_FALLTHROUGH;
case DXIL::OpCode::SampleCmpLevel:
@ -730,28 +797,22 @@ ShaderFlags ShaderFlags::CollectShaderFlags(const Function *F,
break;
}
}
// If we know this function is MS or AS, go ahead and set this flag now.
if (hasDerivatives &&
(entryProps.props.IsMS() || entryProps.props.IsAS())) {
hasDerivativesInMeshAndAmpShaders = true;
}
}
if (!hasRaytracingTier1_1) {
if (const DxilSubobjects *pSubobjects = M->GetSubobjects()) {
for (const auto &it : pSubobjects->GetSubobjects()) {
switch (it.second->GetKind()) {
case DXIL::SubobjectKind::RaytracingPipelineConfig1:
hasRaytracingTier1_1 = true;
break;
case DXIL::SubobjectKind::StateObjectConfig: {
uint32_t Flags;
if (it.second->GetStateObjectConfig(Flags) &&
((Flags & ~(unsigned)DXIL::StateObjectFlags::ValidMask_1_4) != 0))
hasRaytracingTier1_1 = true;
} break;
default:
break;
}
if (hasRaytracingTier1_1)
break;
}
}
if (hasDerivatives && DXIL::CompareVersions(valMajor, valMinor, 1, 8) < 0) {
// Before validator version 1.8, UsesDerivatives flag was not set, and we
// set the DerivativesInMeshAndAmpShaders only if the shader model in the
// module is mesh or amplification.
hasDerivatives = false;
const ShaderModel *SM = M->GetShaderModel();
if (!(SM->IsMS() || SM->IsAS()))
hasDerivativesInMeshAndAmpShaders = false;
}
flag.SetEnableDoublePrecision(hasDouble);
@ -762,7 +823,7 @@ ShaderFlags ShaderFlags::CollectShaderFlags(const Function *F,
flag.SetEnableDoubleExtensions(hasDoubleExtension);
flag.SetWaveOps(hasWaveOps);
flag.SetTiledResources(hasCheckAccessFully ||
(canSetHasLodClamp && hasLodClamp));
(canSetTiledResourcesBasedOnLodClamp && hasLodClamp));
flag.SetEnableMSAD(hasMSAD);
flag.SetUAVLoadAdditionalFormats(hasMulticomponentUAVLoads);
flag.SetViewID(hasViewID);
@ -778,13 +839,16 @@ ShaderFlags ShaderFlags::CollectShaderFlags(const Function *F,
flag.SetSamplerDescriptorHeapIndexing(hasSamplerDescriptorHeapIndexing);
flag.SetAtomicInt64OnHeapResource(hasAtomicInt64OnHeapResource);
flag.SetAdvancedTextureOps(hasAdvancedTextureOps);
flag.SetWriteableMSAATextures(hasWriteableMSAATextures);
flag.SetWriteableMSAATextures(setWriteableMSAATextures_1_7
? hasWriteableMSAATextures_1_7
: hasWriteableMSAATextures);
flag.SetWaveMMA(hasWaveMMA);
// Only bother setting the flag when there are UAVs.
flag.SetResMayNotAlias(canSetResMayNotAlias && hasUAVs &&
!M->GetResMayAlias());
flag.SetSampleCmpGradientOrBias(hasSampleCmpGradientOrBias);
flag.SetExtendedCommandInfo(hasExtendedCommandInfo);
flag.SetUsesDerivatives(hasDerivatives);
return flag;
}

Просмотреть файл

@ -1235,57 +1235,6 @@ private:
unsigned m_ValMajor, m_ValMinor;
struct ShaderCompatInfo {
ShaderCompatInfo()
: minMajor(6), minMinor(0),
mask(((unsigned)1 << (unsigned)DXIL::ShaderKind::Invalid) - 1) {}
unsigned minMajor, minMinor, mask;
};
typedef std::unordered_map<const llvm::Function *, ShaderCompatInfo>
FunctionShaderCompatMap;
FunctionShaderCompatMap m_FuncToShaderCompat;
void UpdateFunctionToShaderCompat(const llvm::Function *dxilFunc) {
#define SFLAG(stage) ((unsigned)1 << (unsigned)DXIL::ShaderKind::stage)
for (const llvm::User *user : dxilFunc->users()) {
if (const llvm::CallInst *CI = dyn_cast<const llvm::CallInst>(user)) {
// Find calling function
const llvm::Function *F =
cast<const llvm::Function>(CI->getParent()->getParent());
// Insert or lookup info
ShaderCompatInfo &info = m_FuncToShaderCompat[F];
unsigned major, minor, mask;
// bWithTranslation = true for library modules
OP::GetMinShaderModelAndMask(CI, /*bWithTranslation*/ true, m_ValMajor,
m_ValMinor, major, minor, mask);
if (major > info.minMajor) {
info.minMajor = major;
info.minMinor = minor;
} else if (major == info.minMajor && minor > info.minMinor) {
info.minMinor = minor;
}
info.mask &= mask;
} else if (const llvm::LoadInst *LI = dyn_cast<LoadInst>(user)) {
// If loading a groupshared variable, limit to CS/AS/MS
if (LI->getPointerAddressSpace() == DXIL::kTGSMAddrSpace) {
const llvm::Function *F =
cast<const llvm::Function>(LI->getParent()->getParent());
ShaderCompatInfo &info = m_FuncToShaderCompat[F];
info.mask &= (SFLAG(Compute) | SFLAG(Mesh) | SFLAG(Amplification));
}
} else if (const llvm::StoreInst *SI = dyn_cast<StoreInst>(user)) {
// If storing to a groupshared variable, limit to CS/AS/MS
if (SI->getPointerAddressSpace() == DXIL::kTGSMAddrSpace) {
const llvm::Function *F =
cast<const llvm::Function>(SI->getParent()->getParent());
ShaderCompatInfo &info = m_FuncToShaderCompat[F];
info.mask &= (SFLAG(Compute) | SFLAG(Mesh) | SFLAG(Amplification));
}
}
}
#undef SFLAG
}
void
FindUsingFunctions(const llvm::Value *User,
llvm::SmallVectorImpl<const llvm::Function *> &functions) {
@ -1711,26 +1660,14 @@ private:
void UpdateFunctionInfo(const DxilModule &DM) {
llvm::Module *M = DM.GetModule();
// We must select the appropriate shader mask for the validator version,
// so we don't set any bits the validator doesn't recognize.
unsigned ValidShaderMask =
(1 << ((unsigned)DXIL::ShaderKind::LastValid + 1)) - 1;
if (DXIL::CompareVersions(m_ValMajor, m_ValMinor, 1, 5) < 0) {
ValidShaderMask = (1 << ((unsigned)DXIL::ShaderKind::Last_1_4 + 1)) - 1;
} else if (DXIL::CompareVersions(m_ValMajor, m_ValMinor, 1, 8) < 0) {
ValidShaderMask = (1 << ((unsigned)DXIL::ShaderKind::Last_1_7 + 1)) - 1;
}
for (auto &function : M->getFunctionList()) {
if (function.isDeclaration() && !function.isIntrinsic() &&
function.getLinkage() ==
llvm::GlobalValue::LinkageTypes::ExternalLinkage) {
if (OP::IsDxilOpFunc(&function)) {
// update min shader model and shader stage mask per function
UpdateFunctionToShaderCompat(&function);
} else {
// collect unresolved dependencies per function
UpdateFunctionDependency(&function);
}
llvm::GlobalValue::LinkageTypes::ExternalLinkage &&
!OP::IsDxilOpFunc(&function)) {
// collect unresolved dependencies per function
UpdateFunctionDependency(&function);
}
}
@ -1783,7 +1720,7 @@ private:
uint32_t functionDependencies = RDAT_NULL_REF;
uint32_t payloadSizeInBytes = 0;
uint32_t attrSizeInBytes = 0;
uint32_t shaderKind = static_cast<uint32_t>(DXIL::ShaderKind::Library);
DXIL::ShaderKind shaderKind = DXIL::ShaderKind::Library;
uint32_t shaderInfo = RDAT_NULL_REF;
if (m_FuncToResNameOffset.find(&function) !=
@ -1801,10 +1738,12 @@ private:
m_pFunctionTable->GetRecordStride())
? &info_latest
: nullptr;
ShaderFlags flags = ShaderFlags::CollectShaderFlags(&function, &DM);
DxilWaveSize waveSize;
const DxilModule::ShaderCompatInfo &compatInfo =
*DM.GetCompatInfoForFunction(&function);
if (DM.HasDxilFunctionProps(&function)) {
const auto &props = DM.GetDxilFunctionProps(&function);
const DxilFunctionProps &props = DM.GetDxilFunctionProps(&function);
if (props.IsClosestHit() || props.IsAnyHit()) {
payloadSizeInBytes = props.ShaderProps.Ray.payloadSizeInBytes;
attrSizeInBytes = props.ShaderProps.Ray.attributeSizeInBytes;
@ -1813,8 +1752,8 @@ private:
} else if (props.IsCallable()) {
payloadSizeInBytes = props.ShaderProps.Ray.paramSizeInBytes;
}
shaderKind = (uint32_t)props.shaderKind;
waveSize = props.WaveSize;
shaderKind = props.shaderKind;
DxilWaveSize waveSize = props.WaveSize;
if (pInfo2 && DM.HasDxilEntryProps(&function)) {
const auto &entryProps = DM.GetDxilEntryProps(&function);
if (waveSize.IsDefined()) {
@ -1829,50 +1768,26 @@ private:
TGSMInFunc[&function]);
} else if (DXIL::CompareVersions(m_ValMajor, m_ValMinor, 1, 8) >
0) {
shaderInfo = AddShaderInfo(function, entryProps, *pInfo2, flags,
TGSMInFunc[&function]);
shaderInfo =
AddShaderInfo(function, entryProps, *pInfo2,
compatInfo.shaderFlags, TGSMInFunc[&function]);
}
}
}
info.Name = mangledIndex;
info.UnmangledName = unmangledIndex;
info.ShaderKind = shaderKind;
info.ShaderKind = static_cast<uint32_t>(shaderKind);
if (pInfo2)
pInfo2->RawShaderRef = shaderInfo;
info.Resources = resourceIndex;
info.FunctionDependencies = functionDependencies;
info.PayloadSizeInBytes = payloadSizeInBytes;
info.AttributeSizeInBytes = attrSizeInBytes;
info.SetFeatureFlags(flags.GetFeatureInfo());
// Init min target 6.0
unsigned minMajor = 6, minMinor = 0;
// Increase min target based on feature flags:
if (flags.GetUseNativeLowPrecision() &&
flags.GetLowPrecisionPresent()) {
minMinor = 2;
} else if (flags.GetBarycentrics() || flags.GetViewID()) {
minMinor = 1;
}
if ((DXIL::ShaderKind)shaderKind == DXIL::ShaderKind::Library) {
// Init mask to all kinds for library functions
info.ShaderStageFlag = ValidShaderMask;
} else {
// Init mask to current kind for shader functions
info.ShaderStageFlag = (unsigned)1 << shaderKind;
}
auto it = m_FuncToShaderCompat.find(&function);
if (it != m_FuncToShaderCompat.end()) {
auto &compatInfo = it->second;
if (compatInfo.minMajor > minMajor) {
minMajor = compatInfo.minMajor;
minMinor = compatInfo.minMinor;
} else if (compatInfo.minMinor > minMinor) {
minMinor = compatInfo.minMinor;
}
info.ShaderStageFlag &= compatInfo.mask;
}
info.SetFeatureFlags(compatInfo.shaderFlags.GetFeatureInfo());
info.ShaderStageFlag = compatInfo.mask;
info.MinShaderTarget =
EncodeVersion((DXIL::ShaderKind)shaderKind, minMajor, minMinor);
EncodeVersion((DXIL::ShaderKind)shaderKind, compatInfo.minMajor,
compatInfo.minMinor);
m_pFunctionTable->Insert(info_latest);
}
}
@ -1957,13 +1872,14 @@ private:
}
public:
DxilRDATWriter(const DxilModule &mod)
: Builder(GetRecordDuplicationAllowed(mod)) {
DxilRDATWriter(DxilModule &mod) : Builder(GetRecordDuplicationAllowed(mod)) {
// Keep track of validator version so we can make a compatible RDAT
mod.GetValidatorVersion(m_ValMajor, m_ValMinor);
RDAT::RuntimeDataPartType maxAllowedType =
RDAT::MaxPartTypeForValVer(m_ValMajor, m_ValMinor);
mod.ComputeShaderCompatInfo();
// Instantiate the parts in the order that validator expects.
Builder.GetStringBufferPart();
m_pResourceTable = Builder.GetOrAddTable<RDAT::RuntimeDataResourceInfo>();
@ -2006,7 +1922,7 @@ DxilPartWriter *hlsl::NewPSVWriter(const DxilModule &M, uint32_t PSVVersion) {
return new DxilPSVWriter(M, PSVVersion);
}
DxilPartWriter *hlsl::NewRDATWriter(const DxilModule &M) {
DxilPartWriter *hlsl::NewRDATWriter(DxilModule &M) {
return new DxilRDATWriter(M);
}

Просмотреть файл

@ -2514,29 +2514,36 @@ void DxilShaderReflection::InitDesc() {
DxilCounters counters = {};
m_pDxilModule->LoadDxilCounters(counters);
// UINT InstructionCount; // Num llvm instructions in all
// functions UINT TempArrayCount; // Number of bytes used in
// arrays (alloca + static global) UINT DynamicFlowControlCount; //
// Number of branches with more than one successor for now UINT
// ArrayInstructionCount; // number of load/store on arrays for now
// UINT InstructionCount; // Num llvm instructions in all functions
// UINT TempArrayCount; // Number of bytes used in arrays (alloca + static
// global)
// UINT DynamicFlowControlCount; // Number of branches with more than one
// successor for now
// UINT ArrayInstructionCount; // number of load/store on arrays for now
pDesc->InstructionCount = counters.insts;
pDesc->TempArrayCount = counters.AllArrayBytes();
pDesc->DynamicFlowControlCount = counters.branches;
pDesc->ArrayInstructionCount = counters.AllArrayAccesses();
// UINT FloatInstructionCount; // Number of floating point arithmetic
// instructions used UINT IntInstructionCount; // Number of signed
// integer arithmetic instructions used UINT UintInstructionCount; // Number
// of unsigned integer arithmetic instructions used
// UINT FloatInstructionCount; // Number of floating point arithmetic
// instructions used
// UINT IntInstructionCount; // Number of signed integer arithmetic
// instructions used
// UINT UintInstructionCount; // Number of unsigned integer arithmetic
// instructions used
pDesc->FloatInstructionCount = counters.floats;
pDesc->IntInstructionCount = counters.ints;
pDesc->UintInstructionCount = counters.uints;
// UINT TextureNormalInstructions; // Number of non-categorized texture
// instructions UINT TextureLoadInstructions; // Number of texture load
// instructions UINT TextureCompInstructions; // Number of texture
// comparison instructions UINT TextureBiasInstructions; // Number of
// texture bias instructions UINT TextureGradientInstructions; // Number of
// instructions
// UINT TextureLoadInstructions; // Number of texture load
// instructions
// UINT TextureCompInstructions; // Number of texture
// comparison instructions
// UINT TextureBiasInstructions; // Number of
// texture bias instructions
// UINT TextureGradientInstructions; // Number of
// texture gradient instructions
pDesc->TextureNormalInstructions = counters.tex_norm;
pDesc->TextureLoadInstructions = counters.tex_load;
@ -2550,22 +2557,25 @@ void DxilShaderReflection::InitDesc() {
pDesc->EmitInstructionCount = counters.gs_emit;
// UINT cBarrierInstructions; // Number of barrier instructions in a
// compute shader UINT cInterlockedInstructions; // Number of
// interlocked instructions UINT cTextureStoreInstructions; // Number of
// compute shader
// UINT cInterlockedInstructions; // Number of
// interlocked instructions
// UINT cTextureStoreInstructions; // Number of
// texture writes
pDesc->cBarrierInstructions = counters.barrier;
pDesc->cInterlockedInstructions = counters.atomic;
pDesc->cTextureStoreInstructions = counters.tex_store;
// Unset: UINT TempRegisterCount; // Don't know how to map this for SSA
// (not going to do reg allocation here) Unset: UINT DefCount; // Not sure
// what to map this to Unset: UINT DclCount; // Number of
// declarations (input + output)
// TODO: map to used input + output signature rows?
// Unset: UINT StaticFlowControlCount; // Number of static flow control
// instructions used This used to map to flow control using special int/bool
// constant registers in DX9. Unset: UINT MacroInstructionCount; // Number
// of macro instructions used Macro instructions are a <= DX9 concept.
// Unset: UINT TempRegisterCount; // Don't know how to map this for SSA (not
// going to do reg allocation here)
// Unset: UINT DefCount; // Not sure what to map this to
// Unset: UINT DclCount; // Number of declarations (input + output)
// TODO: map to used input + output signature rows?
// Unset: UINT StaticFlowControlCount; // Number of static flow control
// instructions used This used to map to flow control using special
// int/bool constant registers in DX9.
// Unset: UINT MacroInstructionCount; // Number of macro instructions used
// Macro instructions are a <= DX9 concept.
}
ID3D12ShaderReflectionConstantBuffer *
@ -2837,45 +2847,53 @@ HRESULT CFunctionReflection::GetDesc(D3D12_FUNCTION_DESC *pDesc) {
}
pDesc->Version = EncodeVersion(kind, pSM->GetMajor(), pSM->GetMinor());
// Unset: LPCSTR Creator; // Creator
// string Unset: UINT Flags; //
// Shader compilation/parse flags
// Unset: LPCSTR Creator; // Creator string
// Unset: UINT Flags; // Shader compilation/parse flags
pDesc->ConstantBuffers = (UINT)m_UsedCBs.size();
pDesc->BoundResources = (UINT)m_UsedResources.size();
// Unset: UINT InstructionCount; // Number of
// emitted instructions Unset: UINT TempRegisterCount; //
// Number of temporary registers used Unset: UINT TempArrayCount; // Number
// of temporary arrays used Unset: UINT DefCount; //
// Number of constant defines Unset: UINT DclCount; //
// Number of declarations (input + output) Unset: UINT
// Unset: UINT InstructionCount; // Number of emitted instructions
// Unset: UINT TempRegisterCount; // Number of temporary registers used
// Unset: UINT TempArrayCount; // Number of temporary arrays used
// Unset: UINT DefCount; // Number of constant defines
// Unset: UINT DclCount; // Number of declarations (input + output)
// Unset: UINT
// TextureNormalInstructions; // Number of non-categorized texture
// instructions Unset: UINT TextureLoadInstructions; //
// Number of texture load instructions Unset: UINT TextureCompInstructions;
// // Number of texture comparison instructions Unset: UINT
// TextureBiasInstructions; // Number of texture bias instructions Unset:
// UINT TextureGradientInstructions; // Number of texture
// gradient instructions Unset: UINT FloatInstructionCount; // Number
// of floating point arithmetic instructions used Unset: UINT
// IntInstructionCount; // Number of signed integer arithmetic
// instructions used Unset: UINT UintInstructionCount; //
// Number of unsigned integer arithmetic instructions used Unset: UINT
// StaticFlowControlCount; // Number of static flow control instructions
// used Unset: UINT DynamicFlowControlCount; // Number
// of dynamic flow control instructions used Unset: UINT
// MacroInstructionCount; // Number of macro instructions used Unset:
// UINT ArrayInstructionCount; // Number of array
// instructions used Unset: UINT MovInstructionCount; //
// Number of mov instructions used Unset: UINT MovcInstructionCount; //
// Number of movc instructions used Unset: UINT ConversionInstructionCount;
// // Number of type conversion instructions used Unset: UINT
// BitwiseInstructionCount; // Number of bitwise arithmetic instructions
// used Unset: D3D_FEATURE_LEVEL MinFeatureLevel; // Min
// target of the function byte code
// instructions
// Unset: UINT TextureLoadInstructions; // Number of texture load
// instructions
// Unset: UINT TextureCompInstructions; // Number of texture comparison
// instructions
// Unset: UINT TextureBiasInstructions;// Number of texture bias instructions
// Unset: UINT TextureGradientInstructions; // Number of texture gradient
// instructions
// Unset: UINT FloatInstructionCount; // Number of floating point arithmetic
// instructions used
// Unset: UINT IntInstructionCount; // Number of signed integer arithmetic
// instructions used
// Unset: UINT UintInstructionCount; // Number of unsigned integer
// arithmetic instructions used
// Unset: UINT StaticFlowControlCount; // Number of static flow control
// instructions used
// Unset: UINT DynamicFlowControlCount; // Number of dynamic flow control
// instructions used
// Unset: UINT MacroInstructionCount; // Number of macro instructions used
// Unset: UINT ArrayInstructionCount; // Number of array instructions used
// Unset: UINT MovInstructionCount; // Number of mov instructions used
// Unset: UINT MovcInstructionCount; // Number of movc instructions used
// Unset: UINT ConversionInstructionCount; // Number of type conversion
// instructions used
// Unset: UINT BitwiseInstructionCount; // Number of bitwise arithmetic
// instructions used
// Unset: D3D_FEATURE_LEVEL MinFeatureLevel; // Min target of the function
// byte code
pDesc->RequiredFeatureFlags =
m_FeatureFlags & ~(UINT64)D3D_SHADER_REQUIRES_EARLY_DEPTH_STENCIL;
// Also Mask off function-level derivatives flag.
pDesc->RequiredFeatureFlags &= ~DXIL::OptFeatureInfo_UsesDerivatives;
if (kind == DXIL::ShaderKind::Pixel && m_pProps &&
m_pProps->ShaderProps.PS.EarlyDepthStencil) {
pDesc->RequiredFeatureFlags |= D3D_SHADER_REQUIRES_EARLY_DEPTH_STENCIL;
@ -2883,13 +2901,12 @@ HRESULT CFunctionReflection::GetDesc(D3D12_FUNCTION_DESC *pDesc) {
pDesc->Name = m_Name.c_str();
// Unset: INT FunctionParameterCount; // Number of
// logical parameters in the function signature (not including return) Unset:
// BOOL HasReturn; // TRUE, if function
// returns a value, false - it is a subroutine Unset: BOOL
// Has10Level9VertexShader; // TRUE, if there is a 10L9 VS blob Unset:
// BOOL Has10Level9PixelShader; // TRUE, if there is a
// 10L9 PS blob
// Unset: INT FunctionParameterCount; // Number of logical parameters in the
// function signature (not including return)
// Unset: BOOL HasReturn; // TRUE, if function returns a value, false - it is
// a subroutine
// Unset: BOOL Has10Level9VertexShader; // TRUE, if there is a 10L9 VS blob
// Unset: BOOL Has10Level9PixelShader; // TRUE, if there is a 10L9 PS blob
return S_OK;
}

Просмотреть файл

@ -39,8 +39,8 @@
// CHECK: AttributeSizeInBytes: 0
// CHECK: FeatureInfo1: 0
// CHECK: FeatureInfo2: 0
// CHECK: ShaderStageFlag: 16384
// CHECK: MinShaderTarget: 917605
// CHECK: ShaderStageFlag: (Amplification)
// CHECK: MinShaderTarget: 0xe0065
// CHECK: MinimumExpectedWaveLaneCount: 0
// CHECK: MaximumExpectedWaveLaneCount: 0
// CHECK: ShaderFlags: 0 (None)

Просмотреть файл

@ -54,8 +54,8 @@
// CHECK: AttributeSizeInBytes: 0
// CHECK: FeatureInfo1: 0
// CHECK: FeatureInfo2: 0
// CHECK: ShaderStageFlag: 65535
// CHECK: MinShaderTarget: 393312
// CHECK: ShaderStageFlag: (Pixel | Vertex | Geometry | Hull | Domain | Compute | Library | RayGeneration | Intersection | AnyHit | ClosestHit | Miss | Callable | Mesh | Amplification | Node)
// CHECK: MinShaderTarget: 0x60060
// CHECK: MinimumExpectedWaveLaneCount: 0
// CHECK: MaximumExpectedWaveLaneCount: 0
// CHECK: ShaderFlags: 0 (None)
@ -73,8 +73,8 @@
// CHECK: AttributeSizeInBytes: 0
// CHECK: FeatureInfo1: 0
// CHECK: FeatureInfo2: 0
// CHECK: ShaderStageFlag: 2
// CHECK: MinShaderTarget: 65632
// CHECK: ShaderStageFlag: (Vertex)
// CHECK: MinShaderTarget: 0x10060
// CHECK: MinimumExpectedWaveLaneCount: 0
// CHECK: MaximumExpectedWaveLaneCount: 0
// CHECK: ShaderFlags: 0 (None)

Просмотреть файл

@ -58,8 +58,8 @@
// CHECK: AttributeSizeInBytes: 0
// CHECK: FeatureInfo1: 0
// CHECK: FeatureInfo2: 0
// CHECK: ShaderStageFlag: 32
// CHECK: MinShaderTarget: 327776
// CHECK: ShaderStageFlag: (Compute)
// CHECK: MinShaderTarget: 0x50060
// CHECK: MinimumExpectedWaveLaneCount: 0
// CHECK: MaximumExpectedWaveLaneCount: 0
// CHECK: ShaderFlags: 0 (None)

Просмотреть файл

@ -15,8 +15,8 @@
// CHECK: AttributeSizeInBytes: 0
// CHECK: FeatureInfo1: 0
// CHECK: FeatureInfo2: 0
// CHECK: ShaderStageFlag: 32768
// CHECK: MinShaderTarget: 983136
// CHECK: ShaderStageFlag: (Node)
// CHECK: MinShaderTarget: 0xf0068
// CHECK: MinimumExpectedWaveLaneCount: 0
// CHECK: MaximumExpectedWaveLaneCount: 0
// CHECK: ShaderFlags: 0 (None)

Просмотреть файл

@ -16,8 +16,8 @@
// CHECK: AttributeSizeInBytes: 0
// CHECK: FeatureInfo1: 0
// CHECK: FeatureInfo2: 0
// CHECK: ShaderStageFlag: 32768
// CHECK: MinShaderTarget: 983136
// CHECK: ShaderStageFlag: (Node)
// CHECK: MinShaderTarget: 0xf0068
// CHECK: MinimumExpectedWaveLaneCount: 0
// CHECK: MaximumExpectedWaveLaneCount: 0
// CHECK: ShaderFlags: 0 (None)

Просмотреть файл

@ -70,8 +70,8 @@ float4 PSMain(int idx : INDEX) : SV_Target {
// CHECK: AttributeSizeInBytes: 0
// CHECK: FeatureInfo1: 0
// CHECK: FeatureInfo2: 0
// CHECK: ShaderStageFlag: 65535
// CHECK: MinShaderTarget: 393312
// CHECK: ShaderStageFlag: (Pixel | Vertex | Geometry | Hull | Domain | Compute | Library | RayGeneration | Intersection | AnyHit | ClosestHit | Miss | Callable | Mesh | Amplification | Node)
// CHECK: MinShaderTarget: 0x60060
// CHECK: MinimumExpectedWaveLaneCount: 0
// CHECK: MaximumExpectedWaveLaneCount: 0
// CHECK: ShaderFlags: 0 (None)
@ -89,8 +89,8 @@ float4 PSMain(int idx : INDEX) : SV_Target {
// CHECK: AttributeSizeInBytes: 0
// CHECK: FeatureInfo1: 0
// CHECK: FeatureInfo2: 0
// CHECK: ShaderStageFlag: 65535
// CHECK: MinShaderTarget: 393312
// CHECK: ShaderStageFlag: (Pixel | Vertex | Geometry | Hull | Domain | Compute | Library | RayGeneration | Intersection | AnyHit | ClosestHit | Miss | Callable | Mesh | Amplification | Node)
// CHECK: MinShaderTarget: 0x60060
// CHECK: MinimumExpectedWaveLaneCount: 0
// CHECK: MaximumExpectedWaveLaneCount: 0
// CHECK: ShaderFlags: 0 (None)
@ -108,8 +108,8 @@ float4 PSMain(int idx : INDEX) : SV_Target {
// CHECK: AttributeSizeInBytes: 0
// CHECK: FeatureInfo1: 0
// CHECK: FeatureInfo2: 0
// CHECK: ShaderStageFlag: 1
// CHECK: MinShaderTarget: 96
// CHECK: ShaderStageFlag: (Pixel)
// CHECK: MinShaderTarget: 0x60
// CHECK: MinimumExpectedWaveLaneCount: 0
// CHECK: MaximumExpectedWaveLaneCount: 0
// CHECK: ShaderFlags: 0 (None)

Просмотреть файл

@ -65,8 +65,8 @@ void RayGen() {
// CHECK: AttributeSizeInBytes: 0
// CHECK: FeatureInfo1: 0
// CHECK: FeatureInfo2: 0
// CHECK: ShaderStageFlag: 128
// CHECK: MinShaderTarget: 458851
// CHECK: ShaderStageFlag: (RayGeneration)
// CHECK: MinShaderTarget: 0x70063
// CHECK: MinimumExpectedWaveLaneCount: 0
// CHECK: MaximumExpectedWaveLaneCount: 0
// CHECK: ShaderFlags: 0 (None)
@ -83,8 +83,8 @@ void RayGen() {
// CHECK: AttributeSizeInBytes: 0
// CHECK: FeatureInfo1: 0
// CHECK: FeatureInfo2: 0
// CHECK: ShaderStageFlag: 65535
// CHECK: MinShaderTarget: 393312
// CHECK: ShaderStageFlag: (Pixel | Vertex | Geometry | Hull | Domain | Compute | Library | RayGeneration | Intersection | AnyHit | ClosestHit | Miss | Callable | Mesh | Amplification | Node)
// CHECK: MinShaderTarget: 0x60060
// CHECK: MinimumExpectedWaveLaneCount: 0
// CHECK: MaximumExpectedWaveLaneCount: 0
// CHECK: ShaderFlags: 0 (None)
@ -101,8 +101,8 @@ void RayGen() {
// CHECK: AttributeSizeInBytes: 0
// CHECK: FeatureInfo1: 0
// CHECK: FeatureInfo2: 0
// CHECK: ShaderStageFlag: 128
// CHECK: MinShaderTarget: 458851
// CHECK: ShaderStageFlag: (RayGeneration)
// CHECK: MinShaderTarget: 0x70063
// CHECK: MinimumExpectedWaveLaneCount: 0
// CHECK: MaximumExpectedWaveLaneCount: 0
// CHECK: ShaderFlags: 0 (None)
@ -119,8 +119,8 @@ void RayGen() {
// CHECK: AttributeSizeInBytes: 0
// CHECK: FeatureInfo1: 0
// CHECK: FeatureInfo2: 0
// CHECK: ShaderStageFlag: 2
// CHECK: MinShaderTarget: 65632
// CHECK: ShaderStageFlag: (Vertex)
// CHECK: MinShaderTarget: 0x10060
// CHECK: MinimumExpectedWaveLaneCount: 0
// CHECK: MaximumExpectedWaveLaneCount: 0
// CHECK: ShaderFlags: (OutputPositionPresent)

Просмотреть файл

@ -57,8 +57,8 @@ float4 PSMain(int idx : INDEX) : SV_Target {
// CHECK: AttributeSizeInBytes: 0
// CHECK: FeatureInfo1: 0
// CHECK: FeatureInfo2: 0
// CHECK: ShaderStageFlag: 65535
// CHECK: MinShaderTarget: 393312
// CHECK: ShaderStageFlag: (Pixel | Vertex | Geometry | Hull | Domain | Compute | Library | RayGeneration | Intersection | AnyHit | ClosestHit | Miss | Callable | Mesh | Amplification | Node)
// CHECK: MinShaderTarget: 0x60060
// CHECK: MinimumExpectedWaveLaneCount: 0
// CHECK: MaximumExpectedWaveLaneCount: 0
// CHECK: ShaderFlags: 0 (None)
@ -76,8 +76,8 @@ float4 PSMain(int idx : INDEX) : SV_Target {
// CHECK: AttributeSizeInBytes: 0
// CHECK: FeatureInfo1: 0
// CHECK: FeatureInfo2: 0
// CHECK: ShaderStageFlag: 65535
// CHECK: MinShaderTarget: 393312
// CHECK: ShaderStageFlag: (Pixel | Vertex | Geometry | Hull | Domain | Compute | Library | RayGeneration | Intersection | AnyHit | ClosestHit | Miss | Callable | Mesh | Amplification | Node)
// CHECK: MinShaderTarget: 0x60060
// CHECK: MinimumExpectedWaveLaneCount: 0
// CHECK: MaximumExpectedWaveLaneCount: 0
// CHECK: ShaderFlags: 0 (None)
@ -95,8 +95,8 @@ float4 PSMain(int idx : INDEX) : SV_Target {
// CHECK: AttributeSizeInBytes: 0
// CHECK: FeatureInfo1: 0
// CHECK: FeatureInfo2: 0
// CHECK: ShaderStageFlag: 65535
// CHECK: MinShaderTarget: 393312
// CHECK: ShaderStageFlag: (Pixel | Vertex | Geometry | Hull | Domain | Compute | Library | RayGeneration | Intersection | AnyHit | ClosestHit | Miss | Callable | Mesh | Amplification | Node)
// CHECK: MinShaderTarget: 0x60060
// CHECK: MinimumExpectedWaveLaneCount: 0
// CHECK: MaximumExpectedWaveLaneCount: 0
// CHECK: ShaderFlags: 0 (None)
@ -114,8 +114,8 @@ float4 PSMain(int idx : INDEX) : SV_Target {
// CHECK: AttributeSizeInBytes: 0
// CHECK: FeatureInfo1: 0
// CHECK: FeatureInfo2: 0
// CHECK: ShaderStageFlag: 1
// CHECK: MinShaderTarget: 96
// CHECK: ShaderStageFlag: (Pixel)
// CHECK: MinShaderTarget: 0x60
// CHECK: MinimumExpectedWaveLaneCount: 0
// CHECK: MaximumExpectedWaveLaneCount: 0
// CHECK: ShaderFlags: 0 (None)
@ -141,8 +141,8 @@ float4 PSMain(int idx : INDEX) : SV_Target {
// CHECK: AttributeSizeInBytes: 0
// CHECK: FeatureInfo1: 0
// CHECK: FeatureInfo2: 0
// CHECK: ShaderStageFlag: 1
// CHECK: MinShaderTarget: 96
// CHECK: ShaderStageFlag: (Pixel)
// CHECK: MinShaderTarget: 0x60
// CHECK: MinimumExpectedWaveLaneCount: 0
// CHECK: MaximumExpectedWaveLaneCount: 0
// CHECK: ShaderFlags: 0 (None)
@ -161,8 +161,8 @@ float4 PSMain(int idx : INDEX) : SV_Target {
// CHECK: AttributeSizeInBytes: 0
// CHECK: FeatureInfo1: 0
// CHECK: FeatureInfo2: 0
// CHECK: ShaderStageFlag: 1
// CHECK: MinShaderTarget: 96
// CHECK: ShaderStageFlag: (Pixel)
// CHECK: MinShaderTarget: 0x60
// CHECK: MinimumExpectedWaveLaneCount: 0
// CHECK: MaximumExpectedWaveLaneCount: 0
// CHECK: ShaderFlags: 0 (None)

Просмотреть файл

@ -105,8 +105,8 @@ HSPerPatchData HSPerPatchFunc1()
// CHECK: AttributeSizeInBytes: 0
// CHECK: FeatureInfo1: 0
// CHECK: FeatureInfo2: 0
// CHECK: ShaderStageFlag: 65535
// CHECK: MinShaderTarget: 393312
// CHECK: ShaderStageFlag: (Pixel | Vertex | Geometry | Hull | Domain | Compute | Library | RayGeneration | Intersection | AnyHit | ClosestHit | Miss | Callable | Mesh | Amplification | Node)
// CHECK: MinShaderTarget: 0x60060
// CHECK: MinimumExpectedWaveLaneCount: 0
// CHECK: MaximumExpectedWaveLaneCount: 0
// CHECK: ShaderFlags: 0 (None)
@ -121,8 +121,8 @@ HSPerPatchData HSPerPatchFunc1()
// CHECK: AttributeSizeInBytes: 0
// CHECK: FeatureInfo1: 0
// CHECK: FeatureInfo2: 0
// CHECK: ShaderStageFlag: 65535
// CHECK: MinShaderTarget: 393312
// CHECK: ShaderStageFlag: (Pixel | Vertex | Geometry | Hull | Domain | Compute | Library | RayGeneration | Intersection | AnyHit | ClosestHit | Miss | Callable | Mesh | Amplification | Node)
// CHECK: MinShaderTarget: 0x60060
// CHECK: MinimumExpectedWaveLaneCount: 0
// CHECK: MaximumExpectedWaveLaneCount: 0
// CHECK: ShaderFlags: 0 (None)
@ -137,8 +137,8 @@ HSPerPatchData HSPerPatchFunc1()
// CHECK: AttributeSizeInBytes: 0
// CHECK: FeatureInfo1: 0
// CHECK: FeatureInfo2: 0
// CHECK: ShaderStageFlag: 8
// CHECK: MinShaderTarget: 196704
// CHECK: ShaderStageFlag: (Hull)
// CHECK: MinShaderTarget: 0x30060
// CHECK: MinimumExpectedWaveLaneCount: 0
// CHECK: MaximumExpectedWaveLaneCount: 0
// CHECK: ShaderFlags: 0 (None)
@ -154,8 +154,8 @@ HSPerPatchData HSPerPatchFunc1()
// CHECK: AttributeSizeInBytes: 0
// CHECK: FeatureInfo1: 0
// CHECK: FeatureInfo2: 0
// CHECK: ShaderStageFlag: 8
// CHECK: MinShaderTarget: 196704
// CHECK: ShaderStageFlag: (Hull)
// CHECK: MinShaderTarget: 0x30060
// CHECK: MinimumExpectedWaveLaneCount: 0
// CHECK: MaximumExpectedWaveLaneCount: 0
// CHECK: ShaderFlags: 0 (None)
@ -171,8 +171,8 @@ HSPerPatchData HSPerPatchFunc1()
// CHECK: AttributeSizeInBytes: 0
// CHECK: FeatureInfo1: 0
// CHECK: FeatureInfo2: 0
// CHECK: ShaderStageFlag: 8
// CHECK: MinShaderTarget: 393312
// CHECK: ShaderStageFlag: (Hull)
// CHECK: MinShaderTarget: 0x60060
// CHECK: MinimumExpectedWaveLaneCount: 0
// CHECK: MaximumExpectedWaveLaneCount: 0
// CHECK: ShaderFlags: 0 (None)

Просмотреть файл

@ -13,10 +13,10 @@
// CHECK: ShaderKind: Mesh
// CHECK: PayloadSizeInBytes: 0
// CHECK: AttributeSizeInBytes: 0
// CHECK: FeatureInfo1: 65536
// CHECK: FeatureInfo1: (ViewID)
// CHECK: FeatureInfo2: 0
// CHECK: ShaderStageFlag: 8192
// CHECK: MinShaderTarget: 852069
// CHECK: ShaderStageFlag: (Mesh)
// CHECK: MinShaderTarget: 0xd0065
// CHECK: MinimumExpectedWaveLaneCount: 0
// CHECK: MaximumExpectedWaveLaneCount: 0
// CHECK: ShaderFlags: (OutputPositionPresent | UsesViewID)

Просмотреть файл

@ -0,0 +1,33 @@
// RUN: %dxilver 1.8 | %dxc -T lib_6_8 %s | %D3DReflect %s | %FileCheck %s -check-prefixes=RDAT
// RUN: %dxilver 1.7 | %dxc -T lib_6_7 -validator-version 1.7 %s | %D3DReflect %s | FileCheck %s -check-prefixes=RDAT
// Ensure min shader target incorporates optional features used
// RDAT: FunctionTable[{{.*}}] = {
// SM 6.1+
///////////////////////////////////////////////////////////////////////////////
// ShaderFeatureInfo_Barycentrics (0x20000) = 131072
// RDAT-LABEL: UnmangledName: "bary1"
// RDAT: FeatureInfo1: (Barycentrics)
// RDAT: FeatureInfo2: 0
// RDAT: ShaderStageFlag: (Pixel)
// RDAT: MinShaderTarget: 0x61
[shader("pixel")]
void bary1(float3 barycentrics : SV_Barycentrics, out float4 target : SV_Target) {
target = float4(barycentrics, 1);
}
// RDAT-LABEL: UnmangledName: "bary2"
// RDAT: FeatureInfo1: (Barycentrics)
// RDAT: FeatureInfo2: 0
// RDAT: ShaderStageFlag: (Pixel)
// RDAT: MinShaderTarget: 0x61
[shader("pixel")]
void bary2(nointerpolation float4 color : COLOR, out float4 target : SV_Target) {
target = GetAttributeAtVertex(color, 1);
}

Просмотреть файл

@ -0,0 +1,25 @@
// RUN: %dxilver 1.8 | %dxc -T lib_6_8 %s | %D3DReflect %s | %FileCheck %s -check-prefixes=RDAT
// RUN: %dxilver 1.7 | %dxc -T lib_6_7 -validator-version 1.7 %s | %D3DReflect %s | FileCheck %s -check-prefixes=RDAT
// Ensure min shader target incorporates optional features used
// RDAT: FunctionTable[{{.*}}] = {
// SM 6.1+
///////////////////////////////////////////////////////////////////////////////
// ShaderFeatureInfo_ViewID (0x10000) = 65536
// ViewID is loaded using an intrinsic, so prior validator already adjusted SM
// for it.
// RDAT-LABEL: UnmangledName: "viewid"
// RDAT: FeatureInfo1: (ViewID)
// RDAT: FeatureInfo2: 0
// RDAT: ShaderStageFlag: (Pixel)
// RDAT: MinShaderTarget: 0x61
[shader("pixel")]
void viewid(uint vid : SV_ViewID, out float4 target : SV_Target) {
target = vid;
}

Просмотреть файл

@ -0,0 +1,96 @@
// RUN: %dxilver 1.8 | %dxc -T lib_6_8 %s | %D3DReflect %s | %FileCheck %s -check-prefixes=RDAT,RDAT18
// RUN: %dxilver 1.7 | %dxc -T lib_6_7 -validator-version 1.7 %s | %D3DReflect %s | FileCheck %s -check-prefixes=RDAT,RDAT17
// Ensure min shader target incorporates shader stage of entry function
// These must be minimal shaders since intrinsic usage associated with the
// shader stage will cause the min target to be set that way.
// This covers raytracing entry points, which should always be SM 6.3+
// RDAT: FunctionTable[{{.*}}] = {
RWByteAddressBuffer BAB : register(u1, space0);
// RDAT-LABEL: UnmangledName: "raygen"
// RDAT: FeatureInfo1: 0
// RDAT: FeatureInfo2: 0
// RDAT: ShaderStageFlag: (RayGeneration)
// RDAT18: MinShaderTarget: 0x70063
// Old: 6.0
// RDAT17: MinShaderTarget: 0x70060
[shader("raygeneration")]
void raygen() {
BAB.Store(0, 0);
}
// RDAT-LABEL: UnmangledName: "intersection"
// RDAT: FeatureInfo1: 0
// RDAT: FeatureInfo2: 0
// RDAT: ShaderStageFlag: (Intersection)
// RDAT18: MinShaderTarget: 0x80063
// Old: 6.0
// RDAT17: MinShaderTarget: 0x80060
[shader("intersection")]
void intersection() {
BAB.Store(0, 0);
}
// RDAT-LABEL: UnmangledName: "anyhit"
// RDAT: FeatureInfo1: 0
// RDAT: FeatureInfo2: 0
// RDAT: ShaderStageFlag: (AnyHit)
// RDAT18: MinShaderTarget: 0x90063
// Old: 6.0
// RDAT17: MinShaderTarget: 0x90060
struct [raypayload] MyPayload {
float2 loc : write(caller) : read(caller);
};
[shader("anyhit")]
void anyhit(inout MyPayload payload : SV_RayPayload,
in BuiltInTriangleIntersectionAttributes attr : SV_IntersectionAttributes ) {
BAB.Store(0, 0);
}
// RDAT-LABEL: UnmangledName: "closesthit"
// RDAT: FeatureInfo1: 0
// RDAT: FeatureInfo2: 0
// RDAT: ShaderStageFlag: (ClosestHit)
// RDAT18: MinShaderTarget: 0xa0063
// Old: 6.0
// RDAT17: MinShaderTarget: 0xa0060
[shader("closesthit")]
void closesthit(inout MyPayload payload : SV_RayPayload,
in BuiltInTriangleIntersectionAttributes attr : SV_IntersectionAttributes ) {
BAB.Store(0, 0);
}
// RDAT-LABEL: UnmangledName: "miss"
// RDAT: FeatureInfo1: 0
// RDAT: FeatureInfo2: 0
// RDAT: ShaderStageFlag: (Miss)
// RDAT18: MinShaderTarget: 0xb0063
// Old: 6.0
// RDAT17: MinShaderTarget: 0xb0060
[shader("miss")]
void miss(inout MyPayload payload : SV_RayPayload) {
BAB.Store(0, 0);
}
// RDAT-LABEL: UnmangledName: "callable"
// RDAT: FeatureInfo1: 0
// RDAT: FeatureInfo2: 0
// RDAT: ShaderStageFlag: (Callable)
// RDAT18: MinShaderTarget: 0xc0063
// Old: 6.0
// RDAT17: MinShaderTarget: 0xc0060
[shader("callable")]
void callable(inout MyPayload param) {
BAB.Store(0, 0);
}

Просмотреть файл

@ -0,0 +1,25 @@
// RUN: %dxilver 1.8 | %dxc -T lib_6_8 %s | %D3DReflect %s | %FileCheck %s -check-prefixes=RDAT,RDAT18
// RUN: %dxilver 1.7 | %dxc -T lib_6_7 -validator-version 1.7 %s | %D3DReflect %s | FileCheck %s -check-prefixes=RDAT,RDAT17
// Ensure min shader target incorporates optional features used
// RDAT: FunctionTable[{{.*}}] = {
// SM 6.4+
///////////////////////////////////////////////////////////////////////////////
// ShaderFeatureInfo_ShadingRate (0x80000) = 524288
// Not sure if already caught.
// RDAT-LABEL: UnmangledName: "ps_shadingrate"
// RDAT: FeatureInfo1: (ShadingRate)
// RDAT: FeatureInfo2: 0
// RDAT: ShaderStageFlag: (Pixel)
// RDAT18: MinShaderTarget: 0x64
// Old 6.0
// RDAT17: MinShaderTarget: 0x60
[shader("pixel")]
void ps_shadingrate(uint rate : SV_ShadingRate, out float4 target : SV_Target) {
target = rate;
}

Просмотреть файл

@ -0,0 +1,67 @@
// RUN: %dxilver 1.8 | %dxc -T lib_6_8 %s | %D3DReflect %s | %FileCheck %s -check-prefixes=RDAT,RDAT18
// RUN: %dxilver 1.7 | %dxc -T lib_6_7 -validator-version 1.7 %s | %D3DReflect %s | FileCheck %s -check-prefixes=RDAT,RDAT17
// Ensure min shader target incorporates shader stage of entry function
// These must be minimal shaders since intrinsic usage associated with the
// shader stage will cause the min target to be set that way.
// This covers mesh and amplification shaders, which should always be SM 6.5+
// RDAT: FunctionTable[{{.*}}] = {
RWByteAddressBuffer BAB : register(u1, space0);
////////////////////////////////////////
// Mesh shader
// Currently, mesh shader is not requiring output vertices or indices, so this
// works. If that requirement were to be enforced, we would have to declare
// these outputs. However, if we do, there should also be a requirement that
// mesh shader vertex output has SV_Position (not enforced currently either).
// If that were to be enforced, and added to the struct, then the validator
// will fail unless you write to all components of SV_Position. This should
// probably only be the case if OutputCounts are set to anything other than 0.
// In any case, all this means that if some rules start to be enforced, we
// will be forced to use things which will produce intrinsic calls in the mesh
// shader which will cause the min target to be set to SM 6.5+ even for
// validator version 1.7 and below.
// RDAT-LABEL: UnmangledName: "mesh"
// RDAT: FeatureInfo1: 0
// RDAT: FeatureInfo2: 0
// RDAT: ShaderStageFlag: (Mesh)
// RDAT18: MinShaderTarget: 0xd0065
// Old: 6.0
// RDAT17: MinShaderTarget: 0xd0060
struct Vertex {
float4 val : UNUSED;
};
[shader("mesh")]
[numthreads(1, 1, 1)]
[outputtopology("triangle")]
void mesh(//out vertices Vertex verts[1],
//out indices uint3 tris[1]
) {
BAB.Store(0, 0);
}
////////////////////////////////////////
// Amplification shader
// It turns out that amplification shaders require exactly one DispatchMesh
// call, which causes the entry to get the correct min target without basing
// it on the shader type.
// RDAT-LABEL: UnmangledName: "amplification"
// RDAT: FeatureInfo1: 0
// RDAT: FeatureInfo2: 0
// RDAT: ShaderStageFlag: (Amplification)
// RDAT: MinShaderTarget: 0xe0065
groupshared Vertex pld;
[shader("amplification")]
[numthreads(8, 8, 1)]
void amplification(uint3 DTid : SV_DispatchThreadID) {
DispatchMesh(1, 1, 1, pld);
}

Просмотреть файл

@ -0,0 +1,85 @@
// RUN: %dxilver 1.8 | %dxc -T lib_6_8 %s | %D3DReflect %s | %FileCheck %s -check-prefixes=RDAT,RDAT18
// RUN: %dxilver 1.7 | %dxc -T lib_6_7 -validator-version 1.7 %s | %D3DReflect %s | FileCheck %s -check-prefixes=RDAT,RDAT17
// Ensure min shader target incorporates optional features used
// RDAT: FunctionTable[{{.*}}] = {
// SM 6.6+
///////////////////////////////////////////////////////////////////////////////
// ShaderFeatureInfo_AtomicInt64OnTypedResource (0x400000) = 4194304
// Typed resource atomics produce an intrinsic that requires 6.6
// producing the correct version requirement without considering the flag.
// RDAT-LABEL: UnmangledName: "atomic_typed"
// RDAT: FeatureInfo1: (Int64Ops | AtomicInt64OnTypedResource)
// RDAT: FeatureInfo2: 0
// RDAT: MinShaderTarget: 0x60066
RWBuffer<uint64_t> RWBuf : register(u0, space0);
[noinline] export
void atomic_typed() {
uint64_t original;
InterlockedExchange(RWBuf[0], 12, original);
}
///////////////////////////////////////////////////////////////////////////////
// ShaderFeatureInfo_AtomicInt64OnGroupShared (0x800000) = 8388608
// RDAT-LABEL: UnmangledName: "atomic_groupshared"
// ShaderFeatureInfo_AtomicInt64OnGroupShared (0x800000) = 8388608
// + ShaderFeatureInfo_Int64Ops (0x8000) = 0x808000 = 8421376
// RDAT: FeatureInfo1: (Int64Ops | AtomicInt64OnGroupShared)
// RDAT: FeatureInfo2: 0
// MinShaderTarget: (Compute(5) << 16) + (SM 6.6 ((6 << 4) + 6)) = 0x50066 = 327782
// RDAT18: MinShaderTarget: 0x50066
// Old: 6.0
// RDAT17: MinShaderTarget: 0x50060
RWByteAddressBuffer BAB : register(u1, space0);
groupshared int64_t gs;
[shader("compute")]
[numthreads(1,1,1)]
void atomic_groupshared(uint tidx : SV_GroupIndex) {
if (tidx == 0)
gs = 0;
GroupMemoryBarrierWithGroupSync();
uint64_t original;
InterlockedExchange(gs, tidx, original);
BAB.Store(tidx * 4, original);
}
///////////////////////////////////////////////////////////////////////////////
// ShaderFeatureInfo_AtomicInt64OnHeapResource (0x10000000) = 268435456
// RDAT-LABEL: UnmangledName: "atomic_heap"
// RDAT: FeatureInfo1: (Int64Ops | ResourceDescriptorHeapIndexing | AtomicInt64OnHeapResource)
// RDAT: FeatureInfo2: 0
// RDAT17: ShaderStageFlag: (Pixel | Vertex | Geometry | Hull | Domain | Compute | Library | RayGeneration | Intersection | AnyHit | ClosestHit | Miss | Callable | Mesh | Amplification)
// RDAT18: ShaderStageFlag: (Pixel | Vertex | Geometry | Hull | Domain | Compute | Library | RayGeneration | Intersection | AnyHit | ClosestHit | Miss | Callable | Mesh | Amplification | Node)
// RDAT: MinShaderTarget: 0x60066
[noinline] export
void atomic_heap() {
uint64_t original;
RWStructuredBuffer<uint64_t> SB64 = ResourceDescriptorHeap[0];
InterlockedExchange(SB64[0], 12, original);
}
// RDAT-LABEL: UnmangledName: "atomic_heap_raygen"
// RDAT18: FeatureInfo1: (Int64Ops | ResourceDescriptorHeapIndexing | AtomicInt64OnHeapResource)
// Old: missed called function
// RDAT17: FeatureInfo1: 0
// RDAT: FeatureInfo2: 0
// RDAT: ShaderStageFlag: (RayGeneration)
// RDAT18: MinShaderTarget: 0x70066
// Old: 6.0
// RDAT17: MinShaderTarget: 0x70060
[shader("raygeneration")]
void atomic_heap_raygen() {
atomic_heap();
}

Просмотреть файл

@ -0,0 +1,145 @@
// RUN: %dxilver 1.8 | %dxc -T lib_6_8 %s | %D3DReflect %s | %FileCheck %s -check-prefixes=RDAT,RDAT18
// RUN: %dxilver 1.7 | %dxc -T lib_6_7 -validator-version 1.7 %s | %D3DReflect %s | FileCheck %s -check-prefixes=RDAT,RDAT17
// RUN: %dxilver 1.6 | %dxc -T lib_6_6 -validator-version 1.6 %s | %D3DReflect %s | FileCheck %s -check-prefixes=RDAT,RDAT16
// Compile to DXIL to check ShaderFlags.
// RUN: %dxilver 1.8 | %dxc -T lib_6_8 %s | %FileCheck %s -check-prefixes=DXIL,DXIL18
// RUN: %dxilver 1.7 | %dxc -T lib_6_7 -validator-version 1.7 %s | FileCheck %s -check-prefixes=DXIL,DXIL17
// RUN: %dxilver 1.6 | %dxc -T lib_6_6 -validator-version 1.6 %s | FileCheck %s -check-prefixes=DXIL,DXIL16
///////////////////////////////////////////////////////////////////////////////
// DXIL checks
// Ensure ShaderFlags do not include UsedsDerivatives, but do include
// DerivativesInMeshAndAmpShaders in validator version 1.8 only. 1.8 should
// no longer include UAVsAtEveryStage, since that shouldn't have applied to
// library profile, only VS, HS, DS, and GS profiles.
// These flag values are raw shader flags, so they are not the same as the
// feature flag values.
// DXIL: !dx.entryPoints = !{![[lib_entry:[0-9]+]],
// DXIL: ![[lib_entry]] = !{null, !"", null, !{{.*}}, ![[shader_flags:[0-9]+]]}
// 65552 = 0x10010 = EnableRawAndStructuredBuffers(0x10) + UAVsAtEveryStage(0x10000)
// DXIL16: ![[shader_flags]] = !{i32 0, i64 65552}
// 8590000144 = 0x200010010 = 0x10010 + ResMayNotAlias(0x200000000)
// DXIL17: ![[shader_flags]] = !{i32 0, i64 8590000144}
// 9126805520 = 0x220000010 = 0x200010010 - UAVsAtEveryStage(0x10000) +
// DerivativesInMeshAndAmpShaders(0x20000000)
// DXIL18: ![[shader_flags]] = !{i32 0, i64 9126805520}
///////////////////////////////////////////////////////////////////////////////
// RDAT checks
// Ensure min shader target incorporates optional features used
// RDAT: FunctionTable[{{.*}}] = {
// SM 6.6+
///////////////////////////////////////////////////////////////////////////////
// ShaderFeatureInfo_DerivativesInMeshAndAmpShaders (0x1000000) = 16777216
// OptFeatureInfo_UsesDerivatives (0x0000010000000000) = FeatureInfo2: 256
// OptFeatureInfo_UsesDerivatives Flag used to indicate derivative use in
// functions, then fixed up for entry functions.
// Val. ver. 1.8 required to recursively check called functions.
// RDAT-LABEL: UnmangledName: "deriv_in_func"
// RDAT: FeatureInfo1: 0
// RDAT18: FeatureInfo2: (Opt_UsesDerivatives)
// Old: deriv use not tracked
// RDAT16: FeatureInfo2: 0
// RDAT17: FeatureInfo2: 0
// RDAT18: ShaderStageFlag: (Pixel | Compute | Library | Mesh | Amplification | Node)
// Old would not report Compute, Mesh, Amplification, or Node compatibility.
// RDAT16: ShaderStageFlag: (Pixel | Library)
// RDAT17: ShaderStageFlag: (Pixel | Library)
// RDAT17: MinShaderTarget: 0x60060
// RDAT18: MinShaderTarget: 0x60060
// Old: Didn't set min target properly for lib function
// RDAT16: MinShaderTarget: 0x60066
RWByteAddressBuffer BAB : register(u1, space0);
[noinline] export
void deriv_in_func(float2 uv) {
BAB.Store(0, ddx(uv));
}
// RDAT-LABEL: UnmangledName: "deriv_in_mesh"
// RDAT18: FeatureInfo1: (DerivativesInMeshAndAmpShaders)
// Old: missed called function
// RDAT16: FeatureInfo1: 0
// RDAT17: FeatureInfo1: 0
// RDAT18: FeatureInfo2: (Opt_UsesDerivatives)
// Old: deriv use not tracked
// RDAT16: FeatureInfo2: 0
// RDAT17: FeatureInfo2: 0
// Mesh(13) = 0x2000 = 8192
// RDAT: ShaderStageFlag: (Mesh)
// RDAT18: MinShaderTarget: 0xd0066
// Old: 6.0
// RDAT16: MinShaderTarget: 0xd0060
// RDAT17: MinShaderTarget: 0xd0060
[shader("mesh")]
[numthreads(8, 8, 1)]
[outputtopology("triangle")]
void deriv_in_mesh(uint3 DTid : SV_DispatchThreadID) {
float2 uv = DTid.xy/float2(8, 8);
deriv_in_func(uv);
}
// RDAT-LABEL: UnmangledName: "deriv_in_compute"
// RDAT: FeatureInfo1: 0
// RDAT18: FeatureInfo2: (Opt_UsesDerivatives)
// Old: deriv use not tracked
// RDAT16: FeatureInfo2: 0
// RDAT17: FeatureInfo2: 0
// RDAT: ShaderStageFlag: (Compute)
// RDAT18: MinShaderTarget: 0x50066
// Old: 6.0
// RDAT16: MinShaderTarget: 0x50060
// RDAT17: MinShaderTarget: 0x50060
[shader("compute")]
[numthreads(8, 8, 1)]
void deriv_in_compute(uint3 DTid : SV_DispatchThreadID) {
float2 uv = DTid.xy/float2(8, 8);
deriv_in_func(uv);
}
// RDAT-LABEL: UnmangledName: "deriv_in_pixel"
// RDAT: FeatureInfo1: 0
// RDAT18: FeatureInfo2: (Opt_UsesDerivatives)
// Old: deriv use not tracked
// RDAT16: FeatureInfo2: 0
// RDAT17: FeatureInfo2: 0
// Pixel(0) = 0x1 = 1
// RDAT: ShaderStageFlag: (Pixel)
// RDAT: MinShaderTarget: 0x60
[shader("pixel")]
void deriv_in_pixel(float2 uv : TEXCOORD) {
deriv_in_func(uv);
}
// Make sure function-level derivative flag isn't in RequiredFeatureFlags,
// and make sure mesh shader sets required flag.
// RDAT-LABEL: ID3D12LibraryReflection:
// RDAT-LABEL: D3D12_FUNCTION_DESC: Name:
// RDAT-SAME: deriv_in_func
// RDAT: RequiredFeatureFlags: 0
// RDAT-LABEL: D3D12_FUNCTION_DESC: Name: deriv_in_compute
// RDAT: RequiredFeatureFlags: 0
// RDAT-LABEL: D3D12_FUNCTION_DESC: Name: deriv_in_mesh
// ShaderFeatureInfo_DerivativesInMeshAndAmpShaders (0x1000000) = 16777216
// RDAT18: RequiredFeatureFlags: 0x1000000
// Old: missed called function
// RDAT16: RequiredFeatureFlags: 0
// RDAT17: RequiredFeatureFlags: 0
// RDAT-LABEL: D3D12_FUNCTION_DESC: Name: deriv_in_pixel
// RDAT: RequiredFeatureFlags: 0

Просмотреть файл

@ -0,0 +1,204 @@
; RUN: %dxilver 1.6 | %D3DReflect %s | FileCheck %s -check-prefixes=RDAT,RDAT16
target datalayout = "e-m:e-p:32:32-i1:32-i8:32-i16:32-i32:32-i64:64-f16:32-f32:32-f64:64-n8:16:32:64"
target triple = "dxil-ms-dx"
%dx.types.Handle = type { i8* }
%dx.types.ResourceProperties = type { i32, i32 }
%struct.RWByteAddressBuffer = type { i32 }
@"\01?BAB@@3URWByteAddressBuffer@@A" = external constant %dx.types.Handle, align 4
; Ensure min shader target incorporates optional features used
; RDAT: FunctionTable[{{.*}}] = {
; SM 6.6+
;/////////////////////////////////////////////////////////////////////////////
; ShaderFeatureInfo_DerivativesInMeshAndAmpShaders (0x1000000) = 16777216
; OptFeatureInfo_UsesDerivatives (0x0000010000000000) = FeatureInfo2: 256
; OptFeatureInfo_UsesDerivatives Flag used to indicate derivative use in
; functions, then fixed up for entry functions.
; Val. ver. 1.8 required to recursively check called functions.
; RDAT-LABEL: UnmangledName: "deriv_in_func"
; RDAT: FeatureInfo1: 0
; RDAT18: FeatureInfo2: (Opt_UsesDerivatives)
; Old: deriv use not tracked
; RDAT16: FeatureInfo2: 0
; RDAT17: FeatureInfo2: 0
; RDAT18: ShaderStageFlag: (Pixel | Compute | Library | Mesh | Amplification | Node)
; Old would not report Compute, Mesh, Amplification, or Node compatibility.
; RDAT16: ShaderStageFlag: (Pixel | Library)
; RDAT17: ShaderStageFlag: (Pixel | Library)
; RDAT17: MinShaderTarget: 0x60060
; RDAT18: MinShaderTarget: 0x60060
; Old: Didn't set min target properly for lib function
; RDAT16: MinShaderTarget: 0x60066
; Function Attrs: noinline nounwind
define void @"\01?deriv_in_func@@YAXV?$vector@M$01@@@Z"(<2 x float> %uv) #0 {
%1 = load %dx.types.Handle, %dx.types.Handle* @"\01?BAB@@3URWByteAddressBuffer@@A", align 4
%2 = extractelement <2 x float> %uv, i64 0
%3 = extractelement <2 x float> %uv, i64 1
%4 = call float @dx.op.unary.f32(i32 83, float %2) ; DerivCoarseX(value)
%5 = call float @dx.op.unary.f32(i32 83, float %3) ; DerivCoarseX(value)
%6 = call %dx.types.Handle @dx.op.createHandleForLib.dx.types.Handle(i32 160, %dx.types.Handle %1) ; CreateHandleForLib(Resource)
%7 = call %dx.types.Handle @dx.op.annotateHandle(i32 216, %dx.types.Handle %6, %dx.types.ResourceProperties { i32 4107, i32 0 }) ; AnnotateHandle(res,props) resource: RWByteAddressBuffer
call void @dx.op.rawBufferStore.f32(i32 140, %dx.types.Handle %7, i32 0, i32 undef, float %4, float %5, float undef, float undef, i8 3, i32 4) ; RawBufferStore(uav,index,elementOffset,value0,value1,value2,value3,mask,alignment)
ret void
}
; RDAT-LABEL: UnmangledName: "deriv_in_mesh"
; RDAT18: FeatureInfo1: (DerivativesInMeshAndAmpShaders)
; Old: missed called function
; RDAT16: FeatureInfo1: 0
; RDAT17: FeatureInfo1: 0
; RDAT18: FeatureInfo2: (Opt_UsesDerivatives)
; Old: deriv use not tracked
; RDAT16: FeatureInfo2: 0
; RDAT17: FeatureInfo2: 0
; RDAT: ShaderStageFlag: (Mesh)
; RDAT18: MinShaderTarget: 0xd0066
; Old: 6.0
; RDAT16: MinShaderTarget: 0xd0060
; RDAT17: MinShaderTarget: 0xd0060
define void @deriv_in_mesh() {
%1 = call i32 @dx.op.threadId.i32(i32 93, i32 0) ; ThreadId(component)
%2 = call i32 @dx.op.threadId.i32(i32 93, i32 1) ; ThreadId(component)
%3 = uitofp i32 %1 to float
%4 = uitofp i32 %2 to float
%5 = fmul fast float %3, 1.250000e-01
%6 = fmul fast float %4, 1.250000e-01
%7 = insertelement <2 x float> undef, float %5, i32 0
%8 = insertelement <2 x float> %7, float %6, i32 1
call void @"\01?deriv_in_func@@YAXV?$vector@M$01@@@Z"(<2 x float> %8)
ret void
}
; RDAT-LABEL: UnmangledName: "deriv_in_compute"
; RDAT: FeatureInfo1: 0
; RDAT18: FeatureInfo2: (Opt_UsesDerivatives)
; Old: deriv use not tracked
; RDAT16: FeatureInfo2: 0
; RDAT17: FeatureInfo2: 0
; RDAT: ShaderStageFlag: (Compute)
; RDAT18: MinShaderTarget: 0x50066
; Old: 6.0
; RDAT16: MinShaderTarget: 0x50060
; RDAT17: MinShaderTarget: 0x50060
define void @deriv_in_compute() {
%1 = call i32 @dx.op.threadId.i32(i32 93, i32 0) ; ThreadId(component)
%2 = call i32 @dx.op.threadId.i32(i32 93, i32 1) ; ThreadId(component)
%3 = uitofp i32 %1 to float
%4 = uitofp i32 %2 to float
%5 = fmul fast float %3, 1.250000e-01
%6 = fmul fast float %4, 1.250000e-01
%7 = insertelement <2 x float> undef, float %5, i32 0
%8 = insertelement <2 x float> %7, float %6, i32 1
call void @"\01?deriv_in_func@@YAXV?$vector@M$01@@@Z"(<2 x float> %8)
ret void
}
; RDAT-LABEL: UnmangledName: "deriv_in_pixel"
; RDAT: FeatureInfo1: 0
; RDAT18: FeatureInfo2: (Opt_UsesDerivatives)
; Old: deriv use not tracked
; RDAT16: FeatureInfo2: 0
; RDAT17: FeatureInfo2: 0
; RDAT: ShaderStageFlag: (Pixel)
; RDAT: MinShaderTarget: 0x60
define void @deriv_in_pixel() {
%1 = call float @dx.op.loadInput.f32(i32 4, i32 0, i32 0, i8 0, i32 undef) ; LoadInput(inputSigId,rowIndex,colIndex,gsVertexAxis)
%2 = insertelement <2 x float> undef, float %1, i64 0
%3 = call float @dx.op.loadInput.f32(i32 4, i32 0, i32 0, i8 1, i32 undef) ; LoadInput(inputSigId,rowIndex,colIndex,gsVertexAxis)
%4 = insertelement <2 x float> %2, float %3, i64 1
call void @"\01?deriv_in_func@@YAXV?$vector@M$01@@@Z"(<2 x float> %4)
ret void
}
; Function Attrs: nounwind readnone
declare i32 @dx.op.threadId.i32(i32, i32) #1
; Function Attrs: nounwind readnone
declare float @dx.op.loadInput.f32(i32, i32, i32, i8, i32) #1
; Function Attrs: nounwind
declare void @dx.op.rawBufferStore.f32(i32, %dx.types.Handle, i32, i32, float, float, float, float, i8, i32) #2
; Function Attrs: nounwind readnone
declare float @dx.op.unary.f32(i32, float) #1
; Function Attrs: nounwind readnone
declare %dx.types.Handle @dx.op.annotateHandle(i32, %dx.types.Handle, %dx.types.ResourceProperties) #1
; Function Attrs: nounwind readonly
declare %dx.types.Handle @dx.op.createHandleForLib.dx.types.Handle(i32, %dx.types.Handle) #3
attributes #0 = { noinline nounwind }
attributes #1 = { nounwind readnone }
attributes #2 = { nounwind }
attributes #3 = { nounwind readonly }
!llvm.ident = !{!0}
!dx.version = !{!1}
!dx.valver = !{!1}
!dx.shaderModel = !{!2}
!dx.resources = !{!3}
!dx.typeAnnotations = !{!6}
!dx.entryPoints = !{!14, !16, !20, !23}
!0 = !{!"dxc(private) 1.7.0.4429 (rdat-minsm-check-flags, 9d3b6ba57)"}
!1 = !{i32 1, i32 6}
!2 = !{!"lib", i32 6, i32 6}
!3 = !{null, !4, null, null}
!4 = !{!5}
!5 = !{i32 0, %struct.RWByteAddressBuffer* bitcast (%dx.types.Handle* @"\01?BAB@@3URWByteAddressBuffer@@A" to %struct.RWByteAddressBuffer*), !"BAB", i32 0, i32 1, i32 1, i32 11, i1 false, i1 false, i1 false, null}
!6 = !{i32 1, void (<2 x float>)* @"\01?deriv_in_func@@YAXV?$vector@M$01@@@Z", !7, void ()* @deriv_in_mesh, !12, void ()* @deriv_in_compute, !12, void ()* @deriv_in_pixel, !12}
!7 = !{!8, !10}
!8 = !{i32 1, !9, !9}
!9 = !{}
!10 = !{i32 0, !11, !9}
!11 = !{i32 7, i32 9}
!12 = !{!13}
!13 = !{i32 0, !9, !9}
!14 = !{null, !"", null, !3, !15}
!15 = !{i32 0, i64 65552}
!16 = !{void ()* @deriv_in_compute, !"deriv_in_compute", null, null, !17}
!17 = !{i32 8, i32 5, i32 4, !18, i32 5, !19}
!18 = !{i32 8, i32 8, i32 1}
!19 = !{i32 0}
!20 = !{void ()* @deriv_in_mesh, !"deriv_in_mesh", null, null, !21}
!21 = !{i32 8, i32 13, i32 9, !22, i32 5, !19}
!22 = !{!18, i32 0, i32 0, i32 2, i32 0}
!23 = !{void ()* @deriv_in_pixel, !"deriv_in_pixel", !24, null, !27}
!24 = !{!25, null, null}
!25 = !{!26}
!26 = !{i32 0, !"TEXCOORD", i8 9, i8 0, !19, i8 2, i32 1, i8 2, i32 0, i8 0, null}
!27 = !{i32 8, i32 0, i32 5, !19}
; Make sure function-level derivative flag isn't in RequiredFeatureFlags,
; and make sure mesh shader sets required flag.
; RDAT-LABEL: ID3D12LibraryReflection:
; RDAT-LABEL: D3D12_FUNCTION_DESC: Name:
; RDAT-SAME: deriv_in_func
; RDAT: RequiredFeatureFlags: 0
; RDAT-LABEL: D3D12_FUNCTION_DESC: Name: deriv_in_compute
; RDAT: RequiredFeatureFlags: 0
; RDAT-LABEL: D3D12_FUNCTION_DESC: Name: deriv_in_mesh
; ShaderFeatureInfo_DerivativesInMeshAndAmpShaders (0x1000000) = 16777216
; RDAT18: RequiredFeatureFlags: 0x1000000
; Old: missed called function
; RDAT17: RequiredFeatureFlags: 0
; RDAT-LABEL: D3D12_FUNCTION_DESC: Name: deriv_in_pixel
; RDAT: RequiredFeatureFlags: 0

Просмотреть файл

@ -0,0 +1,209 @@
; RUN: %dxilver 1.6 | %D3DReflect %s | FileCheck %s -check-prefixes=RDAT,RDAT16
target datalayout = "e-m:e-p:32:32-i1:32-i8:32-i16:32-i32:32-i64:64-f16:32-f32:32-f64:64-n8:16:32:64"
target triple = "dxil-ms-dx"
%dx.types.Handle = type { i8* }
%dx.types.ResourceProperties = type { i32, i32 }
%struct.RWByteAddressBuffer = type { i32 }
@"\01?BAB@@3URWByteAddressBuffer@@A" = external constant %dx.types.Handle, align 4
; Ensure min shader target incorporates optional features used
; Here, we declare the intrinsics first, and reorder the called function
; relative to entries that call it, to ensure iteration order doesn't
; change the result.
; Function Attrs: nounwind readnone
declare i32 @dx.op.threadId.i32(i32, i32) #1
; Function Attrs: nounwind readnone
declare float @dx.op.loadInput.f32(i32, i32, i32, i8, i32) #1
; Function Attrs: nounwind
declare void @dx.op.rawBufferStore.f32(i32, %dx.types.Handle, i32, i32, float, float, float, float, i8, i32) #2
; Function Attrs: nounwind readnone
declare float @dx.op.unary.f32(i32, float) #1
; Function Attrs: nounwind readnone
declare %dx.types.Handle @dx.op.annotateHandle(i32, %dx.types.Handle, %dx.types.ResourceProperties) #1
; Function Attrs: nounwind readonly
declare %dx.types.Handle @dx.op.createHandleForLib.dx.types.Handle(i32, %dx.types.Handle) #3
; RDAT: FunctionTable[{{.*}}] = {
; SM 6.6+
;/////////////////////////////////////////////////////////////////////////////
; ShaderFeatureInfo_DerivativesInMeshAndAmpShaders (0x1000000) = 16777216
; OptFeatureInfo_UsesDerivatives (0x0000010000000000) = FeatureInfo2: 256
; OptFeatureInfo_UsesDerivatives Flag used to indicate derivative use in
; functions, then fixed up for entry functions.
; Val. ver. 1.8 required to recursively check called functions.
; RDAT-LABEL: UnmangledName: "deriv_in_mesh"
; RDAT18: FeatureInfo1: (DerivativesInMeshAndAmpShaders)
; Old: missed called function
; RDAT16: FeatureInfo1: 0
; RDAT17: FeatureInfo1: 0
; RDAT18: FeatureInfo2: (Opt_UsesDerivatives)
; Old: deriv use not tracked
; RDAT16: FeatureInfo2: 0
; RDAT17: FeatureInfo2: 0
; RDAT: ShaderStageFlag: (Mesh)
; RDAT18: MinShaderTarget: 0xd0066
; Old: 6.0
; RDAT16: MinShaderTarget: 0xd0060
; RDAT17: MinShaderTarget: 0xd0060
define void @deriv_in_mesh() {
%1 = call i32 @dx.op.threadId.i32(i32 93, i32 0) ; ThreadId(component)
%2 = call i32 @dx.op.threadId.i32(i32 93, i32 1) ; ThreadId(component)
%3 = uitofp i32 %1 to float
%4 = uitofp i32 %2 to float
%5 = fmul fast float %3, 1.250000e-01
%6 = fmul fast float %4, 1.250000e-01
%7 = insertelement <2 x float> undef, float %5, i32 0
%8 = insertelement <2 x float> %7, float %6, i32 1
call void @"\01?deriv_in_func@@YAXV?$vector@M$01@@@Z"(<2 x float> %8)
ret void
}
; RDAT-LABEL: UnmangledName: "deriv_in_compute"
; RDAT: FeatureInfo1: 0
; RDAT18: FeatureInfo2: (Opt_UsesDerivatives)
; Old: deriv use not tracked
; RDAT16: FeatureInfo2: 0
; RDAT17: FeatureInfo2: 0
; RDAT: ShaderStageFlag: (Compute)
; RDAT18: MinShaderTarget: 0x50066
; Old: 6.0
; RDAT16: MinShaderTarget: 0x50060
; RDAT17: MinShaderTarget: 0x50060
define void @deriv_in_compute() {
%1 = call i32 @dx.op.threadId.i32(i32 93, i32 0) ; ThreadId(component)
%2 = call i32 @dx.op.threadId.i32(i32 93, i32 1) ; ThreadId(component)
%3 = uitofp i32 %1 to float
%4 = uitofp i32 %2 to float
%5 = fmul fast float %3, 1.250000e-01
%6 = fmul fast float %4, 1.250000e-01
%7 = insertelement <2 x float> undef, float %5, i32 0
%8 = insertelement <2 x float> %7, float %6, i32 1
call void @"\01?deriv_in_func@@YAXV?$vector@M$01@@@Z"(<2 x float> %8)
ret void
}
; RDAT-LABEL: UnmangledName: "deriv_in_pixel"
; RDAT: FeatureInfo1: 0
; RDAT18: FeatureInfo2: (Opt_UsesDerivatives)
; Old: deriv use not tracked
; RDAT16: FeatureInfo2: 0
; RDAT17: FeatureInfo2: 0
; RDAT: ShaderStageFlag: (Pixel)
; RDAT: MinShaderTarget: 0x60
define void @deriv_in_pixel() {
%1 = call float @dx.op.loadInput.f32(i32 4, i32 0, i32 0, i8 0, i32 undef) ; LoadInput(inputSigId,rowIndex,colIndex,gsVertexAxis)
%2 = insertelement <2 x float> undef, float %1, i64 0
%3 = call float @dx.op.loadInput.f32(i32 4, i32 0, i32 0, i8 1, i32 undef) ; LoadInput(inputSigId,rowIndex,colIndex,gsVertexAxis)
%4 = insertelement <2 x float> %2, float %3, i64 1
call void @"\01?deriv_in_func@@YAXV?$vector@M$01@@@Z"(<2 x float> %4)
ret void
}
; RDAT-LABEL: UnmangledName: "deriv_in_func"
; RDAT: FeatureInfo1: 0
; RDAT18: FeatureInfo2: (Opt_UsesDerivatives)
; Old: deriv use not tracked
; RDAT16: FeatureInfo2: 0
; RDAT17: FeatureInfo2: 0
; RDAT18: ShaderStageFlag: (Pixel | Compute | Library | Mesh | Amplification | Node)
; Old would not report Compute, Mesh, Amplification, or Node compatibility.
; RDAT16: ShaderStageFlag: (Pixel | Library)
; RDAT17: ShaderStageFlag: (Pixel | Library)
; RDAT17: MinShaderTarget: 0x60060
; RDAT18: MinShaderTarget: 0x60060
; Old: Didn't set min target properly for lib function
; RDAT16: MinShaderTarget: 0x60066
; Function Attrs: noinline nounwind
define void @"\01?deriv_in_func@@YAXV?$vector@M$01@@@Z"(<2 x float> %uv) #0 {
%1 = load %dx.types.Handle, %dx.types.Handle* @"\01?BAB@@3URWByteAddressBuffer@@A", align 4
%2 = extractelement <2 x float> %uv, i64 0
%3 = extractelement <2 x float> %uv, i64 1
%4 = call float @dx.op.unary.f32(i32 83, float %2) ; DerivCoarseX(value)
%5 = call float @dx.op.unary.f32(i32 83, float %3) ; DerivCoarseX(value)
%6 = call %dx.types.Handle @dx.op.createHandleForLib.dx.types.Handle(i32 160, %dx.types.Handle %1) ; CreateHandleForLib(Resource)
%7 = call %dx.types.Handle @dx.op.annotateHandle(i32 216, %dx.types.Handle %6, %dx.types.ResourceProperties { i32 4107, i32 0 }) ; AnnotateHandle(res,props) resource: RWByteAddressBuffer
call void @dx.op.rawBufferStore.f32(i32 140, %dx.types.Handle %7, i32 0, i32 undef, float %4, float %5, float undef, float undef, i8 3, i32 4) ; RawBufferStore(uav,index,elementOffset,value0,value1,value2,value3,mask,alignment)
ret void
}
attributes #0 = { noinline nounwind }
attributes #1 = { nounwind readnone }
attributes #2 = { nounwind }
attributes #3 = { nounwind readonly }
!llvm.ident = !{!0}
!dx.version = !{!1}
!dx.valver = !{!1}
!dx.shaderModel = !{!2}
!dx.resources = !{!3}
!dx.typeAnnotations = !{!6}
!dx.entryPoints = !{!14, !16, !20, !23}
!0 = !{!"dxc(private) 1.7.0.4429 (rdat-minsm-check-flags, 9d3b6ba57)"}
!1 = !{i32 1, i32 6}
!2 = !{!"lib", i32 6, i32 6}
!3 = !{null, !4, null, null}
!4 = !{!5}
!5 = !{i32 0, %struct.RWByteAddressBuffer* bitcast (%dx.types.Handle* @"\01?BAB@@3URWByteAddressBuffer@@A" to %struct.RWByteAddressBuffer*), !"BAB", i32 0, i32 1, i32 1, i32 11, i1 false, i1 false, i1 false, null}
!6 = !{i32 1, void (<2 x float>)* @"\01?deriv_in_func@@YAXV?$vector@M$01@@@Z", !7, void ()* @deriv_in_mesh, !12, void ()* @deriv_in_compute, !12, void ()* @deriv_in_pixel, !12}
!7 = !{!8, !10}
!8 = !{i32 1, !9, !9}
!9 = !{}
!10 = !{i32 0, !11, !9}
!11 = !{i32 7, i32 9}
!12 = !{!13}
!13 = !{i32 0, !9, !9}
!14 = !{null, !"", null, !3, !15}
!15 = !{i32 0, i64 65552}
!16 = !{void ()* @deriv_in_compute, !"deriv_in_compute", null, null, !17}
!17 = !{i32 8, i32 5, i32 4, !18, i32 5, !19}
!18 = !{i32 8, i32 8, i32 1}
!19 = !{i32 0}
!20 = !{void ()* @deriv_in_mesh, !"deriv_in_mesh", null, null, !21}
!21 = !{i32 8, i32 13, i32 9, !22, i32 5, !19}
!22 = !{!18, i32 0, i32 0, i32 2, i32 0}
!23 = !{void ()* @deriv_in_pixel, !"deriv_in_pixel", !24, null, !27}
!24 = !{!25, null, null}
!25 = !{!26}
!26 = !{i32 0, !"TEXCOORD", i8 9, i8 0, !19, i8 2, i32 1, i8 2, i32 0, i8 0, null}
!27 = !{i32 8, i32 0, i32 5, !19}
; Make sure function-level derivative flag isn't in RequiredFeatureFlags,
; and make sure mesh shader sets required flag.
; RDAT-LABEL: ID3D12LibraryReflection:
; RDAT-LABEL: D3D12_FUNCTION_DESC: Name:
; RDAT-SAME: deriv_in_func
; RDAT: RequiredFeatureFlags: 0
; RDAT-LABEL: D3D12_FUNCTION_DESC: Name: deriv_in_compute
; RDAT: RequiredFeatureFlags: 0
; RDAT-LABEL: D3D12_FUNCTION_DESC: Name: deriv_in_mesh
; ShaderFeatureInfo_DerivativesInMeshAndAmpShaders (0x1000000) = 16777216
; RDAT18: RequiredFeatureFlags: 0x1000000
; Old: missed called function
; RDAT16: RequiredFeatureFlags: 0
; RDAT17: RequiredFeatureFlags: 0
; RDAT-LABEL: D3D12_FUNCTION_DESC: Name: deriv_in_pixel
; RDAT: RequiredFeatureFlags: 0

Просмотреть файл

@ -0,0 +1,205 @@
; RUN: %dxilver 1.7 | %D3DReflect %s | FileCheck %s -check-prefixes=RDAT,RDAT17
target datalayout = "e-m:e-p:32:32-i1:32-i8:32-i16:32-i32:32-i64:64-f16:32-f32:32-f64:64-n8:16:32:64"
target triple = "dxil-ms-dx"
%dx.types.Handle = type { i8* }
%dx.types.ResourceProperties = type { i32, i32 }
%struct.RWByteAddressBuffer = type { i32 }
@"\01?BAB@@3URWByteAddressBuffer@@A" = external constant %dx.types.Handle, align 4
; Ensure min shader target incorporates optional features used
; RDAT: FunctionTable[{{.*}}] = {
; SM 6.6+
;/////////////////////////////////////////////////////////////////////////////
; ShaderFeatureInfo_DerivativesInMeshAndAmpShaders (0x1000000) = 16777216
; OptFeatureInfo_UsesDerivatives (0x0000010000000000) = FeatureInfo2: 256
; OptFeatureInfo_UsesDerivatives Flag used to indicate derivative use in
; functions, then fixed up for entry functions.
; Val. ver. 1.8 required to recursively check called functions.
; RDAT-LABEL: UnmangledName: "deriv_in_func"
; RDAT: FeatureInfo1: 0
; RDAT18: FeatureInfo2: (Opt_UsesDerivatives)
; Old: deriv use not tracked
; RDAT16: FeatureInfo2: 0
; RDAT17: FeatureInfo2: 0
; RDAT18: ShaderStageFlag: (Pixel | Compute | Library | Mesh | Amplification | Node)
; Old would not report Compute, Mesh, Amplification, or Node compatibility.
; RDAT16: ShaderStageFlag: (Pixel | Library)
; RDAT17: ShaderStageFlag: (Pixel | Library)
; RDAT17: MinShaderTarget: 0x60060
; RDAT18: MinShaderTarget: 0x60060
; Old: Didn't set min target properly for lib function
; RDAT16: MinShaderTarget: 0x60066
; Function Attrs: noinline nounwind
define void @"\01?deriv_in_func@@YAXV?$vector@M$01@@@Z"(<2 x float> %uv) #0 {
%1 = load %dx.types.Handle, %dx.types.Handle* @"\01?BAB@@3URWByteAddressBuffer@@A", align 4
%2 = extractelement <2 x float> %uv, i64 0
%3 = extractelement <2 x float> %uv, i64 1
%4 = call float @dx.op.unary.f32(i32 83, float %2) ; DerivCoarseX(value)
%5 = call float @dx.op.unary.f32(i32 83, float %3) ; DerivCoarseX(value)
%6 = call %dx.types.Handle @dx.op.createHandleForLib.dx.types.Handle(i32 160, %dx.types.Handle %1) ; CreateHandleForLib(Resource)
%7 = call %dx.types.Handle @dx.op.annotateHandle(i32 216, %dx.types.Handle %6, %dx.types.ResourceProperties { i32 4107, i32 0 }) ; AnnotateHandle(res,props) resource: RWByteAddressBuffer
call void @dx.op.rawBufferStore.f32(i32 140, %dx.types.Handle %7, i32 0, i32 undef, float %4, float %5, float undef, float undef, i8 3, i32 4) ; RawBufferStore(uav,index,elementOffset,value0,value1,value2,value3,mask,alignment)
ret void
}
; RDAT-LABEL: UnmangledName: "deriv_in_mesh"
; RDAT18: FeatureInfo1: (DerivativesInMeshAndAmpShaders)
; Old: missed called function
; RDAT16: FeatureInfo1: 0
; RDAT17: FeatureInfo1: 0
; RDAT18: FeatureInfo2: (Opt_UsesDerivatives)
; Old: deriv use not tracked
; RDAT16: FeatureInfo2: 0
; RDAT17: FeatureInfo2: 0
; RDAT: ShaderStageFlag: (Mesh)
; RDAT18: MinShaderTarget: 0xd0066
; Old: 6.0
; RDAT16: MinShaderTarget: 0xd0060
; RDAT17: MinShaderTarget: 0xd0060
define void @deriv_in_mesh() {
%1 = call i32 @dx.op.threadId.i32(i32 93, i32 0) ; ThreadId(component)
%2 = call i32 @dx.op.threadId.i32(i32 93, i32 1) ; ThreadId(component)
%3 = uitofp i32 %1 to float
%4 = uitofp i32 %2 to float
%5 = fmul fast float %3, 1.250000e-01
%6 = fmul fast float %4, 1.250000e-01
%7 = insertelement <2 x float> undef, float %5, i32 0
%8 = insertelement <2 x float> %7, float %6, i32 1
call void @"\01?deriv_in_func@@YAXV?$vector@M$01@@@Z"(<2 x float> %8)
ret void
}
; RDAT-LABEL: UnmangledName: "deriv_in_compute"
; RDAT: FeatureInfo1: 0
; RDAT18: FeatureInfo2: (Opt_UsesDerivatives)
; Old: deriv use not tracked
; RDAT16: FeatureInfo2: 0
; RDAT17: FeatureInfo2: 0
; RDAT: ShaderStageFlag: (Compute)
; RDAT18: MinShaderTarget: 0x50066
; Old: 6.0
; RDAT16: MinShaderTarget: 0x50060
; RDAT17: MinShaderTarget: 0x50060
define void @deriv_in_compute() {
%1 = call i32 @dx.op.threadId.i32(i32 93, i32 0) ; ThreadId(component)
%2 = call i32 @dx.op.threadId.i32(i32 93, i32 1) ; ThreadId(component)
%3 = uitofp i32 %1 to float
%4 = uitofp i32 %2 to float
%5 = fmul fast float %3, 1.250000e-01
%6 = fmul fast float %4, 1.250000e-01
%7 = insertelement <2 x float> undef, float %5, i32 0
%8 = insertelement <2 x float> %7, float %6, i32 1
call void @"\01?deriv_in_func@@YAXV?$vector@M$01@@@Z"(<2 x float> %8)
ret void
}
; RDAT-LABEL: UnmangledName: "deriv_in_pixel"
; RDAT: FeatureInfo1: 0
; RDAT18: FeatureInfo2: (Opt_UsesDerivatives)
; Old: deriv use not tracked
; RDAT16: FeatureInfo2: 0
; RDAT17: FeatureInfo2: 0
; RDAT: ShaderStageFlag: (Pixel)
; RDAT: MinShaderTarget: 0x60
define void @deriv_in_pixel() {
%1 = call float @dx.op.loadInput.f32(i32 4, i32 0, i32 0, i8 0, i32 undef) ; LoadInput(inputSigId,rowIndex,colIndex,gsVertexAxis)
%2 = insertelement <2 x float> undef, float %1, i64 0
%3 = call float @dx.op.loadInput.f32(i32 4, i32 0, i32 0, i8 1, i32 undef) ; LoadInput(inputSigId,rowIndex,colIndex,gsVertexAxis)
%4 = insertelement <2 x float> %2, float %3, i64 1
call void @"\01?deriv_in_func@@YAXV?$vector@M$01@@@Z"(<2 x float> %4)
ret void
}
; Function Attrs: nounwind readnone
declare i32 @dx.op.threadId.i32(i32, i32) #1
; Function Attrs: nounwind readnone
declare float @dx.op.loadInput.f32(i32, i32, i32, i8, i32) #1
; Function Attrs: nounwind
declare void @dx.op.rawBufferStore.f32(i32, %dx.types.Handle, i32, i32, float, float, float, float, i8, i32) #2
; Function Attrs: nounwind readnone
declare float @dx.op.unary.f32(i32, float) #1
; Function Attrs: nounwind readnone
declare %dx.types.Handle @dx.op.annotateHandle(i32, %dx.types.Handle, %dx.types.ResourceProperties) #1
; Function Attrs: nounwind readonly
declare %dx.types.Handle @dx.op.createHandleForLib.dx.types.Handle(i32, %dx.types.Handle) #3
attributes #0 = { noinline nounwind }
attributes #1 = { nounwind readnone }
attributes #2 = { nounwind }
attributes #3 = { nounwind readonly }
!llvm.ident = !{!0}
!dx.version = !{!1}
!dx.valver = !{!1}
!dx.shaderModel = !{!2}
!dx.resources = !{!3}
!dx.typeAnnotations = !{!6}
!dx.entryPoints = !{!14, !16, !20, !23}
!0 = !{!"dxc(private) 1.7.0.4429 (rdat-minsm-check-flags, 9d3b6ba57)"}
!1 = !{i32 1, i32 7}
!2 = !{!"lib", i32 6, i32 7}
!3 = !{null, !4, null, null}
!4 = !{!5}
!5 = !{i32 0, %struct.RWByteAddressBuffer* bitcast (%dx.types.Handle* @"\01?BAB@@3URWByteAddressBuffer@@A" to %struct.RWByteAddressBuffer*), !"BAB", i32 0, i32 1, i32 1, i32 11, i1 false, i1 false, i1 false, null}
!6 = !{i32 1, void (<2 x float>)* @"\01?deriv_in_func@@YAXV?$vector@M$01@@@Z", !7, void ()* @deriv_in_mesh, !12, void ()* @deriv_in_compute, !12, void ()* @deriv_in_pixel, !12}
!7 = !{!8, !10}
!8 = !{i32 1, !9, !9}
!9 = !{}
!10 = !{i32 0, !11, !9}
!11 = !{i32 7, i32 9}
!12 = !{!13}
!13 = !{i32 0, !9, !9}
!14 = !{null, !"", null, !3, !15}
!15 = !{i32 0, i64 8590000144}
!16 = !{void ()* @deriv_in_compute, !"deriv_in_compute", null, null, !17}
!17 = !{i32 8, i32 5, i32 4, !18, i32 5, !19}
!18 = !{i32 8, i32 8, i32 1}
!19 = !{i32 0}
!20 = !{void ()* @deriv_in_mesh, !"deriv_in_mesh", null, null, !21}
!21 = !{i32 8, i32 13, i32 9, !22, i32 5, !19}
!22 = !{!18, i32 0, i32 0, i32 2, i32 0}
!23 = !{void ()* @deriv_in_pixel, !"deriv_in_pixel", !24, null, !27}
!24 = !{!25, null, null}
!25 = !{!26}
!26 = !{i32 0, !"TEXCOORD", i8 9, i8 0, !19, i8 2, i32 1, i8 2, i32 0, i8 0, null}
!27 = !{i32 8, i32 0, i32 5, !19}
; Make sure function-level derivative flag isn't in RequiredFeatureFlags,
; and make sure mesh shader sets required flag.
; RDAT-LABEL: ID3D12LibraryReflection:
; RDAT-LABEL: D3D12_FUNCTION_DESC: Name:
; RDAT-SAME: deriv_in_func
; RDAT: RequiredFeatureFlags: 0
; RDAT-LABEL: D3D12_FUNCTION_DESC: Name: deriv_in_compute
; RDAT: RequiredFeatureFlags: 0
; RDAT-LABEL: D3D12_FUNCTION_DESC: Name: deriv_in_mesh
; ShaderFeatureInfo_DerivativesInMeshAndAmpShaders (0x1000000) = 16777216
; RDAT18: RequiredFeatureFlags: 0x1000000
; Old: missed called function
; RDAT16: RequiredFeatureFlags: 0
; RDAT17: RequiredFeatureFlags: 0
; RDAT-LABEL: D3D12_FUNCTION_DESC: Name: deriv_in_pixel
; RDAT: RequiredFeatureFlags: 0

Просмотреть файл

@ -0,0 +1,209 @@
; RUN: %dxilver 1.7 | %D3DReflect %s | FileCheck %s -check-prefixes=RDAT,RDAT17
target datalayout = "e-m:e-p:32:32-i1:32-i8:32-i16:32-i32:32-i64:64-f16:32-f32:32-f64:64-n8:16:32:64"
target triple = "dxil-ms-dx"
%dx.types.Handle = type { i8* }
%dx.types.ResourceProperties = type { i32, i32 }
%struct.RWByteAddressBuffer = type { i32 }
@"\01?BAB@@3URWByteAddressBuffer@@A" = external constant %dx.types.Handle, align 4
; Ensure min shader target incorporates optional features used
; Here, we declare the intrinsics first, and reorder the called function
; relative to entries that call it, to ensure iteration order doesn't
; change the result.
; Function Attrs: nounwind readnone
declare i32 @dx.op.threadId.i32(i32, i32) #1
; Function Attrs: nounwind readnone
declare float @dx.op.loadInput.f32(i32, i32, i32, i8, i32) #1
; Function Attrs: nounwind
declare void @dx.op.rawBufferStore.f32(i32, %dx.types.Handle, i32, i32, float, float, float, float, i8, i32) #2
; Function Attrs: nounwind readnone
declare float @dx.op.unary.f32(i32, float) #1
; Function Attrs: nounwind readnone
declare %dx.types.Handle @dx.op.annotateHandle(i32, %dx.types.Handle, %dx.types.ResourceProperties) #1
; Function Attrs: nounwind readonly
declare %dx.types.Handle @dx.op.createHandleForLib.dx.types.Handle(i32, %dx.types.Handle) #3
; RDAT: FunctionTable[{{.*}}] = {
; SM 6.6+
;/////////////////////////////////////////////////////////////////////////////
; ShaderFeatureInfo_DerivativesInMeshAndAmpShaders (0x1000000) = 16777216
; OptFeatureInfo_UsesDerivatives (0x0000010000000000) = FeatureInfo2: 256
; OptFeatureInfo_UsesDerivatives Flag used to indicate derivative use in
; functions, then fixed up for entry functions.
; Val. ver. 1.8 required to recursively check called functions.
; RDAT-LABEL: UnmangledName: "deriv_in_mesh"
; RDAT18: FeatureInfo1: (DerivativesInMeshAndAmpShaders)
; Old: missed called function
; RDAT16: FeatureInfo1: 0
; RDAT17: FeatureInfo1: 0
; RDAT18: FeatureInfo2: (Opt_UsesDerivatives)
; Old: deriv use not tracked
; RDAT16: FeatureInfo2: 0
; RDAT17: FeatureInfo2: 0
; RDAT: ShaderStageFlag: (Mesh)
; RDAT18: MinShaderTarget: 0xd0066
; Old: 6.0
; RDAT16: MinShaderTarget: 0xd0060
; RDAT17: MinShaderTarget: 0xd0060
define void @deriv_in_mesh() {
%1 = call i32 @dx.op.threadId.i32(i32 93, i32 0) ; ThreadId(component)
%2 = call i32 @dx.op.threadId.i32(i32 93, i32 1) ; ThreadId(component)
%3 = uitofp i32 %1 to float
%4 = uitofp i32 %2 to float
%5 = fmul fast float %3, 1.250000e-01
%6 = fmul fast float %4, 1.250000e-01
%7 = insertelement <2 x float> undef, float %5, i32 0
%8 = insertelement <2 x float> %7, float %6, i32 1
call void @"\01?deriv_in_func@@YAXV?$vector@M$01@@@Z"(<2 x float> %8)
ret void
}
; RDAT-LABEL: UnmangledName: "deriv_in_compute"
; RDAT: FeatureInfo1: 0
; RDAT18: FeatureInfo2: (Opt_UsesDerivatives)
; Old: deriv use not tracked
; RDAT16: FeatureInfo2: 0
; RDAT17: FeatureInfo2: 0
; RDAT: ShaderStageFlag: (Compute)
; RDAT18: MinShaderTarget: 0x50066
; Old: 6.0
; RDAT16: MinShaderTarget: 0x50060
; RDAT17: MinShaderTarget: 0x50060
define void @deriv_in_compute() {
%1 = call i32 @dx.op.threadId.i32(i32 93, i32 0) ; ThreadId(component)
%2 = call i32 @dx.op.threadId.i32(i32 93, i32 1) ; ThreadId(component)
%3 = uitofp i32 %1 to float
%4 = uitofp i32 %2 to float
%5 = fmul fast float %3, 1.250000e-01
%6 = fmul fast float %4, 1.250000e-01
%7 = insertelement <2 x float> undef, float %5, i32 0
%8 = insertelement <2 x float> %7, float %6, i32 1
call void @"\01?deriv_in_func@@YAXV?$vector@M$01@@@Z"(<2 x float> %8)
ret void
}
; RDAT-LABEL: UnmangledName: "deriv_in_pixel"
; RDAT: FeatureInfo1: 0
; RDAT18: FeatureInfo2: (Opt_UsesDerivatives)
; Old: deriv use not tracked
; RDAT16: FeatureInfo2: 0
; RDAT17: FeatureInfo2: 0
; RDAT: ShaderStageFlag: (Pixel)
; RDAT: MinShaderTarget: 0x60
define void @deriv_in_pixel() {
%1 = call float @dx.op.loadInput.f32(i32 4, i32 0, i32 0, i8 0, i32 undef) ; LoadInput(inputSigId,rowIndex,colIndex,gsVertexAxis)
%2 = insertelement <2 x float> undef, float %1, i64 0
%3 = call float @dx.op.loadInput.f32(i32 4, i32 0, i32 0, i8 1, i32 undef) ; LoadInput(inputSigId,rowIndex,colIndex,gsVertexAxis)
%4 = insertelement <2 x float> %2, float %3, i64 1
call void @"\01?deriv_in_func@@YAXV?$vector@M$01@@@Z"(<2 x float> %4)
ret void
}
; RDAT-LABEL: UnmangledName: "deriv_in_func"
; RDAT: FeatureInfo1: 0
; RDAT18: FeatureInfo2: (Opt_UsesDerivatives)
; Old: deriv use not tracked
; RDAT16: FeatureInfo2: 0
; RDAT17: FeatureInfo2: 0
; RDAT18: ShaderStageFlag: (Pixel | Compute | Library | Mesh | Amplification | Node)
; Old would not report Compute, Mesh, Amplification, or Node compatibility.
; RDAT16: ShaderStageFlag: (Pixel | Library)
; RDAT17: ShaderStageFlag: (Pixel | Library)
; RDAT17: MinShaderTarget: 0x60060
; RDAT18: MinShaderTarget: 0x60060
; Old: Didn't set min target properly for lib function
; RDAT16: MinShaderTarget: 0x60066
; Function Attrs: noinline nounwind
define void @"\01?deriv_in_func@@YAXV?$vector@M$01@@@Z"(<2 x float> %uv) #0 {
%1 = load %dx.types.Handle, %dx.types.Handle* @"\01?BAB@@3URWByteAddressBuffer@@A", align 4
%2 = extractelement <2 x float> %uv, i64 0
%3 = extractelement <2 x float> %uv, i64 1
%4 = call float @dx.op.unary.f32(i32 83, float %2) ; DerivCoarseX(value)
%5 = call float @dx.op.unary.f32(i32 83, float %3) ; DerivCoarseX(value)
%6 = call %dx.types.Handle @dx.op.createHandleForLib.dx.types.Handle(i32 160, %dx.types.Handle %1) ; CreateHandleForLib(Resource)
%7 = call %dx.types.Handle @dx.op.annotateHandle(i32 216, %dx.types.Handle %6, %dx.types.ResourceProperties { i32 4107, i32 0 }) ; AnnotateHandle(res,props) resource: RWByteAddressBuffer
call void @dx.op.rawBufferStore.f32(i32 140, %dx.types.Handle %7, i32 0, i32 undef, float %4, float %5, float undef, float undef, i8 3, i32 4) ; RawBufferStore(uav,index,elementOffset,value0,value1,value2,value3,mask,alignment)
ret void
}
attributes #0 = { noinline nounwind }
attributes #1 = { nounwind readnone }
attributes #2 = { nounwind }
attributes #3 = { nounwind readonly }
!llvm.ident = !{!0}
!dx.version = !{!1}
!dx.valver = !{!1}
!dx.shaderModel = !{!2}
!dx.resources = !{!3}
!dx.typeAnnotations = !{!6}
!dx.entryPoints = !{!14, !16, !20, !23}
!0 = !{!"dxc(private) 1.7.0.4429 (rdat-minsm-check-flags, 9d3b6ba57)"}
!1 = !{i32 1, i32 7}
!2 = !{!"lib", i32 6, i32 7}
!3 = !{null, !4, null, null}
!4 = !{!5}
!5 = !{i32 0, %struct.RWByteAddressBuffer* bitcast (%dx.types.Handle* @"\01?BAB@@3URWByteAddressBuffer@@A" to %struct.RWByteAddressBuffer*), !"BAB", i32 0, i32 1, i32 1, i32 11, i1 false, i1 false, i1 false, null}
!6 = !{i32 1, void (<2 x float>)* @"\01?deriv_in_func@@YAXV?$vector@M$01@@@Z", !7, void ()* @deriv_in_mesh, !12, void ()* @deriv_in_compute, !12, void ()* @deriv_in_pixel, !12}
!7 = !{!8, !10}
!8 = !{i32 1, !9, !9}
!9 = !{}
!10 = !{i32 0, !11, !9}
!11 = !{i32 7, i32 9}
!12 = !{!13}
!13 = !{i32 0, !9, !9}
!14 = !{null, !"", null, !3, !15}
!15 = !{i32 0, i64 8590000144}
!16 = !{void ()* @deriv_in_compute, !"deriv_in_compute", null, null, !17}
!17 = !{i32 8, i32 5, i32 4, !18, i32 5, !19}
!18 = !{i32 8, i32 8, i32 1}
!19 = !{i32 0}
!20 = !{void ()* @deriv_in_mesh, !"deriv_in_mesh", null, null, !21}
!21 = !{i32 8, i32 13, i32 9, !22, i32 5, !19}
!22 = !{!18, i32 0, i32 0, i32 2, i32 0}
!23 = !{void ()* @deriv_in_pixel, !"deriv_in_pixel", !24, null, !27}
!24 = !{!25, null, null}
!25 = !{!26}
!26 = !{i32 0, !"TEXCOORD", i8 9, i8 0, !19, i8 2, i32 1, i8 2, i32 0, i8 0, null}
!27 = !{i32 8, i32 0, i32 5, !19}
; Make sure function-level derivative flag isn't in RequiredFeatureFlags,
; and make sure mesh shader sets required flag.
; RDAT-LABEL: ID3D12LibraryReflection:
; RDAT-LABEL: D3D12_FUNCTION_DESC: Name:
; RDAT-SAME: deriv_in_func
; RDAT: RequiredFeatureFlags: 0
; RDAT-LABEL: D3D12_FUNCTION_DESC: Name: deriv_in_compute
; RDAT: RequiredFeatureFlags: 0
; RDAT-LABEL: D3D12_FUNCTION_DESC: Name: deriv_in_mesh
; ShaderFeatureInfo_DerivativesInMeshAndAmpShaders (0x1000000) = 16777216
; RDAT18: RequiredFeatureFlags: 0x1000000
; Old: missed called function
; RDAT16: RequiredFeatureFlags: 0
; RDAT17: RequiredFeatureFlags: 0
; RDAT-LABEL: D3D12_FUNCTION_DESC: Name: deriv_in_pixel
; RDAT: RequiredFeatureFlags: 0

Просмотреть файл

@ -0,0 +1,205 @@
; RUN: %dxilver 1.8 | %D3DReflect %s | FileCheck %s -check-prefixes=RDAT,RDAT18
target datalayout = "e-m:e-p:32:32-i1:32-i8:32-i16:32-i32:32-i64:64-f16:32-f32:32-f64:64-n8:16:32:64"
target triple = "dxil-ms-dx"
%dx.types.Handle = type { i8* }
%dx.types.ResourceProperties = type { i32, i32 }
%struct.RWByteAddressBuffer = type { i32 }
@"\01?BAB@@3URWByteAddressBuffer@@A" = external constant %dx.types.Handle, align 4
; Ensure min shader target incorporates optional features used
; RDAT: FunctionTable[{{.*}}] = {
; SM 6.6+
;/////////////////////////////////////////////////////////////////////////////
; ShaderFeatureInfo_DerivativesInMeshAndAmpShaders (0x1000000) = 16777216
; OptFeatureInfo_UsesDerivatives (0x0000010000000000) = FeatureInfo2: 256
; OptFeatureInfo_UsesDerivatives Flag used to indicate derivative use in
; functions, then fixed up for entry functions.
; Val. ver. 1.8 required to recursively check called functions.
; RDAT-LABEL: UnmangledName: "deriv_in_func"
; RDAT: FeatureInfo1: 0
; RDAT18: FeatureInfo2: (Opt_UsesDerivatives)
; Old: deriv use not tracked
; RDAT16: FeatureInfo2: 0
; RDAT17: FeatureInfo2: 0
; RDAT18: ShaderStageFlag: (Pixel | Compute | Library | Mesh | Amplification | Node)
; Old would not report Compute, Mesh, Amplification, or Node compatibility.
; RDAT16: ShaderStageFlag: (Pixel | Library)
; RDAT17: ShaderStageFlag: (Pixel | Library)
; RDAT17: MinShaderTarget: 0x60060
; RDAT18: MinShaderTarget: 0x60060
; Old: Didn't set min target properly for lib function
; RDAT16: MinShaderTarget: 0x60066
; Function Attrs: noinline nounwind
define void @"\01?deriv_in_func@@YAXV?$vector@M$01@@@Z"(<2 x float> %uv) #0 {
%1 = load %dx.types.Handle, %dx.types.Handle* @"\01?BAB@@3URWByteAddressBuffer@@A", align 4
%2 = extractelement <2 x float> %uv, i64 0
%3 = extractelement <2 x float> %uv, i64 1
%4 = call float @dx.op.unary.f32(i32 83, float %2) ; DerivCoarseX(value)
%5 = call float @dx.op.unary.f32(i32 83, float %3) ; DerivCoarseX(value)
%6 = call %dx.types.Handle @dx.op.createHandleForLib.dx.types.Handle(i32 160, %dx.types.Handle %1) ; CreateHandleForLib(Resource)
%7 = call %dx.types.Handle @dx.op.annotateHandle(i32 216, %dx.types.Handle %6, %dx.types.ResourceProperties { i32 4107, i32 0 }) ; AnnotateHandle(res,props) resource: RWByteAddressBuffer
call void @dx.op.rawBufferStore.f32(i32 140, %dx.types.Handle %7, i32 0, i32 undef, float %4, float %5, float undef, float undef, i8 3, i32 4) ; RawBufferStore(uav,index,elementOffset,value0,value1,value2,value3,mask,alignment)
ret void
}
; RDAT-LABEL: UnmangledName: "deriv_in_mesh"
; RDAT18: FeatureInfo1: (DerivativesInMeshAndAmpShaders)
; Old: missed called function
; RDAT16: FeatureInfo1: 0
; RDAT17: FeatureInfo1: 0
; RDAT18: FeatureInfo2: (Opt_UsesDerivatives)
; Old: deriv use not tracked
; RDAT16: FeatureInfo2: 0
; RDAT17: FeatureInfo2: 0
; RDAT: ShaderStageFlag: (Mesh)
; RDAT18: MinShaderTarget: 0xd0066
; Old: 6.0
; RDAT16: MinShaderTarget: 0xd0060
; RDAT17: MinShaderTarget: 0xd0060
define void @deriv_in_mesh() {
%1 = call i32 @dx.op.threadId.i32(i32 93, i32 0) ; ThreadId(component)
%2 = call i32 @dx.op.threadId.i32(i32 93, i32 1) ; ThreadId(component)
%3 = uitofp i32 %1 to float
%4 = uitofp i32 %2 to float
%5 = fmul fast float %3, 1.250000e-01
%6 = fmul fast float %4, 1.250000e-01
%7 = insertelement <2 x float> undef, float %5, i32 0
%8 = insertelement <2 x float> %7, float %6, i32 1
call void @"\01?deriv_in_func@@YAXV?$vector@M$01@@@Z"(<2 x float> %8)
ret void
}
; RDAT-LABEL: UnmangledName: "deriv_in_compute"
; RDAT: FeatureInfo1: 0
; RDAT18: FeatureInfo2: (Opt_UsesDerivatives)
; Old: deriv use not tracked
; RDAT16: FeatureInfo2: 0
; RDAT17: FeatureInfo2: 0
; RDAT: ShaderStageFlag: (Compute)
; RDAT18: MinShaderTarget: 0x50066
; Old: 6.0
; RDAT16: MinShaderTarget: 0x50060
; RDAT17: MinShaderTarget: 0x50060
define void @deriv_in_compute() {
%1 = call i32 @dx.op.threadId.i32(i32 93, i32 0) ; ThreadId(component)
%2 = call i32 @dx.op.threadId.i32(i32 93, i32 1) ; ThreadId(component)
%3 = uitofp i32 %1 to float
%4 = uitofp i32 %2 to float
%5 = fmul fast float %3, 1.250000e-01
%6 = fmul fast float %4, 1.250000e-01
%7 = insertelement <2 x float> undef, float %5, i32 0
%8 = insertelement <2 x float> %7, float %6, i32 1
call void @"\01?deriv_in_func@@YAXV?$vector@M$01@@@Z"(<2 x float> %8)
ret void
}
; RDAT-LABEL: UnmangledName: "deriv_in_pixel"
; RDAT: FeatureInfo1: 0
; RDAT18: FeatureInfo2: (Opt_UsesDerivatives)
; Old: deriv use not tracked
; RDAT16: FeatureInfo2: 0
; RDAT17: FeatureInfo2: 0
; RDAT: ShaderStageFlag: (Pixel)
; RDAT: MinShaderTarget: 0x60
define void @deriv_in_pixel() {
%1 = call float @dx.op.loadInput.f32(i32 4, i32 0, i32 0, i8 0, i32 undef) ; LoadInput(inputSigId,rowIndex,colIndex,gsVertexAxis)
%2 = insertelement <2 x float> undef, float %1, i64 0
%3 = call float @dx.op.loadInput.f32(i32 4, i32 0, i32 0, i8 1, i32 undef) ; LoadInput(inputSigId,rowIndex,colIndex,gsVertexAxis)
%4 = insertelement <2 x float> %2, float %3, i64 1
call void @"\01?deriv_in_func@@YAXV?$vector@M$01@@@Z"(<2 x float> %4)
ret void
}
; Function Attrs: nounwind readnone
declare i32 @dx.op.threadId.i32(i32, i32) #1
; Function Attrs: nounwind readnone
declare float @dx.op.loadInput.f32(i32, i32, i32, i8, i32) #1
; Function Attrs: nounwind
declare void @dx.op.rawBufferStore.f32(i32, %dx.types.Handle, i32, i32, float, float, float, float, i8, i32) #2
; Function Attrs: nounwind readnone
declare float @dx.op.unary.f32(i32, float) #1
; Function Attrs: nounwind readnone
declare %dx.types.Handle @dx.op.annotateHandle(i32, %dx.types.Handle, %dx.types.ResourceProperties) #1
; Function Attrs: nounwind readonly
declare %dx.types.Handle @dx.op.createHandleForLib.dx.types.Handle(i32, %dx.types.Handle) #3
attributes #0 = { noinline nounwind }
attributes #1 = { nounwind readnone }
attributes #2 = { nounwind }
attributes #3 = { nounwind readonly }
!llvm.ident = !{!0}
!dx.version = !{!1}
!dx.valver = !{!1}
!dx.shaderModel = !{!2}
!dx.resources = !{!3}
!dx.typeAnnotations = !{!6}
!dx.entryPoints = !{!14, !16, !20, !23}
!0 = !{!"dxc(private) 1.7.0.4429 (rdat-minsm-check-flags, 9d3b6ba57)"}
!1 = !{i32 1, i32 8}
!2 = !{!"lib", i32 6, i32 8}
!3 = !{null, !4, null, null}
!4 = !{!5}
!5 = !{i32 0, %struct.RWByteAddressBuffer* bitcast (%dx.types.Handle* @"\01?BAB@@3URWByteAddressBuffer@@A" to %struct.RWByteAddressBuffer*), !"BAB", i32 0, i32 1, i32 1, i32 11, i1 false, i1 false, i1 false, null}
!6 = !{i32 1, void (<2 x float>)* @"\01?deriv_in_func@@YAXV?$vector@M$01@@@Z", !7, void ()* @deriv_in_mesh, !12, void ()* @deriv_in_compute, !12, void ()* @deriv_in_pixel, !12}
!7 = !{!8, !10}
!8 = !{i32 1, !9, !9}
!9 = !{}
!10 = !{i32 0, !11, !9}
!11 = !{i32 7, i32 9, i32 13, i32 2}
!12 = !{!13}
!13 = !{i32 0, !9, !9}
!14 = !{null, !"", null, !3, !15}
!15 = !{i32 0, i64 558882684944}
!16 = !{void ()* @deriv_in_compute, !"deriv_in_compute", null, null, !17}
!17 = !{i32 8, i32 5, i32 4, !18, i32 5, !19}
!18 = !{i32 8, i32 8, i32 1}
!19 = !{i32 0}
!20 = !{void ()* @deriv_in_mesh, !"deriv_in_mesh", null, null, !21}
!21 = !{i32 8, i32 13, i32 9, !22, i32 5, !19}
!22 = !{!18, i32 0, i32 0, i32 2, i32 0}
!23 = !{void ()* @deriv_in_pixel, !"deriv_in_pixel", !24, null, !27}
!24 = !{!25, null, null}
!25 = !{!26}
!26 = !{i32 0, !"TEXCOORD", i8 9, i8 0, !19, i8 2, i32 1, i8 2, i32 0, i8 0, null}
!27 = !{i32 8, i32 0, i32 5, !19}
; Make sure function-level derivative flag isn't in RequiredFeatureFlags,
; and make sure mesh shader sets required flag.
; RDAT-LABEL: ID3D12LibraryReflection:
; RDAT-LABEL: D3D12_FUNCTION_DESC: Name:
; RDAT-SAME: deriv_in_func
; RDAT: RequiredFeatureFlags: 0
; RDAT-LABEL: D3D12_FUNCTION_DESC: Name: deriv_in_compute
; RDAT: RequiredFeatureFlags: 0
; RDAT-LABEL: D3D12_FUNCTION_DESC: Name: deriv_in_mesh
; ShaderFeatureInfo_DerivativesInMeshAndAmpShaders (0x1000000) = 16777216
; RDAT18: RequiredFeatureFlags: 0x1000000
; Old: missed called function
; RDAT16: RequiredFeatureFlags: 0
; RDAT17: RequiredFeatureFlags: 0
; RDAT-LABEL: D3D12_FUNCTION_DESC: Name: deriv_in_pixel
; RDAT: RequiredFeatureFlags: 0

Просмотреть файл

@ -0,0 +1,209 @@
; RUN: %dxilver 1.8 | %D3DReflect %s | FileCheck %s -check-prefixes=RDAT,RDAT18
target datalayout = "e-m:e-p:32:32-i1:32-i8:32-i16:32-i32:32-i64:64-f16:32-f32:32-f64:64-n8:16:32:64"
target triple = "dxil-ms-dx"
%dx.types.Handle = type { i8* }
%dx.types.ResourceProperties = type { i32, i32 }
%struct.RWByteAddressBuffer = type { i32 }
@"\01?BAB@@3URWByteAddressBuffer@@A" = external constant %dx.types.Handle, align 4
; Ensure min shader target incorporates optional features used
; Here, we declare the intrinsics first, and reorder the called function
; relative to entries that call it, to ensure iteration order doesn't
; change the result.
; Function Attrs: nounwind readnone
declare i32 @dx.op.threadId.i32(i32, i32) #1
; Function Attrs: nounwind readnone
declare float @dx.op.loadInput.f32(i32, i32, i32, i8, i32) #1
; Function Attrs: nounwind
declare void @dx.op.rawBufferStore.f32(i32, %dx.types.Handle, i32, i32, float, float, float, float, i8, i32) #2
; Function Attrs: nounwind readnone
declare float @dx.op.unary.f32(i32, float) #1
; Function Attrs: nounwind readnone
declare %dx.types.Handle @dx.op.annotateHandle(i32, %dx.types.Handle, %dx.types.ResourceProperties) #1
; Function Attrs: nounwind readonly
declare %dx.types.Handle @dx.op.createHandleForLib.dx.types.Handle(i32, %dx.types.Handle) #3
; RDAT: FunctionTable[{{.*}}] = {
; SM 6.6+
;/////////////////////////////////////////////////////////////////////////////
; ShaderFeatureInfo_DerivativesInMeshAndAmpShaders (0x1000000) = 16777216
; OptFeatureInfo_UsesDerivatives (0x0000010000000000) = FeatureInfo2: 256
; OptFeatureInfo_UsesDerivatives Flag used to indicate derivative use in
; functions, then fixed up for entry functions.
; Val. ver. 1.8 required to recursively check called functions.
; RDAT-LABEL: UnmangledName: "deriv_in_mesh"
; RDAT18: FeatureInfo1: (DerivativesInMeshAndAmpShaders)
; Old: missed called function
; RDAT16: FeatureInfo1: 0
; RDAT17: FeatureInfo1: 0
; RDAT18: FeatureInfo2: (Opt_UsesDerivatives)
; Old: deriv use not tracked
; RDAT16: FeatureInfo2: 0
; RDAT17: FeatureInfo2: 0
; RDAT: ShaderStageFlag: (Mesh)
; RDAT18: MinShaderTarget: 0xd0066
; Old: 6.0
; RDAT16: MinShaderTarget: 0xd0060
; RDAT17: MinShaderTarget: 0xd0060
define void @deriv_in_mesh() {
%1 = call i32 @dx.op.threadId.i32(i32 93, i32 0) ; ThreadId(component)
%2 = call i32 @dx.op.threadId.i32(i32 93, i32 1) ; ThreadId(component)
%3 = uitofp i32 %1 to float
%4 = uitofp i32 %2 to float
%5 = fmul fast float %3, 1.250000e-01
%6 = fmul fast float %4, 1.250000e-01
%7 = insertelement <2 x float> undef, float %5, i32 0
%8 = insertelement <2 x float> %7, float %6, i32 1
call void @"\01?deriv_in_func@@YAXV?$vector@M$01@@@Z"(<2 x float> %8)
ret void
}
; RDAT-LABEL: UnmangledName: "deriv_in_compute"
; RDAT: FeatureInfo1: 0
; RDAT18: FeatureInfo2: (Opt_UsesDerivatives)
; Old: deriv use not tracked
; RDAT16: FeatureInfo2: 0
; RDAT17: FeatureInfo2: 0
; RDAT: ShaderStageFlag: (Compute)
; RDAT18: MinShaderTarget: 0x50066
; Old: 6.0
; RDAT16: MinShaderTarget: 0x50060
; RDAT17: MinShaderTarget: 0x50060
define void @deriv_in_compute() {
%1 = call i32 @dx.op.threadId.i32(i32 93, i32 0) ; ThreadId(component)
%2 = call i32 @dx.op.threadId.i32(i32 93, i32 1) ; ThreadId(component)
%3 = uitofp i32 %1 to float
%4 = uitofp i32 %2 to float
%5 = fmul fast float %3, 1.250000e-01
%6 = fmul fast float %4, 1.250000e-01
%7 = insertelement <2 x float> undef, float %5, i32 0
%8 = insertelement <2 x float> %7, float %6, i32 1
call void @"\01?deriv_in_func@@YAXV?$vector@M$01@@@Z"(<2 x float> %8)
ret void
}
; RDAT-LABEL: UnmangledName: "deriv_in_pixel"
; RDAT: FeatureInfo1: 0
; RDAT18: FeatureInfo2: (Opt_UsesDerivatives)
; Old: deriv use not tracked
; RDAT16: FeatureInfo2: 0
; RDAT17: FeatureInfo2: 0
; RDAT: ShaderStageFlag: (Pixel)
; RDAT: MinShaderTarget: 0x60
define void @deriv_in_pixel() {
%1 = call float @dx.op.loadInput.f32(i32 4, i32 0, i32 0, i8 0, i32 undef) ; LoadInput(inputSigId,rowIndex,colIndex,gsVertexAxis)
%2 = insertelement <2 x float> undef, float %1, i64 0
%3 = call float @dx.op.loadInput.f32(i32 4, i32 0, i32 0, i8 1, i32 undef) ; LoadInput(inputSigId,rowIndex,colIndex,gsVertexAxis)
%4 = insertelement <2 x float> %2, float %3, i64 1
call void @"\01?deriv_in_func@@YAXV?$vector@M$01@@@Z"(<2 x float> %4)
ret void
}
; RDAT-LABEL: UnmangledName: "deriv_in_func"
; RDAT: FeatureInfo1: 0
; RDAT18: FeatureInfo2: (Opt_UsesDerivatives)
; Old: deriv use not tracked
; RDAT16: FeatureInfo2: 0
; RDAT17: FeatureInfo2: 0
; RDAT18: ShaderStageFlag: (Pixel | Compute | Library | Mesh | Amplification | Node)
; Old would not report Compute, Mesh, Amplification, or Node compatibility.
; RDAT16: ShaderStageFlag: (Pixel | Library)
; RDAT17: ShaderStageFlag: (Pixel | Library)
; RDAT17: MinShaderTarget: 0x60060
; RDAT18: MinShaderTarget: 0x60060
; Old: Didn't set min target properly for lib function
; RDAT16: MinShaderTarget: 0x60066
; Function Attrs: noinline nounwind
define void @"\01?deriv_in_func@@YAXV?$vector@M$01@@@Z"(<2 x float> %uv) #0 {
%1 = load %dx.types.Handle, %dx.types.Handle* @"\01?BAB@@3URWByteAddressBuffer@@A", align 4
%2 = extractelement <2 x float> %uv, i64 0
%3 = extractelement <2 x float> %uv, i64 1
%4 = call float @dx.op.unary.f32(i32 83, float %2) ; DerivCoarseX(value)
%5 = call float @dx.op.unary.f32(i32 83, float %3) ; DerivCoarseX(value)
%6 = call %dx.types.Handle @dx.op.createHandleForLib.dx.types.Handle(i32 160, %dx.types.Handle %1) ; CreateHandleForLib(Resource)
%7 = call %dx.types.Handle @dx.op.annotateHandle(i32 216, %dx.types.Handle %6, %dx.types.ResourceProperties { i32 4107, i32 0 }) ; AnnotateHandle(res,props) resource: RWByteAddressBuffer
call void @dx.op.rawBufferStore.f32(i32 140, %dx.types.Handle %7, i32 0, i32 undef, float %4, float %5, float undef, float undef, i8 3, i32 4) ; RawBufferStore(uav,index,elementOffset,value0,value1,value2,value3,mask,alignment)
ret void
}
attributes #0 = { noinline nounwind }
attributes #1 = { nounwind readnone }
attributes #2 = { nounwind }
attributes #3 = { nounwind readonly }
!llvm.ident = !{!0}
!dx.version = !{!1}
!dx.valver = !{!1}
!dx.shaderModel = !{!2}
!dx.resources = !{!3}
!dx.typeAnnotations = !{!6}
!dx.entryPoints = !{!14, !16, !20, !23}
!0 = !{!"dxc(private) 1.7.0.4429 (rdat-minsm-check-flags, 9d3b6ba57)"}
!1 = !{i32 1, i32 8}
!2 = !{!"lib", i32 6, i32 8}
!3 = !{null, !4, null, null}
!4 = !{!5}
!5 = !{i32 0, %struct.RWByteAddressBuffer* bitcast (%dx.types.Handle* @"\01?BAB@@3URWByteAddressBuffer@@A" to %struct.RWByteAddressBuffer*), !"BAB", i32 0, i32 1, i32 1, i32 11, i1 false, i1 false, i1 false, null}
!6 = !{i32 1, void (<2 x float>)* @"\01?deriv_in_func@@YAXV?$vector@M$01@@@Z", !7, void ()* @deriv_in_mesh, !12, void ()* @deriv_in_compute, !12, void ()* @deriv_in_pixel, !12}
!7 = !{!8, !10}
!8 = !{i32 1, !9, !9}
!9 = !{}
!10 = !{i32 0, !11, !9}
!11 = !{i32 7, i32 9, i32 13, i32 2}
!12 = !{!13}
!13 = !{i32 0, !9, !9}
!14 = !{null, !"", null, !3, !15}
!15 = !{i32 0, i64 558882684944}
!16 = !{void ()* @deriv_in_compute, !"deriv_in_compute", null, null, !17}
!17 = !{i32 8, i32 5, i32 4, !18, i32 5, !19}
!18 = !{i32 8, i32 8, i32 1}
!19 = !{i32 0}
!20 = !{void ()* @deriv_in_mesh, !"deriv_in_mesh", null, null, !21}
!21 = !{i32 8, i32 13, i32 9, !22, i32 5, !19}
!22 = !{!18, i32 0, i32 0, i32 2, i32 0}
!23 = !{void ()* @deriv_in_pixel, !"deriv_in_pixel", !24, null, !27}
!24 = !{!25, null, null}
!25 = !{!26}
!26 = !{i32 0, !"TEXCOORD", i8 9, i8 0, !19, i8 2, i32 1, i8 2, i32 0, i8 0, null}
!27 = !{i32 8, i32 0, i32 5, !19}
; Make sure function-level derivative flag isn't in RequiredFeatureFlags,
; and make sure mesh shader sets required flag.
; RDAT-LABEL: ID3D12LibraryReflection:
; RDAT-LABEL: D3D12_FUNCTION_DESC: Name:
; RDAT-SAME: deriv_in_func
; RDAT: RequiredFeatureFlags: 0
; RDAT-LABEL: D3D12_FUNCTION_DESC: Name: deriv_in_compute
; RDAT: RequiredFeatureFlags: 0
; RDAT-LABEL: D3D12_FUNCTION_DESC: Name: deriv_in_mesh
; ShaderFeatureInfo_DerivativesInMeshAndAmpShaders (0x1000000) = 16777216
; RDAT18: RequiredFeatureFlags: 0x1000000
; Old: missed called function
; RDAT16: RequiredFeatureFlags: 0
; RDAT17: RequiredFeatureFlags: 0
; RDAT-LABEL: D3D12_FUNCTION_DESC: Name: deriv_in_pixel
; RDAT: RequiredFeatureFlags: 0

Просмотреть файл

@ -0,0 +1,104 @@
// RUN: %dxilver 1.8 | %dxc -T lib_6_8 %s | %D3DReflect %s | %FileCheck %s -check-prefixes=RDAT,RDAT18
// RUN: %dxilver 1.7 | %dxc -T lib_6_7 -validator-version 1.7 %s | %D3DReflect %s | FileCheck %s -check-prefixes=RDAT,RDAT17
// Ensure min shader target incorporates optional features used
// RDAT: FunctionTable[{{.*}}] = {
// SM 6.6+
///////////////////////////////////////////////////////////////////////////////
// ShaderFeatureInfo_ResourceDescriptorHeapIndexing (0x2000000) = 33554432
// RDAT-LABEL: UnmangledName: "res_heap_index"
// RDAT: FeatureInfo1: (ResourceDescriptorHeapIndexing)
// RDAT: FeatureInfo2: 0
// RDAT17: ShaderStageFlag: (Pixel | Vertex | Geometry | Hull | Domain | Compute | Library | RayGeneration | Intersection | AnyHit | ClosestHit | Miss | Callable | Mesh | Amplification)
// RDAT18: ShaderStageFlag: (Pixel | Vertex | Geometry | Hull | Domain | Compute | Library | RayGeneration | Intersection | AnyHit | ClosestHit | Miss | Callable | Mesh | Amplification | Node)
// RDAT: MinShaderTarget: 0x60066
[noinline] export
void res_heap_index(int i) {
RWStructuredBuffer<int> SB = ResourceDescriptorHeap[0];
SB[0] = i;
}
// RDAT-LABEL: UnmangledName: "res_heap_index_in_compute"
// RDAT18: FeatureInfo1: (ResourceDescriptorHeapIndexing)
// Old: missed called function
// RDAT17: FeatureInfo1: 0
// RDAT: FeatureInfo2: 0
// RDAT: ShaderStageFlag: (Compute)
// RDAT18: MinShaderTarget: 0x50066
// Old: 6.0
// RDAT17: MinShaderTarget: 0x50060
[shader("compute")]
[numthreads(8, 8, 1)]
void res_heap_index_in_compute(uint3 DTid : SV_DispatchThreadID) {
res_heap_index(DTid.x);
}
// RDAT-LABEL: UnmangledName: "res_heap_index_in_raygen"
// RDAT18: FeatureInfo1: (ResourceDescriptorHeapIndexing)
// Old: missed called function
// RDAT17: FeatureInfo1: 0
// RDAT: FeatureInfo2: 0
// RDAT: ShaderStageFlag: (RayGeneration)
// RDAT18: MinShaderTarget: 0x70066
// Old: 6.0
// RDAT17: MinShaderTarget: 0x70060
[shader("raygeneration")]
void res_heap_index_in_raygen() {
res_heap_index(1);
}
///////////////////////////////////////////////////////////////////////////////
// ShaderFeatureInfo_SamplerDescriptorHeapIndexing (0x4000000) = 67108864
// RDAT-LABEL: UnmangledName: "samp_heap_index"
// RDAT: FeatureInfo1: (SamplerDescriptorHeapIndexing)
// RDAT: FeatureInfo2: 0
// RDAT17: ShaderStageFlag: (Pixel | Vertex | Geometry | Hull | Domain | Compute | Library | RayGeneration | Intersection | AnyHit | ClosestHit | Miss | Callable | Mesh | Amplification)
// RDAT18: ShaderStageFlag: (Pixel | Vertex | Geometry | Hull | Domain | Compute | Library | RayGeneration | Intersection | AnyHit | ClosestHit | Miss | Callable | Mesh | Amplification | Node)
// RDAT: MinShaderTarget: 0x60066
RWByteAddressBuffer BAB : register(u1, space0);
Texture2D<float4> T2D : register(t0, space0);
[noinline] export void samp_heap_index(int i) {
SamplerState S = SamplerDescriptorHeap[i];
BAB.Store(0, T2D.SampleLevel(S, float2(0.5, 0.5), 0.0));
}
// RDAT-LABEL: UnmangledName: "samp_heap_index_in_compute"
// RDAT18: FeatureInfo1: (SamplerDescriptorHeapIndexing)
// Old: missed called function
// RDAT17: FeatureInfo1: 0
// RDAT: FeatureInfo2: 0
// RDAT: ShaderStageFlag: (Compute)
// RDAT18: MinShaderTarget: 0x50066
// Old: 6.0
// RDAT17: MinShaderTarget: 0x50060
[shader("compute")]
[numthreads(8, 8, 1)]
void samp_heap_index_in_compute(uint3 DTid : SV_DispatchThreadID) {
samp_heap_index(DTid.x);
}
// RDAT-LABEL: UnmangledName: "samp_heap_index_in_raygen"
// RDAT18: FeatureInfo1: (SamplerDescriptorHeapIndexing)
// Old: missed called function
// RDAT17: FeatureInfo1: 0
// RDAT: FeatureInfo2: 0
// RDAT: ShaderStageFlag: (RayGeneration)
// RDAT18: MinShaderTarget: 0x70066
// Old: 6.0
// RDAT17: MinShaderTarget: 0x70060
[shader("raygeneration")]
void samp_heap_index_in_raygen() {
samp_heap_index(1);
}

Просмотреть файл

@ -0,0 +1,49 @@
// RUN: %dxilver 1.8 | %dxc -T lib_6_8 %s | %D3DReflect %s | %FileCheck %s -check-prefixes=RDAT,RDAT18
// RUN: %dxilver 1.7 | %dxc -T lib_6_7 -validator-version 1.7 %s | %D3DReflect %s | FileCheck %s -check-prefixes=RDAT,RDAT17
// Ensure min shader target incorporates optional features used
// RDAT: FunctionTable[{{.*}}] = {
// SM 6.7+
///////////////////////////////////////////////////////////////////////////////
// ShaderFeatureInfo_AdvancedTextureOps (0x20000000) = 536870912
// RDAT-LABEL: UnmangledName: "sample_offset"
// RDAT: FeatureInfo1: (AdvancedTextureOps)
// RDAT18: FeatureInfo2: (Opt_UsesDerivatives)
// Old: deriv use not tracked
// RDAT17: FeatureInfo2: 0
// RDAT18: ShaderStageFlag: (Pixel | Compute | Library | Mesh | Amplification | Node)
// Old would not report Compute, Mesh, Amplification, or Node compatibility.
// RDAT17: ShaderStageFlag: (Pixel | Library)
// RDAT18: MinShaderTarget: 0x60067
// Old: 6.0
// RDAT17: MinShaderTarget: 0x60060
Texture2D<float4> T2D : register(t0, space0);
SamplerState Samp : register(s0, space0);
RWByteAddressBuffer BAB : register(u1, space0);
[noinline] export
void sample_offset(float2 uv, int2 offsets) {
BAB.Store(0, T2D.Sample(Samp, uv, offsets));
}
// RDAT-LABEL: UnmangledName: "sample_offset_pixel"
// RDAT18: FeatureInfo1: (AdvancedTextureOps)
// Old: missed called function
// RDAT17: FeatureInfo1: 0
// RDAT18: FeatureInfo2: (Opt_UsesDerivatives)
// Old: deriv use not tracked
// RDAT17: FeatureInfo2: 0
// RDAT: ShaderStageFlag: (Pixel)
// RDAT18: MinShaderTarget: 0x67
// Old: 6.0
// RDAT17: MinShaderTarget: 0x60
[shader("pixel")]
void sample_offset_pixel(float4 color : COLOR) {
sample_offset(color.xy, (int)color.zw);
}

Просмотреть файл

@ -0,0 +1,48 @@
// RUN: %dxilver 1.8 | %dxc -T lib_6_8 %s | %D3DReflect %s | %FileCheck %s -check-prefixes=RDAT,RDAT18
// RUN: %dxilver 1.7 | %dxc -T lib_6_7 -validator-version 1.7 %s | %D3DReflect %s | FileCheck %s -check-prefixes=RDAT,RDAT17
// Ensure min shader target incorporates optional features used
// RDAT: FunctionTable[{{.*}}] = {
// SM 6.7+
///////////////////////////////////////////////////////////////////////////////
// ShaderFeatureInfo_WriteableMSAATextures (0x40000000) = 1073741824
// RDAT-LABEL: UnmangledName: "rwmsaa"
// RDAT18: FeatureInfo1: (ResourceDescriptorHeapIndexing | WriteableMSAATextures)
// Old: missed use of WriteableMSAATextures
// RDAT17: FeatureInfo1: (ResourceDescriptorHeapIndexing)
// RDAT: FeatureInfo2: 0
// RDAT17: ShaderStageFlag: (Pixel | Vertex | Geometry | Hull | Domain | Compute | Library | RayGeneration | Intersection | AnyHit | ClosestHit | Miss | Callable | Mesh | Amplification)
// RDAT18: ShaderStageFlag: (Pixel | Vertex | Geometry | Hull | Domain | Compute | Library | RayGeneration | Intersection | AnyHit | ClosestHit | Miss | Callable | Mesh | Amplification | Node)
// RDAT18: MinShaderTarget: 0x60067
// Old: 6.6 (Because of dynamic resources)
// RDAT17: MinShaderTarget: 0x60066
RWByteAddressBuffer BAB : register(u1, space0);
[noinline] export
void rwmsaa() {
// Use dynamic resource to avoid MSAA flag on all functions issue in 1.7
RWTexture2DMS<float, 1> T2DMS = ResourceDescriptorHeap[0];
uint3 whs;
T2DMS.GetDimensions(whs.x, whs.y, whs.z);
BAB.Store(0, whs);
}
// RDAT-LABEL: UnmangledName: "rwmsaa_in_raygen"
// RDAT18: FeatureInfo1: (ResourceDescriptorHeapIndexing | WriteableMSAATextures)
// Old: missed called function
// RDAT17: FeatureInfo1: 0
// RDAT: FeatureInfo2: 0
// RDAT: ShaderStageFlag: (RayGeneration)
// RDAT18: MinShaderTarget: 0x70067
// Old: 6.0
// RDAT17: MinShaderTarget: 0x70060
[shader("raygeneration")]
void rwmsaa_in_raygen() {
rwmsaa();
}

Просмотреть файл

@ -0,0 +1,71 @@
// RUN: %dxilver 1.8 | %dxc -T lib_6_8 %s | %D3DReflect %s | %FileCheck %s -check-prefixes=RDAT,RDAT18
// RUN: %dxilver 1.7 | %dxc -T lib_6_7 -validator-version 1.7 %s | %D3DReflect %s | FileCheck %s -check-prefixes=RDAT,RDAT17
// Ensure min shader target incorporates optional features used
// RDAT: FunctionTable[{{.*}}] = {
// SM 6.7+
///////////////////////////////////////////////////////////////////////////////
// ShaderFeatureInfo_WriteableMSAATextures (0x40000000) = 1073741824
// RDAT-LABEL: UnmangledName: "rwmsaa"
// RDAT: FeatureInfo1: (WriteableMSAATextures)
// RDAT: FeatureInfo2: 0
// RDAT17: ShaderStageFlag: (Pixel | Vertex | Geometry | Hull | Domain | Compute | Library | RayGeneration | Intersection | AnyHit | ClosestHit | Miss | Callable | Mesh | Amplification)
// RDAT18: ShaderStageFlag: (Pixel | Vertex | Geometry | Hull | Domain | Compute | Library | RayGeneration | Intersection | AnyHit | ClosestHit | Miss | Callable | Mesh | Amplification | Node)
// RDAT18: MinShaderTarget: 0x60067
// Old: 6.0
// RDAT17: MinShaderTarget: 0x60060
RWByteAddressBuffer BAB : register(u1, space0);
RWTexture2DMS<float, 1> T2DMS : register(u2, space0);
[noinline] export
void rwmsaa() {
BAB.Store(0, T2DMS.sample[1][uint2(1, 2)]);
}
// RDAT-LABEL: UnmangledName: "no_rwmsaa"
// RDAT18: FeatureInfo1: 0
// 1.7 Incorrectly reports feature use for function
// RDAT17: FeatureInfo1: (WriteableMSAATextures)
// RDAT: FeatureInfo2: 0
// RDAT17: ShaderStageFlag: (Pixel | Vertex | Geometry | Hull | Domain | Compute | Library | RayGeneration | Intersection | AnyHit | ClosestHit | Miss | Callable | Mesh | Amplification)
// RDAT18: ShaderStageFlag: (Pixel | Vertex | Geometry | Hull | Domain | Compute | Library | RayGeneration | Intersection | AnyHit | ClosestHit | Miss | Callable | Mesh | Amplification | Node)
// RDAT: MinShaderTarget: 0x60060
export void no_rwmsaa() {
BAB.Store(0, 0);
}
// RDAT-LABEL: UnmangledName: "rwmsaa_in_raygen"
// Old: set because of global
// RDAT: FeatureInfo1: (WriteableMSAATextures)
// RDAT: FeatureInfo2: 0
// RDAT: ShaderStageFlag: (RayGeneration)
// RDAT18: MinShaderTarget: 0x70067
// Old: 6.0
// RDAT17: MinShaderTarget: 0x70060
[shader("raygeneration")]
void rwmsaa_in_raygen() {
rwmsaa();
}
// RDAT-LABEL: UnmangledName: "rwmsaa_not_used_in_raygen"
// RDAT18: FeatureInfo1: 0
// Old: set because of global
// RDAT17: FeatureInfo1: (WriteableMSAATextures)
// RDAT: FeatureInfo2: 0
// RDAT: ShaderStageFlag: (RayGeneration)
// RDAT18: MinShaderTarget: 0x70063
// Old: 6.0
// RDAT17: MinShaderTarget: 0x70060
[shader("raygeneration")]
void rwmsaa_not_used_in_raygen() {
no_rwmsaa();
}

Просмотреть файл

@ -0,0 +1,36 @@
// RUN: %dxilver 1.8 | %dxc -T lib_6_8 %s | %D3DReflect %s | %FileCheck %s -check-prefixes=RDAT
// Ensure min shader target incorporates optional features used
// RDAT: FunctionTable[{{.*}}] = {
// SM 6.8+
///////////////////////////////////////////////////////////////////////////////
// ShaderFeatureInfo_ExtendedCommandInfo (0x100000000) = FeatureInfo2: 1
RWByteAddressBuffer BAB : register(u1, space0);
// These are loaded using an intrinsic, SM adjusted by dxil op as well.
// RDAT-LABEL: UnmangledName: "startvertexlocation"
// RDAT: FeatureInfo1: 0
// RDAT: FeatureInfo2: (ExtendedCommandInfo)
// RDAT: ShaderStageFlag: (Vertex)
// RDAT: MinShaderTarget: 0x10068
[shader("vertex")]
void startvertexlocation(uint u : SV_StartVertexLocation) {
BAB.Store(0, u);
}
// RDAT-LABEL: UnmangledName: "startinstancelocation"
// RDAT: FeatureInfo1: 0
// RDAT: FeatureInfo2: (ExtendedCommandInfo)
// RDAT: ShaderStageFlag: (Vertex)
// RDAT: MinShaderTarget: 0x10068
[shader("vertex")]
void startinstancelocation(uint u : SV_StartInstanceLocation) {
BAB.Store(0, u);
}

Просмотреть файл

@ -0,0 +1,25 @@
// RUN: %dxilver 1.8 | %dxc -T lib_6_8 %s | %D3DReflect %s | %FileCheck %s -check-prefixes=RDAT
// Ensure min shader target incorporates shader stage of entry function
// These must be minimal shaders since intrinsic usage associated with the
// shader stage will cause the min target to be set that way.
// This covers node shaders, which should always be SM 6.8+
// RDAT: FunctionTable[{{.*}}] = {
RWByteAddressBuffer BAB : register(u1, space0);
// RDAT-LABEL: UnmangledName: "node1"
// RDAT: FeatureInfo1: 0
// RDAT: FeatureInfo2: 0
// RDAT: ShaderStageFlag: (Node)
// RDAT: MinShaderTarget: 0xf0068
[shader("node")]
[NodeLaunch("broadcasting")]
[NodeDispatchGrid(1, 1, 1)]
[NumThreads(1,1,1)]
void node1() {
BAB.Store(0, 0);
}

Просмотреть файл

@ -0,0 +1,49 @@
// RUN: %dxilver 1.8 | %dxc -T lib_6_8 %s | %D3DReflect %s | %FileCheck %s -check-prefixes=RDAT
// Ensure that barrier is allowed for node shaders, and that correct shader
// flags are set.
// RDAT: FunctionTable[{{.*}}] = {
RWByteAddressBuffer BAB : register(u1, space0);
// RDAT-LABEL: UnmangledName: "node_barrier"
// RDAT: FeatureInfo1: 0
// RDAT: FeatureInfo2: 0
// RDAT: ShaderStageFlag: (Node)
// RDAT: MinShaderTarget: 0xf0068
[shader("node")]
[NodeLaunch("broadcasting")]
[NodeDispatchGrid(1, 1, 1)]
[NumThreads(1,1,1)]
void node_barrier() {
GroupMemoryBarrierWithGroupSync();
BAB.Store(0, 0);
}
// RDAT-LABEL: UnmangledName: "use_barrier"
// RDAT: FeatureInfo1: 0
// RDAT: FeatureInfo2: 0
// RDAT: ShaderStageFlag: (Compute | Library | Mesh | Amplification | Node)
// RDAT: MinShaderTarget: 0x60060
[noinline] export
void use_barrier() {
GroupMemoryBarrierWithGroupSync();
}
// RDAT-LABEL: UnmangledName: "node_barrier_in_call"
// RDAT: FeatureInfo1: 0
// RDAT: FeatureInfo2: 0
// RDAT: ShaderStageFlag: (Node)
// RDAT: MinShaderTarget: 0xf0068
[shader("node")]
[NodeLaunch("broadcasting")]
[NodeDispatchGrid(1, 1, 1)]
[NumThreads(1,1,1)]
void node_barrier_in_call() {
use_barrier();
BAB.Store(0, 0);
}

Просмотреть файл

@ -0,0 +1,194 @@
// RUN: %dxilver 1.8 | %dxc -T lib_6_8 %s | %D3DReflect %s | %FileCheck %s -check-prefixes=RDAT
// Ensure that categories of deriv ops are allowed for node shaders.
// Ensure that the OptFeatureInfo_UsesDerivatives flag is set as well.
// RDAT: FunctionTable[{{.*}}] = {
Texture2D<float4> T2D : register(t0, space0);
SamplerState Samp : register(s0, space0);
RWByteAddressBuffer BAB : register(u1, space0);
///////////////////////////////////////////////////////////////////////////////
// Category: derivatives ddx/ddy/ddx_coarse/ddy_coarse/ddx_fine/ddy_fine
// RDAT-LABEL: UnmangledName: "node_deriv"
// RDAT: FeatureInfo1: 0
// RDAT: FeatureInfo2: (Opt_UsesDerivatives)
// RDAT: ShaderStageFlag: (Node)
// RDAT: MinShaderTarget: 0xf0068
[shader("node")]
[NodeLaunch("broadcasting")]
[NodeDispatchGrid(1, 1, 1)]
[NumThreads(4,4,1)]
void node_deriv(uint3 tid : SV_GroupThreadID) {
float2 uv = tid.xy / float2(4, 4);
float2 ddx_uv = ddx(uv);
BAB.Store(0, ddx_uv);
}
// RDAT-LABEL: UnmangledName: "use_deriv"
// RDAT: FeatureInfo1: 0
// RDAT: FeatureInfo2: (Opt_UsesDerivatives)
// RDAT: ShaderStageFlag: (Pixel | Compute | Library | Mesh | Amplification | Node)
// RDAT: MinShaderTarget: 0x60060
[noinline] export
void use_deriv(float2 uv) {
float2 ddx_uv = ddx(uv);
BAB.Store(0, ddx_uv);
}
// RDAT-LABEL: UnmangledName: "node_deriv_in_call"
// RDAT: FeatureInfo1: 0
// RDAT: FeatureInfo2: (Opt_UsesDerivatives)
// RDAT: ShaderStageFlag: (Node)
// RDAT: MinShaderTarget: 0xf0068
[shader("node")]
[NodeLaunch("broadcasting")]
[NodeDispatchGrid(1, 1, 1)]
[NumThreads(4,4,1)]
void node_deriv_in_call(uint3 tid : SV_GroupThreadID) {
float2 uv = tid.xy / float2(4, 4);
use_deriv(uv);
}
///////////////////////////////////////////////////////////////////////////////
// Category: CalculateLOD
// RDAT-LABEL: UnmangledName: "node_calclod"
// RDAT: FeatureInfo1: 0
// RDAT: FeatureInfo2: (Opt_UsesDerivatives)
// RDAT: ShaderStageFlag: (Node)
// RDAT: MinShaderTarget: 0xf0068
[shader("node")]
[NodeLaunch("broadcasting")]
[NodeDispatchGrid(1, 1, 1)]
[NumThreads(4,4,1)]
void node_calclod(uint3 tid : SV_GroupThreadID) {
float2 uv = tid.xy / float2(4, 4);
float lod = T2D.CalculateLevelOfDetail(Samp, uv);
BAB.Store(0, lod);
}
// RDAT-LABEL: UnmangledName: "use_calclod"
// RDAT: FeatureInfo1: 0
// RDAT: FeatureInfo2: (Opt_UsesDerivatives)
// RDAT: ShaderStageFlag: (Pixel | Compute | Library | Mesh | Amplification | Node)
// RDAT: MinShaderTarget: 0x60060
[noinline] export
void use_calclod(float2 uv) {
float lod = T2D.CalculateLevelOfDetail(Samp, uv);
BAB.Store(0, lod);
}
// RDAT-LABEL: UnmangledName: "node_calclod_in_call"
// RDAT: FeatureInfo1: 0
// RDAT: FeatureInfo2: (Opt_UsesDerivatives)
// RDAT: ShaderStageFlag: (Node)
// RDAT: MinShaderTarget: 0xf0068
[shader("node")]
[NodeLaunch("broadcasting")]
[NodeDispatchGrid(1, 1, 1)]
[NumThreads(4,4,1)]
void node_calclod_in_call(uint3 tid : SV_GroupThreadID) {
float2 uv = tid.xy / float2(4, 4);
use_calclod(uv);
}
///////////////////////////////////////////////////////////////////////////////
// Category: Sample with implicit derivatives
// RDAT-LABEL: UnmangledName: "node_sample"
// RDAT: FeatureInfo1: 0
// RDAT: FeatureInfo2: (Opt_UsesDerivatives)
// RDAT: ShaderStageFlag: (Node)
// RDAT: MinShaderTarget: 0xf0068
[shader("node")]
[NodeLaunch("broadcasting")]
[NodeDispatchGrid(1, 1, 1)]
[NumThreads(4,4,1)]
void node_sample(uint3 tid : SV_GroupThreadID) {
float2 uv = tid.xy / float2(4, 4);
float4 color = T2D.Sample(Samp, uv);
BAB.Store(0, color);
}
// RDAT-LABEL: UnmangledName: "use_sample"
// RDAT: FeatureInfo1: 0
// RDAT: FeatureInfo2: (Opt_UsesDerivatives)
// RDAT: ShaderStageFlag: (Pixel | Compute | Library | Mesh | Amplification | Node)
// RDAT: MinShaderTarget: 0x60060
[noinline] export
void use_sample(float2 uv) {
float4 color = T2D.Sample(Samp, uv);
BAB.Store(0, color);
}
// RDAT-LABEL: UnmangledName: "node_sample_in_call"
// RDAT: FeatureInfo1: 0
// RDAT: FeatureInfo2: (Opt_UsesDerivatives)
// RDAT: ShaderStageFlag: (Node)
// RDAT: MinShaderTarget: 0xf0068
[shader("node")]
[NodeLaunch("broadcasting")]
[NodeDispatchGrid(1, 1, 1)]
[NumThreads(4,4,1)]
void node_sample_in_call(uint3 tid : SV_GroupThreadID) {
float2 uv = tid.xy / float2(4, 4);
use_sample(uv);
}
///////////////////////////////////////////////////////////////////////////////
// Category: Quad ops
// Quad ops do not set the UsesDerivatives flag, only requiring wave ops flag.
// RDAT-LABEL: UnmangledName: "node_quad"
// RDAT: FeatureInfo1: (WaveOps)
// RDAT: FeatureInfo2: 0
// RDAT: MinShaderTarget: 0xf0068
[shader("node")]
[NodeLaunch("broadcasting")]
[NodeDispatchGrid(1, 1, 1)]
[NumThreads(4,4,1)]
void node_quad(uint3 tid : SV_GroupThreadID) {
float2 uv = tid.xy / float2(4, 4);
float2 result = QuadReadAcrossDiagonal(uv);
BAB.Store(0, result);
}
// RDAT-LABEL: UnmangledName: "use_quad"
// RDAT: FeatureInfo1: (WaveOps)
// RDAT: FeatureInfo2: 0
// RDAT: ShaderStageFlag: (Pixel | Compute | Library | Mesh | Amplification | Node)
// RDAT: MinShaderTarget: 0x60060
[noinline] export
void use_quad(float2 uv) {
float2 result = QuadReadAcrossDiagonal(uv);
BAB.Store(0, result);
}
// RDAT-LABEL: UnmangledName: "node_quad_in_call"
// RDAT: FeatureInfo1: (WaveOps)
// RDAT: FeatureInfo2: 0
// RDAT: ShaderStageFlag: (Node)
// RDAT: MinShaderTarget: 0xf0068
[shader("node")]
[NodeLaunch("broadcasting")]
[NodeDispatchGrid(1, 1, 1)]
[NumThreads(4,4,1)]
void node_quad_in_call(uint3 tid : SV_GroupThreadID) {
float2 uv = tid.xy / float2(4, 4);
use_quad(uv);
}

Просмотреть файл

@ -0,0 +1,66 @@
// RUN: %dxilver 1.8 | %dxc -T lib_6_8 %s | %D3DReflect %s | %FileCheck %s -check-prefixes=RDAT
// Ensure min shader target incorporates optional features used
// RDAT: FunctionTable[{{.*}}] = {
// SM 6.8+
///////////////////////////////////////////////////////////////////////////////
// ShaderFeatureInfo_SampleCmpGradientOrBias (0x80000000) = 2147483648
Texture2D<float4> T2D : register(t0, space0);
SamplerComparisonState SampCmp : register(s0, space0);
RWByteAddressBuffer BAB : register(u1, space0);
// RDAT-LABEL: UnmangledName: "samplecmpgrad"
// RDAT: FeatureInfo1: (SampleCmpGradientOrBias)
// RDAT: FeatureInfo2: 0
// RDAT: ShaderStageFlag: (Pixel | Vertex | Geometry | Hull | Domain | Compute | Library | RayGeneration | Intersection | AnyHit | ClosestHit | Miss | Callable | Mesh | Amplification | Node)
// RDAT: MinShaderTarget: 0x60068
[noinline] export
void samplecmpgrad() {
// Use SampleCmpGrad in a minimal way that survives dead code elimination.
float4 tex = T2D.SampleCmpGrad(
SampCmp, float2(0.5, 0.5), 0.5,
float2(0.005, 0.005), float2(0.005, 0.005));
BAB.Store(0, tex.x);
}
// RDAT-LABEL: UnmangledName: "samplecmpgrad_compute"
// RDAT: FeatureInfo1: (SampleCmpGradientOrBias)
// RDAT: FeatureInfo2: 0
// RDAT: ShaderStageFlag: (Compute)
// RDAT: MinShaderTarget: 0x50068
[shader("compute")]
[numthreads(1,1,1)]
void samplecmpgrad_compute(uint tidx : SV_GroupIndex) {
samplecmpgrad();
}
// RDAT-LABEL: UnmangledName: "samplecmpbias"
// RDAT: FeatureInfo1: (SampleCmpGradientOrBias)
// RDAT: FeatureInfo2: (Opt_UsesDerivatives)
// RDAT: ShaderStageFlag: (Pixel | Compute | Library | Mesh | Amplification | Node)
// RDAT: MinShaderTarget: 0x60068
[noinline] export
void samplecmpbias() {
// Use SampleCmpGrad in a minimal way that survives dead code elimination.
float4 tex = T2D.SampleCmpBias(SampCmp, float2(0.5, 0.5), 0.5, 0.5);
BAB.Store(0, tex.x);
}
// RDAT-LABEL: UnmangledName: "samplecmpbias_compute"
// RDAT: FeatureInfo1: (SampleCmpGradientOrBias)
// RDAT: FeatureInfo2: (Opt_UsesDerivatives)
// RDAT: ShaderStageFlag: (Compute)
// RDAT: MinShaderTarget: 0x50068
[shader("compute")]
[numthreads(1,1,1)]
void samplecmpbias_compute(uint tidx : SV_GroupIndex) {
samplecmpbias();
}

Просмотреть файл

@ -0,0 +1,47 @@
// RUN: %dxc -T lib_6_x %s | %D3DReflect %s | %FileCheck %s -check-prefixes=RDAT
// Ensure min shader target incorporates optional features used
// SM 6.9+
///////////////////////////////////////////////////////////////////////////////
// ShaderFeatureInfo_WaveMMA (0x8000000) = 134217728
RWByteAddressBuffer BAB : register(u1, space0);
// RDAT-LABEL: UnmangledName: "use_wavematrix"
// RDAT: FeatureInfo1: (WaveOps | WaveMMA)
// RDAT: FeatureInfo2: 0
// RDAT: ShaderStageFlag: (Compute | Library)
// RDAT: MinShaderTarget: 0x60069
[noinline] export
void use_wavematrix() {
// Use WaveMatrix in a minimal way that survives dead code elimination.
WaveMatrixLeft<float, 16, 16> wml;
wml.Fill(0);
wml.Store(BAB, 0, 1024, false);
}
// RDAT-LABEL: UnmangledName: "call_use_wavematrix"
// RDAT: FeatureInfo1: (WaveOps | WaveMMA)
// RDAT: FeatureInfo2: 0
// RDAT: ShaderStageFlag: (Compute | Library)
// RDAT: MinShaderTarget: 0x60069
[noinline] export
void call_use_wavematrix() {
use_wavematrix();
}
// RDAT-LABEL: UnmangledName: "wavematrix_compute"
// RDAT: FeatureInfo1: (WaveOps | WaveMMA)
// RDAT: FeatureInfo2: 0
// RDAT: ShaderStageFlag: (Compute)
// RDAT: MinShaderTarget: 0x50069
[shader("compute")]
[numthreads(1,1,1)]
void wavematrix_compute(uint tidx : SV_GroupIndex) {
call_use_wavematrix();
}

Просмотреть файл

@ -353,6 +353,12 @@ PCSTR g_pFeatureInfoNames[] = {
static_assert(_countof(g_pFeatureInfoNames) == ShaderFeatureInfoCount,
"g_pFeatureInfoNames needs to be updated");
PCSTR g_pOptFeatureInfoNames[] = {
"Function uses derivatives",
};
static_assert(_countof(g_pOptFeatureInfoNames) == OptFeatureInfoCount,
"g_pOptFeatureInfoNames needs to be updated");
void PrintFeatureInfo(const DxilShaderFeatureInfo *pFeatureInfo,
raw_string_ostream &OS, StringRef comment) {
uint64_t featureFlags = pFeatureInfo->FeatureFlags;
@ -365,6 +371,16 @@ void PrintFeatureInfo(const DxilShaderFeatureInfo *pFeatureInfo,
OS << comment << " " << g_pFeatureInfoNames[i] << "\n";
}
OS << comment << "\n";
uint64_t optFeatureFlags = featureFlags >> OptFeatureInfoShift;
if (!optFeatureFlags)
return;
OS << comment << " Note: shader has optional feature flags set:\n";
for (unsigned i = 0; i < OptFeatureInfoCount; i++) {
if (optFeatureFlags & (((uint64_t)1) << i))
OS << comment << " " << g_pOptFeatureInfoNames[i] << "\n";
}
OS << comment << "\n";
}
void PrintResourceFormat(DxilResourceBase &res, unsigned alignment,

Просмотреть файл

@ -783,8 +783,15 @@ FileRunCommandPart::RunD3DReflect(dxc::DxcDllSupport &DllSupport,
IFT(DllSupport.CreateInstance(CLSID_DxcLibrary, &pLibrary));
IFT(DllSupport.CreateInstance(CLSID_DxcAssembler, &pAssembler));
IFT(pLibrary->CreateBlobWithEncodingFromPinned(
(LPCVOID)Prior->StdOut.c_str(), Prior->StdOut.size(), CP_UTF8, &pSource));
// It would be better to properly honour %s for input, but for now, if prior
// output is empty, use the file as input.
if (Prior->StdOut.size()) {
IFT(pLibrary->CreateBlobWithEncodingFromPinned(
(LPCVOID)Prior->StdOut.c_str(), Prior->StdOut.size(), CP_UTF8,
&pSource));
} else {
IFT(pLibrary->CreateBlobFromFile(CommandFileName, nullptr, &pSource));
}
IFT(pAssembler->AssembleToContainer(pSource, &pResult));
IFT(pResult->GetStatus(&resultStatus));

Просмотреть файл

@ -366,6 +366,7 @@ class db_dxil(object):
"compute",
"amplification",
"mesh",
"node",
)
for (
i
@ -448,6 +449,7 @@ class db_dxil(object):
"amplification",
"mesh",
"pixel",
"node",
)
elif i.name.startswith("Bitcast"):
i.category = "Bitcasts with different sizes"
@ -5670,7 +5672,7 @@ class db_dxil(object):
self.build_indices()
for (
i
) in "CalculateLOD,DerivCoarseX,DerivCoarseY,DerivFineX,DerivFineY,Sample,SampleBias,SampleCmp".split(
) in "CalculateLOD,DerivCoarseX,DerivCoarseY,DerivFineX,DerivFineY,Sample,SampleBias,SampleCmp,SampleCmpBias".split(
","
):
self.name_idx[i].is_gradient = True