Răsfoiți Sursa

Merge branch 'rtmaster' into user/texr/integrate-master

Tex Riddell 7 ani în urmă
părinte
comite
ec4219002e
38 a modificat fișierele cu 1598 adăugiri și 822 ștergeri
  1. 212 198
      docs/DXIL.rst
  2. 1 0
      include/dxc/HLSL/DxilContainer.h
  3. 4 3
      include/dxc/HLSL/DxilShaderModel.h
  4. 2 0
      include/dxc/HLSL/DxilUtil.h
  5. 20 1
      include/dxc/HLSL/DxilValidation.h
  6. 1 0
      include/dxc/Support/HLSLOptions.h
  7. 7 3
      include/dxc/Support/HLSLOptions.td
  8. 39 13
      lib/DxcSupport/HLSLOptions.cpp
  9. 3 0
      lib/HLSL/DxilCondenseResources.cpp
  10. 4 0
      lib/HLSL/DxilContainerAssembler.cpp
  11. 1 0
      lib/HLSL/DxilLinker.cpp
  12. 3 2
      lib/HLSL/DxilMetadataHelper.cpp
  13. 0 2
      lib/HLSL/DxilModule.cpp
  14. 1 1
      lib/HLSL/DxilOperations.cpp
  15. 1 1
      lib/HLSL/DxilPreparePasses.cpp
  16. 1 1
      lib/HLSL/DxilShaderFlags.cpp
  17. 22 4
      lib/HLSL/DxilShaderModel.cpp
  18. 25 0
      lib/HLSL/DxilUtil.cpp
  19. 356 536
      lib/HLSL/DxilValidation.cpp
  20. 1 1
      lib/Transforms/Utils/InlineFunction.cpp
  21. 2 0
      tools/clang/include/clang/Frontend/CodeGenOptions.h
  22. 20 27
      tools/clang/lib/CodeGen/CGHLSLMS.cpp
  23. 110 0
      tools/clang/test/CodeGenHLSL/quick-test/lib_hs_shaders_only.hlsl
  24. 38 0
      tools/clang/test/CodeGenHLSL/quick-test/lib_res_param_x.hlsl
  25. 18 0
      tools/clang/test/CodeGenHLSL/quick-test/lib_select_res_x.hlsl
  26. 18 0
      tools/clang/test/CodeGenHLSL/quick-test/lib_select_res_x2.hlsl
  27. 38 0
      tools/clang/test/CodeGenHLSL/quick-test/lib_shaders_only.hlsl
  28. 28 0
      tools/clang/test/CodeGenHLSL/quick-test/raytracing_accept_ignore_hit_fail_lib.hlsl
  29. 34 0
      tools/clang/test/CodeGenHLSL/quick-test/res_select2_x.hlsl
  30. 50 0
      tools/clang/test/CodeGenHLSL/quick-test/res_select3_x.hlsl
  31. 48 0
      tools/clang/test/CodeGenHLSL/quick-test/res_select4_x.hlsl
  32. 44 0
      tools/clang/test/CodeGenHLSL/quick-test/res_select5_x.hlsl
  33. 8 0
      tools/clang/tools/dxcompiler/dxcompilerobj.cpp
  34. 2 2
      tools/clang/unittests/HLSL/DxilContainerTest.cpp
  35. 4 8
      tools/clang/unittests/HLSL/LinkerTest.cpp
  36. 402 3
      tools/clang/unittests/HLSL/ValidationTest.cpp
  37. 16 2
      utils/hct/hctdb.py
  38. 14 14
      utils/hct/hctdb_instrhelp.py

+ 212 - 198
docs/DXIL.rst

@@ -2894,204 +2894,218 @@ The set of validation rules that are known to hold for a DXIL program is identif
 .. <py::lines('VALRULES-RST')>hctdb_instrhelp.get_valrules_rst()</py>
 .. VALRULES-RST:BEGIN
 
