瀏覽代碼

Clean more validation TODOs.

Xiang Li 8 年之前
父節點
當前提交
28b3ffe821

+ 7 - 11
docs/DXIL.rst

@@ -2129,12 +2129,13 @@ FLOW.CALLLIMIT                            Subroutines can nest up to 32 levels d
 FLOW.DEADLOOP                             Loop must have break
 FLOW.NORECUSION                           Recursion is not permitted
 FLOW.REDUCIBLE                            Execution flow must be reducible
-INSTR.ALLOWED                             TODO - Instructions must be of an allowed type
+INSTR.ALLOWED                             Instructions must be of an allowed type
 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.COORDINATECOUNTFORRAWTYPEDBUF       raw/typed buffer don't need 2 coordinates
@@ -2144,7 +2145,6 @@ INSTR.DXILSTRUCTUSER                      Dxil struct types should only used by
 INSTR.DXILSTRUCTUSEROUTOFBOUND            Index out of bound when extract value from dxil struct types
 INSTR.ERR_ALIAS_ARRAY_INDEX_OUT_OF_BOUNDS TODO - ERR_ALIAS_ARRAY_INDEX_OUT_OF_BOUNDS
 INSTR.ERR_ATTRIBUTE_PARAM_SIDE_EFFECT     TODO - expressions with side effects are illegal as attribute parameters for root signature
-INSTR.ERR_CANT_PULL_POSITION              TODO - %0 does not support pull-model evaluation of position
 INSTR.ERR_GUARANTEED_RACE_CONDITION_GSM   TODO - race condition writing to shared memory detected, consider making this write conditional.
 INSTR.ERR_GUARANTEED_RACE_CONDITION_UAV   TODO - race condition writing to shared resource detected, consider making this write conditional.
 INSTR.ERR_LOOP_CONDITION_OUT_OF_BOUNDS    TODO - cannot unroll loop with an out-of-bounds array reference in the condition
@@ -2172,10 +2172,9 @@ INSTR.NOUDIVBYZERO                        TODO - No unsigned integer division by
 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.OPCODE                              TODO - DXIL intrinsic must have a valid constant opcode
-INSTR.OPCODERESERVED                      TODO - Instructions must not reference reserved opcodes
+INSTR.OPCODERESERVED                      Instructions must not reference reserved opcodes
 INSTR.OPCODERESTYPE                       TODO - DXIL intrinsic operating on a resource must be of the correct type
-INSTR.OPCONST                             TODO - DXIL intrinsic requires an immediate constant operand
+INSTR.OPCONST                             DXIL intrinsic requires an immediate constant operand
 INSTR.OPCONSTRANGE                        TODO - Constant values must be in-range for operation
 INSTR.OPERANDRANGE                        TODO - DXIL intrinsic operand must be within defined range
 INSTR.PTRAREA                             TODO - Pointer must refer to a defined area
@@ -2220,17 +2219,16 @@ 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.NOREGISTEROVERLAP                    TODO - User-defined variable locations cannot overlap
 META.NOSEMANTICOVERLAP                    Semantics must not overlap
 META.REQUIRED                             TODO - Required metadata missing
 META.SEMAKINDVALID                        Semantic kind must be valid
 META.SEMANTICCOMPTYPE                     %0 must be %1
-META.SEMANTICLEN                          TODO - Semantic length must be at least 1 and at most 64
+META.SEMANTICLEN                          Semantic length must be at least 1 and at most 64
 META.SIGNATURECOMPTYPE                    signature %0 specifies unrecognized or invalid component type
 META.SIGNATUREOUTOFRANGE                  signature %0 is out of range at row %1 col %2 size %3.
 META.SIGNATUREOVERLAP                     signature %0 use overlaped address at row %1 col %2 size %3.
-META.STRUCTBUFALIGNMENT                   TODO - structured buffer element size must be a multiple of %u bytes in %s (actual size %u bytes)
-META.STRUCTBUFALIGNMENTOUTOFBOUND         TODO - structured buffer elements cannot be larger than %u bytes in %s (actual size %u bytes)
+META.STRUCTBUFALIGNMENT                   StructuredBuffer stride not aligned
+META.STRUCTBUFALIGNMENTOUTOFBOUND         StructuredBuffer stride out of bounds
 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.
@@ -2249,7 +2247,6 @@ SM.DOMAINLOCATIONIDXOOB                   DomainLocation component index out of
 SM.DSINPUTCONTROLPOINTCOUNTRANGE          DS input control point count must be [0..%0].  %1 specified
 SM.ERR_BIND_RESOURCE_RANGE_OVERFLOW       TODO - ERR_BIND_RESOURCE_RANGE_OVERFLOW
 SM.ERR_DUPLICATE_CBUFFER_BANK             TODO - ERR_DUPLICATE_CBUFFER_BANK
-SM.ERR_GEN_SEMANTIC_TOO_LONG              TODO - Semantic length is limited to 64 characters
 SM.ERR_MAX_CBUFFER_EXCEEDED               TODO - The maximum number of constant buffer slots is exceeded for a library (slot index=%u, max slots=%u)
 SM.ERR_MAX_CONST_EXCEEDED                 TODO - ERR_MAX_CONST_EXCEEDED
 SM.ERR_MAX_SAMPLER_EXCEEDED               TODO - The maximum number of sampler slots is exceeded for a library (slot index=%u, max slots=%u)
@@ -2294,7 +2291,6 @@ SM.ROVONLYINPS                            RasterizerOrdered objects are only all
 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.STRUCTBUFMUSTBE4BYTESALIGN             Structured buffer stride should 4 byte align
 SM.TESSFACTORFORDOMAIN                    Required TessFactor for domain not found declared anywhere in Patch Constant data
 SM.TESSFACTORSIZEMATCHDOMAIN              TessFactor size mismatch the domain.
 SM.THREADGROUPCHANNELRANGE                Declared Thread Group %0 size %1 outside valid range [%2..%3]

+ 1 - 33
include/dxc/HLSL/DxilConstants.h

