Skip to content

Commit

Permalink
RDAT: Check flags and WaveSize for min SM; fix flag detection and mer…
Browse files Browse the repository at this point in the history
…ging (#6207) (#6273)

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.

(cherry picked from commit 9c518db)
  • Loading branch information
tex3d authored Feb 10, 2024
1 parent 0eadada commit 6035350
Show file tree
Hide file tree
Showing 47 changed files with 3,228 additions and 318 deletions.
63 changes: 59 additions & 4 deletions include/dxc/DXIL/DxilConstants.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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;
Expand All @@ -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.
Expand Down
26 changes: 26 additions & 0 deletions include/dxc/DXIL/DxilModule.h
Original file line number Diff line number Diff line change
Expand Up @@ -404,6 +404,32 @@ class DxilModule {
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
63 changes: 56 additions & 7 deletions include/dxc/DXIL/DxilShaderFlags.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

namespace hlsl {
class DxilModule;
struct DxilFunctionProps;
}

namespace llvm {
Expand Down Expand Up @@ -125,24 +126,29 @@ class ShaderFlags {
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;
}
Expand All @@ -160,7 +166,7 @@ class ShaderFlags {
void SetDerivativesInMeshAndAmpShaders(bool flag) {
m_bDerivativesInMeshAndAmpShaders = flag;
}
bool GetDerivativesInMeshAndAmpShaders() {
bool GetDerivativesInMeshAndAmpShaders() const {
return m_bDerivativesInMeshAndAmpShaders;
}

Expand All @@ -185,6 +191,7 @@ class ShaderFlags {
return m_bSamplerDescriptorHeapIndexing;
}

// SM 6.7+
void SetResMayNotAlias(bool flag) { m_bResMayNotAlias = flag; }
bool GetResMayNotAlias() const { return m_bResMayNotAlias; }

Expand All @@ -194,9 +201,7 @@ class ShaderFlags {
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;
}
Expand All @@ -205,7 +210,16 @@ class ShaderFlags {
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
Expand All @@ -214,19 +228,25 @@ class ShaderFlags {
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
m_bLowPrecisionPresent : 1; // D3D11_1_SB_GLOBAL_FLAG_ENABLE_MINIMUM_PRECISION
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
Expand All @@ -235,39 +255,56 @@ class ShaderFlags {
// 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

// 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

Expand All @@ -276,18 +313,30 @@ class ShaderFlags {
// 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
4 changes: 3 additions & 1 deletion include/dxc/DxilContainer/DxilContainerAssembler.h
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
Loading

0 comments on commit 6035350

Please sign in to comment.