-====================================== =======================================================================================================================================================================================================================================================================================================
-Rule Code                              Description
-====================================== =======================================================================================================================================================================================================================================================================================================
-BITCODE.VALID                          TODO - Module must be bitcode-valid
-CONTAINER.PARTINVALID                  DXIL Container must not contain unknown parts
-CONTAINER.PARTMATCHES                  DXIL Container Parts must match Module
-CONTAINER.PARTMISSING                  DXIL Container requires certain parts, corresponding to module
-CONTAINER.PARTREPEATED                 DXIL Container must have only one of each part type
-CONTAINER.ROOTSIGNATUREINCOMPATIBLE    Root Signature in DXIL Container must be compatible with shader
-DECL.DXILFNEXTERN                      External function must be a DXIL function
-DECL.DXILNSRESERVED                    The DXIL reserved prefixes must only be used by built-in functions and types
-DECL.FNATTRIBUTE                       Functions should only contain known function attributes
-DECL.FNFLATTENPARAM                    Function parameters must not use struct types
-DECL.FNISCALLED                        Functions can only be used by call instructions
-DECL.NOTUSEDEXTERNAL                   External declaration should not be used
-DECL.USEDEXTERNALFUNCTION              External function must be used
-DECL.USEDINTERNAL                      Internal declaration must be used
-FLOW.DEADLOOP                          Loop must have break
-FLOW.FUNCTIONCALL                      Function with parameter is not permitted
-FLOW.NORECUSION                        Recursion is not permitted
-FLOW.REDUCIBLE                         Execution flow must be reducible
-INSTR.ALLOWED                          Instructions must be of an allowed type
-INSTR.ATTRIBUTEATVERTEXNOINTERPOLATION Attribute %0 must have nointerpolation mode in order to use GetAttributeAtVertex function.
-INSTR.BARRIERMODEFORNONCS              sync in a non-Compute Shader must only sync UAV (sync_uglobal)
-INSTR.BARRIERMODENOMEMORY              sync must include some form of memory barrier - _u (UAV) and/or _g (Thread Group Shared Memory).  Only _t (thread group sync) is optional.
-INSTR.BARRIERMODEUSELESSUGROUP         sync can't specify both _ugroup and _uglobal. If both are needed, just specify _uglobal.
-INSTR.BUFFERUPDATECOUNTERONUAV         BufferUpdateCounter valid only on UAV
-INSTR.CALLOLOAD                        Call to DXIL intrinsic must match overload signature
-INSTR.CANNOTPULLPOSITION               pull-model evaluation of position disallowed
-INSTR.CBUFFERCLASSFORCBUFFERHANDLE     Expect Cbuffer for CBufferLoad handle
-INSTR.CBUFFEROUTOFBOUND                Cbuffer access out of bound
-INSTR.CHECKACCESSFULLYMAPPED           CheckAccessFullyMapped should only used on resource status
-INSTR.COORDINATECOUNTFORRAWTYPEDBUF    raw/typed buffer don't need 2 coordinates
-INSTR.COORDINATECOUNTFORSTRUCTBUF      structured buffer require 2 coordinates
-INSTR.CREATEHANDLEIMMRANGEID           Local resource must map to global resource.
-INSTR.DXILSTRUCTUSER                   Dxil struct types should only used by ExtractValue
-INSTR.DXILSTRUCTUSEROUTOFBOUND         Index out of bound when extract value from dxil struct types
-INSTR.EVALINTERPOLATIONMODE            Interpolation mode on %0 used with eval_* instruction must be linear, linear_centroid, linear_noperspective, linear_noperspective_centroid, linear_sample or linear_noperspective_sample
-INSTR.EXTRACTVALUE                     ExtractValue should only be used on dxil struct types and cmpxchg
-INSTR.FAILTORESLOVETGSMPOINTER         TGSM pointers must originate from an unambiguous TGSM global variable.
-INSTR.HANDLENOTFROMCREATEHANDLE        Resource handle should returned by createHandle
-INSTR.IMMBIASFORSAMPLEB                bias amount for sample_b must be in the range [%0,%1], but %2 was specified as an immediate
-INSTR.INBOUNDSACCESS                   Access to out-of-bounds memory is disallowed
-INSTR.MINPRECISIONNOTPRECISE           Instructions marked precise may not refer to minprecision values
-INSTR.MINPRECISONBITCAST               Bitcast on minprecison types is not allowed
-INSTR.MIPLEVELFORGETDIMENSION          Use mip level on buffer when GetDimensions
-INSTR.MIPONUAVLOAD                     uav load don't support mipLevel/sampleIndex
-INSTR.NOGENERICPTRADDRSPACECAST        Address space cast between pointer types must have one part to be generic address space
-INSTR.NOIDIVBYZERO                     No signed integer division by zero
-INSTR.NOINDEFINITEACOS                 No indefinite arccosine
-INSTR.NOINDEFINITEASIN                 No indefinite arcsine
-INSTR.NOINDEFINITEDSXY                 No indefinite derivative calculation
-INSTR.NOINDEFINITELOG                  No indefinite logarithm
-INSTR.NOREADINGUNINITIALIZED           Instructions should not read uninitialized value
-INSTR.NOUDIVBYZERO                     No unsigned integer division by zero
-INSTR.OFFSETONUAVLOAD                  uav load don't support offset
-INSTR.OLOAD                            DXIL intrinsic overload must be valid
-INSTR.ONLYONEALLOCCONSUME              RWStructuredBuffers may increment or decrement their counters, but not both.
-INSTR.OPCODERESERVED                   Instructions must not reference reserved opcodes
-INSTR.OPCONST                          DXIL intrinsic requires an immediate constant operand
-INSTR.OPCONSTRANGE                     Constant values must be in-range for operation
-INSTR.OPERANDRANGE                     DXIL intrinsic operand must be within defined range
-INSTR.PTRBITCAST                       Pointer type bitcast must be have same size
-INSTR.RESOURCECLASSFORLOAD             load can only run on UAV/SRV resource
-INSTR.RESOURCECLASSFORSAMPLERGATHER    sample, lod and gather should on srv resource.
-INSTR.RESOURCECLASSFORUAVSTORE         store should on uav resource.
-INSTR.RESOURCECOORDINATEMISS           coord uninitialized
-INSTR.RESOURCECOORDINATETOOMANY        out of bound coord must be undef
-INSTR.RESOURCEKINDFORBUFFERLOADSTORE   buffer load/store only works on Raw/Typed/StructuredBuffer
-INSTR.RESOURCEKINDFORCALCLOD           lod requires resource declared as texture1D/2D/3D/Cube/CubeArray/1DArray/2DArray
-INSTR.RESOURCEKINDFORGATHER            gather requires resource declared as texture/2D/Cube/2DArray/CubeArray
-INSTR.RESOURCEKINDFORGETDIM            Invalid resource kind on GetDimensions
-INSTR.RESOURCEKINDFORSAMPLE            sample/_l/_d requires resource declared as texture1D/2D/3D/Cube/1DArray/2DArray/CubeArray
-INSTR.RESOURCEKINDFORSAMPLEC           samplec requires resource declared as texture1D/2D/Cube/1DArray/2DArray/CubeArray
-INSTR.RESOURCEKINDFORTEXTURELOAD       texture load only works on Texture1D/1DArray/2D/2DArray/3D/MS2D/MS2DArray
-INSTR.RESOURCEKINDFORTEXTURESTORE      texture store only works on Texture1D/1DArray/2D/2DArray/3D
-INSTR.RESOURCEOFFSETMISS               offset uninitialized
-INSTR.RESOURCEOFFSETTOOMANY            out of bound offset must be undef
-INSTR.SAMPLECOMPTYPE                   sample_* instructions require resource to be declared to return UNORM, SNORM or FLOAT.
-INSTR.SAMPLEINDEXFORLOAD2DMS           load on Texture2DMS/2DMSArray require sampleIndex
-INSTR.SAMPLERMODEFORLOD                lod instruction requires sampler declared in default mode
-INSTR.SAMPLERMODEFORSAMPLE             sample/_l/_d/_cl_s/gather instruction requires sampler declared in default mode
-INSTR.SAMPLERMODEFORSAMPLEC            sample_c_*/gather_c instructions require sampler declared in comparison mode
-INSTR.SIGNATUREOPERATIONNOTINENTRY     Dxil operation for input output signature must be in entryPoints.
-INSTR.STATUS                           Resource status should only used by CheckAccessFullyMapped
-INSTR.STRUCTBITCAST                    Bitcast on struct types is not allowed
-INSTR.TEXTUREOFFSET                    offset texture instructions must take offset which can resolve to integer literal in the range -8 to 7
-INSTR.TGSMRACECOND                     Race condition writing to shared memory detected, consider making this write conditional
-INSTR.UNDEFRESULTFORGETDIMENSION       GetDimensions used undef dimension %0 on %1
-INSTR.WRITEMASKFORTYPEDUAVSTORE        store on typed uav must write to all four components of the UAV
-INSTR.WRITEMASKMATCHVALUEFORUAVSTORE   uav store write mask must match store value mask, write mask is %0 and store value mask is %1
-META.BARYCENTRICSFLOAT3                only 'float3' type is allowed for SV_Barycentrics.
-META.BARYCENTRICSINTERPOLATION         SV_Barycentrics cannot be used with 'nointerpolation' type
-META.BARYCENTRICSTWOPERSPECTIVES       There can only be up to two input attributes of SV_Barycentrics with different perspective interpolation mode.
-META.BRANCHFLATTEN                     Can't use branch and flatten attributes together
-META.CLIPCULLMAXCOMPONENTS             Combined elements of SV_ClipDistance and SV_CullDistance must fit in 8 components
-META.CLIPCULLMAXROWS                   Combined elements of SV_ClipDistance and SV_CullDistance must fit in two rows.
-META.CONTROLFLOWHINTNOTONCONTROLFLOW   Control flow hint only works on control flow inst
-META.DENSERESIDS                       Resource identifiers must be zero-based and dense
-META.DUPLICATESYSVALUE                 System value may only appear once in signature
-META.ENTRYFUNCTION                     entrypoint not found
-META.FLAGSUSAGE                        Flags must match usage
-META.FORCECASEONSWITCH                 Attribute forcecase only works for switch
-META.FUNCTIONANNOTATION                Cannot find function annotation for %0
-META.GLCNOTONAPPENDCONSUME             globallycoherent cannot be used with append/consume buffers
-META.INTEGERINTERPMODE                 Interpolation mode on integer must be Constant
-META.INTERPMODEINONEROW                Interpolation mode must be identical for all elements packed into the same row.
-META.INTERPMODEVALID                   Interpolation mode must be valid
-META.INVALIDCONTROLFLOWHINT            Invalid control flow hint
-META.KNOWN                             Named metadata should be known
-META.MAXTESSFACTOR                     Hull Shader MaxTessFactor must be [%0..%1].  %2 specified
-META.NOENTRYPROPSFORENTRY              EntryPoints must have entry properties.
-META.NOSEMANTICOVERLAP                 Semantics must not overlap
-META.REQUIRED                          TODO - Required metadata missing
-META.SEMAKINDMATCHESNAME               Semantic name must match system value, when defined.
-META.SEMAKINDVALID                     Semantic kind must be valid
-META.SEMANTICCOMPTYPE                  %0 must be %1
-META.SEMANTICINDEXMAX                  System value semantics have a maximum valid semantic index
-META.SEMANTICLEN                       Semantic length must be at least 1 and at most 64
-META.SEMANTICSHOULDBEALLOCATED         Semantic should have a valid packing location
-META.SEMANTICSHOULDNOTBEALLOCATED      Semantic should have a packing location of -1
-META.SIGNATURECOMPTYPE                 signature %0 specifies unrecognized or invalid component type
-META.SIGNATUREDATAWIDTH                Data width must be identical for all elements packed into the same row.
-META.SIGNATUREILLEGALCOMPONENTORDER    Component ordering for packed elements must be: arbitrary < system value < system generated value
-META.SIGNATUREINDEXCONFLICT            Only elements with compatible indexing rules may be packed together
-META.SIGNATUREOUTOFRANGE               Signature elements must fit within maximum signature size
-META.SIGNATUREOVERLAP                  Signature elements may not overlap in packing location.
-META.STRUCTBUFALIGNMENT                StructuredBuffer stride not aligned
-META.STRUCTBUFALIGNMENTOUTOFBOUND      StructuredBuffer stride out of bounds
-META.SYSTEMVALUEROWS                   System value may only have 1 row
-META.TARGET                            Target triple must be 'dxil-ms-dx'
-META.TESSELLATOROUTPUTPRIMITIVE        Invalid Tessellator Output Primitive specified. Must be point, line, triangleCW or triangleCCW.
-META.TESSELLATORPARTITION              Invalid Tessellator Partitioning specified. Must be integer, pow2, fractional_odd or fractional_even.
-META.TEXTURETYPE                       elements of typed buffers and textures must fit in four 32-bit quantities
-META.USED                              All metadata must be used by dxil
-META.VALIDSAMPLERMODE                  Invalid sampler mode on sampler
-META.VALUERANGE                        Metadata value must be within range
-META.WELLFORMED                        TODO - Metadata must be well-formed in operand count and types
-SM.APPENDANDCONSUMEONSAMEUAV           BufferUpdateCounter inc and dec on a given UAV (%d) cannot both be in the same shader for shader model less than 5.1.
-SM.CBUFFERELEMENTOVERFLOW              CBuffer elements must not overflow
-SM.CBUFFEROFFSETOVERLAP                CBuffer offsets must not overlap
-SM.CBUFFERTEMPLATETYPEMUSTBESTRUCT     D3D12 constant/texture buffer template element can only be a struct
-SM.COMPLETEPOSITION                    Not all elements of SV_Position were written
-SM.COUNTERONLYONSTRUCTBUF              BufferUpdateCounter valid only on structured buffers
-SM.CSNORETURN                          Compute shaders can't return values, outputs must be written in writable resources (UAVs).
-SM.DOMAINLOCATIONIDXOOB                DomainLocation component index out of bounds for the domain.
-SM.DSINPUTCONTROLPOINTCOUNTRANGE       DS input control point count must be [0..%0].  %1 specified
-SM.DXILVERSION                         Target shader model requires specific Dxil Version
-SM.GSINSTANCECOUNTRANGE                GS instance count must be [1..%0].  %1 specified
-SM.GSOUTPUTVERTEXCOUNTRANGE            GS output vertex count must be [0..%0].  %1 specified
-SM.GSTOTALOUTPUTVERTEXDATARANGE        Declared output vertex count (%0) multiplied by the total number of declared scalar components of output data (%1) equals %2.  This value cannot be greater than %3
-SM.GSVALIDINPUTPRIMITIVE               GS input primitive unrecognized
-SM.GSVALIDOUTPUTPRIMITIVETOPOLOGY      GS output primitive topology unrecognized
-SM.HSINPUTCONTROLPOINTCOUNTRANGE       HS input control point count must be [0..%0].  %1 specified
-SM.HULLPASSTHRUCONTROLPOINTCOUNTMATCH  For pass thru hull shader, input control point count must match output control point count
-SM.INSIDETESSFACTORSIZEMATCHDOMAIN     InsideTessFactor rows, columns (%0, %1) invalid for domain %2.  Expected %3 rows and 1 column.
-SM.INVALIDRESOURCECOMPTYPE             Invalid resource return type
-SM.INVALIDRESOURCEKIND                 Invalid resources kind
-SM.INVALIDTEXTUREKINDONUAV             Texture2DMS[Array] or TextureCube[Array] resources are not supported with UAVs
-SM.ISOLINEOUTPUTPRIMITIVEMISMATCH      Hull Shader declared with IsoLine Domain must specify output primitive point or line. Triangle_cw or triangle_ccw output are not compatible with the IsoLine Domain.
-SM.MAXTGSMSIZE                         Total Thread Group Shared Memory storage is %0, exceeded %1
-SM.MAXTHEADGROUP                       Declared Thread Group Count %0 (X*Y*Z) is beyond the valid maximum of %1
-SM.MULTISTREAMMUSTBEPOINT              When multiple GS output streams are used they must be pointlists
-SM.NAME                                Target shader model name must be known
-SM.NOINTERPMODE                        Interpolation mode must be undefined for VS input/PS output/patch constant.
-SM.NOPSOUTPUTIDX                       Pixel shader output registers are not indexable.
-SM.OPCODE                              Opcode must be defined in target shader model
-SM.OPCODEININVALIDFUNCTION             Invalid DXIL opcode usage like StorePatchConstant in patch constant function
-SM.OPERAND                             Operand must be defined in target shader model
-SM.OUTPUTCONTROLPOINTCOUNTRANGE        output control point count must be [0..%0].  %1 specified
-SM.OUTPUTCONTROLPOINTSTOTALSCALARS     Total number of scalars across all HS output control points must not exceed
-SM.PATCHCONSTANTONLYFORHSDS            patch constant signature only valid in HS and DS
-SM.PSCONSISTENTINTERP                  Interpolation mode for PS input position must be linear_noperspective_centroid or linear_noperspective_sample when outputting oDepthGE or oDepthLE and not running at sample frequency (which is forced by inputting SV_SampleIndex or declaring an input linear_sample or linear_noperspective_sample)
-SM.PSCOVERAGEANDINNERCOVERAGE          InnerCoverage and Coverage are mutually exclusive.
-SM.PSMULTIPLEDEPTHSEMANTIC             Pixel Shader only allows one type of depth semantic to be declared
-SM.PSOUTPUTSEMANTIC                    Pixel Shader allows output semantics to be SV_Target, SV_Depth, SV_DepthGreaterEqual, SV_DepthLessEqual, SV_Coverage or SV_StencilRef, %0 found
-SM.PSTARGETCOL0                        SV_Target packed location must start at column 0
-SM.PSTARGETINDEXMATCHESROW             SV_Target semantic index must match packed row location
-SM.RESOURCERANGEOVERLAP                Resource ranges must not overlap
-SM.ROVONLYINPS                         RasterizerOrdered objects are only allowed in 5.0+ pixel shaders
-SM.SAMPLECOUNTONLYON2DMS               Only Texture2DMS/2DMSArray could has sample count
-SM.SEMANTIC                            Semantic must be defined in target shader model
-SM.STREAMINDEXRANGE                    Stream index (%0) must between 0 and %1
-SM.TESSFACTORFORDOMAIN                 Required TessFactor for domain not found declared anywhere in Patch Constant data
-SM.TESSFACTORSIZEMATCHDOMAIN           TessFactor rows, columns (%0, %1) invalid for domain %2.  Expected %3 rows and 1 column.
-SM.THREADGROUPCHANNELRANGE             Declared Thread Group %0 size %1 outside valid range [%2..%3]
-SM.TRIOUTPUTPRIMITIVEMISMATCH          Hull Shader declared with Tri Domain must specify output primitive point, triangle_cw or triangle_ccw. Line output is not compatible with the Tri domain
-SM.UNDEFINEDOUTPUT                     Not all elements of output %0 were written
-SM.VALIDDOMAIN                         Invalid Tessellator Domain specified. Must be isoline, tri or quad
-SM.VIEWIDNEEDSSLOT                     ViewID requires compatible space in pixel shader input signature
-SM.ZEROHSINPUTCONTROLPOINTWITHINPUT    When HS input control point count is 0, no input signature should exist
-TYPES.DEFINED                          Type must be defined based on DXIL primitives
-TYPES.I8                               I8 can only used as immediate value for intrinsic
-TYPES.INTWIDTH                         Int type must be of valid width
-TYPES.NOMULTIDIM                       Only one dimension allowed for array type
-TYPES.NOVECTOR                         Vector types must not be present
-UNI.NOWAVESENSITIVEGRADIENT            Gradient operations are not affected by wave-sensitive data or control flow.
-====================================== =======================================================================================================================================================================================================================================================================================================
+======================================== =======================================================================================================================================================================================================================================================================================================
+Rule Code                                Description
+======================================== =======================================================================================================================================================================================================================================================================================================
+BITCODE.VALID                            TODO - Module must be bitcode-valid
+CONTAINER.PARTINVALID                    DXIL Container must not contain unknown parts
+CONTAINER.PARTMATCHES                    DXIL Container Parts must match Module
+CONTAINER.PARTMISSING                    DXIL Container requires certain parts, corresponding to module
+CONTAINER.PARTREPEATED                   DXIL Container must have only one of each part type
+CONTAINER.ROOTSIGNATUREINCOMPATIBLE      Root Signature in DXIL Container must be compatible with shader
+DECL.ATTRSTRUCT                          Attributes parameter must be struct type
+DECL.DXILFNEXTERN                        External function must be a DXIL function
+DECL.DXILNSRESERVED                      The DXIL reserved prefixes must only be used by built-in functions and types
+DECL.EXTRAARGS                           Extra arguments not allowed for shader functions
+DECL.FNATTRIBUTE                         Functions should only contain known function attributes
+DECL.FNFLATTENPARAM                      Function parameters must not use struct types
+DECL.FNISCALLED                          Functions can only be used by call instructions
+DECL.NOTUSEDEXTERNAL                     External declaration should not be used
+DECL.PARAMSTRUCT                         Callable function parameter must be struct type
+DECL.PAYLOADSTRUCT                       Payload parameter must be struct type
+DECL.RESOURCEINFNSIG                     Resources not allowed in function signatures
+DECL.SHADERMISSINGARG                    payload/params/attributes parameter is required for certain shader types
+DECL.SHADERRETURNVOID                    Shader functions must return void
+DECL.USEDEXTERNALFUNCTION                External function must be used
+DECL.USEDINTERNAL                        Internal declaration must be used
+FLOW.DEADLOOP                            Loop must have break
+FLOW.FUNCTIONCALL                        Function with parameter is not permitted
+FLOW.NORECUSION                          Recursion is not permitted
+FLOW.REDUCIBLE                           Execution flow must be reducible
+INSTR.ALLOWED                            Instructions must be of an allowed type
+INSTR.ATTRIBUTEATVERTEXNOINTERPOLATION   Attribute %0 must have nointerpolation mode in order to use GetAttributeAtVertex function.
+INSTR.BARRIERMODEFORNONCS                sync in a non-Compute Shader must only sync UAV (sync_uglobal)
+INSTR.BARRIERMODENOMEMORY                sync must include some form of memory barrier - _u (UAV) and/or _g (Thread Group Shared Memory).  Only _t (thread group sync) is optional.
+INSTR.BARRIERMODEUSELESSUGROUP           sync can't specify both _ugroup and _uglobal. If both are needed, just specify _uglobal.
+INSTR.BUFFERUPDATECOUNTERONRESHASCOUNTER BufferUpdateCounter valid only when HasCounter is true
+INSTR.BUFFERUPDATECOUNTERONUAV           BufferUpdateCounter valid only on UAV
+INSTR.CALLOLOAD                          Call to DXIL intrinsic must match overload signature
+INSTR.CANNOTPULLPOSITION                 pull-model evaluation of position disallowed
+INSTR.CBUFFERCLASSFORCBUFFERHANDLE       Expect Cbuffer for CBufferLoad handle
+INSTR.CBUFFEROUTOFBOUND                  Cbuffer access out of bound
+INSTR.CHECKACCESSFULLYMAPPED             CheckAccessFullyMapped should only used on resource status
+INSTR.COORDINATECOUNTFORRAWTYPEDBUF      raw/typed buffer don't need 2 coordinates
+INSTR.COORDINATECOUNTFORSTRUCTBUF        structured buffer require 2 coordinates
+INSTR.CREATEHANDLEIMMRANGEID             Local resource must map to global resource.
+INSTR.DXILSTRUCTUSER                     Dxil struct types should only used by ExtractValue
+INSTR.DXILSTRUCTUSEROUTOFBOUND           Index out of bound when extract value from dxil struct types
+INSTR.EVALINTERPOLATIONMODE              Interpolation mode on %0 used with eval_* instruction must be linear, linear_centroid, linear_noperspective, linear_noperspective_centroid, linear_sample or linear_noperspective_sample
+INSTR.EXTRACTVALUE                       ExtractValue should only be used on dxil struct types and cmpxchg
+INSTR.FAILTORESLOVETGSMPOINTER           TGSM pointers must originate from an unambiguous TGSM global variable.
+INSTR.HANDLENOTFROMCREATEHANDLE          Resource handle should returned by createHandle
+INSTR.IMMBIASFORSAMPLEB                  bias amount for sample_b must be in the range [%0,%1], but %2 was specified as an immediate
+INSTR.INBOUNDSACCESS                     Access to out-of-bounds memory is disallowed
+INSTR.MINPRECISIONNOTPRECISE             Instructions marked precise may not refer to minprecision values
+INSTR.MINPRECISONBITCAST                 Bitcast on minprecison types is not allowed
+INSTR.MIPLEVELFORGETDIMENSION            Use mip level on buffer when GetDimensions
+INSTR.MIPONUAVLOAD                       uav load don't support mipLevel/sampleIndex
+INSTR.NOGENERICPTRADDRSPACECAST          Address space cast between pointer types must have one part to be generic address space
+INSTR.NOIDIVBYZERO                       No signed integer division by zero
+INSTR.NOINDEFINITEACOS                   No indefinite arccosine
+INSTR.NOINDEFINITEASIN                   No indefinite arcsine
+INSTR.NOINDEFINITEDSXY                   No indefinite derivative calculation
+INSTR.NOINDEFINITELOG                    No indefinite logarithm
+INSTR.NOREADINGUNINITIALIZED             Instructions should not read uninitialized value
+INSTR.NOUDIVBYZERO                       No unsigned integer division by zero
+INSTR.OFFSETONUAVLOAD                    uav load don't support offset
+INSTR.OLOAD                              DXIL intrinsic overload must be valid
+INSTR.ONLYONEALLOCCONSUME                RWStructuredBuffers may increment or decrement their counters, but not both.
+INSTR.OPCODERESERVED                     Instructions must not reference reserved opcodes
+INSTR.OPCONST                            DXIL intrinsic requires an immediate constant operand
+INSTR.OPCONSTRANGE                       Constant values must be in-range for operation
+INSTR.OPERANDRANGE                       DXIL intrinsic operand must be within defined range
+INSTR.PTRBITCAST                         Pointer type bitcast must be have same size
+INSTR.RESOURCECLASSFORLOAD               load can only run on UAV/SRV resource
+INSTR.RESOURCECLASSFORSAMPLERGATHER      sample, lod and gather should on srv resource.
+INSTR.RESOURCECLASSFORUAVSTORE           store should on uav resource.
+INSTR.RESOURCECOORDINATEMISS             coord uninitialized
+INSTR.RESOURCECOORDINATETOOMANY          out of bound coord must be undef
+INSTR.RESOURCEKINDFORBUFFERLOADSTORE     buffer load/store only works on Raw/Typed/StructuredBuffer
+INSTR.RESOURCEKINDFORCALCLOD             lod requires resource declared as texture1D/2D/3D/Cube/CubeArray/1DArray/2DArray
+INSTR.RESOURCEKINDFORGATHER              gather requires resource declared as texture/2D/Cube/2DArray/CubeArray
+INSTR.RESOURCEKINDFORGETDIM              Invalid resource kind on GetDimensions
+INSTR.RESOURCEKINDFORSAMPLE              sample/_l/_d requires resource declared as texture1D/2D/3D/Cube/1DArray/2DArray/CubeArray
+INSTR.RESOURCEKINDFORSAMPLEC             samplec requires resource declared as texture1D/2D/Cube/1DArray/2DArray/CubeArray
+INSTR.RESOURCEKINDFORTEXTURELOAD         texture load only works on Texture1D/1DArray/2D/2DArray/3D/MS2D/MS2DArray
+INSTR.RESOURCEKINDFORTEXTURESTORE        texture store only works on Texture1D/1DArray/2D/2DArray/3D
+INSTR.RESOURCEKINDFORTRACERAY            TraceRay should only use RTAccelerationStructure
+INSTR.RESOURCEMAPTOSINGLEENTRY           Fail to map resource to resource table
+INSTR.RESOURCEOFFSETMISS                 offset uninitialized
+INSTR.RESOURCEOFFSETTOOMANY              out of bound offset must be undef
+INSTR.RESOURCEUSER                       Resource should only used by Load/GEP/Call
+INSTR.SAMPLECOMPTYPE                     sample_* instructions require resource to be declared to return UNORM, SNORM or FLOAT.
+INSTR.SAMPLEINDEXFORLOAD2DMS             load on Texture2DMS/2DMSArray require sampleIndex
+INSTR.SAMPLERMODEFORLOD                  lod instruction requires sampler declared in default mode
+INSTR.SAMPLERMODEFORSAMPLE               sample/_l/_d/_cl_s/gather instruction requires sampler declared in default mode
+INSTR.SAMPLERMODEFORSAMPLEC              sample_c_*/gather_c instructions require sampler declared in comparison mode
+INSTR.SIGNATUREOPERATIONNOTINENTRY       Dxil operation for input output signature must be in entryPoints.
+INSTR.STATUS                             Resource status should only used by CheckAccessFullyMapped
+INSTR.STRUCTBITCAST                      Bitcast on struct types is not allowed
+INSTR.TEXTUREOFFSET                      offset texture instructions must take offset which can resolve to integer literal in the range -8 to 7
+INSTR.TGSMRACECOND                       Race condition writing to shared memory detected, consider making this write conditional
+INSTR.UNDEFRESULTFORGETDIMENSION         GetDimensions used undef dimension %0 on %1
+INSTR.WRITEMASKFORTYPEDUAVSTORE          store on typed uav must write to all four components of the UAV
+INSTR.WRITEMASKMATCHVALUEFORUAVSTORE     uav store write mask must match store value mask, write mask is %0 and store value mask is %1
+META.BARYCENTRICSFLOAT3                  only 'float3' type is allowed for SV_Barycentrics.
+META.BARYCENTRICSINTERPOLATION           SV_Barycentrics cannot be used with 'nointerpolation' type
+META.BARYCENTRICSTWOPERSPECTIVES         There can only be up to two input attributes of SV_Barycentrics with different perspective interpolation mode.
+META.BRANCHFLATTEN                       Can't use branch and flatten attributes together
+META.CLIPCULLMAXCOMPONENTS               Combined elements of SV_ClipDistance and SV_CullDistance must fit in 8 components
+META.CLIPCULLMAXROWS                     Combined elements of SV_ClipDistance and SV_CullDistance must fit in two rows.
+META.CONTROLFLOWHINTNOTONCONTROLFLOW     Control flow hint only works on control flow inst
+META.DENSERESIDS                         Resource identifiers must be zero-based and dense
+META.DUPLICATESYSVALUE                   System value may only appear once in signature
+META.ENTRYFUNCTION                       entrypoint not found
+META.FLAGSUSAGE                          Flags must match usage
+META.FORCECASEONSWITCH                   Attribute forcecase only works for switch
+META.FUNCTIONANNOTATION                  Cannot find function annotation for %0
+META.GLCNOTONAPPENDCONSUME               globallycoherent cannot be used with append/consume buffers
+META.INTEGERINTERPMODE                   Interpolation mode on integer must be Constant
+META.INTERPMODEINONEROW                  Interpolation mode must be identical for all elements packed into the same row.
+META.INTERPMODEVALID                     Interpolation mode must be valid
+META.INVALIDCONTROLFLOWHINT              Invalid control flow hint
+META.KNOWN                               Named metadata should be known
+META.MAXTESSFACTOR                       Hull Shader MaxTessFactor must be [%0..%1].  %2 specified
+META.NOENTRYPROPSFORENTRY                EntryPoints must have entry properties.
+META.NOSEMANTICOVERLAP                   Semantics must not overlap
+META.REQUIRED                            TODO - Required metadata missing
+META.SEMAKINDMATCHESNAME                 Semantic name must match system value, when defined.
+META.SEMAKINDVALID                       Semantic kind must be valid
+META.SEMANTICCOMPTYPE                    %0 must be %1
+META.SEMANTICINDEXMAX                    System value semantics have a maximum valid semantic index
+META.SEMANTICLEN                         Semantic length must be at least 1 and at most 64
+META.SEMANTICSHOULDBEALLOCATED           Semantic should have a valid packing location
+META.SEMANTICSHOULDNOTBEALLOCATED        Semantic should have a packing location of -1
+META.SIGNATURECOMPTYPE                   signature %0 specifies unrecognized or invalid component type
+META.SIGNATUREDATAWIDTH                  Data width must be identical for all elements packed into the same row.
+META.SIGNATUREILLEGALCOMPONENTORDER      Component ordering for packed elements must be: arbitrary < system value < system generated value
+META.SIGNATUREINDEXCONFLICT              Only elements with compatible indexing rules may be packed together
+META.SIGNATUREOUTOFRANGE                 Signature elements must fit within maximum signature size
+META.SIGNATUREOVERLAP                    Signature elements may not overlap in packing location.
+META.STRUCTBUFALIGNMENT                  StructuredBuffer stride not aligned
+META.STRUCTBUFALIGNMENTOUTOFBOUND        StructuredBuffer stride out of bounds
+META.SYSTEMVALUEROWS                     System value may only have 1 row
+META.TARGET                              Target triple must be 'dxil-ms-dx'
+META.TESSELLATOROUTPUTPRIMITIVE          Invalid Tessellator Output Primitive specified. Must be point, line, triangleCW or triangleCCW.
+META.TESSELLATORPARTITION                Invalid Tessellator Partitioning specified. Must be integer, pow2, fractional_odd or fractional_even.
+META.TEXTURETYPE                         elements of typed buffers and textures must fit in four 32-bit quantities
+META.USED                                All metadata must be used by dxil
+META.VALIDSAMPLERMODE                    Invalid sampler mode on sampler
+META.VALUERANGE                          Metadata value must be within range
+META.WELLFORMED                          TODO - Metadata must be well-formed in operand count and types
+SM.64BITRAWBUFFERLOADSTORE               i64/f64 rawBufferLoad/Store overloads are allowed after SM 6.3
+SM.APPENDANDCONSUMEONSAMEUAV             BufferUpdateCounter inc and dec on a given UAV (%d) cannot both be in the same shader for shader model less than 5.1.
+SM.CBUFFERELEMENTOVERFLOW                CBuffer elements must not overflow
+SM.CBUFFEROFFSETOVERLAP                  CBuffer offsets must not overlap
+SM.CBUFFERTEMPLATETYPEMUSTBESTRUCT       D3D12 constant/texture buffer template element can only be a struct
+SM.COMPLETEPOSITION                      Not all elements of SV_Position were written
+SM.COUNTERONLYONSTRUCTBUF                BufferUpdateCounter valid only on structured buffers
+SM.CSNOSIGNATURES                        Compute shaders must not have shader signatures.
+SM.DOMAINLOCATIONIDXOOB                  DomainLocation component index out of bounds for the domain.
+SM.DSINPUTCONTROLPOINTCOUNTRANGE         DS input control point count must be [0..%0].  %1 specified
+SM.DXILVERSION                           Target shader model requires specific Dxil Version
+SM.GSINSTANCECOUNTRANGE                  GS instance count must be [1..%0].  %1 specified
+SM.GSOUTPUTVERTEXCOUNTRANGE              GS output vertex count must be [0..%0].  %1 specified
+SM.GSTOTALOUTPUTVERTEXDATARANGE          Declared output vertex count (%0) multiplied by the total number of declared scalar components of output data (%1) equals %2.  This value cannot be greater than %3
+SM.GSVALIDINPUTPRIMITIVE                 GS input primitive unrecognized
+SM.GSVALIDOUTPUTPRIMITIVETOPOLOGY        GS output primitive topology unrecognized
+SM.HSINPUTCONTROLPOINTCOUNTRANGE         HS input control point count must be [0..%0].  %1 specified
+SM.HULLPASSTHRUCONTROLPOINTCOUNTMATCH    For pass thru hull shader, input control point count must match output control point count
+SM.INSIDETESSFACTORSIZEMATCHDOMAIN       InsideTessFactor rows, columns (%0, %1) invalid for domain %2.  Expected %3 rows and 1 column.
+SM.INVALIDRESOURCECOMPTYPE               Invalid resource return type
+SM.INVALIDRESOURCEKIND                   Invalid resources kind
+SM.INVALIDTEXTUREKINDONUAV               Texture2DMS[Array] or TextureCube[Array] resources are not supported with UAVs
+SM.ISOLINEOUTPUTPRIMITIVEMISMATCH        Hull Shader declared with IsoLine Domain must specify output primitive point or line. Triangle_cw or triangle_ccw output are not compatible with the IsoLine Domain.
+SM.MAXTGSMSIZE                           Total Thread Group Shared Memory storage is %0, exceeded %1
+SM.MAXTHEADGROUP                         Declared Thread Group Count %0 (X*Y*Z) is beyond the valid maximum of %1
+SM.MULTISTREAMMUSTBEPOINT                When multiple GS output streams are used they must be pointlists
+SM.NAME                                  Target shader model name must be known
+SM.NOINTERPMODE                          Interpolation mode must be undefined for VS input/PS output/patch constant.
+SM.NOPSOUTPUTIDX                         Pixel shader output registers are not indexable.
+SM.OPCODE                                Opcode must be defined in target shader model
+SM.OPCODEININVALIDFUNCTION               Invalid DXIL opcode usage like StorePatchConstant in patch constant function
+SM.OPERAND                               Operand must be defined in target shader model
+SM.OUTPUTCONTROLPOINTCOUNTRANGE          output control point count must be [0..%0].  %1 specified
+SM.OUTPUTCONTROLPOINTSTOTALSCALARS       Total number of scalars across all HS output control points must not exceed
+SM.PATCHCONSTANTONLYFORHSDS              patch constant signature only valid in HS and DS
+SM.PSCONSISTENTINTERP                    Interpolation mode for PS input position must be linear_noperspective_centroid or linear_noperspective_sample when outputting oDepthGE or oDepthLE and not running at sample frequency (which is forced by inputting SV_SampleIndex or declaring an input linear_sample or linear_noperspective_sample)
+SM.PSCOVERAGEANDINNERCOVERAGE            InnerCoverage and Coverage are mutually exclusive.
+SM.PSMULTIPLEDEPTHSEMANTIC               Pixel Shader only allows one type of depth semantic to be declared
+SM.PSOUTPUTSEMANTIC                      Pixel Shader allows output semantics to be SV_Target, SV_Depth, SV_DepthGreaterEqual, SV_DepthLessEqual, SV_Coverage or SV_StencilRef, %0 found
+SM.PSTARGETCOL0                          SV_Target packed location must start at column 0
+SM.PSTARGETINDEXMATCHESROW               SV_Target semantic index must match packed row location
+SM.RAYSHADERPAYLOADSIZE                  For shader '%0', %1 size is smaller than argument's allocation size
+SM.RAYSHADERSIGNATURES                   Ray tracing shader '%0' should not have any shader signatures
+SM.RESOURCERANGEOVERLAP                  Resource ranges must not overlap
+SM.ROVONLYINPS                           RasterizerOrdered objects are only allowed in 5.0+ pixel shaders
+SM.SAMPLECOUNTONLYON2DMS                 Only Texture2DMS/2DMSArray could has sample count
+SM.SEMANTIC                              Semantic must be defined in target shader model
+SM.STREAMINDEXRANGE                      Stream index (%0) must between 0 and %1
+SM.TESSFACTORFORDOMAIN                   Required TessFactor for domain not found declared anywhere in Patch Constant data
+SM.TESSFACTORSIZEMATCHDOMAIN             TessFactor rows, columns (%0, %1) invalid for domain %2.  Expected %3 rows and 1 column.
+SM.THREADGROUPCHANNELRANGE               Declared Thread Group %0 size %1 outside valid range [%2..%3]
+SM.TRIOUTPUTPRIMITIVEMISMATCH            Hull Shader declared with Tri Domain must specify output primitive point, triangle_cw or triangle_ccw. Line output is not compatible with the Tri domain
+SM.UNDEFINEDOUTPUT                       Not all elements of output %0 were written
+SM.VALIDDOMAIN                           Invalid Tessellator Domain specified. Must be isoline, tri or quad
+SM.VIEWIDNEEDSSLOT                       ViewID requires compatible space in pixel shader input signature
+SM.ZEROHSINPUTCONTROLPOINTWITHINPUT      When HS input control point count is 0, no input signature should exist
+TYPES.DEFINED                            Type must be defined based on DXIL primitives
+TYPES.I8                                 I8 can only used as immediate value for intrinsic
+TYPES.INTWIDTH                           Int type must be of valid width
+TYPES.NOMULTIDIM                         Only one dimension allowed for array type
+TYPES.NOVECTOR                           Vector types must not be present
+UNI.NOWAVESENSITIVEGRADIENT              Gradient operations are not affected by wave-sensitive data or control flow.
+======================================== =======================================================================================================================================================================================================================================================================================================
 
 .. VALRULES-RST:END
 