@@ -56,6 +56,7 @@ namespace DXIL {
   const unsigned kMaxD3D11SamplerCount = 16;
   const unsigned kMaxD3D11CBufferCount = 14;
   const unsigned kMaxCBufferSize = 4096;
+  const unsigned kMaxStructBufferStride = 2048;
   const unsigned kMaxD3D10UAVCount = 8;
   const unsigned kMaxD3D10CS4UAVCount = 1;
   const unsigned kMaxD3D11UAVCount = 64;
@@ -90,39 +91,6 @@ namespace DXIL {
   const float kMaxMipLodBias = 15.99f;
   const float kMinMipLodBias = -16.0f;
 
-  const unsigned kCS_4_X_BUCKET00_MAX_BYTES_TGSM_WRITABLE_PER_THREAD = 256;
-  const unsigned kCS_4_X_BUCKET00_MAX_NUM_THREADS_PER_GROUP = 64;
-  const unsigned kCS_4_X_BUCKET01_MAX_BYTES_TGSM_WRITABLE_PER_THREAD = 240;
-  const unsigned kCS_4_X_BUCKET01_MAX_NUM_THREADS_PER_GROUP = 68;
-  const unsigned kCS_4_X_BUCKET02_MAX_BYTES_TGSM_WRITABLE_PER_THREAD = 224;
-  const unsigned kCS_4_X_BUCKET02_MAX_NUM_THREADS_PER_GROUP = 72;
-  const unsigned kCS_4_X_BUCKET03_MAX_BYTES_TGSM_WRITABLE_PER_THREAD = 208;
-  const unsigned kCS_4_X_BUCKET03_MAX_NUM_THREADS_PER_GROUP = 76;
-  const unsigned kCS_4_X_BUCKET04_MAX_BYTES_TGSM_WRITABLE_PER_THREAD = 192;
-  const unsigned kCS_4_X_BUCKET04_MAX_NUM_THREADS_PER_GROUP = 84;
-  const unsigned kCS_4_X_BUCKET05_MAX_BYTES_TGSM_WRITABLE_PER_THREAD = 176;
-  const unsigned kCS_4_X_BUCKET05_MAX_NUM_THREADS_PER_GROUP = 92;
-  const unsigned kCS_4_X_BUCKET06_MAX_BYTES_TGSM_WRITABLE_PER_THREAD = 160;
-  const unsigned kCS_4_X_BUCKET06_MAX_NUM_THREADS_PER_GROUP = 100;
-  const unsigned kCS_4_X_BUCKET07_MAX_BYTES_TGSM_WRITABLE_PER_THREAD = 144;
-  const unsigned kCS_4_X_BUCKET07_MAX_NUM_THREADS_PER_GROUP = 112;
-  const unsigned kCS_4_X_BUCKET08_MAX_BYTES_TGSM_WRITABLE_PER_THREAD = 128;
-  const unsigned kCS_4_X_BUCKET08_MAX_NUM_THREADS_PER_GROUP = 128;
-  const unsigned kCS_4_X_BUCKET09_MAX_BYTES_TGSM_WRITABLE_PER_THREAD = 112;
-  const unsigned kCS_4_X_BUCKET09_MAX_NUM_THREADS_PER_GROUP = 144;
-  const unsigned kCS_4_X_BUCKET10_MAX_BYTES_TGSM_WRITABLE_PER_THREAD = 96;
-  const unsigned kCS_4_X_BUCKET10_MAX_NUM_THREADS_PER_GROUP = 168;
-  const unsigned kCS_4_X_BUCKET11_MAX_BYTES_TGSM_WRITABLE_PER_THREAD = 80;
-  const unsigned kCS_4_X_BUCKET11_MAX_NUM_THREADS_PER_GROUP = 204;
-  const unsigned kCS_4_X_BUCKET12_MAX_BYTES_TGSM_WRITABLE_PER_THREAD = 64;
-  const unsigned kCS_4_X_BUCKET12_MAX_NUM_THREADS_PER_GROUP = 256;
-  const unsigned kCS_4_X_BUCKET13_MAX_BYTES_TGSM_WRITABLE_PER_THREAD = 48;
-  const unsigned kCS_4_X_BUCKET13_MAX_NUM_THREADS_PER_GROUP = 340;
-  const unsigned kCS_4_X_BUCKET14_MAX_BYTES_TGSM_WRITABLE_PER_THREAD = 32;
-  const unsigned kCS_4_X_BUCKET14_MAX_NUM_THREADS_PER_GROUP = 512;
-  const unsigned kCS_4_X_BUCKET15_MAX_BYTES_TGSM_WRITABLE_PER_THREAD = 16;
-  const unsigned kCS_4_X_BUCKET15_MAX_NUM_THREADS_PER_GROUP	= 768;
-
   enum class ComponentType : uint8_t { 
     Invalid = 0,
     I1, I16, U16, I32, U32, I64, U64,

+ 7 - 11
include/dxc/HLSL/DxilValidation.h

@@ -36,7 +36,7 @@ enum class ValidationRule : unsigned {
   DeclUsedInternal, // Internal declaration must be used
 
   // Instruction
-  InstrAllowed, // TODO - Instructions must be of an allowed type
+  InstrAllowed, // Instructions must be of an allowed type
   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.
@@ -44,6 +44,7 @@ enum class ValidationRule : unsigned {
   InstrCBufferClassForCBufferHandle, // Expect Cbuffer for CBufferLoad handle
   InstrCBufferOutOfBound, // Cbuffer access out of bound
   InstrCallOload, // Call to DXIL intrinsic must match overload signature
+  InstrCannotPullPosition, // pull-model evaluation of position disallowed
   InstrCoordinateCountForRawTypedBuf, // raw/typed buffer don't need 2 coordinates
   InstrCoordinateCountForStructBuf, // structured buffer require 2 coordinates
   InstrDeterminateDerivative, // gradient operation uses a value that may not be defined for all pixels (in UAV loads can not participate in gradient operations)
@@ -51,7 +52,6 @@ enum class ValidationRule : unsigned {
   InstrDxilStructUserOutOfBound, // Index out of bound when extract value from dxil struct types
   InstrERR_ALIAS_ARRAY_INDEX_OUT_OF_BOUNDS, // TODO - ERR_ALIAS_ARRAY_INDEX_OUT_OF_BOUNDS
   InstrERR_ATTRIBUTE_PARAM_SIDE_EFFECT, // TODO - expressions with side effects are illegal as attribute parameters for root signature
-  InstrERR_CANT_PULL_POSITION, // TODO - %0 does not support pull-model evaluation of position
   InstrERR_GUARANTEED_RACE_CONDITION_GSM, // TODO - race condition writing to shared memory detected, consider making this write conditional.
   InstrERR_GUARANTEED_RACE_CONDITION_UAV, // TODO - race condition writing to shared resource detected, consider making this write conditional.
   InstrERR_LOOP_CONDITION_OUT_OF_BOUNDS, // TODO - cannot unroll loop with an out-of-bounds array reference in the condition
@@ -79,10 +79,9 @@ enum class ValidationRule : unsigned {
   InstrOffsetOnUAVLoad, // uav load don't support offset
   InstrOload, // DXIL intrinsic overload must be valid
   InstrOnlyOneAllocConsume, // RWStructuredBuffers may increment or decrement their counters, but not both.
-  InstrOpCode, // TODO - DXIL intrinsic must have a valid constant opcode
   InstrOpCodeResType, // TODO - DXIL intrinsic operating on a resource must be of the correct type
-  InstrOpCodeReserved, // TODO - Instructions must not reference reserved opcodes
-  InstrOpConst, // TODO - DXIL intrinsic requires an immediate constant operand
+  InstrOpCodeReserved, // Instructions must not reference reserved opcodes
+  InstrOpConst, // DXIL intrinsic requires an immediate constant operand
   InstrOpConstRange, // TODO - Constant values must be in-range for operation
   InstrOperandRange, // TODO - DXIL intrinsic operand must be within defined range
   InstrPtrArea, // TODO - Pointer must refer to a defined area
@@ -129,17 +128,16 @@ enum class ValidationRule : unsigned {
   MetaInvalidControlFlowHint, // Invalid control flow hint
   MetaKnown, // Named metadata should be known
   MetaMaxTessFactor, // Hull Shader MaxTessFactor must be [%0..%1].  %2 specified
-  MetaNoRegisterOverlap, // TODO - User-defined variable locations cannot overlap
   MetaNoSemanticOverlap, // Semantics must not overlap
   MetaRequired, // TODO - Required metadata missing
   MetaSemaKindValid, // Semantic kind must be valid
   MetaSemanticCompType, // %0 must be %1
-  MetaSemanticLen, // TODO - Semantic length must be at least 1 and at most 64
+  MetaSemanticLen, // Semantic length must be at least 1 and at most 64
   MetaSignatureCompType, // signature %0 specifies unrecognized or invalid component type
   MetaSignatureOutOfRange, // signature %0 is out of range at row %1 col %2 size %3.
   MetaSignatureOverlap, // signature %0 use overlaped address at row %1 col %2 size %3.
-  MetaStructBufAlignment, // TODO - structured buffer element size must be a multiple of %u bytes in %s (actual size %u bytes)
-  MetaStructBufAlignmentOutOfBound, // TODO - structured buffer elements cannot be larger than %u bytes in %s (actual size %u bytes)
+  MetaStructBufAlignment, // StructuredBuffer stride not aligned
+  MetaStructBufAlignmentOutOfBound, // StructuredBuffer stride out of bounds
   MetaTarget, // Target triple must be 'dxil-ms-dx'
   MetaTessellatorOutputPrimitive, // Invalid Tessellator Output Primitive specified. Must be point, line, triangleCW or triangleCCW.
   MetaTessellatorPartition, // Invalid Tessellator Partitioning specified. Must be integer, pow2, fractional_odd or fractional_even.
@@ -167,7 +165,6 @@ enum class ValidationRule : unsigned {
   SmDomainLocationIdxOOB, // DomainLocation component index out of bounds for the domain.
   SmERR_BIND_RESOURCE_RANGE_OVERFLOW, // TODO - ERR_BIND_RESOURCE_RANGE_OVERFLOW
   SmERR_DUPLICATE_CBUFFER_BANK, // TODO - ERR_DUPLICATE_CBUFFER_BANK
-  SmERR_GEN_SEMANTIC_TOO_LONG, // TODO - Semantic length is limited to 64 characters
   SmERR_MAX_CBUFFER_EXCEEDED, // TODO - The maximum number of constant buffer slots is exceeded for a library (slot index=%u, max slots=%u)
   SmERR_MAX_CONST_EXCEEDED, // TODO - ERR_MAX_CONST_EXCEEDED
   SmERR_MAX_SAMPLER_EXCEEDED, // TODO - The maximum number of sampler slots is exceeded for a library (slot index=%u, max slots=%u)
@@ -212,7 +209,6 @@ enum class ValidationRule : unsigned {
   SmSampleCountOnlyOn2DMS, // Only Texture2DMS/2DMSArray could has sample count
   SmSemantic, // Semantic must be defined in target shader model
   SmStreamIndexRange, // Stream index (%0) must between 0 and %1
-  SmStructBufMustBe4BytesAlign, // Structured buffer stride should 4 byte align
   SmTessFactorForDomain, // Required TessFactor for domain not found declared anywhere in Patch Constant data
   SmTessFactorSizeMatchDomain, // TessFactor size mismatch the domain.
   SmThreadGroupChannelRange, // Declared Thread Group %0 size %1 outside valid range [%2..%3]

+ 42 - 14
lib/HLSL/DxilValidation.cpp

@@ -55,11 +55,10 @@ const char *hlsl::GetValidationRuleText(ValidationRule value) {
     case hlsl::ValidationRule::MetaUsed: return "TODO - All metadata must be used";
     case hlsl::ValidationRule::MetaTarget: return "Unknown target triple '%0'";
     case hlsl::ValidationRule::MetaWellFormed: return "TODO - Metadata must be well-formed in operand count and types";
-    case hlsl::ValidationRule::MetaSemanticLen: return "TODO - Semantic length must be at least 1 and at most 64";
+    case hlsl::ValidationRule::MetaSemanticLen: return "Semantic length must be at least 1 and at most 64";
     case hlsl::ValidationRule::MetaInterpModeValid: return "Invalid interpolation mode for '%0'";
     case hlsl::ValidationRule::MetaSemaKindValid: return "Semantic kind for '%0' is invalid";
     case hlsl::ValidationRule::MetaNoSemanticOverlap: return "Semantic '%0' overlap at %1";
-    case hlsl::ValidationRule::MetaNoRegisterOverlap: return "TODO - User-defined variable locations cannot overlap";
     case hlsl::ValidationRule::MetaValueRange: return "Metadata value must be within range";
     case hlsl::ValidationRule::MetaFlagsUsage: return "Flags must match usage";
     case hlsl::ValidationRule::MetaDenseResIDs: return "Resource identifiers must be zero-based and dense";
@@ -75,21 +74,20 @@ const char *hlsl::GetValidationRuleText(ValidationRule value) {
     case hlsl::ValidationRule::MetaValidSamplerMode: return "Invalid sampler mode on sampler ";
     case hlsl::ValidationRule::MetaFunctionAnnotation: return "Cannot find function annotation for %0";
     case hlsl::ValidationRule::MetaGlcNotOnAppendConsume: return "globallycoherent cannot be used with append/consume buffers";
-    case hlsl::ValidationRule::MetaStructBufAlignment: return "TODO - structured buffer element size must be a multiple of %u bytes in %s (actual size %u bytes)";
-    case hlsl::ValidationRule::MetaStructBufAlignmentOutOfBound: return "TODO - structured buffer elements cannot be larger than %u bytes in %s (actual size %u bytes)";
+    case hlsl::ValidationRule::MetaStructBufAlignment: return "structured buffer element size must be a multiple of %0 bytes (actual size %1 bytes)";
+    case hlsl::ValidationRule::MetaStructBufAlignmentOutOfBound: return "structured buffer elements cannot be larger than %0 bytes (actual size %1 bytes)";
     case hlsl::ValidationRule::MetaEntryFunction: return "entrypoint not found";
     case hlsl::ValidationRule::MetaInvalidControlFlowHint: return "Invalid control flow hint";
     case hlsl::ValidationRule::MetaBranchFlatten: return "Can't use branch and flatten attributes together";
     case hlsl::ValidationRule::MetaForceCaseOnSwitch: return "Attribute forcecase only works for switch";
-    case hlsl::ValidationRule::InstrOpCode: return "TODO - DXIL intrinsic must have a valid constant opcode";
     case hlsl::ValidationRule::InstrOload: return "DXIL intrinsic overload must be valid";
     case hlsl::ValidationRule::InstrCallOload: return "Call to DXIL intrinsic '%0' does not match an allowed overload signature";
     case hlsl::ValidationRule::InstrResID: return "TODO - DXIL instruction must refer to valid resource IDs";
     case hlsl::ValidationRule::InstrTypeCast: return "TODO - Type cast must be valid";
     case hlsl::ValidationRule::InstrPtrArea: return "TODO - Pointer must refer to a defined area";
     case hlsl::ValidationRule::InstrOpConst: return "%0 of %1 must be an immediate constant";
-    case hlsl::ValidationRule::InstrAllowed: return "TODO - Instructions must be of an allowed type";
-    case hlsl::ValidationRule::InstrOpCodeReserved: return "TODO - Instructions must not reference reserved opcodes";
+    case hlsl::ValidationRule::InstrAllowed: return "Instructions must be of an allowed type";
+    case hlsl::ValidationRule::InstrOpCodeReserved: return "Instructions must not reference reserved opcodes";
     case hlsl::ValidationRule::InstrTextureOpArgs: return "TODO - Instructions that depend on texture type must match operands";
     case hlsl::ValidationRule::InstrTextureLod: return "TODO - Level-of-detail is only defined for Texture1D, Texture2D, Texture3D and TextureCube";
     case hlsl::ValidationRule::InstrOpCodeResType: return "TODO - DXIL intrinsic operating on a resource must be of the correct type";
@@ -114,7 +112,7 @@ const char *hlsl::GetValidationRuleText(ValidationRule value) {
     case hlsl::ValidationRule::InstrDeterminateDerivative: return "gradient operation uses a value that may not be defined for all pixels (in UAV loads can not participate in gradient operations)";
     case hlsl::ValidationRule::InstrERR_NON_LITERAL_RESOURCE: return "TODO - Resources being indexed cannot come from conditional expressions, they must come from literal expressions.";
     case hlsl::ValidationRule::InstrERR_NON_LITERAL_STREAM: return "TODO - stream parameter must come from a literal expression";
-    case hlsl::ValidationRule::InstrERR_CANT_PULL_POSITION: return "TODO - %0 does not support pull-model evaluation of position";
+    case hlsl::ValidationRule::InstrCannotPullPosition: return "%0 does not support pull-model evaluation of position";
     case hlsl::ValidationRule::InstrERR_LOOP_CONDITION_OUT_OF_BOUNDS: return "TODO - cannot unroll loop with an out-of-bounds array reference in the condition";
     case hlsl::ValidationRule::InstrERR_ATTRIBUTE_PARAM_SIDE_EFFECT: return "TODO - expressions with side effects are illegal as attribute parameters for root signature";
     case hlsl::ValidationRule::InstrERR_RESOURCE_UNINITIALIZED: return "TODO - Resource being indexed is uninitialized.";
@@ -205,7 +203,6 @@ const char *hlsl::GetValidationRuleText(ValidationRule value) {
     case hlsl::ValidationRule::SmInvalidResourceCompType: return "Invalid resource return type";
     case hlsl::ValidationRule::SmSampleCountOnlyOn2DMS: return "Only Texture2DMS/2DMSArray could has sample count";
     case hlsl::ValidationRule::SmCounterOnlyOnStructBuf: return "BufferUpdateCounter valid only on structured buffers";
-    case hlsl::ValidationRule::SmStructBufMustBe4BytesAlign: return "Structured buffer stride should 4 byte align";
     case hlsl::ValidationRule::SmGSTotalOutputVertexDataRange: return "TODO: 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";
     case hlsl::ValidationRule::SmMultiStreamMustBePoint: return "Multiple GS output streams are used but '%0' is not pointlist";
     case hlsl::ValidationRule::SmCompletePosition: return "Not all elements of SV_Position were written";
@@ -216,7 +213,6 @@ const char *hlsl::GetValidationRuleText(ValidationRule value) {
     case hlsl::ValidationRule::SmERR_MAX_SAMPLER_EXCEEDED: return "TODO - The maximum number of sampler slots is exceeded for a library (slot index=%u, max slots=%u)";
     case hlsl::ValidationRule::SmERR_MAX_TEXTURE_EXCEEDED: return "TODO - The maximum number of texture slots is exceeded for a library (slot index=%u, max slots=%u)";
     case hlsl::ValidationRule::SmERR_MAX_CBUFFER_EXCEEDED: return "TODO - The maximum number of constant buffer slots is exceeded for a library (slot index=%u, max slots=%u)";
-    case hlsl::ValidationRule::SmERR_GEN_SEMANTIC_TOO_LONG: return "TODO - Semantic length is limited to 64 characters";
     case hlsl::ValidationRule::SmERR_DUPLICATE_CBUFFER_BANK: return "TODO - ERR_DUPLICATE_CBUFFER_BANK";
     case hlsl::ValidationRule::SmERR_UNABLE_TO_BIND_RESOURCE: return "TODO - ERR_UNABLE_TO_BIND_RESOURCE";
     case hlsl::ValidationRule::SmERR_UNABLE_TO_BIND_UNBOUNDED_RESOURCE: return "TODO - ERR_UNABLE_TO_BIND_UNBOUNDED_RESOURCE";
@@ -339,7 +335,10 @@ struct ValidationContext {
       if (pArg == nullptr)
         pArg = "<null>";
 
-      unsigned offset = ruleText.find(argIdx);
+      std::string::size_type offset = ruleText.find(argIdx);
+      if (offset == std::string::npos)
+        continue;
+
       unsigned size = argIdx.size();
       ruleText.replace(offset, size, args[i]);
     }
@@ -366,6 +365,17 @@ struct ValidationContext {
     Failed = true;
   }
 
+  void EmitResourceFormatError(const hlsl::DxilResourceBase *Res,
+                               ValidationRule rule,
+                               ArrayRef<const char *> args) {
+    std::string ruleText = GetValidationRuleText(rule);
+    FormatRuleText(ruleText, args);
+    DiagPrinter << ruleText;
+    DiagPrinter << '\'' << Res->GetGlobalName() << '\'';
+    DiagPrinter << '\n';
+    Failed = true;
+  }
+
   bool IsDebugFunctionCall(Instruction *I) {
     CallInst *CI = dyn_cast<CallInst>(I);
     return CI && CI->getCalledFunction()->getName().startswith("llvm.dbg.");
@@ -1171,6 +1181,11 @@ static void ValidateDxilOperationCallInProfile(CallInst *CI,
             CI, ValidationRule::InstrEvalInterpolationMode, {pSE->GetName()});
         break;
       }
+      if (pSE->GetSemantic()->GetKind() == DXIL::SemanticKind::Position) {
+        ValCtx.EmitInstrFormatError(
+            CI, ValidationRule::InstrCannotPullPosition,
+            {ValCtx.DxilMod.GetShaderModel()->GetName()});
+      }
     }
   } break;
   case DXIL::OpCode::GetDimensions: {
@@ -2394,10 +2409,18 @@ static void ValidateResource(hlsl::DxilResource &res,
   }
 
   if (res.IsStructuredBuffer()) {
-    bool alignedTo4Bytes = (res.GetElementStride() & 3) == 0;
+    unsigned stride = res.GetElementStride();
+    bool alignedTo4Bytes = (stride & 3) == 0;
     if (!alignedTo4Bytes) {
-      ValCtx.EmitResourceError(&res,
-                               ValidationRule::SmStructBufMustBe4BytesAlign);
+      ValCtx.EmitResourceFormatError(
+          &res, ValidationRule::MetaStructBufAlignment,
+          {std::to_string(4).c_str(), std::to_string(stride).c_str()});
+    }
+    if (stride > DXIL::kMaxStructBufferStride) {
+      ValCtx.EmitResourceFormatError(
+          &res, ValidationRule::MetaStructBufAlignmentOutOfBound,
+          {std::to_string(DXIL::kMaxStructBufferStride).c_str(),
+           std::to_string(stride).c_str()});
     }
   }
 }
@@ -2596,6 +2619,11 @@ static void ValidateSignatureElement(DxilSignatureElement &SE,
   CompType::Kind compKind = SE.GetCompType().GetKind();
   DXIL::InterpolationMode Mode = SE.GetInterpolationMode()->GetKind();
 
+  StringRef Name = SE.GetName();
+  if (Name.size() < 1 || Name.size() > 64) {
+    ValCtx.EmitSignatureError(&SE, ValidationRule::MetaSemanticLen);
+  }
+
   switch (compKind) {
   case CompType::Kind::U64:
   case CompType::Kind::I64:

+ 10 - 0
tools/clang/test/CodeGenHLSL/evalPos.hlsl

@@ -0,0 +1,10 @@
+// RUN: %dxc -E main -T ps_5_0 %s | FileCheck %s
+
+// CHECK: ps_5_0 does not support pull-model evaluation of position
+
+float4 main(float4 a : SV_POSITION) : SV_Target
+{
+  float4 r = EvaluateAttributeCentroid(a.yxzw);
+
+  return r;
+}

+ 1 - 0
tools/clang/test/CodeGenHLSL/struct_buf1.hlsl

@@ -31,5 +31,6 @@ float4 main(float idx1 : Idx1, float idx2 : Idx2) : SV_Target
   buf2[idx1*3].a = r.xy;
   buf2[idx1*3].b = r.xyz;
   buf2[idx1*3].c[idx2] = r.yw;
+  buf2[0].a = buf1.Load(1).b.xy;
   return r;
 }

+ 0 - 198
tools/clang/test/HLSL/dxil_validation/struct_buf1.ll

@@ -1,198 +0,0 @@
-; RUN: %dxv %s | FileCheck %s
-
-; CHECK: globallycoherent cannot be used with append/consume buffers'buf2'
-; CHECK:Structured buffer stride should 4 byte align'buf2'
-; CHECK:Structured buffer stride should 4 byte align'buf1'
-; CHECK: structured buffer require 2 coordinates
-
-
-
-
-target datalayout = "e-m:e-p:32:32-i64:64-f80:32-n8:16:32-a:0:32-S32"
-target triple = "dxil-ms-dx"
-
-%class.StructuredBuffer = type { %struct.Foo }
-%struct.Foo = type { <2 x float>, <3 x float>, [4 x <2 x i32>] }
-%class.RWStructuredBuffer = type { %struct.Foo }
-%dx.types.Handle = type { i8* }
-%dx.types.ResRet.f32 = type { float, float, float, float, i32 }
-%dx.types.ResRet.i32 = type { i32, i32, i32, i32, i32 }
-
-@"\01?buf1@@3V?$StructuredBuffer@UFoo@@@@A" = available_externally global %class.StructuredBuffer zeroinitializer, align 4
-@"\01?buf2@@3V?$RWStructuredBuffer@UFoo@@@@A" = available_externally global %class.RWStructuredBuffer zeroinitializer, align 4
[email protected] = external addrspace(1) constant %class.StructuredBuffer
[email protected] = external addrspace(1) constant %struct.Foo
[email protected] = external addrspace(1) constant %class.RWStructuredBuffer
[email protected] = appending global [5 x i8*] [i8* bitcast (%class.RWStructuredBuffer* @"\01?buf2@@3V?$RWStructuredBuffer@UFoo@@@@A" to i8*), i8* addrspacecast (i8 addrspace(1)* bitcast (%class.StructuredBuffer addrspace(1)* @dx.typevar.0 to i8 addrspace(1)*) to i8*), i8* addrspacecast (i8 addrspace(1)* bitcast (%struct.Foo addrspace(1)* @dx.typevar.1 to i8 addrspace(1)*) to i8*), i8* addrspacecast (i8 addrspace(1)* bitcast (%class.RWStructuredBuffer addrspace(1)* @dx.typevar.2 to i8 addrspace(1)*) to i8*), i8* bitcast (%class.StructuredBuffer* @"\01?buf1@@3V?$StructuredBuffer@UFoo@@@@A" to i8*)], section "llvm.metadata"
-
-; Function Attrs: nounwind
-define void @main.flat(float, float, <4 x float>* nocapture readnone) #0 {
-entry:
-  %buf2_UAV_structbuf = tail call %dx.types.Handle @dx.op.createHandle(i32 58, i8 1, i32 0, i32 0, i1 false)
-  %buf1_texture_structbuf = tail call %dx.types.Handle @dx.op.createHandle(i32 58, i8 0, i32 0, i32 0, i1 false)
-  %3 = tail call float @dx.op.loadInput.f32(i32 4, i32 1, i32 0, i8 0, i32 undef)
-  %4 = tail call float @dx.op.loadInput.f32(i32 4, i32 0, i32 0, i8 0, i32 undef)
-  %conv = fptosi float %4 to i32
-  %BufferLoad = tail call %dx.types.ResRet.f32 @dx.op.bufferLoad.f32(i32 69, %dx.types.Handle %buf1_texture_structbuf, i32 %conv, i32 0)
-  %5 = extractvalue %dx.types.ResRet.f32 %BufferLoad, 0
-  %6 = extractvalue %dx.types.ResRet.f32 %BufferLoad, 1
-  %BufferLoad1 = tail call %dx.types.ResRet.f32 @dx.op.bufferLoad.f32(i32 69, %dx.types.Handle %buf1_texture_structbuf, i32 %conv, i32 undef)
-  %7 = extractvalue %dx.types.ResRet.f32 %BufferLoad1, 0
-  %8 = extractvalue %dx.types.ResRet.f32 %BufferLoad1, 1
-  %9 = extractvalue %dx.types.ResRet.f32 %BufferLoad1, 2
-  %add3.i0 = fadd fast float %7, %5
-  %add3.i1 = fadd fast float %8, %6
-  %conv4 = fptoui float %3 to i32
-  %10 = shl i32 %conv4, 3
-  %11 = add i32 %10, 20
-  %BufferLoad2 = tail call %dx.types.ResRet.i32 @dx.op.bufferLoad.i32(i32 69, %dx.types.Handle %buf1_texture_structbuf, i32 %conv, i32 %11)
-  %12 = extractvalue %dx.types.ResRet.i32 %BufferLoad2, 0
-  %13 = extractvalue %dx.types.ResRet.i32 %BufferLoad2, 1
-  %conv7.i0 = sitofp i32 %12 to float
-  %conv7.i1 = sitofp i32 %13 to float
-  %add8.i1 = fadd fast float %add3.i1, %conv7.i1
-  %conv9 = fptosi float %3 to i32
-  %BufferLoad3 = tail call %dx.types.ResRet.f32 @dx.op.bufferLoad.f32(i32 69, %dx.types.Handle %buf1_texture_structbuf, i32 %conv9, i32 0)
-  %14 = extractvalue %dx.types.ResRet.f32 %BufferLoad3, 0
-  %15 = extractvalue %dx.types.ResRet.f32 %BufferLoad3, 1
-  %add12.i0 = fadd fast float %add3.i0, %14
-  %add12.i1 = fadd fast float %add8.i1, %15
-  %BufferLoad4 = tail call %dx.types.ResRet.f32 @dx.op.bufferLoad.f32(i32 69, %dx.types.Handle %buf1_texture_structbuf, i32 %conv9, i32 8)
-  %16 = extractvalue %dx.types.ResRet.f32 %BufferLoad4, 0
-  %17 = extractvalue %dx.types.ResRet.f32 %BufferLoad4, 1
-  %18 = extractvalue %dx.types.ResRet.f32 %BufferLoad4, 2
-  %add18.i0 = fadd fast float %add12.i0, %16
-  %add18.i1 = fadd fast float %add12.i1, %17
-  %add18.i2 = fadd fast float %18, %9
-  %BufferLoad5 = tail call %dx.types.ResRet.i32 @dx.op.bufferLoad.i32(i32 69, %dx.types.Handle %buf1_texture_structbuf, i32 %conv9, i32 %11)
-  %19 = extractvalue %dx.types.ResRet.i32 %BufferLoad5, 0
-  %20 = extractvalue %dx.types.ResRet.i32 %BufferLoad5, 1
-  %conv28.i0 = sitofp i32 %19 to float
-  %conv28.i1 = sitofp i32 %20 to float
-  %add29.i0 = fadd fast float %conv28.i0, %conv7.i0
-  %add29.i1 = fadd fast float %add18.i1, %conv28.i1
-  %add34 = fadd fast float %4, 2.000000e+02
-  %conv35 = fptosi float %add34 to i32
-  %BufferLoad6 = tail call %dx.types.ResRet.f32 @dx.op.bufferLoad.f32(i32 69, %dx.types.Handle %buf2_UAV_structbuf, i32 %conv35, i32 0)
-  %21 = extractvalue %dx.types.ResRet.f32 %BufferLoad6, 0
-  %22 = extractvalue %dx.types.ResRet.f32 %BufferLoad6, 1
-  %add38.i0 = fadd fast float %add18.i0, %21
-  %add38.i1 = fadd fast float %add29.i1, %22
-  %BufferLoad7 = tail call %dx.types.ResRet.f32 @dx.op.bufferLoad.f32(i32 69, %dx.types.Handle %buf2_UAV_structbuf, i32 %conv35, i32 8)
-  %23 = extractvalue %dx.types.ResRet.f32 %BufferLoad7, 0
-  %24 = extractvalue %dx.types.ResRet.f32 %BufferLoad7, 1
-  %25 = extractvalue %dx.types.ResRet.f32 %BufferLoad7, 2
-  %add43.i0 = fadd fast float %add38.i0, %23
-  %add43.i1 = fadd fast float %add38.i1, %24
-  %add43.i2 = fadd fast float %add18.i2, %25
-  %BufferLoad8 = tail call %dx.types.ResRet.i32 @dx.op.bufferLoad.i32(i32 69, %dx.types.Handle %buf2_UAV_structbuf, i32 %conv35, i32 %11)
-  %26 = extractvalue %dx.types.ResRet.i32 %BufferLoad8, 0
-  %27 = extractvalue %dx.types.ResRet.i32 %BufferLoad8, 1
-  %conv50.i0 = sitofp i32 %26 to float
-  %conv50.i1 = sitofp i32 %27 to float
-  %add51.i0 = fadd fast float %add29.i0, %conv50.i0
-  %add51.i1 = fadd fast float %add43.i1, %conv50.i1
-  %add52 = fadd fast float %3, 2.000000e+02
-  %conv53 = fptosi float %add52 to i32
-  %BufferLoad9 = tail call %dx.types.ResRet.f32 @dx.op.bufferLoad.f32(i32 69, %dx.types.Handle %buf2_UAV_structbuf, i32 %conv53, i32 0)
-  %28 = extractvalue %dx.types.ResRet.f32 %BufferLoad9, 0
-  %29 = extractvalue %dx.types.ResRet.f32 %BufferLoad9, 1
-  %add56.i0 = fadd fast float %add43.i0, %28
-  %add56.i1 = fadd fast float %add51.i1, %29
-  %BufferLoad10 = tail call %dx.types.ResRet.f32 @dx.op.bufferLoad.f32(i32 69, %dx.types.Handle %buf2_UAV_structbuf, i32 %conv53, i32 8)
-  %30 = extractvalue %dx.types.ResRet.f32 %BufferLoad10, 0
-  %31 = extractvalue %dx.types.ResRet.f32 %BufferLoad10, 1
-  %32 = extractvalue %dx.types.ResRet.f32 %BufferLoad10, 2
-  %add65.i0 = fadd fast float %add56.i0, %30
-  %add65.i1 = fadd fast float %add56.i1, %31
-  %add65.i2 = fadd fast float %add43.i2, %32
-  %BufferLoad11 = tail call %dx.types.ResRet.i32 @dx.op.bufferLoad.i32(i32 69, %dx.types.Handle %buf2_UAV_structbuf, i32 %conv53, i32 %11)
-  %33 = extractvalue %dx.types.ResRet.i32 %BufferLoad11, 0
-  %34 = extractvalue %dx.types.ResRet.i32 %BufferLoad11, 1
-  %conv76.i0 = sitofp i32 %33 to float
-  %conv76.i1 = sitofp i32 %34 to float
-  %add77.i0 = fadd fast float %add51.i0, %conv76.i0
-  %add77.i1 = fadd fast float %add65.i1, %conv76.i1
-  %mul = fmul fast float %4, 3.000000e+00
-  %conv82 = fptoui float %mul to i32
-  tail call void @dx.op.bufferStore.f32(i32 70, %dx.types.Handle %buf2_UAV_structbuf, i32 %conv82, i32 0, float %add65.i0, float %add77.i1, float undef, float undef, i8 3)
-  tail call void @dx.op.bufferStore.f32(i32 70, %dx.types.Handle %buf2_UAV_structbuf, i32 %conv82, i32 8, float %add65.i0, float %add77.i1, float %add65.i2, float undef, i8 7)
-  %conv89.i0 = fptosi float %add77.i1 to i32
-  %conv89.i1 = fptosi float %add77.i0 to i32
-  tail call void @dx.op.bufferStore.i32(i32 70, %dx.types.Handle %buf2_UAV_structbuf, i32 %conv82, i32 %11, i32 %conv89.i0, i32 %conv89.i1, i32 undef, i32 undef, i8 3)
-  tail call void @dx.op.storeOutput.f32(i32 5, i32 0, i32 0, i8 0, float %add65.i0)
-  tail call void @dx.op.storeOutput.f32(i32 5, i32 0, i32 0, i8 1, float %add77.i1)
-  tail call void @dx.op.storeOutput.f32(i32 5, i32 0, i32 0, i8 2, float %add65.i2)
-  tail call void @dx.op.storeOutput.f32(i32 5, i32 0, i32 0, i8 3, float %add77.i0)
-  ret void
-}
-
-; Function Attrs: nounwind readnone
-declare float @dx.op.loadInput.f32(i32, i32, i32, i8, i32) #1
-
-; Function Attrs: nounwind
-declare void @dx.op.storeOutput.f32(i32, i32, i32, i8, float) #0
-
-; Function Attrs: nounwind readnone
-declare %dx.types.Handle @dx.op.createHandle(i32, i8, i32, i32, i1) #1
-
-; Function Attrs: nounwind readonly
-declare %dx.types.ResRet.f32 @dx.op.bufferLoad.f32(i32, %dx.types.Handle, i32, i32) #2
-
-; Function Attrs: nounwind readonly
-declare %dx.types.ResRet.i32 @dx.op.bufferLoad.i32(i32, %dx.types.Handle, i32, i32) #2
-
-; Function Attrs: nounwind
-declare void @dx.op.bufferStore.f32(i32, %dx.types.Handle, i32, i32, float, float, float, float, i8) #0
-
-; Function Attrs: nounwind
-declare void @dx.op.bufferStore.i32(i32, %dx.types.Handle, i32, i32, i32, i32, i32, i32, i8) #0
-
-attributes #0 = { nounwind }
-attributes #1 = { nounwind readnone }
-attributes #2 = { nounwind readonly }
-
-!llvm.ident = !{!0}
-!dx.version = !{!1}
-!dx.shaderModel = !{!2}
-!dx.resources = !{!3}
-!dx.typeAnnotations = !{!9, !16}
-!dx.entryPoints = !{!29}
-
-!0 = !{!"clang version 3.7 (tags/RELEASE_370/final)"}
-!1 = !{i32 0, i32 7}
-!2 = !{!"ps", i32 5, i32 1}
-!3 = !{!4, !7, null, null}
-!4 = !{!5}
-!5 = !{i32 0, %class.StructuredBuffer* @"\01?buf1@@3V?$StructuredBuffer@UFoo@@@@A", !"buf1", i32 0, i32 0, i32 1, i32 12, i32 0, !6}
-!6 = !{i32 1, i32 50}
-!7 = !{!8}
-!8 = !{i32 0, %class.RWStructuredBuffer* @"\01?buf2@@3V?$RWStructuredBuffer@UFoo@@@@A", !"buf2", i32 0, i32 0, i32 1, i32 12, i1 true, i1 true, i1 false, !6}
-!9 = !{i32 0, %class.StructuredBuffer addrspace(1)* @dx.typevar.0, !10, %struct.Foo addrspace(1)* @dx.typevar.1, !12, %class.RWStructuredBuffer addrspace(1)* @dx.typevar.2, !10}
-!10 = !{i32 88, !11}
-!11 = !{i32 3, i32 0, i32 6, !"h"}
-!12 = !{i32 88, !13, !14, !15}
-!13 = !{i32 3, i32 0, i32 6, !"a", i32 7, i32 9}
-!14 = !{i32 3, i32 16, i32 6, !"b", i32 7, i32 9}
-!15 = !{i32 3, i32 32, i32 6, !"c", i32 7, i32 4}
-!16 = !{i32 1, void (float, float, <4 x float>*)* @main.flat, !17}
-!17 = !{!18, !20, !23, !26}
-!18 = !{i32 0, !19, !19}
-!19 = !{}
-!20 = !{i32 0, !21, !22}
-!21 = !{i32 4, !"Idx1", i32 7, i32 9}
-!22 = !{i32 1}
-!23 = !{i32 0, !24, !25}
-!24 = !{i32 4, !"Idx2", i32 7, i32 9}
-!25 = !{i32 2}
-!26 = !{i32 1, !27, !28}
-!27 = !{i32 4, !"SV_Target", i32 7, i32 9}
-!28 = !{i32 0}
-!29 = !{void (float, float, <4 x float>*)* @main.flat, !"", !30, !3, !36}
-!30 = !{!31, !34, null}
-!31 = !{!32, !33}
-!32 = !{i32 0, !"Idx", i8 9, i8 0, !22, i8 2, i32 1, i8 1, i32 0, i8 0, null}
-!33 = !{i32 1, !"Idx", i8 9, i8 0, !25, i8 2, i32 1, i8 1, i32 1, i8 0, null}
-!34 = !{!35}
-!35 = !{i32 0, !"SV_Target", i8 9, i8 16, !28, i8 0, i32 1, i8 4, i32 0, i8 0, null}
-!36 = !{i32 0, i64 8208}

+ 5 - 0
tools/clang/unittests/HLSL/CompilerTest.cpp

@@ -330,6 +330,7 @@ public:
   TEST_METHOD(CodeGenEmptyStruct)
   TEST_METHOD(CodeGenEarlyDepthStencil)
   TEST_METHOD(CodeGenEval)
+  TEST_METHOD(CodeGenEvalPos)
   TEST_METHOD(CodeGenFirstbitHi)
   TEST_METHOD(CodeGenFirstbitLo)
   TEST_METHOD(CodeGenFloatMaxtessfactor)
@@ -1803,6 +1804,10 @@ TEST_F(CompilerTest, CodeGenEval) {
   CodeGenTestCheck(L"..\\CodeGenHLSL\\eval.hlsl");
 }
 
+TEST_F(CompilerTest, CodeGenEvalPos) {
+  CodeGenTestCheck(L"..\\CodeGenHLSL\\evalPos.hlsl");
+}
+
 TEST_F(CompilerTest, CodeGenFirstbitHi) {
   CodeGenTestCheck(L"..\\CodeGenHLSL\\firstbitHi.hlsl");
 }

+ 72 - 4
tools/clang/unittests/HLSL/ValidationTest.cpp

@@ -60,6 +60,14 @@ public:
   TEST_METHOD(ControlFlowHint)
   TEST_METHOD(ControlFlowHint1)
   TEST_METHOD(ControlFlowHint2)
+  TEST_METHOD(SemanticLength1)
+  TEST_METHOD(SemanticLength64)
+  TEST_METHOD(PullModelPosition)
+  TEST_METHOD(StructBufStrideAlign)
+  TEST_METHOD(StructBufStrideOutOfBound)
+  TEST_METHOD(StructBufGlobalCoherentAndCounter)
+  TEST_METHOD(StructBufLoadCoordinates)
+  TEST_METHOD(StructBufStoreCoordinates)
 
   TEST_METHOD(WhenInstrDisallowedThenFail);
   TEST_METHOD(WhenDepthNotFloatThenFail);
@@ -88,7 +96,6 @@ public:
   TEST_METHOD(SimpleHs4Fail);
   TEST_METHOD(SimpleDs1Fail);
   TEST_METHOD(SimpleGs1Fail);
-  TEST_METHOD(StructBuf1Fail);
   TEST_METHOD(UavBarrierFail);
   TEST_METHOD(UndefValueFail);
   TEST_METHOD(UpdateCounterFail);
@@ -443,9 +450,6 @@ TEST_F(ValidationTest, SimpleDs1Fail) {
 TEST_F(ValidationTest, SimpleGs1Fail) {
   TestCheck(L"dxil_validation\\SimpleGs1.ll");
 }
-TEST_F(ValidationTest, StructBuf1Fail) {
-  TestCheck(L"dxil_validation\\struct_buf1.ll");
-}
 TEST_F(ValidationTest, UavBarrierFail) {
   TestCheck(L"dxil_validation\\uavBarrier.ll");
 }
@@ -597,6 +601,70 @@ TEST_F(ValidationTest, ControlFlowHint2) {
       "Invalid control flow hint");
 }
 
+TEST_F(ValidationTest, SemanticLength1) {
+    RewriteAssemblyCheckMsg(
+      L"..\\CodeGenHLSL\\binary1.hlsl", "ps_6_0",
+      "!\"C\"",
+      "!\"\"",
+      "Semantic length must be at least 1 and at most 64");
+}
+
+TEST_F(ValidationTest, SemanticLength64) {
+    RewriteAssemblyCheckMsg(
+      L"..\\CodeGenHLSL\\binary1.hlsl", "ps_6_0",
+      "!\"C\"",
+      "!\"CSESESESESESESESESESESESESESESESESESESESESESESESESESESESESESESESE\"",
+      "Semantic length must be at least 1 and at most 64");
+}
+
+TEST_F(ValidationTest, PullModelPosition) {
+    RewriteAssemblyCheckMsg(
+      L"..\\CodeGenHLSL\\eval.hlsl", "ps_5_0",
+      "!\"A\", i8 9, i8 0",
+      "!\"SV_Position\", i8 9, i8 3",
+      "does not support pull-model evaluation of position");
+}
+
+TEST_F(ValidationTest, StructBufGlobalCoherentAndCounter) {
+    RewriteAssemblyCheckMsg(
+      L"..\\CodeGenHLSL\\struct_buf1.hlsl", "ps_5_0",
+      "!\"buf2\", i32 0, i32 0, i32 1, i32 12, i1 false, i1 false",
+      "!\"buf2\", i32 0, i32 0, i32 1, i32 12, i1 true, i1 true",
+      "globallycoherent cannot be used with append/consume buffers'buf2'");
+}
+
+TEST_F(ValidationTest, StructBufStrideAlign) {
+    RewriteAssemblyCheckMsg(
+      L"..\\CodeGenHLSL\\struct_buf1.hlsl", "ps_5_0",
+      "!7 = !{i32 1, i32 52}",
+      "!7 = !{i32 1, i32 50}",
+      "structured buffer element size must be a multiple of 4 bytes (actual size 50 bytes)");
+}
+
+TEST_F(ValidationTest, StructBufStrideOutOfBound) {
+    RewriteAssemblyCheckMsg(
+      L"..\\CodeGenHLSL\\struct_buf1.hlsl", "ps_5_0",
+      "!7 = !{i32 1, i32 52}",
+      "!7 = !{i32 1, i32 2052}",
+      "structured buffer elements cannot be larger than 2048 bytes (actual size 2052 bytes)");
+}
+
+TEST_F(ValidationTest, StructBufLoadCoordinates) {
+    RewriteAssemblyCheckMsg(
+      L"..\\CodeGenHLSL\\struct_buf1.hlsl", "ps_5_0",
+      "bufferLoad.f32(i32 69, %dx.types.Handle %buf1_texture_structbuf, i32 1, i32 8)",
+      "bufferLoad.f32(i32 69, %dx.types.Handle %buf1_texture_structbuf, i32 1, i32 undef)",
+      "structured buffer require 2 coordinates");
+}
+
+TEST_F(ValidationTest, StructBufStoreCoordinates) {
+    RewriteAssemblyCheckMsg(
+      L"..\\CodeGenHLSL\\struct_buf1.hlsl", "ps_5_0",
+      "bufferStore.f32(i32 70, %dx.types.Handle %buf2_UAV_structbuf, i32 0, i32 0",
+      "bufferStore.f32(i32 70, %dx.types.Handle %buf2_UAV_structbuf, i32 0, i32 undef",
+      "structured buffer require 2 coordinates");
+}
+
 TEST_F(ValidationTest, WhenWaveAffectsGradientThenFail) {
   TestCheck(L"val-wave-failures-ps.hlsl");
 }

+ 7 - 11
utils/hct/hctdb.py

@@ -1377,11 +1377,10 @@ class db_dxil(object):
         self.add_valrule("Meta.Used", "TODO - All metadata must be used")
         self.add_valrule_msg("Meta.Target", "Target triple must be 'dxil-ms-dx'", "Unknown target triple '%0'")
         self.add_valrule("Meta.WellFormed", "TODO - Metadata must be well-formed in operand count and types")
-        self.add_valrule("Meta.SemanticLen", "TODO - Semantic length must be at least 1 and at most 64")
+        self.add_valrule("Meta.SemanticLen", "Semantic length must be at least 1 and at most 64")
         self.add_valrule_msg("Meta.InterpModeValid", "Interpolation mode must be valid", "Invalid interpolation mode for '%0'")
         self.add_valrule_msg("Meta.SemaKindValid", "Semantic kind must be valid", "Semantic kind for '%0' is invalid")
         self.add_valrule_msg("Meta.NoSemanticOverlap", "Semantics must not overlap", "Semantic '%0' overlap at %1")
-        self.add_valrule("Meta.NoRegisterOverlap", "TODO - User-defined variable locations cannot overlap")
         self.add_valrule("Meta.ValueRange", "Metadata value must be within range")
         self.add_valrule("Meta.FlagsUsage", "Flags must match usage")
         self.add_valrule("Meta.DenseResIDs", "Resource identifiers must be zero-based and dense")
@@ -1397,22 +1396,21 @@ class db_dxil(object):
         self.add_valrule("Meta.ValidSamplerMode", "Invalid sampler mode on sampler ")
         self.add_valrule("Meta.FunctionAnnotation", "Cannot find function annotation for %0")
         self.add_valrule("Meta.GlcNotOnAppendConsume", "globallycoherent cannot be used with append/consume buffers")
-        self.add_valrule("Meta.StructBufAlignment", "TODO - structured buffer element size must be a multiple of %u bytes in %s (actual size %u bytes)")
-        self.add_valrule("Meta.StructBufAlignmentOutOfBound", "TODO - structured buffer elements cannot be larger than %u bytes in %s (actual size %u bytes)")
+        self.add_valrule_msg("Meta.StructBufAlignment", "StructuredBuffer stride not aligned","structured buffer element size must be a multiple of %0 bytes (actual size %1 bytes)")
+        self.add_valrule_msg("Meta.StructBufAlignmentOutOfBound", "StructuredBuffer stride out of bounds","structured buffer elements cannot be larger than %0 bytes (actual size %1 bytes)")
         self.add_valrule("Meta.EntryFunction", "entrypoint not found")
         self.add_valrule("Meta.InvalidControlFlowHint", "Invalid control flow hint")
         self.add_valrule("Meta.BranchFlatten", "Can't use branch and flatten attributes together")
         self.add_valrule("Meta.ForceCaseOnSwitch", "Attribute forcecase only works for switch")
 
-        self.add_valrule("Instr.OpCode", "TODO - DXIL intrinsic must have a valid constant opcode")
         self.add_valrule("Instr.Oload", "DXIL intrinsic overload must be valid")
         self.add_valrule_msg("Instr.CallOload", "Call to DXIL intrinsic must match overload signature", "Call to DXIL intrinsic '%0' does not match an allowed overload signature")
         self.add_valrule("Instr.ResID", "TODO - DXIL instruction must refer to valid resource IDs")
         self.add_valrule("Instr.TypeCast", "TODO - Type cast must be valid")
         self.add_valrule("Instr.PtrArea", "TODO - Pointer must refer to a defined area")
-        self.add_valrule_msg("Instr.OpConst", "TODO - DXIL intrinsic requires an immediate constant operand", "%0 of %1 must be an immediate constant")
-        self.add_valrule("Instr.Allowed", "TODO - Instructions must be of an allowed type")
-        self.add_valrule("Instr.OpCodeReserved", "TODO - Instructions must not reference reserved opcodes")
+        self.add_valrule_msg("Instr.OpConst", "DXIL intrinsic requires an immediate constant operand", "%0 of %1 must be an immediate constant")
+        self.add_valrule("Instr.Allowed", "Instructions must be of an allowed type")
+        self.add_valrule("Instr.OpCodeReserved", "Instructions must not reference reserved opcodes")
         self.add_valrule("Instr.TextureOpArgs", "TODO - Instructions that depend on texture type must match operands")
         self.add_valrule("Instr.TextureLod", "TODO - Level-of-detail is only defined for Texture1D, Texture2D, Texture3D and TextureCube")
         self.add_valrule("Instr.OpCodeResType", "TODO - DXIL intrinsic operating on a resource must be of the correct type")
@@ -1446,7 +1444,7 @@ class db_dxil(object):
         self.add_valrule("Instr.DeterminateDerivative", "gradient operation uses a value that may not be defined for all pixels (in UAV loads can not participate in gradient operations)")
         self.add_valrule("Instr.ERR_NON_LITERAL_RESOURCE", "TODO - Resources being indexed cannot come from conditional expressions, they must come from literal expressions.")
         self.add_valrule("Instr.ERR_NON_LITERAL_STREAM", "TODO - stream parameter must come from a literal expression")
-        self.add_valrule("Instr.ERR_CANT_PULL_POSITION", "TODO - %0 does not support pull-model evaluation of position")
+        self.add_valrule_msg("Instr.CannotPullPosition", "pull-model evaluation of position disallowed", "%0 does not support pull-model evaluation of position")
         self.add_valrule("Instr.ERR_LOOP_CONDITION_OUT_OF_BOUNDS", "TODO - cannot unroll loop with an out-of-bounds array reference in the condition")
         self.add_valrule("Instr.ERR_ATTRIBUTE_PARAM_SIDE_EFFECT", "TODO - expressions with side effects are illegal as attribute parameters for root signature")
         self.add_valrule("Instr.ERR_RESOURCE_UNINITIALIZED", "TODO - Resource being indexed is uninitialized.")
@@ -1547,7 +1545,6 @@ class db_dxil(object):
         self.add_valrule("Sm.InvalidResourceCompType","Invalid resource return type")
         self.add_valrule("Sm.SampleCountOnlyOn2DMS","Only Texture2DMS/2DMSArray could has sample count")
         self.add_valrule("Sm.CounterOnlyOnStructBuf", "BufferUpdateCounter valid only on structured buffers")
-        self.add_valrule("Sm.StructBufMustBe4BytesAlign", "Structured buffer stride should 4 byte align")
         self.add_valrule("Sm.GSTotalOutputVertexDataRange", "TODO: 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")
         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")
@@ -1558,7 +1555,6 @@ class db_dxil(object):
         self.add_valrule("Sm.ERR_MAX_SAMPLER_EXCEEDED", "TODO - The maximum number of sampler slots is exceeded for a library (slot index=%u, max slots=%u)")
         self.add_valrule("Sm.ERR_MAX_TEXTURE_EXCEEDED", "TODO - The maximum number of texture slots is exceeded for a library (slot index=%u, max slots=%u)")
         self.add_valrule("Sm.ERR_MAX_CBUFFER_EXCEEDED", "TODO - The maximum number of constant buffer slots is exceeded for a library (slot index=%u, max slots=%u)")
-        self.add_valrule("Sm.ERR_GEN_SEMANTIC_TOO_LONG", "TODO - Semantic length is limited to 64 characters")
         self.add_valrule("Sm.ERR_DUPLICATE_CBUFFER_BANK", "TODO - ERR_DUPLICATE_CBUFFER_BANK")
         self.add_valrule("Sm.ERR_UNABLE_TO_BIND_RESOURCE", "TODO - ERR_UNABLE_TO_BIND_RESOURCE")
         self.add_valrule("Sm.ERR_UNABLE_TO_BIND_UNBOUNDED_RESOURCE", "TODO - ERR_UNABLE_TO_BIND_UNBOUNDED_RESOURCE")