diff --git a/tools/clang/include/clang/Basic/DiagnosticSemaKinds.td b/tools/clang/include/clang/Basic/DiagnosticSemaKinds.td index 34a2195cbc..04f9788190 100644 --- a/tools/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/tools/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -8066,6 +8066,19 @@ def err_hlsl_vk_static_pointer_cast_type: Error< "vk::static_pointer_cast() content type must be base class of argument's content type">; def warn_spirv_node_shaders_experimental : Warning< "SPIR-V implementation of node shaders is experimental and subject to change">; + +def err_hlsl_spv_inline_builtin_redefinition + : Error<"%0 cannot be used on a variable already associated with the " + "built-in %1">; +def err_hlsl_spv_inline_builtin_incompatible + : Error<"%0 incompatible with the BuiltIn %1">; +def err_hlsl_spv_inline_location_redefinition + : Error<"invalid %0 : target already associated with another location %1">; +def err_hlsl_spv_inline_invalid_decoration_single_operand_missing + : Error<"decoration %0 requires 1 operand">; +def err_hlsl_spv_inline_storage_class_redefinition + : Error<"%0 cannot be used on a variable already associated to another " + "storage class %1">; // SPIRV Change Ends let CategoryName = "OpenMP Issue" in { diff --git a/tools/clang/include/clang/Sema/SemaHLSL.h b/tools/clang/include/clang/Sema/SemaHLSL.h index 80ce8ddd7d..f52d6686b7 100644 --- a/tools/clang/include/clang/Sema/SemaHLSL.h +++ b/tools/clang/include/clang/Sema/SemaHLSL.h @@ -139,6 +139,8 @@ GetBestViableFunction(clang::Sema &S, clang::SourceLocation Loc, bool ShouldSkipNRVO(clang::Sema &sema, clang::QualType returnType, clang::VarDecl *VD, clang::FunctionDecl *FD); +void NormalizeInlineSPIRVAttributes(clang::Sema &S, clang::Decl *D); + /// Processes an attribute for a declaration. /// Sema with context. /// Annotated declaration. diff --git a/tools/clang/lib/SPIRV/DeclResultIdMapper.cpp b/tools/clang/lib/SPIRV/DeclResultIdMapper.cpp index 98051f5844..54a55dc481 100644 --- a/tools/clang/lib/SPIRV/DeclResultIdMapper.cpp +++ b/tools/clang/lib/SPIRV/DeclResultIdMapper.cpp @@ -330,6 +330,10 @@ bool shouldSkipInStructLayout(const Decl *decl) { return true; } + if (decl->hasAttr()) { + return true; + } + // External visibility if (const auto *declDecl = dyn_cast(decl)) if (!declDecl->hasExternalFormalLinkage()) @@ -1183,6 +1187,7 @@ SpirvVariable *DeclResultIdMapper::createExternVar(const VarDecl *var) { SpirvVariable *DeclResultIdMapper::createExternVar(const VarDecl *var, QualType type) { const bool isGroupShared = var->hasAttr(); + const bool hasInlineSpirvSC = var->hasAttr(); const bool isACSBuffer = isAppendStructuredBuffer(type) || isConsumeStructuredBuffer(type); const bool isRWSBuffer = isRWStructuredBuffer(type); @@ -1190,7 +1195,7 @@ SpirvVariable *DeclResultIdMapper::createExternVar(const VarDecl *var, const auto rule = getLayoutRuleForExternVar(type, spirvOptions); const auto loc = var->getLocation(); - if (!isGroupShared && !isResourceType(type) && + if (!isGroupShared && !isResourceType(type) && !hasInlineSpirvSC && !isResourceOnlyStructure(type)) { // We currently cannot support global structures that contain both resources @@ -1293,6 +1298,10 @@ SpirvVariable *DeclResultIdMapper::createExternVar(const VarDecl *var, return varInstr; const auto *bindingAttr = var->getAttr(); + + if (var->hasAttr() && !bindingAttr) + return varInstr; + resourceVars.emplace_back(varInstr, var, loc, getResourceBinding(var), bindingAttr, var->getAttr()); diff --git a/tools/clang/lib/Sema/SemaDeclAttr.cpp b/tools/clang/lib/Sema/SemaDeclAttr.cpp index 085874a0ed..f5029a2fa9 100644 --- a/tools/clang/lib/Sema/SemaDeclAttr.cpp +++ b/tools/clang/lib/Sema/SemaDeclAttr.cpp @@ -5326,6 +5326,11 @@ void Sema::ProcessDeclAttributes(Scope *S, Decl *D, const Declarator &PD) { D->addAttr(*i); } // HLSL Change Ends + + // SPIR-V Change Starts + if (LangOpts.HLSL) + hlsl::NormalizeInlineSPIRVAttributes(*this, D); + // SPIR-V Change Ends } /// Is the given declaration allowed to use a forbidden type? diff --git a/tools/clang/lib/Sema/SemaHLSL.cpp b/tools/clang/lib/Sema/SemaHLSL.cpp index e9c8c90a2d..e4c6ff068d 100644 --- a/tools/clang/lib/Sema/SemaHLSL.cpp +++ b/tools/clang/lib/Sema/SemaHLSL.cpp @@ -48,10 +48,18 @@ #include "llvm/ADT/StringRef.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/raw_ostream.h" + +#ifdef ENABLE_SPIRV_CODEGEN +// Enables functions like spv::BuiltInToString() +#define SPV_ENABLE_UTILITY_CODE +#include "spirv/unified1/spirv.hpp11" +#endif + #include #include #include #include +#include enum ArBasicKind { AR_BASIC_BOOL, @@ -14593,6 +14601,162 @@ void ValidateDispatchGridValues(DiagnosticsEngine &Diags, << A.getName() << A.getRange(); } +void hlsl::NormalizeInlineSPIRVAttributes(Sema &S, Decl *D) { +#ifdef ENABLE_SPIRV_CODEGEN + // Collecting the values that can be set across multiple attributes. + std::optional> StorageClass; + std::optional> Location; + std::optional> BuiltIn; + + // Vector collecting all the other attributes. + clang::AttrVec NewAttrs; + + for (auto *A : D->attrs()) { + if (auto *DA = dyn_cast(A)) { + spv::Decoration Decoration = spv::Decoration(DA->getDecorate()); + if (Decoration == spv::Decoration::Location) { + if (DA->literals_size() != 1) { + S.Diags.Report( + A->getLocation(), + diag:: + err_hlsl_spv_inline_invalid_decoration_single_operand_missing) + << "Location"; + return; + } + unsigned Index = *DA->literals_begin(); + if (Location.has_value() && Location->first != Index) { + S.Diags.Report(A->getLocation(), + diag::err_hlsl_spv_inline_location_redefinition) + << DA << Location->first; + return; + } + Location = {Index, DA->getLocation()}; + } else if (Decoration == spv::Decoration::BuiltIn) { + if (DA->literals_size() != 1) { + S.Diags.Report( + A->getLocation(), + diag:: + err_hlsl_spv_inline_invalid_decoration_single_operand_missing) + << "BuiltIn"; + return; + } + spv::BuiltIn ID = spv::BuiltIn(*DA->literals_begin()); + if (BuiltIn.has_value() && ID != BuiltIn->first) { + S.Diags.Report(A->getLocation(), + diag::err_hlsl_spv_inline_builtin_redefinition) + << DA << spv::BuiltInToString(BuiltIn->first); + return; + } + BuiltIn = {ID, DA->getLocation()}; + } else { + NewAttrs.push_back(A); + } + } else if (auto *SCA = dyn_cast(A)) { + spv::StorageClass SC = spv::StorageClass(SCA->getStclass()); + if (StorageClass.has_value() && StorageClass->first != SC) { + S.Diags.Report(A->getLocation(), + diag::err_hlsl_spv_inline_storage_class_redefinition) + << SCA << spv::StorageClassToString(StorageClass->first); + return; + } + StorageClass = {SC, SCA->getLocation()}; + } else if (auto *LA = dyn_cast(A)) { + if (Location.has_value() && + Location->first != static_cast(LA->getNumber())) { + S.Diags.Report(A->getLocation(), + diag::err_hlsl_spv_inline_location_redefinition) + << LA << Location->first; + return; + } + Location = {LA->getNumber(), LA->getLocation()}; + } else if (auto *BA = dyn_cast(A)) { + if (StorageClass.has_value() && + StorageClass->first != spv::StorageClass::Output) { + S.Diags.Report(A->getLocation(), + diag::err_hlsl_spv_inline_storage_class_redefinition) + << BA << spv::StorageClassToString(StorageClass->first); + return; + } + StorageClass = {spv::StorageClass::Output, BA->getLocation()}; + + spv::BuiltIn ID = spv::BuiltIn(BA->getBuiltInID()); + if (BuiltIn.has_value() && ID != BuiltIn->first) { + S.Diags.Report(A->getLocation(), + diag::err_hlsl_spv_inline_builtin_redefinition) + << BA << spv::BuiltInToString(BuiltIn->first); + return; + } + BuiltIn = {ID, BA->getLocation()}; + + } else if (auto *BA = dyn_cast(A)) { + if (StorageClass.has_value() && + StorageClass->first != spv::StorageClass::Input) { + S.Diags.Report(A->getLocation(), + diag::err_hlsl_spv_inline_storage_class_redefinition) + << BA << spv::StorageClassToString(StorageClass->first); + return; + } + StorageClass = {spv::StorageClass::Input, BA->getLocation()}; + + spv::BuiltIn ID = spv::BuiltIn(BA->getBuiltInID()); + if (BuiltIn.has_value() && ID != BuiltIn->first) { + S.Diags.Report(A->getLocation(), + diag::err_hlsl_spv_inline_builtin_redefinition) + << BA << spv::BuiltInToString(BuiltIn->first); + return; + } + BuiltIn = {ID, BA->getLocation()}; + } else { + NewAttrs.push_back(A); + } + } + + if (BuiltIn.has_value()) { + // Location should not be set if a BuiltIn is requested. + if (Location.has_value()) { + S.Diags.Report(D->getLocation(), + diag::err_hlsl_spv_inline_builtin_incompatible) + << "Location" << spv::BuiltInToString(BuiltIn->first); + return; + } + + // BuiltIn requires either Input or Output storage class. + if (StorageClass.has_value() && + StorageClass->first == spv::StorageClass::Input) + NewAttrs.push_back(new (S.Context) VKExtBuiltinInputAttr( + BuiltIn->second, S.Context, static_cast(BuiltIn->first), + 0)); + else if (StorageClass.has_value() && + StorageClass->first == spv::StorageClass::Output) + NewAttrs.push_back(new (S.Context) VKExtBuiltinOutputAttr( + BuiltIn->second, S.Context, static_cast(BuiltIn->first), + 0)); + else if (isa(D) || isa(D)) { + unsigned BuiltInID = static_cast(BuiltIn->first); + NewAttrs.push_back(new (S.Context) VKDecorateExtAttr( + BuiltIn->second, S.Context, /* BuiltIn */ 11, &BuiltInID, 1, 0)); + } else + S.Diags.Report(D->getLocation(), + diag::err_hlsl_spv_inline_builtin_incompatible) + << std::string("StorageClass ") + + spv::StorageClassToString(StorageClass->first) + << spv::BuiltInToString(BuiltIn->first); + } else { + if (Location.has_value()) + NewAttrs.push_back(new (S.Context) VKLocationAttr( + Location->second, S.Context, static_cast(Location->first), + 0)); + if (StorageClass.has_value()) + NewAttrs.push_back(new (S.Context) VKStorageClassExtAttr( + StorageClass->second, S.Context, + static_cast(StorageClass->first), 0)); + } + + D->dropAttrs(); + D->setAttrs(NewAttrs); +#endif // ENABLE_SPIRV_CODEGEN +} + void hlsl::HandleDeclAttributeForHLSL(Sema &S, Decl *D, const AttributeList &A, bool &Handled) { DXASSERT_NOMSG(D != nullptr); diff --git a/tools/clang/test/CodeGenSPIRV/inline-spirv/spv.inline.builtin.both.error.hlsl b/tools/clang/test/CodeGenSPIRV/inline-spirv/spv.inline.builtin.both.error.hlsl deleted file mode 100644 index f7983678db..0000000000 --- a/tools/clang/test/CodeGenSPIRV/inline-spirv/spv.inline.builtin.both.error.hlsl +++ /dev/null @@ -1,9 +0,0 @@ -// RUN: not %dxc -T ps_6_0 -E main -fcgl %s -spirv 2>&1 | FileCheck %s - -// CHECK: error: vk::ext_builtin_input cannot be used together with vk::ext_builtin_output -[[vk::ext_builtin_input(/* NumWorkgroups */ 24)]] -[[vk::ext_builtin_output(/* NumWorkgroups */ 24)]] -static uint3 invalid; - -void main() { -} diff --git a/tools/clang/test/CodeGenSPIRV/inline-spirv/spv.intrinsicStorageClass.hlsl b/tools/clang/test/CodeGenSPIRV/inline-spirv/spv.intrinsicStorageClass.hlsl index bc2e6b94b0..762af25d77 100644 --- a/tools/clang/test/CodeGenSPIRV/inline-spirv/spv.intrinsicStorageClass.hlsl +++ b/tools/clang/test/CodeGenSPIRV/inline-spirv/spv.intrinsicStorageClass.hlsl @@ -1,15 +1,18 @@ // RUN: %dxc -T ps_6_0 -E main -spirv -Vd -fcgl %s -spirv | FileCheck %s -//CHECK: [[payloadTy:%[a-zA-Z0-9_]+]] = OpTypeStruct %v4float -//CHECK-NEXT: [[payloadTyPtr:%[a-zA-Z0-9_]+]] = OpTypePointer RayPayloadKHR [[payloadTy]] -//CHECK: [[crossTy:%[a-zA-Z0-9_]+]] = OpTypePointer CrossWorkgroup %int -//CHECK: {{%[a-zA-Z0-9_]+}} = OpVariable [[payloadTyPtr]] RayPayloadKHR -//CHECK: {{%[a-zA-Z0-9_]+}} = OpVariable [[crossTy]] CrossWorkgroup - +[[vk::ext_extension("SPV_KHR_ray_tracing")]] +[[vk::ext_capability(/* RayTracingKHR */ 4479)]] [[vk::ext_storage_class(/*RayPayloadKHR*/5338)]] float4 payload; +// CHECK-DAG: [[ptr_payload_v4:%[a-zA-Z0-9_]+]] = OpTypePointer RayPayloadKHR %v4float +// CHECK-DAG: %payload = OpVariable [[ptr_payload_v4]] RayPayloadKHR int main() : SV_Target0 { - [[vk::ext_storage_class(/* CrossWorkgroup */ 5)]] int foo = 3; + + [[vk::ext_storage_class(/* CrossWorkgroup */ 5)]] + int foo = 3; +// CHECK-DAG: [[ptr_cw_int:%[a-zA-Z0-9_]+]] = OpTypePointer CrossWorkgroup %int +// CHECK-DAG: %foo = OpVariable [[ptr_cw_int]] CrossWorkgroup + return foo; } diff --git a/tools/clang/test/CodeGenSPIRV/inline-spirv/spv.raytracing.hlsl b/tools/clang/test/CodeGenSPIRV/inline-spirv/spv.raytracing.hlsl new file mode 100644 index 0000000000..0d6c19904c --- /dev/null +++ b/tools/clang/test/CodeGenSPIRV/inline-spirv/spv.raytracing.hlsl @@ -0,0 +1,22 @@ +// RUN: %dxc %s -T cs_6_8 -spirv -fspv-target-env=vulkan1.3 -E main -O0 | FileCheck %s + +// CHECK-DAG: OpCapability RuntimeDescriptorArray +// CHECK-DAG: OpCapability RayQueryKHR + +// CHECK-DAG: OpDecorate %MyScene DescriptorSet 1 +// CHECK-DAG: OpDecorate %MyScene Binding 3 + +using A = vk::SpirvOpaqueType; +// CHECK: %[[name:[^ ]+]] = OpTypeAccelerationStructureKHR + +using RA [[vk::ext_capability(/* RuntimeDescriptorArray */ 5302)]] = vk::SpirvOpaqueType; +// CHECK: %[[rarr:[^ ]+]] = OpTypeRuntimeArray %[[name]] + +// CHECK: %[[ptr:[^ ]+]] = OpTypePointer UniformConstant %[[rarr]] +// CHECK: %MyScene = OpVariable %[[ptr]] UniformConstant +[[vk::binding(3, 1)]] +[[vk::ext_storage_class(0)]] +RA MyScene; + +[numthreads(1, 1, 1)] +void main() {} diff --git a/tools/clang/test/SemaHLSL/inline-spirv/spv.inline.builtin.bad.storage.hlsl b/tools/clang/test/SemaHLSL/inline-spirv/spv.inline.builtin.bad.storage.hlsl new file mode 100644 index 0000000000..4abd608074 --- /dev/null +++ b/tools/clang/test/SemaHLSL/inline-spirv/spv.inline.builtin.bad.storage.hlsl @@ -0,0 +1,9 @@ +// RUN: %dxc -T cs_6_0 -E main -fcgl %s -spirv -verify + +[[vk::ext_decorate(/* BuiltIn */ 11, /* WorkgroupId */ 26)]] +[[vk::ext_storage_class(/* UniformConstant */ 0)]] +// expected-error@+1{{StorageClass UniformConstant incompatible with the BuiltIn WorkgroupId}} +static uint3 input; + +[numthreads(1, 1, 1)] +void main() { } diff --git a/tools/clang/test/SemaHLSL/inline-spirv/spv.inline.builtin.both.error.hlsl b/tools/clang/test/SemaHLSL/inline-spirv/spv.inline.builtin.both.error.hlsl new file mode 100644 index 0000000000..89d2b873cc --- /dev/null +++ b/tools/clang/test/SemaHLSL/inline-spirv/spv.inline.builtin.both.error.hlsl @@ -0,0 +1,9 @@ +// RUN: %dxc -T ps_6_0 -E main -fcgl %s -spirv -verify + +// expected-error@+1{{'ext_builtin_input' cannot be used on a variable already associated to another storage class Output}} +[[vk::ext_builtin_input(/* NumWorkgroups */ 24)]] +[[vk::ext_builtin_output(/* NumWorkgroups */ 24)]] +static uint3 invalid; + +void main() { +} diff --git a/tools/clang/test/SemaHLSL/inline-spirv/spv.inline.builtin.location.hlsl b/tools/clang/test/SemaHLSL/inline-spirv/spv.inline.builtin.location.hlsl new file mode 100644 index 0000000000..3db779ed1e --- /dev/null +++ b/tools/clang/test/SemaHLSL/inline-spirv/spv.inline.builtin.location.hlsl @@ -0,0 +1,10 @@ +// RUN: %dxc -T cs_6_0 -E main -fcgl %s -spirv -verify + +[[vk::ext_decorate(/* BuiltIn */ 11, /* WorkgroupId */ 26)]] +[[vk::ext_builtin_input(/* WorkgroupId */ 26)]] +[[vk::ext_decorate(/* Location */ 30, 0)]] +// expected-error@+1{{Location incompatible with the BuiltIn WorkgroupId}} +static uint3 input; + +[numthreads(1, 1, 1)] +void main() { } diff --git a/tools/clang/test/SemaHLSL/inline-spirv/spv.inline.builtin.missing.hlsl b/tools/clang/test/SemaHLSL/inline-spirv/spv.inline.builtin.missing.hlsl new file mode 100644 index 0000000000..caa0fcb91f --- /dev/null +++ b/tools/clang/test/SemaHLSL/inline-spirv/spv.inline.builtin.missing.hlsl @@ -0,0 +1,8 @@ +// RUN: %dxc -T cs_6_0 -E main -fcgl %s -spirv -verify + +// expected-error@+1{{decoration BuiltIn requires 1 operand}} +[[vk::ext_decorate(/* BuiltIn */ 11)]] +static uint3 input; + +[numthreads(1, 1, 1)] +void main() {} diff --git a/tools/clang/test/SemaHLSL/inline-spirv/spv.inline.builtin.multiple.error.hlsl b/tools/clang/test/SemaHLSL/inline-spirv/spv.inline.builtin.multiple.error.hlsl new file mode 100644 index 0000000000..6d9e4b00fd --- /dev/null +++ b/tools/clang/test/SemaHLSL/inline-spirv/spv.inline.builtin.multiple.error.hlsl @@ -0,0 +1,10 @@ +// RUN: %dxc -T cs_6_0 -E main -fcgl %s -spirv -verify + +// expected-error@+1{{'ext_decorate' cannot be used on a variable already associated with the built-in LocalInvocationId}} +[[vk::ext_decorate(/* BuiltIn */ 11, /* WorkgroupId */ 26)]] +[[vk::ext_decorate(/* BuiltIn */ 11, /* LocalInvocationId */ 27)]] +[[vk::ext_storage_class(/* Input */ 1)]] +static uint3 invalid; + +[numthreads(1, 1, 1)] +void main() { } diff --git a/tools/clang/test/SemaHLSL/inline-spirv/spv.inline.builtin.multiple.input.hlsl b/tools/clang/test/SemaHLSL/inline-spirv/spv.inline.builtin.multiple.input.hlsl new file mode 100644 index 0000000000..b156c4ff09 --- /dev/null +++ b/tools/clang/test/SemaHLSL/inline-spirv/spv.inline.builtin.multiple.input.hlsl @@ -0,0 +1,9 @@ +// RUN: %dxc -T cs_6_0 -E main -fcgl %s -spirv -verify + +// expected-error@+1{{'ext_builtin_input' cannot be used on a variable already associated with the built-in WorkgroupId}} +[[vk::ext_builtin_input(/* NumWorkgroups */ 24)]] +[[vk::ext_builtin_input(/* WorkgroupId */ 26)]] +static uint3 invalid; + +[numthreads(1, 1, 1)] +void main() { } diff --git a/tools/clang/test/SemaHLSL/inline-spirv/spv.inline.builtin.multiple.input.manual.hlsl b/tools/clang/test/SemaHLSL/inline-spirv/spv.inline.builtin.multiple.input.manual.hlsl new file mode 100644 index 0000000000..215b1ef590 --- /dev/null +++ b/tools/clang/test/SemaHLSL/inline-spirv/spv.inline.builtin.multiple.input.manual.hlsl @@ -0,0 +1,11 @@ +// RUN: %dxc -T cs_6_9 -E main -ast-dump -spirv %s | FileCheck %s + +[[vk::ext_decorate(/* BuiltIn */ 11, /* WorkgroupId */ 26)]] +[[vk::ext_builtin_input(/* WorkgroupId */ 26)]] +static uint3 input; + +// CHECK: VarDecl 0x{{.+}} <{{.+}}> col:14 input 'uint3':'vector' static +// CHECK-NEXT: VKExtBuiltinInputAttr 0x{{.+}} 26 + +[numthreads(1, 1, 1)] +void main() { } diff --git a/tools/clang/test/SemaHLSL/inline-spirv/spv.inline.builtin.multiple.input.storage.conflict.hlsl b/tools/clang/test/SemaHLSL/inline-spirv/spv.inline.builtin.multiple.input.storage.conflict.hlsl new file mode 100644 index 0000000000..f6fd2bbfea --- /dev/null +++ b/tools/clang/test/SemaHLSL/inline-spirv/spv.inline.builtin.multiple.input.storage.conflict.hlsl @@ -0,0 +1,9 @@ +// RUN: %dxc -T cs_6_9 -E main -spirv %s -verify + +// expected-error@+1{{'ext_storage_class' cannot be used on a variable already associated to another storage class Input}} +[[vk::ext_storage_class(/* Output */ 3)]] +[[vk::ext_builtin_input(/* WorkgroupId */ 26)]] +static uint3 input; + +[numthreads(1, 1, 1)] +void main() { } diff --git a/tools/clang/test/SemaHLSL/inline-spirv/spv.inline.builtin.multiple.input.storage.hlsl b/tools/clang/test/SemaHLSL/inline-spirv/spv.inline.builtin.multiple.input.storage.hlsl new file mode 100644 index 0000000000..cacba6c564 --- /dev/null +++ b/tools/clang/test/SemaHLSL/inline-spirv/spv.inline.builtin.multiple.input.storage.hlsl @@ -0,0 +1,10 @@ +// RUN: %dxc -T cs_6_9 -E main -ast-dump -spirv %s | FileCheck %s + +[[vk::ext_storage_class(/* Input */ 1)]] +[[vk::ext_builtin_input(/* WorkgroupId */ 26)]] +static uint3 input; +// CHECK: VarDecl 0x{{.+}} <{{.+}}> col:14 input 'uint3':'vector' static +// CHECK-NEXT: VKExtBuiltinInputAttr 0x{{.+}} 26 + +[numthreads(1, 1, 1)] +void main() { } diff --git a/tools/clang/test/SemaHLSL/inline-spirv/spv.inline.builtin.multiple.input.storage2.hlsl b/tools/clang/test/SemaHLSL/inline-spirv/spv.inline.builtin.multiple.input.storage2.hlsl new file mode 100644 index 0000000000..958bac4dec --- /dev/null +++ b/tools/clang/test/SemaHLSL/inline-spirv/spv.inline.builtin.multiple.input.storage2.hlsl @@ -0,0 +1,10 @@ +// RUN: %dxc -T cs_6_9 -E main -ast-dump -spirv %s | FileCheck %s + +[[vk::ext_builtin_input(/* WorkgroupId */ 26)]] +[[vk::ext_storage_class(/* Input */ 1)]] +static uint3 input; +// CHECK: VarDecl 0x{{.+}} <{{.+}}> col:14 input 'uint3':'vector' static +// CHECK-NEXT: VKExtBuiltinInputAttr 0x{{.+}} 26 + +[numthreads(1, 1, 1)] +void main() { } diff --git a/tools/clang/test/SemaHLSL/inline-spirv/spv.inline.builtin.multiple.output.hlsl b/tools/clang/test/SemaHLSL/inline-spirv/spv.inline.builtin.multiple.output.hlsl new file mode 100644 index 0000000000..087ead35d0 --- /dev/null +++ b/tools/clang/test/SemaHLSL/inline-spirv/spv.inline.builtin.multiple.output.hlsl @@ -0,0 +1,9 @@ +// RUN: %dxc -T cs_6_0 -E main -fcgl %s -spirv -verify + +// expected-error@+1{{'ext_builtin_output' cannot be used on a variable already associated with the built-in WorkgroupId}} +[[vk::ext_builtin_output(/* NumWorkgroups */ 24)]] +[[vk::ext_builtin_output(/* WorkgroupId */ 26)]] +static uint3 invalid; + +[numthreads(1, 1, 1)] +void main() { } diff --git a/tools/clang/test/SemaHLSL/inline-spirv/spv.inline.builtin.multiple.output.manual.hlsl b/tools/clang/test/SemaHLSL/inline-spirv/spv.inline.builtin.multiple.output.manual.hlsl new file mode 100644 index 0000000000..8d380b2b50 --- /dev/null +++ b/tools/clang/test/SemaHLSL/inline-spirv/spv.inline.builtin.multiple.output.manual.hlsl @@ -0,0 +1,11 @@ +// RUN: %dxc -T cs_6_9 -E main -ast-dump -spirv %s | FileCheck %s + +[[vk::ext_decorate(/* BuiltIn */ 11, /* WorkgroupId */ 26)]] +[[vk::ext_builtin_output(/* WorkgroupId */ 26)]] +static uint3 input; + +// CHECK: VarDecl 0x{{.+}} <{{.+}}> col:14 input 'uint3':'vector' static +// CHECK-NEXT: VKExtBuiltinOutputAttr 0x{{.+}} 26 + +[numthreads(1, 1, 1)] +void main() { } diff --git a/tools/clang/test/SemaHLSL/inline-spirv/spv.inline.builtin.multiple.output.storage.conflict.hlsl b/tools/clang/test/SemaHLSL/inline-spirv/spv.inline.builtin.multiple.output.storage.conflict.hlsl new file mode 100644 index 0000000000..02884ae65f --- /dev/null +++ b/tools/clang/test/SemaHLSL/inline-spirv/spv.inline.builtin.multiple.output.storage.conflict.hlsl @@ -0,0 +1,10 @@ +// RUN: %dxc -T vs_6_9 -E main -spirv %s -verify + +// expected-error@+1{{'ext_storage_class' cannot be used on a variable already associated to another storage class Output}} +[[vk::ext_storage_class(/* Input */ 1)]] +[[vk::ext_builtin_output(/* Position */ 0)]] +static float4 output; + +void main() { +} + diff --git a/tools/clang/test/SemaHLSL/inline-spirv/spv.inline.builtin.multiple.output.storage.hlsl b/tools/clang/test/SemaHLSL/inline-spirv/spv.inline.builtin.multiple.output.storage.hlsl new file mode 100644 index 0000000000..6ff9dfb552 --- /dev/null +++ b/tools/clang/test/SemaHLSL/inline-spirv/spv.inline.builtin.multiple.output.storage.hlsl @@ -0,0 +1,10 @@ +// RUN: %dxc -T vs_6_9 -E main -ast-dump -spirv %s | FileCheck %s + +[[vk::ext_storage_class(/* Output */ 3)]] +[[vk::ext_builtin_output(/* Position */ 0)]] +static float4 output; +// CHECK: VarDecl 0x{{.+}} <{{.+}}> col:15 output 'float4':'vector' static +// CHECK-NEXT: VKExtBuiltinOutputAttr 0x{{.+}} 0 + +void main() { +} diff --git a/tools/clang/test/SemaHLSL/inline-spirv/spv.inline.builtin.multiple.output.storage2.hlsl b/tools/clang/test/SemaHLSL/inline-spirv/spv.inline.builtin.multiple.output.storage2.hlsl new file mode 100644 index 0000000000..2ed27bfc10 --- /dev/null +++ b/tools/clang/test/SemaHLSL/inline-spirv/spv.inline.builtin.multiple.output.storage2.hlsl @@ -0,0 +1,10 @@ +// RUN: %dxc -T vs_6_9 -E main -ast-dump -spirv %s | FileCheck %s + +[[vk::ext_builtin_output(/* Position */ 0)]] +[[vk::ext_storage_class(/* Output */ 3)]] +static float4 output; +// CHECK: VarDecl 0x{{.+}} <{{.+}}> col:15 output 'float4':'vector' static +// CHECK-NEXT: VKExtBuiltinOutputAttr 0x{{.+}} 0 + +void main() { +} diff --git a/tools/clang/test/SemaHLSL/inline-spirv/spv.inline.builtin.multiple.same.hlsl b/tools/clang/test/SemaHLSL/inline-spirv/spv.inline.builtin.multiple.same.hlsl new file mode 100644 index 0000000000..709b9d5322 --- /dev/null +++ b/tools/clang/test/SemaHLSL/inline-spirv/spv.inline.builtin.multiple.same.hlsl @@ -0,0 +1,12 @@ +// RUN: %dxc -T cs_6_9 -E main -ast-dump -spirv %s | FileCheck %s + +[[vk::ext_decorate(/* BuiltIn */ 11, /* WorkgroupId */ 26)]] +[[vk::ext_decorate(/* BuiltIn */ 11, /* WorkgroupId */ 26)]] +[[vk::ext_storage_class(/* Input */ 1)]] +static uint3 input; + +// CHECK: VarDecl 0x{{.+}} <{{.+}}> col:14 input 'uint3':'vector' static +// CHECK-NEXT: VKExtBuiltinInputAttr 0x{{.+}} 26 + +[numthreads(1, 1, 1)] +void main() {} diff --git a/tools/clang/test/SemaHLSL/inline-spirv/spv.inline.location.error.hlsl b/tools/clang/test/SemaHLSL/inline-spirv/spv.inline.location.error.hlsl new file mode 100644 index 0000000000..caf17f07fb --- /dev/null +++ b/tools/clang/test/SemaHLSL/inline-spirv/spv.inline.location.error.hlsl @@ -0,0 +1,8 @@ +// RUN: %dxc -T vs_6_0 -E main -fcgl %s -spirv -verify + +// expected-error@+1{{invalid 'ext_decorate' : target already associated with another location 1}} +[[vk::ext_decorate(/* Location */ 30, 0)]] +[[vk::ext_decorate(/* Location */ 30, 1)]] +static float4 output; + +void main() {} diff --git a/tools/clang/test/SemaHLSL/inline-spirv/spv.inline.location.error2.hlsl b/tools/clang/test/SemaHLSL/inline-spirv/spv.inline.location.error2.hlsl new file mode 100644 index 0000000000..acb9820f75 --- /dev/null +++ b/tools/clang/test/SemaHLSL/inline-spirv/spv.inline.location.error2.hlsl @@ -0,0 +1,8 @@ +// RUN: %dxc -T vs_6_0 -E main -fcgl %s -spirv -verify + +// expected-error@+1{{'location' attribute only applies to functions, parameters, and fields}} +[[vk::location(0)]] +[[vk::ext_decorate(/* Location */ 30, 1)]] +static float4 output; + +void main() {} diff --git a/tools/clang/test/SemaHLSL/inline-spirv/spv.inline.location.error3.hlsl b/tools/clang/test/SemaHLSL/inline-spirv/spv.inline.location.error3.hlsl new file mode 100644 index 0000000000..a236db2ab8 --- /dev/null +++ b/tools/clang/test/SemaHLSL/inline-spirv/spv.inline.location.error3.hlsl @@ -0,0 +1,8 @@ +// RUN: %dxc -T vs_6_0 -E main -fcgl %s -spirv -verify + +// expected-error@+1{{decoration Location requires 1 operand}} +[[vk::ext_decorate(/* Location */ 30)]] +[[vk::ext_decorate(/* Location */ 30, 1)]] +static float4 output; + +void main() {} diff --git a/tools/clang/test/SemaHLSL/inline-spirv/spv.inline.location.hlsl b/tools/clang/test/SemaHLSL/inline-spirv/spv.inline.location.hlsl new file mode 100644 index 0000000000..2e9e2393fa --- /dev/null +++ b/tools/clang/test/SemaHLSL/inline-spirv/spv.inline.location.hlsl @@ -0,0 +1,9 @@ +// RUN: %dxc -T vs_6_9 -E main -ast-dump -spirv %s | FileCheck %s + +[[vk::ext_decorate(/* Location */ 30, 0)]] +static float4 output; + +// CHECK: VarDecl 0x{{.+}} <{{.+}}> col:15 output 'float4':'vector' static +// CHECK-NEXT: VKLocationAttr 0x{{.+}} 0 + +void main() {} diff --git a/tools/clang/test/SemaHLSL/inline-spirv/spv.inline.location.multiple.hlsl b/tools/clang/test/SemaHLSL/inline-spirv/spv.inline.location.multiple.hlsl new file mode 100644 index 0000000000..85c43f1ddb --- /dev/null +++ b/tools/clang/test/SemaHLSL/inline-spirv/spv.inline.location.multiple.hlsl @@ -0,0 +1,10 @@ +// RUN: %dxc -T vs_6_9 -E main -ast-dump -spirv %s | FileCheck %s + +[[vk::ext_decorate(/* Location */ 30, 1)]] +[[vk::ext_decorate(/* Location */ 30, 1)]] +static float4 output; + +// CHECK: VarDecl 0x{{.+}} <{{.+}}> col:15 output 'float4':'vector' static +// CHECK-NEXT: VKLocationAttr 0x{{.+}} 1 + +void main() {}