+ 1 - 0
include/dxc/HLSL/DxilContainer.h

@@ -429,6 +429,7 @@ DxilPartWriter *NewProgramSignatureWriter(const DxilModule &M, DXIL::SignatureKi
 DxilPartWriter *NewRootSignatureWriter(const RootSignatureHandle &S);
 DxilPartWriter *NewFeatureInfoWriter(const DxilModule &M);
 DxilPartWriter *NewPSVWriter(const DxilModule &M, uint32_t PSVVersion = 0);
+DxilPartWriter *NewRDATWriter(const DxilModule &M, uint32_t InfoVersion = 0);
 
 class DxilContainerWriter : public DxilPartWriter  {
 public:

+ 4 - 3
include/dxc/HLSL/DxilShaderModel.h

@@ -30,6 +30,7 @@ public:
   // Major/Minor version of highest shader model
   static const unsigned kHighestMajor = 6;
   static const unsigned kHighestMinor = 3;
+  static const unsigned kOfflineMinor = 0xF;
 
   bool IsPS() const     { return m_Kind == Kind::Pixel; }
   bool IsVS() const     { return m_Kind == Kind::Vertex; }
@@ -58,7 +59,7 @@ public:
   bool IsSM62Plus() const   { return IsSMAtLeast(6, 2); }
   bool IsSM63Plus() const   { return IsSMAtLeast(6, 3); }
   const char *GetName() const { return m_pszName; }
-  std::string GetKindName() const;
+  const char *GetKindName() const;
   unsigned GetNumTempRegs() const { return DXIL::kMaxTempRegCount; }
   unsigned GetNumInputRegs() const { return m_NumInputRegs; }
   unsigned GetNumOutputRegs() const { return m_NumOutputRegs; }
@@ -72,7 +73,7 @@ public:
   static const ShaderModel *Get(unsigned Idx);
   static const ShaderModel *Get(Kind Kind, unsigned Major, unsigned Minor);
   static const ShaderModel *GetByName(const char *pszName);
-  static std::string GetKindName(Kind kind);
+  static const char *GetKindName(Kind kind);
 
   bool operator==(const ShaderModel &other) const;
   bool operator!=(const ShaderModel &other) const { return !(*this == other); }
@@ -93,7 +94,7 @@ private:
               unsigned m_NumInputRegs, unsigned m_NumOutputRegs,
               bool m_bUAVs, bool m_bTypedUavs, unsigned m_UAVRegsLim);
 
-  static const unsigned kNumShaderModels = 48;
+  static const unsigned kNumShaderModels = 49;
   static const ShaderModel ms_ShaderModels[kNumShaderModels];
 
   static const ShaderModel *GetInvalid();

+ 2 - 0
include/dxc/HLSL/DxilUtil.h

@@ -90,6 +90,8 @@ namespace dxilutil {
   std::unique_ptr<llvm::Module> LoadModuleFromBitcode(llvm::MemoryBuffer *MB,
     llvm::LLVMContext &Ctx, std::string &DiagStr);
   void PrintDiagnosticHandler(const llvm::DiagnosticInfo &DI, void *Context);
+  // Returns true if type contains HLSL Object type (resource)
+  bool ContainsHLSLObjectType(llvm::Type *Ty);
 }
 
 }

+ 20 - 1
include/dxc/HLSL/DxilValidation.h

