diff --git a/include/dxc/Support/HLSLOptions.td b/include/dxc/Support/HLSLOptions.td index cd7dfb2f0c..5f6f7d4848 100644 --- a/include/dxc/Support/HLSLOptions.td +++ b/include/dxc/Support/HLSLOptions.td @@ -601,3 +601,6 @@ def rw_decl_global_cb : Flag<["-", "/"], "decl-global-cb">, Group; // Also removed: compress, decompress, /Gch (child effect), /Gpp (partial precision) // /Op - no support for preshaders. + +def devsh_disable_hlsl_intrinsics : Flag<["-"], "devsh-disable-hlsl-intrinsics">, Group, Flags<[CoreOption, DriverOption]>, + HelpText<"Disable HLSL intrinsics">; diff --git a/include/dxc/Support/SPIRVOptions.h b/include/dxc/Support/SPIRVOptions.h index 352cf6c2ec..615ebfd444 100644 --- a/include/dxc/Support/SPIRVOptions.h +++ b/include/dxc/Support/SPIRVOptions.h @@ -38,6 +38,7 @@ enum class SpirvLayoutRule { }; struct SpirvCodeGenOptions { + bool devshDisableHLSLIntrinsics; /// Disable legalization and optimization and emit raw SPIR-V bool codeGenHighLevel; bool debugInfoFile; diff --git a/lib/DxcSupport/HLSLOptions.cpp b/lib/DxcSupport/HLSLOptions.cpp index 0c9330b1d1..89a12bf1aa 100644 --- a/lib/DxcSupport/HLSLOptions.cpp +++ b/lib/DxcSupport/HLSLOptions.cpp @@ -1074,6 +1074,8 @@ int ReadDxcOpts(const OptTable *optionTable, unsigned flagsToInclude, // SPIRV Change Starts #ifdef ENABLE_SPIRV_CODEGEN + opts.SpirvOptions.devshDisableHLSLIntrinsics = + Args.hasFlag(OPT_devsh_disable_hlsl_intrinsics, OPT_INVALID, false); opts.GenSPIRV = Args.hasFlag(OPT_spirv, OPT_INVALID, false); opts.SpirvOptions.invertY = Args.hasFlag(OPT_fvk_invert_y, OPT_INVALID, false); diff --git a/tools/clang/lib/Sema/SemaHLSL.cpp b/tools/clang/lib/Sema/SemaHLSL.cpp index e9c8c90a2d..12f398cde9 100644 --- a/tools/clang/lib/Sema/SemaHLSL.cpp +++ b/tools/clang/lib/Sema/SemaHLSL.cpp @@ -5131,12 +5131,360 @@ class HLSLExternalSource : public ExternalSemaSource { bool IsValidObjectElement(LPCSTR tableName, IntrinsicOp op, QualType objectElement); + static bool checkIfIntrinsicIsAllowed(StringRef intrinsicNameIdentifier) + { + static const std::unordered_set forbiddenHLSLIntrinsics = { + "D3DCOLORtoUBYTE4", + "Abort", + "AcceptHitAndEndSearch", + "AddUint64", + "AllocateRayQuery", + "AllMemoryBarrier", + "AllMemoryBarrierWithGroupSync", + "Append", + "Barrier", + "CallShader", + "CalculateLevelOfDetail", + "CalculateLevelOfDetailUnclamped", + "CheckAccessFullyMapped", + "CommitNonOpaqueTriangleHit", + "CommitProceduralPrimitiveHit", + "CommittedInstanceContributionToHitGroupIndex", + "CommittedInstanceID", + "CommittedInstanceIndex", + "CommittedObjectRayDirection", + "CommittedObjectRayOrigin", + "CommittedObjectToWorld3x4", + "CommittedObjectToWorld4x3", + "CommittedPrimitiveIndex", + "CommittedRayT", + "CommittedStatus", + "CommittedTriangleBarycentrics", + "CommittedTriangleFrontFace", + "CommittedWorldToObject3x4", + "CommittedWorldToObject4x3", + "Consume", + "Count", + "CreateResourceFromHeap", + "CandidateGeometryIndex", + "CandidateInstanceContributionToHitGroupIndex", + "CandidateInstanceID", + "CandidateInstanceIndex", + "CandidateObjectRayDirection", + "CandidateObjectRayOrigin", + "CandidateObjectToWorld3x4", + "CandidateObjectToWorld4x3", + "CandidatePrimitiveIndex", + "CandidateProceduralPrimitiveNonOpaque", + "CandidateTriangleBarycentrics", + "CandidateTriangleFrontFace", + "CandidateTriangleRayT", + "CandidateType", + "CandidateWorldToObject3x4", + "CandidateWorldToObject4x3", + "DispatchMesh", + "DispatchRaysDimensions", + "DispatchRaysIndex", + "EvaluateAttributeAtSample", + "EvaluateAttributeCentroid", + "EvaluateAttributeSnapped", + "FinishedCrossGroupSharing", + "FromRayQuery", + "Gather", + "GatherAlpha", + "GatherBlue", + "GatherCmp", + "GatherCmpAlpha", + "GatherCmpBlue", + "GatherCmpGreen", + "GatherCmpRed", + "GatherGreen", + "GatherRaw", + "GatherRed", + "GeometryIndex", + "GetAttributeAtVertex", + "GetBufferContents", + "GetDimensions", + "GetHitKind", + "GetInstanceID", + "GetInstanceIndex", + "GetObjectRayDirection", + "GetObjectRayOrigin", + "GetObjectToWorld3x4", + "GetObjectToWorld4x3", + "GetPrimitiveIndex", + "GetRayFlags", + "GetRayTCurrent", + "GetRayTMin", + "GetRemainingRecursionLevels", + "GetRenderTargetSampleCount", + "GetRenderTargetSamplePosition", + "GetSamplePosition", + "GetShaderTableIndex", + "GetWorldRayDirection", + "GetWorldRayOrigin", + "GetWorldToObject3x4", + "GetWorldToObject4x3", + "HitKind", + "IgnoreHit", + "IncrementCounter", + "InstanceID", + "InstanceIndex", + "InterlockedAdd", + "InterlockedAdd64", + "InterlockedAnd", + "InterlockedAnd64", + "InterlockedCompareExchange", + "InterlockedCompareExchange64", + "InterlockedCompareExchangeFloatBitwise", + "InterlockedCompareStore", + "InterlockedCompareStore64", + "InterlockedCompareStoreFloatBitwise", + "InterlockedExchange", + "InterlockedExchange64", + "InterlockedExchangeFloat", + "InterlockedMax", + "InterlockedMax64", + "InterlockedMin", + "InterlockedMin64", + "InterlockedOr", + "InterlockedOr64", + "InterlockedXor", + "InterlockedXor64", + "Invoke", + "IsHit", + "IsMiss", + "IsNop", + "IsValid", + "Load", + "LoadLocalRootTableConstant", + "MakeMiss", + "MakeNop", + "MaybeReorderThread", + "NonUniformResourceIndex", + "ObjectRayDirection", + "ObjectRayOrigin", + "ObjectToWorld", + "ObjectToWorld3x4", + "ObjectToWorld4x3", + "OutputComplete", + "PrimitiveIndex", + "Proceed", + "Process2DQuadTessFactorsAvg", + "Process2DQuadTessFactorsMax", + "Process2DQuadTessFactorsMin", + "ProcessIsolineTessFactors", + "ProcessQuadTessFactorsAvg", + "ProcessQuadTessFactorsMax", + "ProcessQuadTessFactorsMin", + "ProcessTriTessFactorsAvg", + "ProcessTriTessFactorsMax", + "ProcessTriTessFactorsMin", + "QuadAll", + "QuadAny", + "QuadReadAcrossDiagonal", + "QuadReadAcrossX", + "QuadReadAcrossY", + "QuadReadLaneAt", + "RawBufferLoad", + "RawBufferStore", + "RayFlags", + "RayTCurrent", + "RayTMin", + "ReadClock", + "ReportHit", + "RestartStrip", + "SetMeshOutputCounts", + "SubpassLoad", + "TraceRay", + "TraceRayInline", + "WorldRayDirection", + "WorldRayOrigin", + "WorldToObject", + "WorldToObject3x4", + "WorldToObject4x3", + "WriteSamplerFeedback", + "WriteSamplerFeedbackBias", + "WriteSamplerFeedbackGrad", + "WriteSamplerFeedbackLevel", + "__builtin_MatVecMul", + "__builtin_MatVecMulAdd", + "__builtin_OuterProductAccumulate", + "__builtin_VectorAccumulate", + "abort", + "abs", + "acos", + "all", + "and", + "any", + "asdouble", + "asfloat", + "asfloat16", + "asin", + "asint", + "asint16", + "asuint", + "asuint16", + "atan", + "atan2", + "ceil", + "clamp", + "clip", + "cos", + "cosh", + "countbits", + "cross", + "ddx", + "ddx_coarse", + "ddx_fine", + "ddy", + "ddy_coarse", + "ddy_fine", + "degrees", + "determinant", + "distance", + "dot", + "dot2add", + "dot4add_i8packed", + "dot4add_u8packed", + "dst", + "exp", + "exp2", + "ext_execution_mode", + "ext_execution_mode_id", + "f16tof32", + "f32tof16", + "faceforward", + "firstbithigh", + "firstbitlow", + "floor", + "fma", + "fmod", + "frac", + "frexp", + "fwidth", + "isfinite", + "isinf", + "isnan", + "isnormal", + "ldexp", + "length", + "lerp", + "lit", + "log", + "log10", + "log2", + "mad", + "max", + "min", + "modf", + "msad4", + "mul", + "normalize", + "or", + "pack_clamp_s8", + "pack_clamp_u8", + "pack_s8", + "pack_u8", + "pow", + "printf", + "radians", + "rcp", + "reflect", + "refract", + "reinterpret_pointer_cast", + "reversebits", + "round", + "rsqrt", + "saturate", + "select", + "sign", + "sin", + "sincos", + "sinh", + "smoothstep", + "source_mark", + "sqrt", + "static_pointer_cast", + "step", + "tan", + "tanh", + "tex1D", + "tex1Dbias", + "tex1Dgrad", + "tex1Dlod", + "tex1Dproj", + "tex2D", + "tex2Dbias", + "tex2Dgrad", + "tex2Dlod", + "tex2Dproj", + "tex3D", + "tex3Dbias", + "tex3Dgrad", + "tex3Dlod", + "tex3Dproj", + "texCUBE", + "texCUBEbias", + "texCUBEgrad", + "texCUBElod", + "texCUBEproj", + "transpose", + "trunc", + "unpack_s8s16", + "unpack_s8s32", + "unpack_u8u16", + "unpack_u8u32", + "WaveActiveAllEqual", + "WaveActiveAllTrue", + "WaveActiveAnyTrue", + "WaveActiveBallot", + "WaveActiveBitAnd", + "WaveActiveBitOr", + "WaveActiveBitXor", + "WaveActiveCountBits", + "WaveActiveMax", + "WaveActiveMin", + "WaveActiveProduct", + "WaveActiveSum", + "WaveGetLaneCount", + "WaveGetLaneIndex", + "WaveIsFirstLane", + "WaveMatch", + "WaveMultiPrefixBitAnd", + "WaveMultiPrefixBitOr", + "WaveMultiPrefixBitXor", + "WaveMultiPrefixCountBits", + "WaveMultiPrefixProduct", + "WaveMultiPrefixSum", + "WavePrefixCountBits", + "WavePrefixProduct", + "WavePrefixSum", + "WaveReadLaneAt", + "WaveReadLaneFirst" + + }; + + auto it = forbiddenHLSLIntrinsics.find(std::string(intrinsicNameIdentifier)); + + return it == forbiddenHLSLIntrinsics.end(); + } + // Returns the iterator with the first entry that matches the requirement IntrinsicDefIter FindIntrinsicByNameAndArgCount(const HLSL_INTRINSIC *table, size_t tableSize, StringRef typeName, StringRef nameIdentifier, size_t argumentCount) { + // TODO: only check if the flag "devsh-disable-hlsl-intrinsics" is enabled + if (!checkIfIntrinsicIsAllowed(nameIdentifier)) + { + return IntrinsicDefIter::CreateStart( + table, tableSize, table + tableSize, + IntrinsicTableDefIter::CreateStart(m_intrinsicTables, typeName, + nameIdentifier, argumentCount)); + } + // This is implemented by a linear scan for now. // We tested binary search on tables, and there was no performance gain on // samples probably for the following reasons.