@@ -41,12 +41,19 @@ enum class ValidationRule : unsigned {
   ContainerRootSignatureIncompatible, // Root Signature in DXIL Container must be compatible with shader
 
   // Declaration
+  DeclAttrStruct, // Attributes parameter must be struct type
   DeclDxilFnExtern, // External function must be a DXIL function
   DeclDxilNsReserved, // The DXIL reserved prefixes must only be used by built-in functions and types
+  DeclExtraArgs, // Extra arguments not allowed for shader functions
   DeclFnAttribute, // Functions should only contain known function attributes
   DeclFnFlattenParam, // Function parameters must not use struct types
   DeclFnIsCalled, // Functions can only be used by call instructions
   DeclNotUsedExternal, // External declaration should not be used
+  DeclParamStruct, // Callable function parameter must be struct type
+  DeclPayloadStruct, // Payload parameter must be struct type
+  DeclResourceInFnSig, // Resources not allowed in function signatures
+  DeclShaderMissingArg, // payload/params/attributes parameter is required for certain shader types
+  DeclShaderReturnVoid, // Shader functions must return void
   DeclUsedExternalFunction, // External function must be used
   DeclUsedInternal, // Internal declaration must be used
 
@@ -56,6 +63,7 @@ enum class ValidationRule : unsigned {
   InstrBarrierModeForNonCS, // sync in a non-Compute Shader must only sync UAV (sync_uglobal)
   InstrBarrierModeNoMemory, // sync must include some form of memory barrier - _u (UAV) and/or _g (Thread Group Shared Memory).  Only _t (thread group sync) is optional. 
   InstrBarrierModeUselessUGroup, // sync can't specify both _ugroup and _uglobal. If both are needed, just specify _uglobal.
+  InstrBufferUpdateCounterOnResHasCounter, // BufferUpdateCounter valid only when HasCounter is true
   InstrBufferUpdateCounterOnUAV, // BufferUpdateCounter valid only on UAV
   InstrCBufferClassForCBufferHandle, // Expect Cbuffer for CBufferLoad handle
   InstrCBufferOutOfBound, // Cbuffer access out of bound
@@ -106,8 +114,11 @@ enum class ValidationRule : unsigned {
   InstrResourceKindForSampleC, // samplec requires resource declared as texture1D/2D/Cube/1DArray/2DArray/CubeArray
   InstrResourceKindForTextureLoad, // texture load only works on Texture1D/1DArray/2D/2DArray/3D/MS2D/MS2DArray
   InstrResourceKindForTextureStore, // texture store only works on Texture1D/1DArray/2D/2DArray/3D
+  InstrResourceKindForTraceRay, // TraceRay should only use RTAccelerationStructure
+  InstrResourceMapToSingleEntry, // Fail to map resource to resource table
   InstrResourceOffsetMiss, // offset uninitialized
   InstrResourceOffsetTooMany, // out of bound offset must be undef
+  InstrResourceUser, // Resource should only used by Load/GEP/Call
   InstrSampleCompType, // sample_* instructions require resource to be declared to return UNORM, SNORM or FLOAT.
   InstrSampleIndexForLoad2DMS, // load on Texture2DMS/2DMSArray require sampleIndex
   InstrSamplerModeForLOD, // lod instruction requires sampler declared in default mode
@@ -178,11 +189,12 @@ enum class ValidationRule : unsigned {
   FlowReducible, // Execution flow must be reducible
 
   // Shader model
+  Sm64bitRawBufferLoadStore, // i64/f64 rawBufferLoad/Store overloads are allowed after SM 6.3
   SmAppendAndConsumeOnSameUAV, // BufferUpdateCounter inc and dec on a given UAV (%d) cannot both be in the same shader for shader model less than 5.1.
   SmCBufferElementOverflow, // CBuffer elements must not overflow
   SmCBufferOffsetOverlap, // CBuffer offsets must not overlap
   SmCBufferTemplateTypeMustBeStruct, // D3D12 constant/texture buffer template element can only be a struct
-  SmCSNoReturn, // Compute shaders can't return values, outputs must be written in writable resources (UAVs).
+  SmCSNoSignatures, // Compute shaders must not have shader signatures.
   SmCompletePosition, // Not all elements of SV_Position were written
   SmCounterOnlyOnStructBuf, // BufferUpdateCounter valid only on structured buffers
   SmDSInputControlPointCountRange, // DS input control point count must be [0..%0].  %1 specified
@@ -219,6 +231,8 @@ enum class ValidationRule : unsigned {
   SmPSTargetIndexMatchesRow, // SV_Target semantic index must match packed row location
   SmPatchConstantOnlyForHSDS, // patch constant signature only valid in HS and DS
   SmROVOnlyInPS, // RasterizerOrdered objects are only allowed in 5.0+ pixel shaders
+  SmRayShaderPayloadSize, // For shader '%0', %1 size is smaller than argument's allocation size
+  SmRayShaderSignatures, // Ray tracing shader '%0' should not have any shader signatures
   SmResourceRangeOverlap, // Resource ranges must not overlap
   SmSampleCountOnlyOn2DMS, // Only Texture2DMS/2DMSArray could has sample count
   SmSemantic, // Semantic must be defined in target shader model
@@ -261,6 +275,11 @@ bool VerifyPSVMatches(_In_ llvm::Module *pModule,
                       _In_reads_bytes_(PSVSize) const void *pPSVData,
                       _In_ uint32_t PSVSize);
 
+// PSV = data for Pipeline State Validation
+bool VerifyRDATMatches(_In_ llvm::Module *pModule,
+                       _In_reads_bytes_(RDATSize) const void *pRDATData,
+                       _In_ uint32_t RDATSize);
+
 bool VerifyFeatureInfoMatches(_In_ llvm::Module *pModule,
                               _In_reads_bytes_(FeatureInfoSize) const void *pFeatureInfoData,
                               _In_ uint32_t FeatureInfoSize);

+ 1 - 0
include/dxc/Support/HLSLOptions.h

@@ -156,6 +156,7 @@ public:
   bool DisaseembleHex = false; //OPT_Lx
   bool LegacyMacroExpansion = false; // OPT_flegacy_macro_expansion
   unsigned long AutoBindingSpace = UINT_MAX; // OPT_auto_binding_space
+  bool ExportShadersOnly = false; // OPT_export_shaders_only
 
   bool IsRootSignatureProfile();
   bool IsLibraryProfile();

+ 7 - 3
include/dxc/Support/HLSLOptions.td

@@ -232,8 +232,12 @@ def rootsig_define : Separate<["-", "/"], "rootsig-define">, Group<hlslcomp_Grou
 def enable_16bit_types: Flag<["-", "/"], "enable-16bit-types">, Flags<[CoreOption, DriverOption]>, Group<hlslcomp_Group>,
   HelpText<"Enable 16bit types and disable min precision types. Available in HLSL 2018 and shader model 6.2">;
 def ignore_line_directives : Flag<["-", "/"], "ignore-line-directives">, HelpText<"Ignore line directives">, Flags<[CoreOption]>, Group<hlslcomp_Group>;
-def auto_binding_space : Separate<["-", "/"], "auto-binding-space">, Group<hlslcomp_Group>, Flags<[CoreOption]>, HelpText<"Set auto binding space - enables auto resource binding in libraries">;
-def exports : Separate<["-", "/"], "exports">, Group<hlslcomp_Group>, Flags<[CoreOption]>, HelpText<"Specify exports when compiling a library: export1[[,export1_clone,...]=internal_name][;...]">;
+def auto_binding_space : Separate<["-", "/"], "auto-binding-space">, Group<hlslcomp_Group>, Flags<[CoreOption]>,
+  HelpText<"Set auto binding space - enables auto resource binding in libraries">;
+def exports : Separate<["-", "/"], "exports">, Group<hlslcomp_Group>, Flags<[CoreOption]>,
+  HelpText<"Specify exports when compiling a library: export1[[,export1_clone,...]=internal_name][;...]">;
+def export_shaders_only : Flag<["-", "/"], "export-shaders-only">, Group<hlslcomp_Group>, Flags<[CoreOption]>,
+  HelpText<"Only export shaders when compiling a library">;
 
 // SPIRV Change Starts
 def spirv : Flag<["-"], "spirv">, Group<spirv_Group>, Flags<[CoreOption, DriverOption]>,
@@ -268,7 +272,7 @@ def Wno_vk_ignored_features : Joined<["-"], "Wno-vk-ignored-features">, Group<sp
 // fxc-based flags that don't match those previously defined.
 
 def target_profile : JoinedOrSeparate<["-", "/"], "T">, Flags<[CoreOption]>, Group<hlslcomp_Group>, MetaVarName<"<profile>">,
-  HelpText<"Set target profile. \n\t<profile>: ps_6_0, ps_6_1, ps_6_2, vs_6_0, vs_6_1, vs_6_2, \n\t\t cs_6_0, cs_6_1, cs_6_2, gs_6_0, gs_6_1, gs_6_2, \n\t\t ds_6_0, ds_6_1, ds_6_2, hs_6_0, hs_6_1, hs_6_2, \n\t\t lib_6_0, lib_6_1, lib_6_2">;
+  HelpText<"Set target profile. \n\t<profile>: ps_6_0, ps_6_1, ps_6_2, ps_6_3, \n\t\t vs_6_0, vs_6_1, vs_6_2, vs_6_3, \n\t\t cs_6_0, cs_6_1, cs_6_2, cs_6_3, \n\t\t gs_6_0, gs_6_1, gs_6_2, gs_6_3, \n\t\t ds_6_0, ds_6_1, ds_6_2, ds_6_3, \n\t\t hs_6_0, hs_6_1, hs_6_2, hs_6_3, \n\t\t lib_6_3">;
 def entrypoint :  JoinedOrSeparate<["-", "/"], "E">, Flags<[CoreOption]>, Group<hlslcomp_Group>,
   HelpText<"Entry point name">;
 // /I <include> - already defined above

+ 39 - 13
lib/DxcSupport/HLSLOptions.cpp

@@ -193,17 +193,29 @@ StringRefUtf16::StringRefUtf16(llvm::StringRef value) {
 }
 
 static bool GetTargetVersionFromString(llvm::StringRef ref, unsigned *major, unsigned *minor) {
-  try {
-    *major = (unsigned)std::stoul(std::string(1, ref[ref.size() - 3]));
-    *minor = (unsigned)std::stoul(std::string(1, ref[ref.size() - 1]));
-    return true;
-  }
-  catch (std::invalid_argument &) {
+  *major = *minor = -1;
+  unsigned len = ref.size();
+  if (len < 6 || len > 11) // length: ps_6_0 to rootsig_1_0
     return false;
-  }
-  catch (std::out_of_range &) {
+  if (ref[len - 4] != '_' || ref[len - 2] != '_')
     return false;
-  }
+
+  char cMajor = ref[len - 3];
+  char cMinor = ref[len - 1];
+
+  if (cMajor >= '0' && cMajor <= '9')
+    *major = cMajor - '0';
+  else
+    return false;
+
+  if (cMinor == 'x')
+    *minor = 0xF;
+  else if (cMinor >= '0' && cMinor <= '9')
+    *minor = cMinor - '0';
+  else
+    return false;
+
+  return true;
 }
 
 namespace hlsl {
@@ -285,9 +297,14 @@ int ReadDxcOpts(const OptTable *optionTable, unsigned flagsToInclude,
       // Set entry point to impossible name.
       opts.EntryPoint = "lib.no::entry";
     }
-  } else if (Args.getLastArg(OPT_exports)) {
-    errors << "library profile required when using -exports option";
-    return 1;
+  } else {
+    if (Args.getLastArg(OPT_exports)) {
+      errors << "library profile required when using -exports option";
+      return 1;
+    } else if (Args.hasFlag(OPT_export_shaders_only, OPT_INVALID, false)) {
+      errors << "library profile required when using -export-shaders-only option";
+      return 1;
+    }
   }
 
   llvm::StringRef ver = Args.getLastArgValue(OPT_hlsl_version);
@@ -379,7 +396,10 @@ int ReadDxcOpts(const OptTable *optionTable, unsigned flagsToInclude,
   unsigned Major = 0;
   unsigned Minor = 0;
   if (!opts.TargetProfile.empty()) {
-    GetTargetVersionFromString(opts.TargetProfile, &Major, &Minor);
+    if (!GetTargetVersionFromString(opts.TargetProfile, &Major, &Minor)) {
+      errors << "unable to parse shader model.";
+      return 1;
+    }
   }
 
   if (opts.TargetProfile.empty() || Major < 6 || (Major == 6 && Minor < 2)) {
@@ -442,6 +462,7 @@ int ReadDxcOpts(const OptTable *optionTable, unsigned flagsToInclude,
   opts.DisassembleByteOffset = Args.hasFlag(OPT_No, OPT_INVALID, false);
   opts.DisaseembleHex = Args.hasFlag(OPT_Lx, OPT_INVALID, false);
   opts.LegacyMacroExpansion = Args.hasFlag(OPT_flegacy_macro_expansion, OPT_INVALID, false);
+  opts.ExportShadersOnly = Args.hasFlag(OPT_export_shaders_only, OPT_INVALID, false);
 
   if (opts.DefaultColMajor && opts.DefaultRowMajor) {
     errors << "Cannot specify /Zpr and /Zpc together, use /? to get usage information";
@@ -514,6 +535,11 @@ int ReadDxcOpts(const OptTable *optionTable, unsigned flagsToInclude,
     return 1;
   }
 
+  if (opts.IsLibraryProfile() && Minor == 0xF) {
+    // Disable validation for offline link only target
+    opts.DisableValidation = true;
+  }
+
   // SPIRV Change Starts
 #ifdef ENABLE_SPIRV_CODEGEN
   const bool genSpirv = opts.GenSPIRV = Args.hasFlag(OPT_spirv, OPT_INVALID, false);

+ 3 - 0
lib/HLSL/DxilCondenseResources.cpp

@@ -506,6 +506,9 @@ public:
 
     bChanged |= AllocateDxilResources(DM);
 
+    if (m_bIsLib && DM.GetShaderModel()->GetMinor() == ShaderModel::kOfflineMinor)
+      return bChanged;
+
     // Make sure no select on resource.
     bChanged |= RemovePhiOnResource();
 

+ 4 - 0
lib/HLSL/DxilContainerAssembler.cpp

@@ -1236,6 +1236,10 @@ DxilPartWriter *hlsl::NewPSVWriter(const DxilModule &M, uint32_t PSVVersion) {
   return new DxilPSVWriter(M, PSVVersion);
 }
 
+DxilPartWriter *hlsl::NewRDATWriter(const DxilModule &M, uint32_t InfoVersion) {
+  return new DxilRDATWriter(M, InfoVersion);
+}
+
 class DxilContainerWriter_impl : public DxilContainerWriter  {
 private:
   class DxilPart {

+ 1 - 0
lib/HLSL/DxilLinker.cpp

@@ -1046,6 +1046,7 @@ void DxilLinkJob::RunPreparePass(Module &M) {
   PM.add(createGlobalDCEPass());
 
   PM.add(createDxilLowerCreateHandleForLibPass());
+  PM.add(createDxilTranslateRawBuffer());
   PM.add(createDxilFinalizeModulePass());
   PM.add(createComputeViewIdStatePass());
   PM.add(createDxilDeadFunctionEliminationPass());

+ 3 - 2
lib/HLSL/DxilMetadataHelper.cpp

@@ -164,7 +164,7 @@ void DxilMDHelper::EmitDxilShaderModel(const ShaderModel *pSM) {
   pShaderModelNamedMD = m_pModule->getOrInsertNamedMetadata(kDxilShaderModelMDName);
 
   Metadata *MDVals[kDxilShaderModelNumFields];
-  MDVals[kDxilShaderModelTypeIdx ] = MDString::get(m_Ctx, pSM->GetKindName().c_str());
+  MDVals[kDxilShaderModelTypeIdx ] = MDString::get(m_Ctx, pSM->GetKindName());
   MDVals[kDxilShaderModelMajorIdx] = Uint32ToConstMD(pSM->GetMajor());
   MDVals[kDxilShaderModelMinorIdx] = Uint32ToConstMD(pSM->GetMinor());
 
@@ -184,7 +184,8 @@ void DxilMDHelper::LoadDxilShaderModel(const ShaderModel *&pSM) {
   unsigned Major = ConstMDToUint32(pShaderModelMD->getOperand(kDxilShaderModelMajorIdx));
   unsigned Minor = ConstMDToUint32(pShaderModelMD->getOperand(kDxilShaderModelMinorIdx));
   string ShaderModelName = pShaderTypeMD->getString();
-  ShaderModelName += "_" + std::to_string(Major) + "_" + std::to_string(Minor);
+  ShaderModelName += "_" + std::to_string(Major) + "_" +
+    (Minor == ShaderModel::kOfflineMinor ? "x" : std::to_string(Minor));
   pSM = ShaderModel::GetByName(ShaderModelName.c_str());
   if (!pSM->IsValidForDxil()) {
     char ErrorMsgTxt[40];

+ 0 - 2
lib/HLSL/DxilModule.cpp

@@ -1295,8 +1295,6 @@ void DxilModule::LoadDxilMetadata() {
 
       std::unique_ptr<DxilEntryProps> pEntryProps =
           llvm::make_unique<DxilEntryProps>(props, m_bUseMinPrecision);
-      DXASSERT(pSignatures->get() == nullptr || !props.IsRay(),
-               "Raytracing has no signature");
       m_pMDHelper->LoadDxilSignatures(*pSignatures, pEntryProps->sig);
 
       m_DxilEntryPropsMap[pFunc] = std::move(pEntryProps);

+ 1 - 1
lib/HLSL/DxilOperations.cpp

@@ -589,7 +589,7 @@ void OP::GetMinShaderModelAndMask(OpCode C, bool bWithTranslation,
   // Instructions: IgnoreHit=155, AcceptHitAndEndSearch=156
   if ((155 <= op && op <= 156)) {
     major = 6;  minor = 3;
-    mask = SFLAG(Library) | SFLAG(AnyHit);
+    mask = SFLAG(AnyHit);
     return;
   }
   // Instructions: CallShader=159

+ 1 - 1
lib/HLSL/DxilPreparePasses.cpp

@@ -525,7 +525,7 @@ void DxilEmitMetadata::patchIsFrontfaceTy(Module &M) {
     return;
   unsigned ValMajor, ValMinor;
   DM.GetValidatorVersion(ValMajor, ValMinor);
-  bool bForceUint = ValMajor >= 1 && ValMinor >= 2;
+  bool bForceUint = ValMajor == 0 || (ValMajor >= 1 && ValMinor >= 2);
   if (pSM->IsPS()) {
     patchIsFrontface(DM.GetInputSignature(), bForceUint);
   } else if (pSM->IsGS()) {

+ 1 - 1
lib/HLSL/DxilShaderFlags.cpp

@@ -224,7 +224,7 @@ ShaderFlags ShaderFlags::CollectShaderFlags(const Function *F,
   // Try to maintain compatibility with a v1.0 validator if that's what we have.
   uint32_t valMajor, valMinor;
   M->GetValidatorVersion(valMajor, valMinor);
-  bool hasMulticomponentUAVLoadsBackCompat = valMajor <= 1 && valMinor == 0;
+  bool hasMulticomponentUAVLoadsBackCompat = valMajor == 1 && valMinor == 0;
 
   Type *int16Ty = Type::getInt16Ty(F->getContext());
   Type *int64Ty = Type::getInt64Ty(F->getContext());

+ 22 - 4
lib/HLSL/DxilShaderModel.cpp

@@ -59,6 +59,8 @@ bool ShaderModel::IsValidForDxil() const {
       case 2:
       case 3:
         return true;
+      case kOfflineMinor:
+        return m_Kind == Kind::Library;
       }
     }
     break;
@@ -139,6 +141,12 @@ const ShaderModel *ShaderModel::GetByName(const char *pszName) {
         break;
       }
       else return GetInvalid();
+    case 'x':
+      if (kind == Kind::Library && Major == 6) {
+        Minor = kOfflineMinor;
+        break;
+      }
+      else return GetInvalid();
     default:  return GetInvalid();
   }
   if (pszName[Idx++] != 0)
@@ -161,6 +169,7 @@ void ShaderModel::GetDxilVersion(unsigned &DxilMajor, unsigned &DxilMinor) const
     DxilMinor = 2;
     break;
   case 3:
+  case kOfflineMinor: // Always update this to highest dxil version
     DxilMinor = 3;
     break;
   default:
@@ -185,6 +194,10 @@ void ShaderModel::GetMinValidatorVersion(unsigned &ValMajor, unsigned &ValMinor)
   case 3:
     ValMinor = 3;
     break;
+  case kOfflineMinor:
+    ValMajor = 0;
+    ValMinor = 0;
+    break;
   default:
     DXASSERT(0, "IsValidForDxil() should have caught this.");
     break;
@@ -192,15 +205,17 @@ void ShaderModel::GetMinValidatorVersion(unsigned &ValMajor, unsigned &ValMinor)
 }
 
 static const char *ShaderModelKindNames[] = {
-    "ps", "vs", "gs", "hs", "ds", "cs", "lib", "invalid",
+    "ps", "vs", "gs", "hs", "ds", "cs", "lib",
+    "raygeneration", "intersection", "anyhit", "closesthit", "miss", "callable",
+    "invalid",
 };
 
-std::string ShaderModel::GetKindName() const {
+const char * ShaderModel::GetKindName() const {
   return GetKindName(m_Kind);
 }
 
-std::string ShaderModel::GetKindName(Kind kind) {
-  return std::string(ShaderModelKindNames[static_cast<unsigned int>(kind)]);
+const char * ShaderModel::GetKindName(Kind kind) {
+  return ShaderModelKindNames[static_cast<unsigned int>(kind)];
 }
 
 const ShaderModel *ShaderModel::GetInvalid() {
@@ -265,6 +280,9 @@ const ShaderModel ShaderModel::ms_ShaderModels[kNumShaderModels] = {
   SM(Kind::Library,  6, 2, "lib_6_2",  32, 32,  true,  true,  UINT_MAX),
   SM(Kind::Library,  6, 3, "lib_6_3",  32, 32,  true,  true,  UINT_MAX),
 
+  // lib_6_x is for offline linking only, and relaxes restrictions
+  SM(Kind::Library,  6, kOfflineMinor, "lib_6_x",  32, 32,  true,  true,  UINT_MAX),
+
   SM(Kind::Invalid,  0, 0, "invalid", 0,  0,   false, false, 0),
 };
 

+ 25 - 0
lib/HLSL/DxilUtil.cpp

@@ -14,6 +14,7 @@
 #include "dxc/HLSL/DxilTypeSystem.h"
 #include "dxc/HLSL/DxilUtil.h"
 #include "dxc/HLSL/DxilModule.h"
+#include "dxc/HLSL/HLModule.h"
 #include "llvm/Bitcode/ReaderWriter.h"
 #include "llvm/IR/DiagnosticInfo.h"
 #include "llvm/IR/DiagnosticPrinter.h"
@@ -370,5 +371,29 @@ llvm::Instruction *FirstNonAllocaInsertionPt(llvm::Function* F) {
     F->getEntryBlock().getFirstInsertionPt());
 }
 
+bool ContainsHLSLObjectType(llvm::Type *Ty) {
+  // Unwrap pointer/array
+  while (llvm::isa<llvm::PointerType>(Ty))
+    Ty = llvm::cast<llvm::PointerType>(Ty)->getPointerElementType();
+  while (llvm::isa<llvm::ArrayType>(Ty))
+    Ty = llvm::cast<llvm::ArrayType>(Ty)->getArrayElementType();
+
+  if (llvm::StructType *ST = llvm::dyn_cast<llvm::StructType>(Ty)) {
+    if (ST->getName().startswith("dx.types."))
+      return true;
+    // TODO: How is this suppoed to check for Input/OutputPatch types if
+    // these have already been eliminated in function arguments during CG?
+    if (HLModule::IsHLSLObjectType(Ty))
+      return true;
+    // Otherwise, recurse elements of UDT
+    for (auto ETy : ST->elements()) {
+      if (ContainsHLSLObjectType(ETy))
+        return true;
+    }
+  }
+  return false;
+}
+
+
 }
 }

Fișier diff suprimat deoarece este prea mare
+ 356 - 536
lib/HLSL/DxilValidation.cpp


+ 1 - 1
lib/Transforms/Utils/InlineFunction.cpp

@@ -1432,7 +1432,7 @@ bool llvm::InlineFunction(CallSite CS, InlineFunctionInfo &IFI,
   if (PHI) {
     auto &DL = Caller->getParent()->getDataLayout();
     if (Value *V = SimplifyInstruction(PHI, DL, nullptr, nullptr,
-                                       &IFI.ACT->getAssumptionCache(*Caller))) {
+          IFI.ACT ? &IFI.ACT->getAssumptionCache(*Caller) : nullptr)) { // HLSL Change: fix nullptr dereference
       PHI->replaceAllUsesWith(V);
       PHI->eraseFromParent();
     }

+ 2 - 0
tools/clang/include/clang/Frontend/CodeGenOptions.h

@@ -204,6 +204,8 @@ public:
   unsigned HLSLDefaultSpace = UINT_MAX;
   /// HLSLLibraryExports specifies desired exports, with optional renaming
   std::vector<std::string> HLSLLibraryExports;
+  /// ExportShadersOnly limits library export functions to shaders
+  bool ExportShadersOnly = false;
   // HLSL Change Ends
   /// Regular expression to select optimizations for which we should enable
   /// optimization remarks. Transformation passes whose name matches this

+ 20 - 27
tools/clang/lib/CodeGen/CGHLSLMS.cpp

@@ -391,7 +391,8 @@ CGMSHLSLRuntime::CGMSHLSLRuntime(CodeGenModule &CGM)
   // set profile
   m_pHLModule->SetShaderModel(SM);
   // set entry name
-  m_pHLModule->SetEntryFunctionName(CGM.getCodeGenOpts().HLSLEntryFunction);
+  if (!SM->IsLib())
+    m_pHLModule->SetEntryFunctionName(CGM.getCodeGenOpts().HLSLEntryFunction);
 
   // set root signature version.
   if (CGM.getLangOpts().RootSigMinor == 0) {
@@ -4396,29 +4397,6 @@ void CGMSHLSLRuntime::SetPatchConstantFunctionWithAttr(
   
 }
 
-static bool ContainsDisallowedTypeForExport(llvm::Type *Ty) {
-  // Unwrap pointer/array
-  while (llvm::isa<llvm::PointerType>(Ty))
-    Ty = llvm::cast<llvm::PointerType>(Ty)->getPointerElementType();
-  while (llvm::isa<llvm::ArrayType>(Ty))
-    Ty = llvm::cast<llvm::ArrayType>(Ty)->getArrayElementType();
-
-  if (llvm::StructType *ST = llvm::dyn_cast<llvm::StructType>(Ty)) {
-    if (ST->getName().startswith("dx.types."))
-      return true;
-    // TODO: How is this suppoed to check for Input/OutputPatch types if
-    // these have already been eliminated in function arguments during CG?
-    if (HLModule::IsHLSLObjectType(Ty))
-      return true;
-    // Otherwise, recurse elements of UDT
-    for (auto ETy : ST->elements()) {
-      if (ContainsDisallowedTypeForExport(ETy))
-        return true;
-    }
-  }
-  return false;
-}
-
 static void ReportDisallowedTypeInExportParam(CodeGenModule &CGM, StringRef name) {
   DiagnosticsEngine &Diags = CGM.getDiags();
   unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error,
@@ -4600,8 +4578,23 @@ void CGMSHLSLRuntime::FinishCodeGen() {
     }
   }
 
+  if (CGM.getCodeGenOpts().ExportShadersOnly) {
+    for (Function &f : m_pHLModule->GetModule()->functions()) {
+      // Skip declarations, intrinsics, shaders, and non-external linkage
+      if (f.isDeclaration() || f.isIntrinsic() ||
+          GetHLOpcodeGroup(&f) != HLOpcodeGroup::NotHL ||
+          m_pHLModule->HasDxilFunctionProps(&f) ||
+          m_pHLModule->IsPatchConstantShader(&f) ||
+          f.getLinkage() != GlobalValue::LinkageTypes::ExternalLinkage)
+        continue;
+      // Mark non-shader user functions as InternalLinkage
+      f.setLinkage(GlobalValue::LinkageTypes::InternalLinkage);
+    }
+  }
+
   // Disallow resource arguments in (non-entry) function exports
-  if (m_bIsLib) {
+  // unless offline linking target.
+  if (m_bIsLib && m_pHLModule->GetShaderModel()->GetMinor() != ShaderModel::kOfflineMinor) {
     for (Function &f : m_pHLModule->GetModule()->functions()) {
       // Skip llvm intrinsics, non-external linkage, entry/patch constant func, and HL intrinsics
       if (!f.isIntrinsic() &&
@@ -4610,12 +4603,12 @@ void CGMSHLSLRuntime::FinishCodeGen() {
           !m_pHLModule->IsPatchConstantShader(&f) &&
           GetHLOpcodeGroup(&f) == HLOpcodeGroup::NotHL) {
         // Verify no resources in param/return types
-        if (ContainsDisallowedTypeForExport(f.getReturnType())) {
+        if (dxilutil::ContainsHLSLObjectType(f.getReturnType())) {
           ReportDisallowedTypeInExportParam(CGM, f.getName());
           continue;
         }
         for (auto &Arg : f.args()) {
-          if (ContainsDisallowedTypeForExport(Arg.getType())) {
+          if (dxilutil::ContainsHLSLObjectType(Arg.getType())) {
             ReportDisallowedTypeInExportParam(CGM, f.getName());
             break;
           }

+ 110 - 0
tools/clang/test/CodeGenHLSL/quick-test/lib_hs_shaders_only.hlsl

@@ -0,0 +1,110 @@
+// RUN: %dxc -auto-binding-space 13 -T lib_6_3 -export-shaders-only %s | FileCheck %s
+
+// CHECK: class.Buffer
+// CHECK-NOT: unused
+// CHECK-NOT: @"\01?HSPerPatchFunc1@@YA?AUHSPerPatchData@@V?$InputPatch@UPSSceneIn@@$0BA@@@@Z"
+// CHECK: define void @"\01?HSPerPatchFunc2
+// CHECK: define void @HSMain1()
+// CHECK: define void @HSMain2()
+// CHECK: define void @HSMain3()
+// CHECK: define void @"\01?HSPerPatchFunc1@@YA?AUHSPerPatchData@@XZ"
+
+Buffer<float> T_unused;
+
+Buffer<float> GetBuffer_unused() { return T_unused; }
+
+struct PSSceneIn
+{
+  float4 pos  : SV_Position;
+  float2 tex  : TEXCOORD0;
+  float3 norm : NORMAL;
+};
+
+struct HSPerPatchData
+{
+  float edges[3] : SV_TessFactor;
+  float inside   : SV_InsideTessFactor;
+};
+
+struct HSPerPatchDataQuad
+{
+  float edges[4] : SV_TessFactor;
+  float inside[2]   : SV_InsideTessFactor;
+};
+
+// Should not be selected, since later candidate function with same name exists.
+// If selected, it should fail, since patch size mismatches HS function.
+HSPerPatchData HSPerPatchFunc1(
+  const InputPatch< PSSceneIn, 16 > points)
+{
+  HSPerPatchData d;
+
+  d.edges[0] = -5;
+  d.edges[1] = -6;
+  d.edges[2] = -7;
+  d.inside = T_unused.Load(1).x;
+
+  return d;
+}
+
+HSPerPatchDataQuad HSPerPatchFunc2(
+  const InputPatch< PSSceneIn, 4 > points)
+{
+  HSPerPatchDataQuad d;
+
+  d.edges[0] = -5;
+  d.edges[1] = -6;
+  d.edges[2] = -7;
+  d.edges[3] = -7;
+  d.inside[0] = -8;
+  d.inside[1] = -8;
+
+  return d;
+}
+
+
+[shader("hull")]
+[domain("tri")]
+[partitioning("fractional_odd")]
+[outputtopology("triangle_cw")]
+[patchconstantfunc("HSPerPatchFunc1")]
+[outputcontrolpoints(3)]
+void HSMain1( const uint id : SV_OutputControlPointID,
+              const InputPatch< PSSceneIn, 3 > points )
+{
+}
+
+[shader("hull")]
+[domain("quad")]
+[partitioning("fractional_odd")]
+[outputtopology("triangle_cw")]
+[patchconstantfunc("HSPerPatchFunc2")]
+[outputcontrolpoints(4)]
+void HSMain2( const uint id : SV_OutputControlPointID,
+              const InputPatch< PSSceneIn, 4 > points )
+{
+}
+
+[shader("hull")]
+[domain("tri")]
+[partitioning("fractional_odd")]
+[outputtopology("triangle_ccw")]
+[patchconstantfunc("HSPerPatchFunc1")]
+[outputcontrolpoints(3)]
+void HSMain3( const uint id : SV_OutputControlPointID,
+              const InputPatch< PSSceneIn, 3 > points )
+{
+}
+
+// actual selected HSPerPatchFunc1 for HSMain1 and HSMain3
+HSPerPatchData HSPerPatchFunc1()
+{
+  HSPerPatchData d;
+
+  d.edges[0] = -5;
+  d.edges[1] = -6;
+  d.edges[2] = -7;
+  d.inside = -8;
+
+  return d;
+}

+ 38 - 0
tools/clang/test/CodeGenHLSL/quick-test/lib_res_param_x.hlsl

@@ -0,0 +1,38 @@
+// RUN: %dxc -T lib_6_x  %s | FileCheck %s
+
+// resources in return/params allowed for lib_6_x
+// CHECK: alloca %struct.T
+// CHECK: store %struct.RWByteAddressBuffer
+// CHECK: call void @"\01?resStruct@@YA?AUT2@@UT@@V?$vector@I$01@@@Z"(%struct.T2
+// CHECK: %[[ptr:[^, ]]] = getelementptr inbounds %struct.T2
+// CHECK: %[[val:[^, ]]] = load %"class.RWStructuredBuffer<D>", %"class.RWStructuredBuffer<D>"* %[[ptr]]
+// CHECK: call %dx.types.Handle @"dx.op.createHandleForLib.class.RWStructuredBuffer<D>"(i32 160, %"class.RWStructuredBuffer<D>" %[[val]])
+
+
+struct T {
+RWByteAddressBuffer outputBuffer;
+RWByteAddressBuffer outputBuffer2;
+};
+
+struct D {
+  float4 a;
+  int4 b;
+};
+
+struct T2 {
+   RWStructuredBuffer<D> uav;
+};
+
+T2 resStruct(T t, uint2 id);
+
+RWByteAddressBuffer outputBuffer;
+RWByteAddressBuffer outputBuffer2;
+
+[numthreads(8, 8, 1)]
+void main( uint2 id : SV_DispatchThreadID )
+{
+    T t = {outputBuffer,outputBuffer2};
+    T2 t2 = resStruct(t, id);
+    uint counter = t2.uav.IncrementCounter();
+    t2.uav[counter].b.xy = id;
+}

+ 18 - 0
tools/clang/test/CodeGenHLSL/quick-test/lib_select_res_x.hlsl

@@ -0,0 +1,18 @@
+// RUN: %dxc -T lib_6_x -Od -Zi -auto-binding-space 11 %s | FileCheck %s
+
+// lib_6_x allows phi on resource, targeting offline linking only.
+// CHECK: phi %struct.ByteAddressBuffer
+
+RWByteAddressBuffer outputBuffer : register(u0);
+ByteAddressBuffer ReadBuffer : register(t0);
+ByteAddressBuffer ReadBuffer1 : register(t1);
+
+void test( uint cond)
+{
+	ByteAddressBuffer buffer = ReadBuffer;
+        if (cond > 2)
+           buffer = ReadBuffer1;
+
+	uint v= buffer.Load(0);
+    outputBuffer.Store(0, v);
+}

+ 18 - 0
tools/clang/test/CodeGenHLSL/quick-test/lib_select_res_x2.hlsl

@@ -0,0 +1,18 @@
+// RUN: %dxc -T lib_6_x -auto-binding-space 11 %s | FileCheck %s
+
+// lib_6_x allows select on resource, targeting offline linking only.
+// CHECK: select i1 %{{[^, ]+}}, %struct.ByteAddressBuffer
+
+RWByteAddressBuffer outputBuffer : register(u0);
+ByteAddressBuffer ReadBuffer : register(t0);
+ByteAddressBuffer ReadBuffer1 : register(t1);
+
+void test( uint cond)
+{
+	ByteAddressBuffer buffer = ReadBuffer;
+        if (cond > 2)
+           buffer = ReadBuffer1;
+
+	uint v= buffer.Load(0);
+    outputBuffer.Store(0, v);
+}

+ 38 - 0
tools/clang/test/CodeGenHLSL/quick-test/lib_shaders_only.hlsl

@@ -0,0 +1,38 @@
+// RUN: %dxc -auto-binding-space 13 -T lib_6_3 -export-shaders-only %s | FileCheck %s
+
+// CHECK: %struct.Payload
+// CHECK: class.Buffer
+// CHECK-NOT: unused
+// CHECK: define void @"\01?AnyHit
+// CHECK: define void @"\01?Callable
+// CHECK: define void @PSMain()
+
+Buffer<float> T_unused;
+
+Buffer<float> GetBuffer_unused() { return T_unused; }
+float unused_nonshader_export() { return 1.0; }
+float unused_nonshader_export2() { return unused_nonshader_export(); }
+
+
+struct Payload {
+  float f;
+};
+
+[shader("anyhit")]
+void AnyHit(inout Payload p, BuiltInTriangleIntersectionAttributes a) {
+  p.f += a.barycentrics.x;
+  if (p.f > 1.0)
+    AcceptHitAndEndSearch();
+  p.f += a.barycentrics.y;
+}
+
+[shader("callable")]
+void Callable(inout Payload p) {
+  p.f += 0.2;
+}
+
+[shader("pixel")]
+float4 PSMain(float2 coord : TEXCOORD) : SV_Target {
+  return coord.xyxy;
+}
+

+ 28 - 0
tools/clang/test/CodeGenHLSL/quick-test/raytracing_accept_ignore_hit_fail_lib.hlsl

@@ -0,0 +1,28 @@
+// RUN: %dxc -T lib_6_3 -auto-binding-space 11 %s | FileCheck %s
+
+// verify failure for exported library function
+// CHECK: Opcode IgnoreHit not valid in shader model lib_6_3(lib)
+// CHECK: Opcode AcceptHitAndEndSearch not valid in shader model lib_6_3(lib)
+
+
+struct Payload {
+  float foo;
+};
+struct Attr {
+  float2 bary;
+};
+
+void libfunc(inout Payload p, Attr a)  {
+  float4 result = 2.6;
+  if (p.foo < 2) {
+    result.x = 1;             // unused
+    AcceptHitAndEndSearch();  // does not return
+    result.y = 3;             // dead code
+  }
+  if (a.bary.x < 9) {
+    result.x = 2;             // unused
+    IgnoreHit();              // does not return
+    result.y = 4;             // dead code
+  }
+   p.foo = result;
+}

+ 34 - 0
tools/clang/test/CodeGenHLSL/quick-test/res_select2_x.hlsl

@@ -0,0 +1,34 @@
+// RUN: %dxc -T lib_6_x -auto-binding-space 11 %s | FileCheck %s
+
+// lib_6_x does not reduce phi/select of resource or handle in lib.
+// CHECK: phi %"class.RWBuffer
+// CHECK: select i1 %{{[^,]+}}, %"class.
+// CHECK: ret <4 x float>
+
+RWBuffer<float4> BufArray[2][2][3];
+
+float4 test(int i, int j, int m) {
+  RWBuffer<float4> a = BufArray[m][0][0];
+  RWBuffer<float4> b = BufArray[0][m][1];
+  RWBuffer<float4> c = BufArray[0][1][m];
+  RWBuffer<float4> bufarr[2][3] = BufArray[m];
+
+  RWBuffer<float4> buf = c;
+  while (i > 9) {
+     while (j < 4) {
+        if (i < m)
+          buf = b;
+        else
+          bufarr[i%2][j%3] = buf;
+        buf[j] = i;
+        j++;
+     }
+     if (m > j)
+       buf = a;
+     buf[m] = i;
+     i--;
+  }
+  buf[i] = j;
+  bufarr[m%2][j%3][j] = m;
+  return j;
+}

+ 50 - 0
tools/clang/test/CodeGenHLSL/quick-test/res_select3_x.hlsl

@@ -0,0 +1,50 @@
+// RUN: %dxc -T lib_6_x -auto-binding-space 11 %s | FileCheck %s
+
+// lib_6_x allows phi/select of resource in lib.
+// phi/select of handle should not be produced in this case, but would be allowed if it were.
+
+// CHECK: entry:
+// CHECK-NOT: phi %dx.types.Handle
+// CHECK-NOT: select i1 %{{[^,]+}}, %dx.types.Handle
+// CHECK: phi %"class.
+// CHECK-NOT: phi %dx.types.Handle
+// CHECK-NOT: select i1 %{{[^,]+}}, %dx.types.Handle
+// CHECK: select i1 %{{[^,]+}}, %"class.
+// CHECK-NOT: phi %dx.types.Handle
+// CHECK-NOT: select i1 %{{[^,]+}}, %dx.types.Handle
+
+// Make sure get dimensions returns 24
+// CHECK: ret i32 24
+
+struct MyStruct {
+  float2 a;
+  int b;
+  float3 c;
+};
+
+RWStructuredBuffer<MyStruct> BufArray[3];
+
+uint test(int i, int j, int m) {
+  RWStructuredBuffer<MyStruct> a = BufArray[0];
+  RWStructuredBuffer<MyStruct> b = BufArray[1];
+  RWStructuredBuffer<MyStruct> c = BufArray[2];
+
+  RWStructuredBuffer<MyStruct> buf = c;
+  while (i > 9) {
+     while (j < 4) {
+        if (i < m)
+          buf = b;
+        buf[j].b = i;
+        j++;
+     }
+     if (m > j)
+       buf = a;
+     buf[m].b = i;
+     i--;
+  }
+  buf[i].b = j;
+  uint dim = 0;
+  uint stride = 0;
+  buf.GetDimensions(dim, stride);
+  return stride;
+}

+ 48 - 0
tools/clang/test/CodeGenHLSL/quick-test/res_select4_x.hlsl

@@ -0,0 +1,48 @@
+// RUN: %dxc -T lib_6_x -auto-binding-space 11 %s | FileCheck %s
+
+// lib_6_x allows phi/select of resource in lib.
+// phi/select of handle should not be produced in this case, but would be allowed if it were.
+
+// CHECK: entry:
+// CHECK-NOT: phi %dx.types.Handle
+// CHECK-NOT: select i1 %{{[^,]+}}, %dx.types.Handle
+// CHECK: phi %"class.
+// CHECK-NOT: phi %dx.types.Handle
+// CHECK-NOT: select i1 %{{[^,]+}}, %dx.types.Handle
+// CHECK: select i1 %{{[^,]+}}, %"class.
+// CHECK-NOT: phi %dx.types.Handle
+// CHECK-NOT: select i1 %{{[^,]+}}, %dx.types.Handle
+
+// Make sure get dimensions returns 24
+// CHECK: ret i32 24
+
+struct MyStruct {
+  float2 a;
+  int b;
+  float3 c;
+};
+
+RWStructuredBuffer<MyStruct> a;
+RWStructuredBuffer<MyStruct> b;
+RWStructuredBuffer<MyStruct> c;
+
+uint test(int i, int j, int m) {
+  RWStructuredBuffer<MyStruct> buf = c;
+  while (i > 9) {
+     while (j < 4) {
+        if (i < m)
+          buf = b;
+        buf[j].b = i;
+        j++;
+     }
+     if (m > j)
+       buf = a;
+     buf[m].b = i;
+     i--;
+  }
+  buf[i].b = j;
+  uint dim = 0;
+  uint stride = 0;
+  buf.GetDimensions(dim, stride);
+  return stride;
+}

+ 44 - 0
tools/clang/test/CodeGenHLSL/quick-test/res_select5_x.hlsl

@@ -0,0 +1,44 @@
+// RUN: %dxc -T lib_6_x -auto-binding-space 11 %s | FileCheck %s
+
+// lib_6_x allows phi/select of resource in lib.
+// phi/select of handle should not be produced in this case, but would be allowed if it were.
+
+// CHECK: entry:
+// CHECK-NOT: phi %dx.types.Handle
+// CHECK-NOT: select i1 %{{[^,]+}}, %dx.types.Handle
+// CHECK: phi %"class.
+// CHECK-NOT: phi %dx.types.Handle
+// CHECK-NOT: select i1 %{{[^,]+}}, %dx.types.Handle
+// CHECK: select i1 %{{[^,]+}}, %"class.
+// CHECK-NOT: phi %dx.types.Handle
+// CHECK-NOT: select i1 %{{[^,]+}}, %dx.types.Handle
+// CHECK: ret <4 x float>
+
+RWBuffer<float4> BufArray[2][2][3];
+RWBuffer<float4> Buf2;
+
+float4 test(int i, int j, int m) {
+  RWBuffer<float4> a = BufArray[m][0][0];
+  RWBuffer<float4> b = BufArray[0][m][1];
+  RWBuffer<float4> c = BufArray[0][1][m];
+  RWBuffer<float4> bufarr[2][3] = BufArray[m];
+
+  RWBuffer<float4> buf = c;
+  while (i > 9) {
+     while (j < 4) {
+        if (i < m)
+          buf = b;
+        else
+          bufarr[i%2][j%3] = Buf2;  // Illegal: assign different global resource
+        buf[j] = i;
+        j++;
+     }
+     if (m > j)
+       buf = a;
+     buf[m] = i;
+     i--;
+  }
+  buf[i] = j;
+  bufarr[m%2][j%3][j] = m;
+  return j;
+}

+ 8 - 0
tools/clang/tools/dxcompiler/dxcompilerobj.cpp

@@ -400,6 +400,11 @@ public:
       }
       compiler.getLangOpts().IsHLSLLibrary = opts.IsLibraryProfile();
 
+      // Clear entry function if library target
+      if (compiler.getLangOpts().IsHLSLLibrary)
+        compiler.getLangOpts().HLSLEntryFunction =
+          compiler.getCodeGenOpts().HLSLEntryFunction = "";
+
       // NOTE: this calls the validation component from dxil.dll; the built-in
       // validator can be used as a fallback.
       bool produceFullContainer = !opts.CodeGenHighLevel && !opts.AstDump && !opts.OptDump && rootSigMajor == 0;
@@ -900,6 +905,9 @@ public:
 
     // processed export names from -exports option:
     compiler.getCodeGenOpts().HLSLLibraryExports = Opts.Exports;
+
+    // only export shader functions for library
+    compiler.getCodeGenOpts().ExportShadersOnly = Opts.ExportShadersOnly;
   }
 
   // IDxcVersionInfo

+ 2 - 2
tools/clang/unittests/HLSL/DxilContainerTest.cpp

@@ -879,8 +879,8 @@ TEST_F(DxilContainerTest, CompileWhenOkThenCheckRDAT2) {
       "register(u0); Texture2D<float> ThreeTextures[3] : register(t0); "
       "float function1();"
       "[shader(\"raygeneration\")] void RayGenMain() { Uav[0] = "
-      "ThreeTextures[0].Sample(Sampler, float2(0, 0)) + "
-      "ThreeTextures[2].Sample(Sampler, float2(0, 0)) + function1(); }";
+      "ThreeTextures[0].SampleLevel(Sampler, float2(0, 0), 0) + "
+      "ThreeTextures[2].SampleLevel(Sampler, float2(0, 0), 0) + function1(); }";
   CComPtr<IDxcCompiler> pCompiler;
   CComPtr<IDxcBlobEncoding> pSource;
   CComPtr<IDxcBlob> pProgram;

+ 4 - 8
tools/clang/unittests/HLSL/LinkerTest.cpp

@@ -47,13 +47,13 @@ public:
   TEST_METHOD(RunLinkMatArrayParam);
   TEST_METHOD(RunLinkMatParam);
   TEST_METHOD(RunLinkMatParamToLib);
-  //TEST_METHOD(RunLinkResRet);
+  TEST_METHOD(RunLinkResRet);
   TEST_METHOD(RunLinkToLib);
   TEST_METHOD(RunLinkToLibExport);
   TEST_METHOD(RunLinkFailReDefineGlobal);
   TEST_METHOD(RunLinkFailProfileMismatch);
   TEST_METHOD(RunLinkFailEntryNoProps);
-  //TEST_METHOD(RunLinkFailSelectRes);
+  TEST_METHOD(RunLinkFailSelectRes);
   TEST_METHOD(RunLinkToLibWithUnresolvedFunctions);
   TEST_METHOD(RunLinkToLibWithUnresolvedFunctionsExports);
   TEST_METHOD(RunLinkToLibWithExportNamesSwapped);
@@ -85,7 +85,7 @@ public:
     CComPtr<IDxcOperationResult> pResult;
     CComPtr<IDxcBlob> pProgram;
 
-    CA2W shWide("lib_6_1", CP_UTF8);
+    CA2W shWide("lib_6_x", CP_UTF8);
     VERIFY_SUCCEEDED(
         m_dllSupport.CreateInstance(CLSID_DxcCompiler, &pCompiler));
     VERIFY_SUCCEEDED(pCompiler->Compile(pSource, L"hlsl.hlsl", L"", shWide,
@@ -359,7 +359,6 @@ TEST_F(LinkerTest, RunLinkMatParamToLib) {
        {"bitcast <12 x float>* %1 to %class.matrix.float.4.3*"}, {});
 }
 
-#if 0 // unsupported for lib_6_3, but possibly future or offline-only target
 TEST_F(LinkerTest, RunLinkResRet) {
   CComPtr<IDxcBlob> pEntryLib;
   CompileLib(L"..\\CodeGenHLSL\\shader-compat-suite\\lib_out_param_res.hlsl", &pEntryLib);
@@ -377,7 +376,6 @@ TEST_F(LinkerTest, RunLinkResRet) {
 
   Link(L"test", L"ps_6_0", pLinker, {libName, libName2}, {}, {"alloca"});
 }
-#endif
 
 TEST_F(LinkerTest, RunLinkToLib) {
   LPCWSTR option[] = {L"-Zi"};
@@ -424,7 +422,6 @@ TEST_F(LinkerTest, RunLinkToLibExport) {
     {L"-exports", L"renamed_test,cloned_test=\\01?mat_test@@YA?AV?$vector@M$02@@V?$vector@M$03@@0AIAV?$matrix@M$03$02@@@Z;main"});
 }
 
-#if 0 // unsupported for lib_6_3, but possibly future or offline-only target
 TEST_F(LinkerTest, RunLinkFailSelectRes) {
   if (m_ver.SkipDxilVersion(1, 3)) return;
   CComPtr<IDxcBlob> pEntryLib;
@@ -442,9 +439,8 @@ TEST_F(LinkerTest, RunLinkFailSelectRes) {
   RegisterDxcModule(libName2, pLib, pLinker);
 
   LinkCheckMsg(L"main", L"ps_6_0", pLinker, {libName, libName2},
-               {"Local resource must map to global resource"});
+               {"local resource not guaranteed to map to unique global resource"});
 }
-#endif
 
 TEST_F(LinkerTest, RunLinkToLibWithUnresolvedFunctions) {
   LPCWSTR option[] = { L"-Zi" };

+ 402 - 3
tools/clang/unittests/HLSL/ValidationTest.cpp

@@ -324,6 +324,7 @@ public:
   TEST_METHOD(UndefValueFail);
   TEST_METHOD(UpdateCounterFail);
   TEST_METHOD(LocalResCopy);
+  TEST_METHOD(ResCounter);
 
   TEST_METHOD(WhenSmUnknownThenFail);
   TEST_METHOD(WhenSmLegacyThenFail);
@@ -359,12 +360,24 @@ public:
   TEST_METHOD(WhenProgramSigMismatchThenFail2);
   TEST_METHOD(WhenProgramPCSigMissingThenFail);
   TEST_METHOD(WhenPSVMismatchThenFail);
+  TEST_METHOD(WhenRDATMismatchThenFail);
   TEST_METHOD(WhenFeatureInfoMismatchThenFail);
+  TEST_METHOD(RayShaderWithSignaturesFail)
 
   TEST_METHOD(ViewIDInCSFail)
   TEST_METHOD(ViewIDIn60Fail)
   TEST_METHOD(ViewIDNoSpaceFail)
 
+  TEST_METHOD(LibFunctionResInSig)
+  TEST_METHOD(RayPayloadIsStruct)
+  TEST_METHOD(RayAttrIsStruct)
+  TEST_METHOD(CallableParamIsStruct)
+  TEST_METHOD(RayShaderExtraArg)
+  TEST_METHOD(ResInShaderStruct)
+  TEST_METHOD(WhenPayloadSizeTooSmallThenFail)
+  TEST_METHOD(WhenMissingPayloadThenFail)
+  TEST_METHOD(ShaderFunctionReturnTypeVoid)
+
   dxc::DxcDllSupport m_dllSupport;
   VersionSupportInfo m_ver;
 
@@ -415,9 +428,13 @@ public:
 
     CA2W shWide(pShaderModel, CP_UTF8);
 
+    wchar_t *pEntryName = L"main";
+    if (llvm::StringRef(pShaderModel).startswith("lib_"))
+      pEntryName = L"";
+
     VERIFY_SUCCEEDED(
         m_dllSupport.CreateInstance(CLSID_DxcCompiler, &pCompiler));
-    VERIFY_SUCCEEDED(pCompiler->Compile(pSource, L"hlsl.hlsl", L"main", shWide,
+    VERIFY_SUCCEEDED(pCompiler->Compile(pSource, L"hlsl.hlsl", pEntryName, shWide,
                                         pArguments, argCount, pDefines,
                                         defineCount, nullptr, &pResult));
     CheckOperationResultMsgs(pResult, nullptr, false, false);
@@ -3035,6 +3052,19 @@ TEST_F(ValidationTest, WhenPSVMismatchThenFail) {
   );
 }
 
+TEST_F(ValidationTest, WhenRDATMismatchThenFail) {
+  ReplaceContainerPartsCheckMsgs(
+    "float4 main(float f) : semantic { return f; }",
+    "float4 main() : semantic { return 0; }",
+    "lib_6_3",
+    { DFCC_RuntimeData },
+    {
+      "Container part 'Runtime Data (RDAT)' does not match expected for module.",
+      "Validation failed."
+    }
+    );
+}
+
 TEST_F(ValidationTest, WhenFeatureInfoMismatchThenFail) {
   ReplaceContainerPartsCheckMsgs(
     "float4 main(uint2 foo : FOO) : SV_Target { return asdouble(foo.x, foo.y) * 2.0; }",
@@ -3048,6 +3078,51 @@ TEST_F(ValidationTest, WhenFeatureInfoMismatchThenFail) {
   );
 }
 
+TEST_F(ValidationTest, RayShaderWithSignaturesFail) {
+  if (m_ver.SkipDxilVersion(1, 3)) return;
+  RewriteAssemblyCheckMsg(
+    "struct Payload { float f; }; struct Attributes { float2 b; };\n"
+    "struct Param { float f; };\n"
+    "[shader(\"raygeneration\")] void RayGenProto() { return; }\n"
+    "[shader(\"intersection\")] void IntersectionProto() { return; }\n"
+    "[shader(\"anyhit\")] void AnyHitProto(inout Payload p, in Attributes a) { p.f += a.b.x; }\n"
+    "[shader(\"closesthit\")] void ClosestHitProto(inout Payload p, in Attributes a) { p.f += a.b.y; }\n"
+    "[shader(\"miss\")] void MissProto(inout Payload p) { p.f += 1.0; }\n"
+    "[shader(\"callable\")] void CallableProto(inout Param p) { p.f += 1.0; }\n"
+    "[shader(\"vertex\")] float VSOutOnly() : OUTPUT { return 1; }\n"
+    "[shader(\"vertex\")] void VSInOnly(float f : INPUT) : OUTPUT {}\n"
+    "[shader(\"vertex\")] float VSInOut(float f : INPUT) : OUTPUT { return f; }\n"
+    , "lib_6_3",
+    {  "!{void \\(\\)\\* @VSInOnly, !\"VSInOnly\", !([0-9]+), null,(.*)!\\1 = "
+      ,"!{void \\(\\)\\* @VSOutOnly, !\"VSOutOnly\", !([0-9]+), null,(.*)!\\1 = "
+      ,"!{void \\(\\)\\* @VSInOut, !\"VSInOut\", !([0-9]+), null,(.*)!\\1 = "
+      ,"!{void \\(\\)\\* @\"\\\\01\\?RayGenProto@@YAXXZ\", !\"\\\\01\\?RayGenProto@@YAXXZ\", null, null,"
+      ,"!{void \\(\\)\\* @\"\\\\01\\?IntersectionProto@@YAXXZ\", !\"\\\\01\\?IntersectionProto@@YAXXZ\", null, null,"
+      ,"!{void \\(%struct.Payload\\*, %struct.Attributes\\*\\)\\* @\"\\\\01\\?AnyHitProto@@YAXUPayload@@UAttributes@@@Z\", !\"\\\\01\\?AnyHitProto@@YAXUPayload@@UAttributes@@@Z\", null, null,"
+      ,"!{void \\(%struct.Payload\\*, %struct.Attributes\\*\\)\\* @\"\\\\01\\?ClosestHitProto@@YAXUPayload@@UAttributes@@@Z\", !\"\\\\01\\?ClosestHitProto@@YAXUPayload@@UAttributes@@@Z\", null, null,"
+      ,"!{void \\(%struct.Payload\\*\\)\\* @\"\\\\01\\?MissProto@@YAXUPayload@@@Z\", !\"\\\\01\\?MissProto@@YAXUPayload@@@Z\", null, null,"
+      ,"!{void \\(%struct.Param\\*\\)\\* @\"\\\\01\\?CallableProto@@YAXUParam@@@Z\", !\"\\\\01\\?CallableProto@@YAXUParam@@@Z\", null, null,"
+    },
+    {  "!{void ()* @VSInOnly, !\"VSInOnly\", !1001, null,\\2!1001 = "
+      ,"!{void ()* @VSOutOnly, !\"VSOutOnly\", !1002, null,\\2!1002 = "
+      ,"!{void ()* @VSInOut, !\"VSInOut\", !1003, null,\\2!1003 = "
+      ,"!{void ()* @\"\\\\01?RayGenProto@@YAXXZ\", !\"\\\\01?RayGenProto@@YAXXZ\", !1001, null,"
+      ,"!{void ()* @\"\\\\01?IntersectionProto@@YAXXZ\", !\"\\\\01?IntersectionProto@@YAXXZ\", !1002, null,"
+      ,"!{void (%struct.Payload*, %struct.Attributes*)* @\"\\\\01?AnyHitProto@@YAXUPayload@@UAttributes@@@Z\", !\"\\\\01?AnyHitProto@@YAXUPayload@@UAttributes@@@Z\", !1003, null,"
+      ,"!{void (%struct.Payload*, %struct.Attributes*)* @\"\\\\01?ClosestHitProto@@YAXUPayload@@UAttributes@@@Z\", !\"\\\\01?ClosestHitProto@@YAXUPayload@@UAttributes@@@Z\", !1001, null,"
+      ,"!{void (%struct.Payload*)* @\"\\\\01?MissProto@@YAXUPayload@@@Z\", !\"\\\\01?MissProto@@YAXUPayload@@@Z\", !1002, null,"
+      ,"!{void (%struct.Param*)* @\"\\\\01?CallableProto@@YAXUParam@@@Z\", !\"\\\\01?CallableProto@@YAXUParam@@@Z\", !1003, null,"
+    },
+    {  "Ray tracing shader '\\\\01\\?RayGenProto@@YAXXZ' should not have any shader signatures"
+      ,"Ray tracing shader '\\\\01\\?IntersectionProto@@YAXXZ' should not have any shader signatures"
+      ,"Ray tracing shader '\\\\01\\?AnyHitProto@@YAXUPayload@@UAttributes@@@Z' should not have any shader signatures"
+      ,"Ray tracing shader '\\\\01\\?ClosestHitProto@@YAXUPayload@@UAttributes@@@Z' should not have any shader signatures"
+      ,"Ray tracing shader '\\\\01\\?MissProto@@YAXUPayload@@@Z' should not have any shader signatures"
+      ,"Ray tracing shader '\\\\01\\?CallableProto@@YAXUParam@@@Z' should not have any shader signatures"
+    },
+    /*bRegex*/true);
+}
+
 TEST_F(ValidationTest, ViewIDInCSFail) {
   if (m_ver.SkipDxilVersion(1,1)) return;
   RewriteAssemblyCheckMsg(" \
@@ -3208,7 +3283,18 @@ TEST_F(ValidationTest, Float32DenormModeAttribute) {
     { "\"fp32-denorm-mode\"=\"ftz\"" },
     { "\"fp32-denorm-mode\"=\"invalid_mode\"" },
     "contains invalid attribute 'fp32-denorm-mode' with value 'invalid_mode'",
-    true);
+    false);
+}
+
+TEST_F(ValidationTest, ResCounter) {
+    if (m_ver.SkipDxilVersion(1, 3)) return;
+    RewriteAssemblyCheckMsg(
+        "RWStructuredBuffer<float4> buf; float GetCounter() {return buf.IncrementCounter();}",
+        "lib_6_3",
+        { "!\"buf\", i32 0, i32 -1, i32 1, i32 12, i1 false, i1 true, i1 false, !" },
+        { "!\"buf\", i32 0, i32 -1, i32 1, i32 12, i1 false, i1 false, i1 false, !" },
+        "BufferUpdateCounter valid only when HasCounter is true",
+        true);
 }
 
 TEST_F(ValidationTest, FunctionAttributes) {
@@ -3220,5 +3306,318 @@ TEST_F(ValidationTest, FunctionAttributes) {
     { "\"fp32-denorm-mode\"=\"ftz\"" },
     { "\"dummy_attribute\"=\"invalid_mode\"" },
     "contains invalid attribute 'dummy_attribute' with value 'invalid_mode'",
-    true);
+    false);
 }// TODO: reject non-zero padding
+
+TEST_F(ValidationTest, LibFunctionResInSig) {
+  if (m_ver.SkipDxilVersion(1, 3)) return;
+  RewriteAssemblyCheckMsg(
+    "Texture2D<float4> T1;\n"
+    "struct ResInStruct { float f; Texture2D<float4> T; };\n"
+    "struct ResStructInStruct { float f; ResInStruct S; };\n"
+    "ResStructInStruct fnResInReturn(float f) : SV_Target {\n"
+    "  ResStructInStruct S1; S1.f = S1.S.f = f; S1.S.T = T1;\n"
+    "  return S1; }\n"
+    "float fnResInArg(ResStructInStruct S1) : SV_Target {\n"
+    "  return S1.f; }\n"
+    "struct Data { float f; };\n"
+    "float fnStreamInArg(float f, inout PointStream<Data> S1) : SV_Target {\n"
+    "  S1.Append((Data)f); return 1.0; }\n"
+    , "lib_6_x",
+    { "!{!\"lib\", i32 6, i32 15}", "!dx.valver = !{!2}" },
+    { "!{!\"lib\", i32 6, i32 3}", "!dx.valver = !{!1002}\n!1002 = !{i32 1, i32 3}" },
+    {  "Function '\\01?fnResInReturn@@YA?AUResStructInStruct@@M@Z' uses resource in function signature"
+      ,"Function '\\01?fnResInArg@@YAMUResStructInStruct@@@Z' uses resource in function signature"
+      ,"Function '\\01?fnStreamInArg@@YAMMV?$PointStream@UData@@@@@Z' uses resource in function signature"
+      // TODO: Unable to lower stream append, since it's used in a non-GS function.
+      // Should we fail to compile earlier (even on lib_6_x), or add lowering to linker?
+      ,"Function 'dx.hl.op..void (i32, %\"class.PointStream<Data>\"*, float*)' uses resource in function signature"
+    },
+    false);
+}
+
+TEST_F(ValidationTest, RayPayloadIsStruct) {
+  if (m_ver.SkipDxilVersion(1, 3)) return;
+  RewriteAssemblyCheckMsg(
+    "struct Payload { float f; }; struct Attributes { float2 b; };\n"
+    "[shader(\"anyhit\")] void AnyHitProto(inout Payload p, in Attributes a) { p.f += a.b.x; }\n"
+    "void BadAnyHit(inout float f, in Attributes a) { f += a.b.x; }\n"
+    "[shader(\"closesthit\")] void ClosestHitProto(inout Payload p, in Attributes a) { p.f += a.b.y; }\n"
+    "void BadClosestHit(inout float f, in Attributes a) { f += a.b.y; }\n"
+    "[shader(\"miss\")] void MissProto(inout Payload p) { p.f += 1.0; }\n"
+    "void BadMiss(inout float f) { f += 1.0; }\n"
+    , "lib_6_3",
+    { "!{void (%struct.Payload*, %struct.Attributes*)* @\"\\01?AnyHitProto@@YAXUPayload@@UAttributes@@@Z\", "
+        "!\"\\01?AnyHitProto@@YAXUPayload@@UAttributes@@@Z\",",
+      "!{void (%struct.Payload*, %struct.Attributes*)* @\"\\01?ClosestHitProto@@YAXUPayload@@UAttributes@@@Z\", "
+        "!\"\\01?ClosestHitProto@@YAXUPayload@@UAttributes@@@Z\",",
+      "!{void (%struct.Payload*)* @\"\\01?MissProto@@YAXUPayload@@@Z\", "
+        "!\"\\01?MissProto@@YAXUPayload@@@Z\","
+    },
+    { "!{void (float*, %struct.Attributes*)* @\"\\01?BadAnyHit@@YAXAIAMUAttributes@@@Z\", "
+        "!\"\\01?BadAnyHit@@YAXAIAMUAttributes@@@Z\",",
+      "!{void (float*, %struct.Attributes*)* @\"\\01?BadClosestHit@@YAXAIAMUAttributes@@@Z\", "
+        "!\"\\01?BadClosestHit@@YAXAIAMUAttributes@@@Z\",",
+      "!{void (float*)* @\"\\01?BadMiss@@YAXAIAM@Z\", "
+        "!\"\\01?BadMiss@@YAXAIAM@Z\","
+    },
+    {  "Argument 'f' must be a struct type for payload in shader function '\\01?BadAnyHit@@YAXAIAMUAttributes@@@Z'"
+      ,"Argument 'f' must be a struct type for payload in shader function '\\01?BadClosestHit@@YAXAIAMUAttributes@@@Z'"
+      ,"Argument 'f' must be a struct type for payload in shader function '\\01?BadMiss@@YAXAIAM@Z'"
+    },
+    false);
+}
+
+TEST_F(ValidationTest, RayAttrIsStruct) {
+  if (m_ver.SkipDxilVersion(1, 3)) return;
+  RewriteAssemblyCheckMsg(
+    "struct Payload { float f; }; struct Attributes { float2 b; };\n"
+    "[shader(\"anyhit\")] void AnyHitProto(inout Payload p, in Attributes a) { p.f += a.b.x; }\n"
+    "void BadAnyHit(inout Payload p, in float a) { p.f += a; }\n"
+    "[shader(\"closesthit\")] void ClosestHitProto(inout Payload p, in Attributes a) { p.f += a.b.y; }\n"
+    "void BadClosestHit(inout Payload p, in float a) { p.f += a; }\n"
+    , "lib_6_3",
+    { "!{void (%struct.Payload*, %struct.Attributes*)* @\"\\01?AnyHitProto@@YAXUPayload@@UAttributes@@@Z\", "
+        "!\"\\01?AnyHitProto@@YAXUPayload@@UAttributes@@@Z\",",
+      "!{void (%struct.Payload*, %struct.Attributes*)* @\"\\01?ClosestHitProto@@YAXUPayload@@UAttributes@@@Z\", "
+        "!\"\\01?ClosestHitProto@@YAXUPayload@@UAttributes@@@Z\","
+    },
+    { "!{void (%struct.Payload*, float)* @\"\\01?BadAnyHit@@YAXUPayload@@M@Z\", "
+        "!\"\\01?BadAnyHit@@YAXUPayload@@M@Z\",",
+      "!{void (%struct.Payload*, float)* @\"\\01?BadClosestHit@@YAXUPayload@@M@Z\", "
+        "!\"\\01?BadClosestHit@@YAXUPayload@@M@Z\","
+    },
+    {  "Argument 'a' must be a struct type for attributes in shader function '\\01?BadAnyHit@@YAXUPayload@@M@Z'"
+      ,"Argument 'a' must be a struct type for attributes in shader function '\\01?BadClosestHit@@YAXUPayload@@M@Z'"
+    },
+    false);
+}
+
+TEST_F(ValidationTest, CallableParamIsStruct) {
+  if (m_ver.SkipDxilVersion(1, 3)) return;
+  RewriteAssemblyCheckMsg(
+    "struct Param { float f; };\n"
+    "[shader(\"callable\")] void CallableProto(inout Param p) { p.f += 1.0; }\n"
+    "void BadCallable(inout float f) { f += 1.0; }\n"
+    , "lib_6_3",
+    { "!{void (%struct.Param*)* @\"\\01?CallableProto@@YAXUParam@@@Z\", "
+        "!\"\\01?CallableProto@@YAXUParam@@@Z\","
+    },
+    { "!{void (float*)* @\"\\01?BadCallable@@YAXAIAM@Z\", "
+        "!\"\\01?BadCallable@@YAXAIAM@Z\","
+    },
+    {  "Argument 'f' must be a struct type for callable shader function '\\01?BadCallable@@YAXAIAM@Z'"
+    },
+    false);
+}
+
+TEST_F(ValidationTest, RayShaderExtraArg) {
+  if (m_ver.SkipDxilVersion(1, 3)) return;
+  RewriteAssemblyCheckMsg(
+    "struct Payload { float f; }; struct Attributes { float2 b; };\n"
+    "struct Param { float f; };\n"
+    "[shader(\"anyhit\")] void AnyHitProto(inout Payload p, in Attributes a) { p.f += a.b.x; }\n"
+    "[shader(\"closesthit\")] void ClosestHitProto(inout Payload p, in Attributes a) { p.f += a.b.y; }\n"
+    "[shader(\"miss\")] void MissProto(inout Payload p) { p.f += 1.0; }\n"
+    "[shader(\"callable\")] void CallableProto(inout Param p) { p.f += 1.0; }\n"
+    "void BadAnyHit(inout Payload p, in Attributes a, float f) { p.f += f; }\n"
+    "void BadClosestHit(inout Payload p, in Attributes a, float f) { p.f += f; }\n"
+    "void BadMiss(inout Payload p, float f) { p.f += f; }\n"
+    "void BadCallable(inout Param p, float f) { p.f += f; }\n"
+    , "lib_6_3",
+    { "!{void (%struct.Payload*, %struct.Attributes*)* @\"\\01?AnyHitProto@@YAXUPayload@@UAttributes@@@Z\", "
+        "!\"\\01?AnyHitProto@@YAXUPayload@@UAttributes@@@Z\"",
+      "!{void (%struct.Payload*, %struct.Attributes*)* @\"\\01?ClosestHitProto@@YAXUPayload@@UAttributes@@@Z\", "
+        "!\"\\01?ClosestHitProto@@YAXUPayload@@UAttributes@@@Z\"",
+      "!{void (%struct.Payload*)* @\"\\01?MissProto@@YAXUPayload@@@Z\", "
+        "!\"\\01?MissProto@@YAXUPayload@@@Z\"",
+      "!{void (%struct.Param*)* @\"\\01?CallableProto@@YAXUParam@@@Z\", "
+        "!\"\\01?CallableProto@@YAXUParam@@@Z\""
+    },
+    { "!{void (%struct.Payload*, %struct.Attributes*, float)* @\"\\01?BadAnyHit@@YAXUPayload@@UAttributes@@M@Z\", "
+        "!\"\\01?BadAnyHit@@YAXUPayload@@UAttributes@@M@Z\"",
+      "!{void (%struct.Payload*, %struct.Attributes*, float)* @\"\\01?BadClosestHit@@YAXUPayload@@UAttributes@@M@Z\", "
+        "!\"\\01?BadClosestHit@@YAXUPayload@@UAttributes@@M@Z\"",
+      "!{void (%struct.Payload*, float)* @\"\\01?BadMiss@@YAXUPayload@@M@Z\", "
+        "!\"\\01?BadMiss@@YAXUPayload@@M@Z\"",
+      "!{void (%struct.Param*, float)* @\"\\01?BadCallable@@YAXUParam@@M@Z\", "
+        "!\"\\01?BadCallable@@YAXUParam@@M@Z\""
+    },
+    {  "Extra argument 'f' not allowed for shader function '\\01?BadAnyHit@@YAXUPayload@@UAttributes@@M@Z'"
+      ,"Extra argument 'f' not allowed for shader function '\\01?BadClosestHit@@YAXUPayload@@UAttributes@@M@Z'"
+      ,"Extra argument 'f' not allowed for shader function '\\01?BadMiss@@YAXUPayload@@M@Z'"
+      ,"Extra argument 'f' not allowed for shader function '\\01?BadCallable@@YAXUParam@@M@Z'"
+    },
+    false);
+}
+
+TEST_F(ValidationTest, ResInShaderStruct) {
+  if (m_ver.SkipDxilVersion(1, 3)) return;
+  // Verify resource not used in shader argument structure
+  RewriteAssemblyCheckMsg(
+    "struct ResInStruct { float f; Texture2D<float4> T; };\n"
+    "struct ResStructInStruct { float f; ResInStruct S; };\n"
+    "struct Payload { float f; }; struct Attributes { float2 b; };\n"
+    "[shader(\"anyhit\")] void AnyHitProto(inout Payload p, in Attributes a) { p.f += a.b.x; }\n"
+    "void BadAnyHit(inout ResStructInStruct p, in Attributes a) { p.f += a.b.x; }\n"
+    "[shader(\"closesthit\")] void ClosestHitProto(inout Payload p, in Attributes a) { p.f += a.b.y; }\n"
+    "void BadClosestHit(inout ResStructInStruct p, in Attributes a) { p.f += a.b.x; }\n"
+    "[shader(\"miss\")] void MissProto(inout Payload p) { p.f += 1.0; }\n"
+    "void BadMiss(inout ResStructInStruct p) { p.f += 1.0; }\n"
+    "struct Param { float f; };\n"
+    "[shader(\"callable\")] void CallableProto(inout Param p) { p.f += 1.0; }\n"
+    "void BadCallable(inout ResStructInStruct p) { p.f += 1.0; }\n"
+    , "lib_6_x",
+    { "!{!\"lib\", i32 6, i32 15}", "!dx.valver = !{!2}",
+      "!{void (%struct.Payload*, %struct.Attributes*)* @\"\\01?AnyHitProto@@YAXUPayload@@UAttributes@@@Z\", "
+        "!\"\\01?AnyHitProto@@YAXUPayload@@UAttributes@@@Z\",",
+      "!{void (%struct.Payload*, %struct.Attributes*)* @\"\\01?ClosestHitProto@@YAXUPayload@@UAttributes@@@Z\", "
+        "!\"\\01?ClosestHitProto@@YAXUPayload@@UAttributes@@@Z\",",
+      "!{void (%struct.Payload*)* @\"\\01?MissProto@@YAXUPayload@@@Z\", "
+        "!\"\\01?MissProto@@YAXUPayload@@@Z\",",
+      "!{void (%struct.Param*)* @\"\\01?CallableProto@@YAXUParam@@@Z\", "
+        "!\"\\01?CallableProto@@YAXUParam@@@Z\","
+    },
+    { "!{!\"lib\", i32 6, i32 3}", "!dx.valver = !{!1002}\n!1002 = !{i32 1, i32 3}",
+      "!{void (%struct.ResStructInStruct*, %struct.Attributes*)* @\"\\01?BadAnyHit@@YAXUResStructInStruct@@UAttributes@@@Z\", "
+        "!\"\\01?BadAnyHit@@YAXUResStructInStruct@@UAttributes@@@Z\",",
+      "!{void (%struct.ResStructInStruct*, %struct.Attributes*)* @\"\\01?BadClosestHit@@YAXUResStructInStruct@@UAttributes@@@Z\", "
+        "!\"\\01?BadClosestHit@@YAXUResStructInStruct@@UAttributes@@@Z\",",
+      "!{void (%struct.ResStructInStruct*)* @\"\\01?BadMiss@@YAXUResStructInStruct@@@Z\", "
+        "!\"\\01?BadMiss@@YAXUResStructInStruct@@@Z\",",
+      "!{void (%struct.ResStructInStruct*)* @\"\\01?BadCallable@@YAXUResStructInStruct@@@Z\", "
+        "!\"\\01?BadCallable@@YAXUResStructInStruct@@@Z\",",
+    },
+    {  "Function '\\01?BadAnyHit@@YAXUResStructInStruct@@UAttributes@@@Z' uses resource in function signature"
+      ,"Function '\\01?BadClosestHit@@YAXUResStructInStruct@@UAttributes@@@Z' uses resource in function signature"
+      ,"Function '\\01?BadMiss@@YAXUResStructInStruct@@@Z' uses resource in function signature"
+      ,"Function '\\01?BadCallable@@YAXUResStructInStruct@@@Z' uses resource in function signature"
+    },
+    false);
+}
+
+TEST_F(ValidationTest, WhenPayloadSizeTooSmallThenFail) {
+  if (m_ver.SkipDxilVersion(1, 3)) return;
+  RewriteAssemblyCheckMsg(
+    "struct Payload { float f; }; struct Attributes { float2 b; };\n"
+    "struct Param { float f; };\n"
+    "[shader(\"raygeneration\")] void RayGenProto() { return; }\n"
+    "[shader(\"intersection\")] void IntersectionProto() { return; }\n"
+    "[shader(\"anyhit\")] void AnyHitProto(inout Payload p, in Attributes a) { p.f += a.b.x; }\n"
+    "[shader(\"closesthit\")] void ClosestHitProto(inout Payload p, in Attributes a) { p.f += a.b.y; }\n"
+    "[shader(\"miss\")] void MissProto(inout Payload p) { p.f += 1.0; }\n"
+    "[shader(\"callable\")] void CallableProto(inout Param p) { p.f += 1.0; }\n"
+    "\n"
+    "struct BadPayload { float2 f; }; struct BadAttributes { float3 b; };\n"
+    "struct BadParam { float2 f; };\n"
+    "void BadRayGen() { return; }\n"
+    "void BadIntersection() { return; }\n"
+    "void BadAnyHit(inout BadPayload p, in BadAttributes a) { p.f += a.b.x; }\n"
+    "void BadClosestHit(inout BadPayload p, in BadAttributes a) { p.f += a.b.y; }\n"
+    "void BadMiss(inout BadPayload p) { p.f += 1.0; }\n"
+    "void BadCallable(inout BadParam p) { p.f += 1.0; }\n"
+    , "lib_6_3",
+    {  "!{void ()* @\"\\01?RayGenProto@@YAXXZ\", !\"\\01?RayGenProto@@YAXXZ\","
+      ,"!{void ()* @\"\\01?IntersectionProto@@YAXXZ\", !\"\\01?IntersectionProto@@YAXXZ\","
+      ,"!{void (%struct.Payload*, %struct.Attributes*)* @\"\\01?AnyHitProto@@YAXUPayload@@UAttributes@@@Z\", !\"\\01?AnyHitProto@@YAXUPayload@@UAttributes@@@Z\","
+      ,"!{void (%struct.Payload*, %struct.Attributes*)* @\"\\01?ClosestHitProto@@YAXUPayload@@UAttributes@@@Z\", !\"\\01?ClosestHitProto@@YAXUPayload@@UAttributes@@@Z\","
+      ,"!{void (%struct.Payload*)* @\"\\01?MissProto@@YAXUPayload@@@Z\", !\"\\01?MissProto@@YAXUPayload@@@Z\","
+      ,"!{void (%struct.Param*)* @\"\\01?CallableProto@@YAXUParam@@@Z\", !\"\\01?CallableProto@@YAXUParam@@@Z\","
+    },
+    {  "!{void ()* @\"\\01?BadRayGen@@YAXXZ\", !\"\\01?BadRayGen@@YAXXZ\","
+      ,"!{void ()* @\"\\01?BadIntersection@@YAXXZ\", !\"\\01?BadIntersection@@YAXXZ\","
+      ,"!{void (%struct.BadPayload*, %struct.BadAttributes*)* @\"\\01?BadAnyHit@@YAXUBadPayload@@UBadAttributes@@@Z\", !\"\\01?BadAnyHit@@YAXUBadPayload@@UBadAttributes@@@Z\","
+      ,"!{void (%struct.BadPayload*, %struct.BadAttributes*)* @\"\\01?BadClosestHit@@YAXUBadPayload@@UBadAttributes@@@Z\", !\"\\01?BadClosestHit@@YAXUBadPayload@@UBadAttributes@@@Z\","
+      ,"!{void (%struct.BadPayload*)* @\"\\01?BadMiss@@YAXUBadPayload@@@Z\", !\"\\01?BadMiss@@YAXUBadPayload@@@Z\","
+      ,"!{void (%struct.BadParam*)* @\"\\01?BadCallable@@YAXUBadParam@@@Z\", !\"\\01?BadCallable@@YAXUBadParam@@@Z\","
+    },
+    {  "For shader '\\01?BadAnyHit@@YAXUBadPayload@@UBadAttributes@@@Z', payload size is smaller than argument's allocation size"
+      ,"For shader '\\01?BadAnyHit@@YAXUBadPayload@@UBadAttributes@@@Z', attribute size is smaller than argument's allocation size"
+      ,"For shader '\\01?BadClosestHit@@YAXUBadPayload@@UBadAttributes@@@Z', payload size is smaller than argument's allocation size"
+      ,"For shader '\\01?BadClosestHit@@YAXUBadPayload@@UBadAttributes@@@Z', attribute size is smaller than argument's allocation size"
+      ,"For shader '\\01?BadMiss@@YAXUBadPayload@@@Z', payload size is smaller than argument's allocation size"
+      ,"For shader '\\01?BadCallable@@YAXUBadParam@@@Z', params size is smaller than argument's allocation size"
+    },
+    false);
+}
+
+TEST_F(ValidationTest, WhenMissingPayloadThenFail) {
+  if (m_ver.SkipDxilVersion(1, 3)) return;
+  RewriteAssemblyCheckMsg(
+    "struct Payload { float f; }; struct Attributes { float2 b; };\n"
+    "struct Param { float f; };\n"
+    "[shader(\"anyhit\")] void AnyHitProto(inout Payload p, in Attributes a) { p.f += a.b.x; }\n"
+    "[shader(\"closesthit\")] void ClosestHitProto(inout Payload p, in Attributes a) { p.f += a.b.y; }\n"
+    "[shader(\"miss\")] void MissProto(inout Payload p) { p.f += 1.0; }\n"
+    "[shader(\"callable\")] void CallableProto(inout Param p) { p.f += 1.0; }\n"
+    "void BadAnyHit(inout Payload p) { p.f += 1.0; }\n"
+    "void BadClosestHit() {}\n"
+    "void BadMiss() {}\n"
+    "void BadCallable() {}\n"
+    , "lib_6_3",
+    {  "!{void (%struct.Payload*, %struct.Attributes*)* @\"\\01?AnyHitProto@@YAXUPayload@@UAttributes@@@Z\", !\"\\01?AnyHitProto@@YAXUPayload@@UAttributes@@@Z\","
+      ,"!{void (%struct.Payload*, %struct.Attributes*)* @\"\\01?ClosestHitProto@@YAXUPayload@@UAttributes@@@Z\", !\"\\01?ClosestHitProto@@YAXUPayload@@UAttributes@@@Z\","
+      ,"!{void (%struct.Payload*)* @\"\\01?MissProto@@YAXUPayload@@@Z\", !\"\\01?MissProto@@YAXUPayload@@@Z\","
+      ,"!{void (%struct.Param*)* @\"\\01?CallableProto@@YAXUParam@@@Z\", !\"\\01?CallableProto@@YAXUParam@@@Z\","
+    },
+    {  "!{void (%struct.Payload*)* @\"\\01?BadAnyHit@@YAXUPayload@@@Z\", !\"\\01?BadAnyHit@@YAXUPayload@@@Z\","
+      ,"!{void ()* @\"\\01?BadClosestHit@@YAXXZ\", !\"\\01?BadClosestHit@@YAXXZ\","
+      ,"!{void ()* @\"\\01?BadMiss@@YAXXZ\", !\"\\01?BadMiss@@YAXXZ\","
+      ,"!{void ()* @\"\\01?BadCallable@@YAXXZ\", !\"\\01?BadCallable@@YAXXZ\","
+    },
+    {  "anyhit shader '\\01?BadAnyHit@@YAXUPayload@@@Z' missing required attributes parameter"
+      ,"closesthit shader '\\01?BadClosestHit@@YAXXZ' missing required payload parameter"
+      ,"closesthit shader '\\01?BadClosestHit@@YAXXZ' missing required attributes parameter"
+      ,"miss shader '\\01?BadMiss@@YAXXZ' missing required payload parameter"
+      ,"callable shader '\\01?BadCallable@@YAXXZ' missing required params parameter"
+    },
+    false);
+}
+
+TEST_F(ValidationTest, ShaderFunctionReturnTypeVoid) {
+  if (m_ver.SkipDxilVersion(1, 3)) return;
+  // Verify resource not used in shader argument structure
+  RewriteAssemblyCheckMsg(
+    "struct Payload { float f; }; struct Attributes { float2 b; };\n"
+    "struct Param { float f; };\n"
+    "[shader(\"raygeneration\")] void RayGenProto() { return; }\n"
+    "[shader(\"anyhit\")] void AnyHitProto(inout Payload p, in Attributes a) { p.f += a.b.x; }\n"
+    "[shader(\"closesthit\")] void ClosestHitProto(inout Payload p, in Attributes a) { p.f += a.b.y; }\n"
+    "[shader(\"miss\")] void MissProto(inout Payload p) { p.f += 1.0; }\n"
+    "[shader(\"callable\")] void CallableProto(inout Param p) { p.f += 1.0; }\n"
+    "float BadRayGen() { return 1; }\n"
+    "float BadAnyHit(inout Payload p, in Attributes a) { return p.f; }\n"
+    "float BadClosestHit(inout Payload p, in Attributes a) { return p.f; }\n"
+    "float BadMiss(inout Payload p) { return p.f; }\n"
+    "float BadCallable(inout Param p) { return p.f; }\n"
+    , "lib_6_3",
+    { "!{void ()* @\"\\01?RayGenProto@@YAXXZ\", "
+        "!\"\\01?RayGenProto@@YAXXZ\",",
+      "!{void (%struct.Payload*, %struct.Attributes*)* @\"\\01?AnyHitProto@@YAXUPayload@@UAttributes@@@Z\", "
+        "!\"\\01?AnyHitProto@@YAXUPayload@@UAttributes@@@Z\",",
+      "!{void (%struct.Payload*, %struct.Attributes*)* @\"\\01?ClosestHitProto@@YAXUPayload@@UAttributes@@@Z\", "
+        "!\"\\01?ClosestHitProto@@YAXUPayload@@UAttributes@@@Z\",",
+      "!{void (%struct.Payload*)* @\"\\01?MissProto@@YAXUPayload@@@Z\", "
+        "!\"\\01?MissProto@@YAXUPayload@@@Z\",",
+      "!{void (%struct.Param*)* @\"\\01?CallableProto@@YAXUParam@@@Z\", "
+        "!\"\\01?CallableProto@@YAXUParam@@@Z\","
+    },
+    { "!{float ()* @\"\\01?BadRayGen@@YAMXZ\", "
+        "!\"\\01?BadRayGen@@YAMXZ\",",
+      "!{float (%struct.Payload*, %struct.Attributes*)* @\"\\01?BadAnyHit@@YAMUPayload@@UAttributes@@@Z\", "
+        "!\"\\01?BadAnyHit@@YAMUPayload@@UAttributes@@@Z\",",
+      "!{float (%struct.Payload*, %struct.Attributes*)* @\"\\01?BadClosestHit@@YAMUPayload@@UAttributes@@@Z\", "
+        "!\"\\01?BadClosestHit@@YAMUPayload@@UAttributes@@@Z\",",
+      "!{float (%struct.Payload*)* @\"\\01?BadMiss@@YAMUPayload@@@Z\", "
+        "!\"\\01?BadMiss@@YAMUPayload@@@Z\",",
+      "!{float (%struct.Param*)* @\"\\01?BadCallable@@YAMUParam@@@Z\", "
+        "!\"\\01?BadCallable@@YAMUParam@@@Z\","
+    },
+    {  "Shader function '\\01?BadRayGen@@YAMXZ' must have void return type"
+      ,"Shader function '\\01?BadAnyHit@@YAMUPayload@@UAttributes@@@Z' must have void return type"
+      ,"Shader function '\\01?BadClosestHit@@YAMUPayload@@UAttributes@@@Z' must have void return type"
+      ,"Shader function '\\01?BadMiss@@YAMUPayload@@@Z' must have void return type"
+      ,"Shader function '\\01?BadCallable@@YAMUParam@@@Z' must have void return type"
+    },
+    false);
+}

+ 16 - 2
utils/hct/hctdb.py

@@ -356,7 +356,7 @@ class db_dxil(object):
         for i in "IgnoreHit,AcceptHitAndEndSearch".split(","):
             self.name_idx[i].category = "AnyHit Terminals"
             self.name_idx[i].shader_model = 6,3
-            self.name_idx[i].shader_stages = ("library","anyhit")
+            self.name_idx[i].shader_stages = ("anyhit",)
         for i in "CallShader".split(","):
             self.name_idx[i].category = "Indirect Shader Invocation"
             self.name_idx[i].shader_model = 6,3
@@ -1908,6 +1908,9 @@ class db_dxil(object):
         self.add_valrule("Instr.ResourceClassForSamplerGather", "sample, lod and gather should on srv resource.")
         self.add_valrule("Instr.ResourceClassForUAVStore", "store should on uav resource.")
         self.add_valrule("Instr.ResourceClassForLoad", "load can only run on UAV/SRV resource")
+        self.add_valrule("Instr.ResourceMapToSingleEntry", "Fail to map resource to resource table")
+        self.add_valrule("Instr.ResourceUser", "Resource should only used by Load/GEP/Call")
+        self.add_valrule("Instr.ResourceKindForTraceRay", "TraceRay should only use RTAccelerationStructure")
         self.add_valrule("Instr.OffsetOnUAVLoad", "uav load don't support offset")
         self.add_valrule("Instr.MipOnUAVLoad", "uav load don't support mipLevel/sampleIndex")
         self.add_valrule("Instr.SampleIndexForLoad2DMS", "load on Texture2DMS/2DMSArray require sampleIndex")
@@ -1918,6 +1921,7 @@ class db_dxil(object):
         self.add_valrule("Instr.DxilStructUserOutOfBound", "Index out of bound when extract value from dxil struct types")
         self.add_valrule("Instr.HandleNotFromCreateHandle", "Resource handle should returned by createHandle")
         self.add_valrule("Instr.BufferUpdateCounterOnUAV", "BufferUpdateCounter valid only on UAV")
+        self.add_valrule("Instr.BufferUpdateCounterOnResHasCounter", "BufferUpdateCounter valid only when HasCounter is true")
         self.add_valrule("Instr.CBufferOutOfBound", "Cbuffer access out of bound")
         self.add_valrule("Instr.CBufferClassForCBufferHandle", "Expect Cbuffer for CBufferLoad handle")
         self.add_valrule("Instr.FailToResloveTGSMPointer", "TGSM pointers must originate from an unambiguous TGSM global variable.")
@@ -1986,13 +1990,16 @@ class db_dxil(object):
         self.add_valrule_msg("Sm.MultiStreamMustBePoint", "When multiple GS output streams are used they must be pointlists", "Multiple GS output streams are used but '%0' is not pointlist")
         self.add_valrule("Sm.CompletePosition", "Not all elements of SV_Position were written")
         self.add_valrule("Sm.UndefinedOutput", "Not all elements of output %0 were written")
-        self.add_valrule("Sm.CSNoReturn", "Compute shaders can't return values, outputs must be written in writable resources (UAVs).")
+        self.add_valrule("Sm.CSNoSignatures", "Compute shaders must not have shader signatures.")
         self.add_valrule("Sm.CBufferTemplateTypeMustBeStruct", "D3D12 constant/texture buffer template element can only be a struct")
         self.add_valrule_msg("Sm.ResourceRangeOverlap", "Resource ranges must not overlap", "Resource %0 with base %1 size %2 overlap with other resource with base %3 size %4 in space %5")
         self.add_valrule_msg("Sm.CBufferOffsetOverlap", "CBuffer offsets must not overlap", "CBuffer %0 has offset overlaps at %1")
         self.add_valrule_msg("Sm.CBufferElementOverflow", "CBuffer elements must not overflow", "CBuffer %0 size insufficient for element at offset %1")
         self.add_valrule_msg("Sm.OpcodeInInvalidFunction", "Invalid DXIL opcode usage like StorePatchConstant in patch constant function", "opcode '%0' should only be used in '%1'")
         self.add_valrule_msg("Sm.ViewIDNeedsSlot", "ViewID requires compatible space in pixel shader input signature", "Pixel shader input signature lacks available space for ViewID")
+        self.add_valrule("Sm.64bitRawBufferLoadStore", "i64/f64 rawBufferLoad/Store overloads are allowed after SM 6.3")
+        self.add_valrule("Sm.RayShaderSignatures", "Ray tracing shader '%0' should not have any shader signatures")
+        self.add_valrule("Sm.RayShaderPayloadSize", "For shader '%0', %1 size is smaller than argument's allocation size")
 
         # fxc relaxed check of gradient check.
         #self.add_valrule("Uni.NoUniInDiv", "TODO - No instruction requiring uniform execution can be present in divergent block")
@@ -2013,6 +2020,13 @@ class db_dxil(object):
         self.add_valrule_msg("Decl.FnIsCalled", "Functions can only be used by call instructions", "Function '%0' is used for something other than calling")
         self.add_valrule_msg("Decl.FnFlattenParam", "Function parameters must not use struct types", "Type '%0' is a struct type but is used as a parameter in function '%1'")
         self.add_valrule_msg("Decl.FnAttribute", "Functions should only contain known function attributes", "Function '%0' contains invalid attribute '%1' with value '%2'")
+        self.add_valrule_msg("Decl.ResourceInFnSig", "Resources not allowed in function signatures", "Function '%0' uses resource in function signature")
+        self.add_valrule_msg("Decl.PayloadStruct", "Payload parameter must be struct type", "Argument '%0' must be a struct type for payload in shader function '%1'")
+        self.add_valrule_msg("Decl.AttrStruct", "Attributes parameter must be struct type", "Argument '%0' must be a struct type for attributes in shader function '%1'")
+        self.add_valrule_msg("Decl.ParamStruct", "Callable function parameter must be struct type", "Argument '%0' must be a struct type for callable shader function '%1'")
+        self.add_valrule_msg("Decl.ExtraArgs", "Extra arguments not allowed for shader functions", "Extra argument '%0' not allowed for shader function '%1'")
+        self.add_valrule_msg("Decl.ShaderReturnVoid", "Shader functions must return void", "Shader function '%0' must have void return type")
+        self.add_valrule_msg("Decl.ShaderMissingArg", "payload/params/attributes parameter is required for certain shader types", "%0 shader '%1' missing required %2 parameter")
 
         # Assign sensible category names and build up an enumeration description
         cat_names = {

+ 14 - 14
utils/hct/hctdb_instrhelp.py

@@ -983,19 +983,19 @@ def get_min_sm_and_mask_text():
     return code
 
 check_pSM_for_shader_stage = {
-    'vertex': 'pSM->IsVS()',
-    'pixel': 'pSM->IsPS()',
-    'geometry': 'pSM->IsGS()',
-    'compute': 'pSM->IsCS()',
-    'hull': 'pSM->IsHS()',
-    'domain': 'pSM->IsDS()',
-    'library': 'pSM->IsLib()',
-    'raygeneration': 'pSM->GetKind() == DXIL::ShaderKind::RayGeneration',
-    'intersection': 'pSM->GetKind() == DXIL::ShaderKind::Intersection',
-    'anyhit': 'pSM->GetKind() == DXIL::ShaderKind::AnyHit',
-    'closesthit': 'pSM->GetKind() == DXIL::ShaderKind::ClosestHit',
-    'miss': 'pSM->GetKind() == DXIL::ShaderKind::Miss',
-    'callable': 'pSM->GetKind() == DXIL::ShaderKind::Callable',
+    'vertex': 'SK == DXIL::ShaderKind::Vertex',
+    'pixel': 'SK == DXIL::ShaderKind::Pixel',
+    'geometry': 'SK == DXIL::ShaderKind::Geometry',
+    'compute': 'SK == DXIL::ShaderKind::Compute',
+    'hull': 'SK == DXIL::ShaderKind::Hull',
+    'domain': 'SK == DXIL::ShaderKind::Domain',
+    'library': 'SK == DXIL::ShaderKind::Library',
+    'raygeneration': 'SK == DXIL::ShaderKind::RayGeneration',
+    'intersection': 'SK == DXIL::ShaderKind::Intersection',
+    'anyhit': 'SK == DXIL::ShaderKind::AnyHit',
+    'closesthit': 'SK == DXIL::ShaderKind::ClosestHit',
+    'miss': 'SK == DXIL::ShaderKind::Miss',
+    'callable': 'SK == DXIL::ShaderKind::Callable',
 }
 
 def get_valopcode_sm_text():
@@ -1015,7 +1015,7 @@ def get_valopcode_sm_text():
 
         model_cond = stage_cond = None
         if last_model != (6,0):
-            model_cond = "pSM->GetMajor() > %d || (pSM->GetMajor() == %d && pSM->GetMinor() >= %d)" % (
+            model_cond = "major > %d || (major == %d && minor >= %d)" % (
                 last_model[0], last_model[0], last_model[1])
         if last_stage:
             stage_cond = ' || '.join([check_pSM_for_shader_stage[c] for c in last_stage])

Unele fișiere nu au fost afișate deoarece prea multe fișiere au fost modificate în acest diff