diff --git a/.github/workflows/clang-format-checker.yml b/.github/workflows/clang-format-checker.yml index bc0d21c7dd..9075eba7f0 100644 --- a/.github/workflows/clang-format-checker.yml +++ b/.github/workflows/clang-format-checker.yml @@ -12,6 +12,16 @@ jobs: with: fetch-depth: 2 + - name: Find merge base + run: | + while ! git merge-base origin/$GITHUB_BASE_REF origin/$GITHUB_HEAD_REF > /dev/null; do + depth=$((depth+100)) + git fetch --depth=$depth origin $GITHUB_BASE_REF && git fetch --depth=$depth origin $GITHUB_HEAD_REF + if [ "$depth" -gt "10000" ]; then + exit 1 + fi + done + - name: Get changed files id: changed-files uses: tj-actions/changed-files@v39 diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index eb463b313f..7ca785ee54 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -44,6 +44,8 @@ Here's a few things you should always do when making changes to the code base: The coding, style, and general engineering guidelines follow those described in the docs/CodingStandards.rst. For additional guidelines in code specific to HLSL, see the docs/HLSLChanges.rst file. +DXC has adopted a clang-format requirement for all incoming changes. PRs to DXC should have the _changed code_ clang formatted to the LLVM style, and leave the remaining portions of the file unchanged. This can be done using the `git-clang-format` tool or IDE driven workflows. A GitHub action will run on all PRs to validate that the change is properly formatted. + **Commit/Pull Request Format** ``` diff --git a/azure-pipelines.yml b/azure-pipelines.yml index f515fc6de6..57aa2b69c0 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -34,10 +34,6 @@ stages: call utils\hct\hctstart.cmd %HLSL_SRC_DIR% %HLSL_BLD_DIR% call utils\hct\hcttest.cmd -$(configuration) noexec displayName: 'DXIL Tests' - - script: | - call utils\hct\hctstart.cmd %HLSL_SRC_DIR% %HLSL_BLD_DIR% - call utils\hct\hcttest.cmd -$(configuration) spirv_only - displayName: 'SPIRV Tests' - job: Nix timeoutInMinutes: 90 diff --git a/cmake/modules/HandleLLVMOptions.cmake b/cmake/modules/HandleLLVMOptions.cmake index c85ad3befb..984794e64e 100644 --- a/cmake/modules/HandleLLVMOptions.cmake +++ b/cmake/modules/HandleLLVMOptions.cmake @@ -533,7 +533,11 @@ if(LLVM_USE_SANITIZER) message(WARNING "Unsupported value of LLVM_USE_SANITIZER: ${LLVM_USE_SANITIZER}") endif() else() - message(WARNING "LLVM_USE_SANITIZER is not supported on this platform.") + if (LLVM_USE_SANITIZER STREQUAL "Address") + append("-fsanitize=address" CMAKE_C_FLAGS CMAKE_CXX_FLAGS) + else() + message(WARNING "Unsupported value of LLVM_USE_SANITIZER: ${LLVM_USE_SANITIZER}") + endif() endif() if (LLVM_USE_SANITIZE_COVERAGE) append("-fsanitize-coverage=edge,indirect-calls,8bit-counters,trace-cmp" CMAKE_C_FLAGS CMAKE_CXX_FLAGS) diff --git a/docs/SPIR-V.rst b/docs/SPIR-V.rst index d0b29d02c0..1938b8e0fd 100644 --- a/docs/SPIR-V.rst +++ b/docs/SPIR-V.rst @@ -297,10 +297,10 @@ Supported extensions * SPV_EXT_mesh_shader * SPV_EXT_shader_stencil_support * SPV_AMD_shader_early_and_late_fragment_tests -* SPV_AMD_shader_explicit_vertex_parameter * SPV_GOOGLE_hlsl_functionality1 * SPV_GOOGLE_user_type * SPV_NV_mesh_shader +* SPV_KHR_fragment_shading_barycentric Vulkan specific attributes -------------------------- @@ -1583,7 +1583,7 @@ some system-value (SV) semantic strings will be translated into SPIR-V +---------------------------+-------------+----------------------------------------+-----------------------+-----------------------------+ | SV_StencilRef | PSOut | ``FragStencilRefEXT`` | N/A | ``StencilExportEXT`` | +---------------------------+-------------+----------------------------------------+-----------------------+-----------------------------+ -| SV_Barycentrics | PSIn | ``BaryCoord*AMD`` | N/A | ``Shader`` | +| SV_Barycentrics | PSIn | ``BaryCoord*KHR`` | N/A | ``FragmentBarycentricKHR`` | +---------------------------+-------------+----------------------------------------+-----------------------+-----------------------------+ | | GSOut | ``Layer`` | N/A | ``Geometry`` | | +-------------+----------------------------------------+-----------------------+-----------------------------+ diff --git a/external/SPIRV-Tools b/external/SPIRV-Tools index 360d469b9e..1928c76cd6 160000 --- a/external/SPIRV-Tools +++ b/external/SPIRV-Tools @@ -1 +1 @@ -Subproject commit 360d469b9eac54d6c6e20f609f9ec35e3a5380ad +Subproject commit 1928c76cd6a5a6aa41a8fdb862dc23effb597748 diff --git a/include/dxc/Support/microcom.h b/include/dxc/Support/microcom.h index a4d7882ce3..189cdf93d3 100644 --- a/include/dxc/Support/microcom.h +++ b/include/dxc/Support/microcom.h @@ -74,7 +74,9 @@ template void DxcCallDestructor(T *obj) { obj->T::~T(); } #define DXC_MICROCOM_REF_FIELD(m_dwRef) \ volatile std::atomic m_dwRef = {0}; #define DXC_MICROCOM_ADDREF_IMPL(m_dwRef) \ - ULONG STDMETHODCALLTYPE AddRef() override { return (ULONG)++m_dwRef; } + ULONG STDMETHODCALLTYPE AddRef() noexcept override { \ + return (ULONG)++m_dwRef; \ + } #define DXC_MICROCOM_ADDREF_RELEASE_IMPL(m_dwRef) \ DXC_MICROCOM_ADDREF_IMPL(m_dwRef) \ ULONG STDMETHODCALLTYPE Release() override { \ @@ -107,7 +109,7 @@ inline T *CreateOnMalloc(IMalloc *pMalloc, Args &&...args) { #define DXC_MICROCOM_TM_ADDREF_RELEASE_IMPL() \ DXC_MICROCOM_ADDREF_IMPL(m_dwRef) \ - ULONG STDMETHODCALLTYPE Release() override { \ + ULONG STDMETHODCALLTYPE Release() noexcept override { \ ULONG result = (ULONG)--m_dwRef; \ if (result == 0) { \ CComPtr pTmp(m_pMalloc); \ diff --git a/include/dxc/Test/HlslTestUtils.h b/include/dxc/Test/HlslTestUtils.h index 99ccb28af9..666feb9dcd 100644 --- a/include/dxc/Test/HlslTestUtils.h +++ b/include/dxc/Test/HlslTestUtils.h @@ -19,7 +19,18 @@ #include #include #ifdef _WIN32 + +// Disable -Wignored-qualifiers for WexTestClass.h. +// For const size_t GetSize() const; in TestData.h. +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wignored-qualifiers" +#endif #include "WexTestClass.h" +#ifdef __clang__ +#pragma clang diagnostic pop +#endif + #include #else #include "WEXAdapter.h" diff --git a/include/dxc/dxcpix.h b/include/dxc/dxcpix.h index 5a69a01a48..87edc974d9 100644 --- a/include/dxc/dxcpix.h +++ b/include/dxc/dxcpix.h @@ -13,7 +13,9 @@ #define __DXC_PIX__ #include "dxc/dxcapi.h" +#ifdef _WIN32 #include "objidl.h" +#endif struct __declspec(uuid("199d8c13-d312-4197-a2c1-07a532999727")) IDxcPixType : public IUnknown { diff --git a/include/llvm/ADT/Triple.h b/include/llvm/ADT/Triple.h index 3f7f9e2660..10a1e1a20b 100644 --- a/include/llvm/ADT/Triple.h +++ b/include/llvm/ADT/Triple.h @@ -509,6 +509,12 @@ class Triple { getOS() == Triple::PS4; } + // HLSL Change Begin - Add DXIL Triple. + bool isDXIL() const { + return getArch() == Triple::dxil || getArch() == Triple::dxil64; + } + // HLSL Change End - Add DXIL Triple. + /// @} /// @name Mutators /// @{ diff --git a/include/llvm/IR/Operator.h b/include/llvm/IR/Operator.h index 5a94b8befd..dd580ec9fe 100644 --- a/include/llvm/IR/Operator.h +++ b/include/llvm/IR/Operator.h @@ -501,6 +501,26 @@ class BitCastOperator } }; +// HLSL CHANGE: Add this helper class from upstream. +class AddrSpaceCastOperator + : public ConcreteOperator { + friend class AddrSpaceCastInst; + friend class ConstantExpr; + +public: + Value *getPointerOperand() { return getOperand(0); } + + const Value *getPointerOperand() const { return getOperand(0); } + + unsigned getSrcAddressSpace() const { + return getPointerOperand()->getType()->getPointerAddressSpace(); + } + + unsigned getDestAddressSpace() const { + return getType()->getPointerAddressSpace(); + } +}; + } // End llvm namespace #endif diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt index 224d779741..41c3269872 100644 --- a/lib/CMakeLists.txt +++ b/lib/CMakeLists.txt @@ -27,9 +27,7 @@ add_subdirectory(DXIL) # HLSL Change add_subdirectory(DxilContainer) # HLSL Change add_subdirectory(DxilPdbInfo) # HLSL Change add_subdirectory(DxilPIXPasses) # HLSL Change -if(WIN32) # HLSL Change - add_subdirectory(DxilDia) # HLSL Change -endif(WIN32) # HLSL Change +add_subdirectory(DxilDia) # HLSL Change add_subdirectory(DxilRootSignature) # HLSL Change add_subdirectory(DxcBindingTable) # HLSL Change add_subdirectory(DxrFallback) # HLSL Change diff --git a/lib/DXIL/DxilOperations.cpp b/lib/DXIL/DxilOperations.cpp index 3ed425d497..4b4e16e9db 100644 --- a/lib/DXIL/DxilOperations.cpp +++ b/lib/DXIL/DxilOperations.cpp @@ -685,7 +685,7 @@ const OP::OpCodeProperty OP::m_OpCodeProps[(unsigned)OP::OpCode::NumOpCodes] = { "SampleCmp", OCC::SampleCmp, "sampleCmp", - {false, true, true, false, false, false, true, true, false, false, + {false, true, true, false, false, false, false, false, false, false, false}, Attribute::ReadOnly, }, @@ -694,7 +694,7 @@ const OP::OpCodeProperty OP::m_OpCodeProps[(unsigned)OP::OpCode::NumOpCodes] = { "SampleCmpLevelZero", OCC::SampleCmpLevelZero, "sampleCmpLevelZero", - {false, true, true, false, false, false, true, true, false, false, + {false, true, true, false, false, false, false, false, false, false, false}, Attribute::ReadOnly, }, diff --git a/lib/DXIL/DxilSignatureElement.cpp b/lib/DXIL/DxilSignatureElement.cpp index f63b8feebb..bf8ee0abe0 100644 --- a/lib/DXIL/DxilSignatureElement.cpp +++ b/lib/DXIL/DxilSignatureElement.cpp @@ -51,6 +51,9 @@ void DxilSignatureElement::Initialize(llvm::StringRef Name, m_SemanticStartIndex = IndexVector[0]; // Find semantic in the table. m_pSemantic = Semantic::GetByName(m_SemanticName, m_sigPointKind); + // Replace semantic name with canonical name if it's a system value. + if (!m_pSemantic->IsInvalid() && !m_pSemantic->IsArbitrary()) + m_SemanticName = m_pSemantic->GetName(); SetCompType(ElementType); m_InterpMode = InterpMode; m_SemanticIndex = IndexVector; diff --git a/lib/DXIL/DxilUtilDbgInfoAndMisc.cpp b/lib/DXIL/DxilUtilDbgInfoAndMisc.cpp index ab4a952b51..f6e2424f8b 100644 --- a/lib/DXIL/DxilUtilDbgInfoAndMisc.cpp +++ b/lib/DXIL/DxilUtilDbgInfoAndMisc.cpp @@ -37,7 +37,18 @@ using namespace hlsl; namespace { -Value *MergeGEP(GEPOperator *SrcGEP, GEPOperator *GEP) { +// Attempt to merge the two GEPs into a single GEP. +// +// If `AsCast` is non-null the merged GEP will be wrapped +// in an addrspacecast before replacing users. This allows +// merging GEPs of the form +// +// gep(addrspacecast(gep(p0, gep_args0) to p1*), gep_args1) +// into +// addrspacecast(gep(p0, gep_args0+gep_args1) to p1*) +// +Value *MergeGEP(GEPOperator *SrcGEP, GEPOperator *GEP, + AddrSpaceCastOperator *AsCast) { IRBuilder<> Builder(GEP->getContext()); StringRef Name = ""; if (Instruction *I = dyn_cast(GEP)) { @@ -75,7 +86,7 @@ Value *MergeGEP(GEPOperator *SrcGEP, GEPOperator *GEP) { } // Update the GEP in place if possible. - if (SrcGEP->getNumOperands() == 2) { + if (SrcGEP->getNumOperands() == 2 && !AsCast) { GEP->setOperand(0, SrcGEP->getOperand(0)); GEP->setOperand(1, Sum); return GEP; @@ -94,12 +105,64 @@ Value *MergeGEP(GEPOperator *SrcGEP, GEPOperator *GEP) { DXASSERT(!Indices.empty(), "must merge"); Value *newGEP = Builder.CreateInBoundsGEP(nullptr, SrcGEP->getOperand(0), Indices, Name); + + // Wrap the new gep in an addrspacecast if needed. + if (AsCast) + newGEP = Builder.CreateAddrSpaceCast( + newGEP, PointerType::get(GEP->getType()->getPointerElementType(), + AsCast->getDestAddressSpace())); GEP->replaceAllUsesWith(newGEP); if (Instruction *I = dyn_cast(GEP)) I->eraseFromParent(); return newGEP; } +// Examine the gep and try to merge it when the input pointer is +// itself a gep. We handle two forms here: +// +// gep(gep(p)) +// gep(addrspacecast(gep(p))) +// +// If the gep was merged successfully then return the updated value, otherwise +// return nullptr. +// +// When the gep is sucessfully merged we will delete the gep and also try to +// delete the nested gep and addrspacecast. +static Value *TryMegeWithNestedGEP(GEPOperator *GEP) { + // Sentinal value to return when we fail to merge. + Value *FailedToMerge = nullptr; + + Value *Ptr = GEP->getPointerOperand(); + GEPOperator *prevGEP = dyn_cast(Ptr); + AddrSpaceCastOperator *AsCast = nullptr; + + // If there is no directly nested gep try looking through an addrspacecast to + // find one. + if (!prevGEP) { + AsCast = dyn_cast(Ptr); + if (AsCast) + prevGEP = dyn_cast(AsCast->getPointerOperand()); + } + + // Not a nested gep expression. + if (!prevGEP) + return FailedToMerge; + + // Try merging the two geps. + Value *newGEP = MergeGEP(prevGEP, GEP, AsCast); + if (!newGEP) + return FailedToMerge; + + // Delete the nested gep and addrspacecast if no more users. + if (AsCast && AsCast->user_empty() && isa(AsCast)) + cast(AsCast)->eraseFromParent(); + + if (prevGEP->user_empty() && isa(prevGEP)) + cast(prevGEP)->eraseFromParent(); + + return newGEP; +} + } // namespace namespace hlsl { @@ -130,23 +193,14 @@ bool MergeGepUse(Value *V) { // merge any GEP users of the untranslated bitcast addUsersToWorklist(V); } + } else if (isa(V)) { + addUsersToWorklist(V); } else if (GEPOperator *GEP = dyn_cast(V)) { - if (GEPOperator *prevGEP = - dyn_cast(GEP->getPointerOperand())) { - // merge the 2 GEPs, returns nullptr if couldn't merge - if (Value *newGEP = MergeGEP(prevGEP, GEP)) { - changed = true; - worklist.push_back(newGEP); - // delete prevGEP if no more users - if (prevGEP->user_empty() && isa(prevGEP)) { - cast(prevGEP)->eraseFromParent(); - } - } else { - addUsersToWorklist(GEP); - } + if (Value *newGEP = TryMegeWithNestedGEP(GEP)) { + changed = true; + worklist.push_back(newGEP); } else { - // nothing to merge yet, add GEP users - addUsersToWorklist(V); + addUsersToWorklist(GEP); } } } diff --git a/lib/DxilDia/CMakeLists.txt b/lib/DxilDia/CMakeLists.txt index adb5cd842e..2423d38740 100644 --- a/lib/DxilDia/CMakeLists.txt +++ b/lib/DxilDia/CMakeLists.txt @@ -5,33 +5,67 @@ if (WIN32) find_package(DiaSDK REQUIRED) # Used for constants and declarations. endif (WIN32) -add_llvm_library(LLVMDxilDia - DxcPixCompilationInfo.cpp - DxcPixDxilDebugInfo.cpp - DxcPixDxilStorage.cpp - DxcPixEntrypoints.cpp - DxcPixLiveVariables.cpp - DxcPixLiveVariables_FragmentIterator.cpp - DxcPixTypes.cpp - DxcPixVariables.cpp - DxilDia.cpp - DxilDiaDataSource.cpp - DxilDiaEnumTables.cpp - DxilDiaSession.cpp - DxilDiaSymbolManager.cpp - DxilDiaTable.cpp - DxilDiaTableFrameData.cpp - DxilDiaTableInjectedSources.cpp - DxilDiaTableInputAssemblyFile.cpp - DxilDiaTableLineNumbers.cpp - DxilDiaTableSections.cpp - DxilDiaTableSegmentMap.cpp - DxilDiaTableSourceFiles.cpp - DxilDiaTableSymbols.cpp +if (WIN32) + add_llvm_library(LLVMDxilDia + DxcPixCompilationInfo.cpp + DxcPixDxilDebugInfo.cpp + DxcPixDxilStorage.cpp + DxcPixEntrypoints.cpp + DxcPixLiveVariables.cpp + DxcPixLiveVariables_FragmentIterator.cpp + DxcPixTypes.cpp + DxcPixVariables.cpp + DxilDia.cpp + DxilDiaDataSource.cpp + DxilDiaEnumTables.cpp + DxilDiaSession.cpp + DxilDiaSymbolManager.cpp + DxilDiaTable.cpp + DxilDiaTableFrameData.cpp + DxilDiaTableInjectedSources.cpp + DxilDiaTableInputAssemblyFile.cpp + DxilDiaTableLineNumbers.cpp + DxilDiaTableSections.cpp + DxilDiaTableSegmentMap.cpp + DxilDiaTableSourceFiles.cpp + DxilDiaTableSymbols.cpp + + ADDITIONAL_HEADER_DIRS + ${LLVM_MAIN_INCLUDE_DIR}/llvm/IR + ) +else(WIN32) + # DxcPixLiveVariables_FragmentIterator is not dependent on dia. + # It is used by PixTest. + set(HLSL_IGNORE_SOURCES + DxcPixCompilationInfo.cpp + DxcPixDxilDebugInfo.cpp + DxcPixDxilStorage.cpp + DxcPixEntrypoints.cpp + DxcPixLiveVariables.cpp + DxcPixTypes.cpp + DxcPixVariables.cpp + DxilDia.cpp + DxilDiaDataSource.cpp + DxilDiaEnumTables.cpp + DxilDiaSession.cpp + DxilDiaSymbolManager.cpp + DxilDiaTable.cpp + DxilDiaTableFrameData.cpp + DxilDiaTableInjectedSources.cpp + DxilDiaTableInputAssemblyFile.cpp + DxilDiaTableLineNumbers.cpp + DxilDiaTableSections.cpp + DxilDiaTableSegmentMap.cpp + DxilDiaTableSourceFiles.cpp + DxilDiaTableSymbols.cpp + ) + add_llvm_library(LLVMDxilDia + DxcPixLiveVariables_FragmentIterator.cpp - ADDITIONAL_HEADER_DIRS - ${LLVM_MAIN_INCLUDE_DIR}/llvm/IR -) + ADDITIONAL_HEADER_DIRS + ${LLVM_MAIN_INCLUDE_DIR}/llvm/IR + ) +endif(WIN32) if (WIN32) target_link_libraries(LLVMDxilDia PRIVATE ${LIBRARIES} ${DIASDK_LIBRARIES}) diff --git a/lib/HLSL/DxilValidation.cpp b/lib/HLSL/DxilValidation.cpp index f7d5ef4caa..1e94faf049 100644 --- a/lib/HLSL/DxilValidation.cpp +++ b/lib/HLSL/DxilValidation.cpp @@ -975,7 +975,7 @@ static void ValidateSampleInst(CallInst *CI, Value *srvHandle, isSampleCompTy |= compTy == DXIL::ComponentType::SNormF16; isSampleCompTy |= compTy == DXIL::ComponentType::UNormF16; const ShaderModel *pSM = ValCtx.DxilMod.GetShaderModel(); - if (pSM->IsSM67Plus()) { + if (pSM->IsSM67Plus() && !IsSampleC) { isSampleCompTy |= compTy == DXIL::ComponentType::I16; isSampleCompTy |= compTy == DXIL::ComponentType::U16; isSampleCompTy |= compTy == DXIL::ComponentType::I32; diff --git a/lib/Support/Unix/Signals.inc b/lib/Support/Unix/Signals.inc index 885391f0bc..57479c2760 100644 --- a/lib/Support/Unix/Signals.inc +++ b/lib/Support/Unix/Signals.inc @@ -144,9 +144,6 @@ static void RemoveFilesToRemove() { // memory. std::vector& FilesToRemoveRef = *FilesToRemove; for (unsigned i = 0, e = FilesToRemoveRef.size(); i != e; ++i) { - // We rely on a std::string implementation for which repeated calls to - // 'c_str()' don't allocate memory. We pre-call 'c_str()' on all of these - // strings to try to ensure this is safe. const char *path = FilesToRemoveRef[i].c_str(); // Get the status so we can determine if it's a file or directory. If we @@ -235,21 +232,7 @@ bool llvm::sys::RemoveFileOnSignal(StringRef Filename, std::string* ErrMsg) { { sys::SmartScopedLock Guard(*SignalsMutex); - std::vector& FilesToRemoveRef = *FilesToRemove; - std::string *OldPtr = - FilesToRemoveRef.empty() ? nullptr : &FilesToRemoveRef[0]; - FilesToRemoveRef.push_back(Filename); - - // We want to call 'c_str()' on every std::string in this vector so that if - // the underlying implementation requires a re-allocation, it happens here - // rather than inside of the signal handler. If we see the vector grow, we - // have to call it on every entry. If it remains in place, we only need to - // call it on the latest one. - if (OldPtr == &FilesToRemoveRef[0]) - FilesToRemoveRef.back().c_str(); - else - for (unsigned i = 0, e = FilesToRemoveRef.size(); i != e; ++i) - FilesToRemoveRef[i].c_str(); + FilesToRemove->push_back(Filename); } RegisterHandlers(); @@ -264,13 +247,6 @@ void llvm::sys::DontRemoveFileOnSignal(StringRef Filename) { std::vector::iterator I = FilesToRemove->end(); if (RI != FilesToRemove->rend()) I = FilesToRemove->erase(RI.base()-1); - - // We need to call c_str() on every element which would have been moved by - // the erase. These elements, in a C++98 implementation where c_str() - // requires a reallocation on the first call may have had the call to c_str() - // made on insertion become invalid by being copied down an element. - for (std::vector::iterator E = FilesToRemove->end(); I != E; ++I) - I->c_str(); } /// AddSignalHandler - Add a function to be called when a signal is delivered diff --git a/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp b/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp index 15e0889b51..1b79cd8e4b 100644 --- a/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp +++ b/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp @@ -12,6 +12,7 @@ //===----------------------------------------------------------------------===// #include "InstCombineInternal.h" +#include "llvm/ADT/Triple.h" // HLSL Change #include "llvm/Analysis/InstructionSimplify.h" #include "llvm/IR/ConstantRange.h" #include "llvm/IR/Intrinsics.h" @@ -1634,6 +1635,11 @@ static bool CollectBSwapParts(Value *V, int OverallLeftShift, uint32_t ByteMask, /// MatchBSwap - Given an OR instruction, check to see if this is a bswap idiom. /// If so, insert the new bswap intrinsic and return it. Instruction *InstCombiner::MatchBSwap(BinaryOperator &I) { + // HLSL Change begin - Disable bswap matching for DXIL. + Triple T(I.getModule()->getTargetTriple()); + if (T.isDXIL()) + return nullptr; + // HLSL Change end - Disable bswap matching for DXIL. IntegerType *ITy = dyn_cast(I.getType()); if (!ITy || ITy->getBitWidth() % 16 || // ByteMask only allows up to 32-byte values. diff --git a/lib/Transforms/Scalar/DxilRemoveDeadBlocks.cpp b/lib/Transforms/Scalar/DxilRemoveDeadBlocks.cpp index fee8595c91..54308eed2e 100644 --- a/lib/Transforms/Scalar/DxilRemoveDeadBlocks.cpp +++ b/lib/Transforms/Scalar/DxilRemoveDeadBlocks.cpp @@ -346,8 +346,7 @@ static void EnsureDxilModule(Module *M) { return; for (Function &F : *M) { if (OP::IsDxilOpFunc(&F)) { - bool bSkipInit = true; // Metadata is not necessarily valid yet. - M->GetOrCreateDxilModule(bSkipInit); + M->GetOrCreateDxilModule(); break; } } diff --git a/lib/Transforms/Scalar/LowerTypePasses.cpp b/lib/Transforms/Scalar/LowerTypePasses.cpp index 2750c80222..8b6b96bb09 100644 --- a/lib/Transforms/Scalar/LowerTypePasses.cpp +++ b/lib/Transforms/Scalar/LowerTypePasses.cpp @@ -161,6 +161,7 @@ bool LowerTypePass::runOnModule(Module &M) { HLModule::UpdateGlobalVariableDebugInfo(GV, Finder, NewGV); } // Replace users. + GV->removeDeadConstantUsers(); lowerUseWithNewValue(GV, NewGV); // Remove GV. GV->removeDeadConstantUsers(); diff --git a/projects/dxilconv/include/ShaderBinary/ShaderBinary.h b/projects/dxilconv/include/ShaderBinary/ShaderBinary.h index f73abac9c4..38f0dae598 100644 --- a/projects/dxilconv/include/ShaderBinary/ShaderBinary.h +++ b/projects/dxilconv/include/ShaderBinary/ShaderBinary.h @@ -239,6 +239,11 @@ class COperandBase { public: COperandBase() { Clear(); } COperandBase(const COperandBase &Op) { memcpy(this, &Op, sizeof(*this)); } + COperandBase &operator=(const COperandBase &Op) { + if (this != &Op) + memcpy(this, &Op, sizeof(*this)); + return *this; + } D3D10_SB_OPERAND_TYPE OperandType() const { return m_Type; } const COperandIndex *OperandIndex(UINT Index) const { return &m_Index[Index]; diff --git a/test/Analysis/lit.local.cfg b/test/Analysis/lit.local.cfg index 8e391c57b7..471c2b3281 100644 --- a/test/Analysis/lit.local.cfg +++ b/test/Analysis/lit.local.cfg @@ -1,4 +1,4 @@ -config.unsupported = True # HLSL Change - Disable lit suites. +config.suffixes = [] # HLSL Change - Disable lit suites. # Failing Tests (26): # LLVM :: Analysis/BasicAA/2008-04-15-Byval.ll diff --git a/test/Assembler/lit.local.cfg b/test/Assembler/lit.local.cfg index c000f452a1..e497164a50 100644 --- a/test/Assembler/lit.local.cfg +++ b/test/Assembler/lit.local.cfg @@ -1,4 +1,4 @@ -config.unsupported = True # HLSL Change - Disable lit suites. +config.suffixes = [] # HLSL Change - Disable lit suites. # Failing Tests (5): # LLVM :: Assembler/2007-09-29-GC.ll diff --git a/test/CodeGen/lit.local.cfg b/test/CodeGen/lit.local.cfg index 039670617e..76730bee2a 100644 --- a/test/CodeGen/lit.local.cfg +++ b/test/CodeGen/lit.local.cfg @@ -1 +1 @@ -config.unsupported = True # HLSL Change - Disable lit suites. +config.suffixes = [] # HLSL Change - Disable lit suites. diff --git a/test/Feature/lit.local.cfg b/test/Feature/lit.local.cfg index e6107464f2..0e32d63388 100644 --- a/test/Feature/lit.local.cfg +++ b/test/Feature/lit.local.cfg @@ -1,4 +1,4 @@ -config.unsupported = True # HLSL Change - Disable lit suites. +config.suffixes = [] # HLSL Change - Disable lit suites. # Failing Tests (6): # LLVM :: Feature/intrinsic-noduplicate.ll diff --git a/test/HLSL/passes/instcombine/disable-bswap-match.ll b/test/HLSL/passes/instcombine/disable-bswap-match.ll new file mode 100644 index 0000000000..f7a7378882 --- /dev/null +++ b/test/HLSL/passes/instcombine/disable-bswap-match.ll @@ -0,0 +1,31 @@ +; RUN: opt -instcombine -S %s | FileCheck %s + +; CHECK-NOT: call i32 @llvm.bswap.i32 +target datalayout = "e-m:e-p:32:32-i1:32-i8:32-i16:32-i32:32-i64:64-f16:32-f32:32-f64:64-n8:16:32:64" +target triple = "dxil-ms-dx" + +; Function Attrs: nounwind +define i32 @main(i32 %input) #0 { + %1 = shl i32 %input, 24 + %2 = and i32 %1, -16777216 + %3 = shl i32 %input, 8 + %4 = and i32 %3, 16711680 + %5 = or i32 %2, %4 + %6 = lshr i32 %input, 8 + %7 = and i32 %6, 65280 + %8 = or i32 %5, %7 + %9 = lshr i32 %input, 24 + %10 = and i32 %9, 255 + %11 = or i32 %8, %10 + ret i32 %11 +} + +attributes #0 = { nounwind } + +!llvm.module.flags = !{!0} +!pauseresume = !{!1} +!llvm.ident = !{!2} + +!0 = !{i32 2, !"Debug Info Version", i32 3} +!1 = !{!"hlsl-dxilemit", !"hlsl-dxilload"} +!2 = !{!"dxc(private) 1.7.0.14160 (main, adb2dc70fbd-dirty)"} diff --git a/test/HLSL/passes/multi_dim_one_dim/gep_addrspacecast_gep.ll b/test/HLSL/passes/multi_dim_one_dim/gep_addrspacecast_gep.ll new file mode 100644 index 0000000000..4eb5302388 --- /dev/null +++ b/test/HLSL/passes/multi_dim_one_dim/gep_addrspacecast_gep.ll @@ -0,0 +1,198 @@ +; RUN: opt -S -multi-dim-one-dim %s | FileCheck %s +; +; Tests for the pass that changes multi-dimension global variable accesses into +; a flattened one-dimensional access. The tests focus on the case where the geps +; need to be merged but are separated by an addrspacecast operation. This was +; causing the pass to fail because it could not merge the gep through the +; addrspace cast. + +; Naming convention: gep0_addrspacecast_gep1 + +target datalayout = "e-m:e-p:32:32-i1:32-i8:32-i16:32-i32:32-i64:64-f16:32-f32:32-f64:64-n8:16:32:64" +target triple = "dxil-ms-dx" + +@ArrayOfArray = addrspace(3) global [256 x [9 x float]] undef, align 4 +@ArrayOfArrayOfArray = addrspace(3) global [256 x [9 x [3 x float]]] undef, align 4 + +; Test that we can merge the geps when all parts are instructions. +; CHECK-LABEL: @merge_gep_instr_instr_instr +; CHECK: load float, float* addrspacecast (float addrspace(3)* getelementptr inbounds ([2304 x float], [2304 x float] addrspace(3)* @ArrayOfArray.1dim, i32 0, i32 1) to float*) +define void @merge_gep_instr_instr_instr() { +entry: + %gep0 = getelementptr inbounds [256 x [9 x float]], [256 x [9 x float]] addrspace(3)* @ArrayOfArray, i32 0, i32 0 + %asc = addrspacecast [9 x float] addrspace(3)* %gep0 to [9 x float]* + %gep1 = getelementptr inbounds [9 x float], [9 x float]* %asc, i32 0, i32 1 + %load = load float, float* %gep1 + ret void +} + +; Test that we can merge the geps when the inner gep are constants. +; CHECK-LABEL: @merge_gep_instr_instr_const +; CHECK: load float, float* addrspacecast (float addrspace(3)* getelementptr inbounds ([2304 x float], [2304 x float] addrspace(3)* @ArrayOfArray.1dim, i32 0, i32 1) to float*) +define void @merge_gep_instr_instr_const() { +entry: + %asc = addrspacecast [9 x float] addrspace(3)* getelementptr inbounds ([256 x [9 x float]], [256 x [9 x float]] addrspace(3)* @ArrayOfArray, i32 0, i32 0) to [9 x float]* + %gep1 = getelementptr inbounds [9 x float], [9 x float]* %asc, i32 0, i32 1 + %load = load float, float* %gep1 + ret void +} + +; Test that we can merge the geps when the addrspace and inner gep are constants. +; CHECK-LABEL: @merge_gep_instr_const_const +; CHECK: load float, float* addrspacecast (float addrspace(3)* getelementptr inbounds ([2304 x float], [2304 x float] addrspace(3)* @ArrayOfArray.1dim, i32 0, i32 1) to float*) +define void @merge_gep_instr_const_const() { +entry: + %gep1 = getelementptr inbounds [9 x float], [9 x float]* addrspacecast ([9 x float] addrspace(3)* getelementptr inbounds ([256 x [9 x float]], [256 x [9 x float]] addrspace(3)* @ArrayOfArray, i32 0, i32 0) to [9 x float]*), i32 0, i32 1 + %load = load float, float* %gep1 + ret void +} + +; Test that we can merge the geps when all parts are constants. +; CHECK-LABEL: @merge_gep_const_const +; CHECK: load float, float* addrspacecast (float addrspace(3)* getelementptr inbounds ([2304 x float], [2304 x float] addrspace(3)* @ArrayOfArray.1dim, i32 0, i32 1) to float*) +define void @merge_gep_const_const_const() { +entry: + %load = load float, float* getelementptr inbounds ([9 x float], [9 x float]* addrspacecast ([9 x float] addrspace(3)* getelementptr inbounds ([256 x [9 x float]], [256 x [9 x float]] addrspace(3)* @ArrayOfArray, i32 0, i32 0) to [9 x float]*), i32 0, i32 1) + ret void +} + +; Test that we compute the correct index when the outer array has +; a non-zero constant index. +; CHECK-LABEL: @merge_gep_const_outer_array_index +; CHECK: load float, float* addrspacecast (float addrspace(3)* getelementptr inbounds ([2304 x float], [2304 x float] addrspace(3)* @ArrayOfArray.1dim, i32 0, i32 66) to float*) +define void @merge_gep_const_outer_array_index() { +entry: + %gep0 = getelementptr inbounds [256 x [9 x float]], [256 x [9 x float]] addrspace(3)* @ArrayOfArray, i32 0, i32 7 + %asc = addrspacecast [9 x float] addrspace(3)* %gep0 to [9 x float]* + %gep1 = getelementptr inbounds [9 x float], [9 x float]* %asc, i32 0, i32 3 + %load = load float, float* %gep1 + ret void +} + +; Test that we compute the correct index when the outer array has +; a non-constant index. +; CHECK-LABEL: @merge_gep_dynamic_outer_array_index +; CHECK: %0 = mul i32 %idx, 9 +; CHECK: %1 = add i32 3, %0 +; CHECK: %2 = getelementptr [2304 x float], [2304 x float] addrspace(3)* @ArrayOfArray.1dim, i32 0, i32 %1 +; CHECK: %3 = addrspacecast float addrspace(3)* %2 to float* +; CHECK: load float, float* %3 +define void @merge_gep_dynamic_outer_array_index(i32 %idx) { +entry: + %gep0 = getelementptr inbounds [256 x [9 x float]], [256 x [9 x float]] addrspace(3)* @ArrayOfArray, i32 0, i32 %idx + %asc = addrspacecast [9 x float] addrspace(3)* %gep0 to [9 x float]* + %gep1 = getelementptr inbounds [9 x float], [9 x float]* %asc, i32 0, i32 3 + %load = load float, float* %gep1 + ret void +} + +; Test that we compute the correct index when the both arrays have +; a non-constant index. +; CHECK-LABEL: @merge_gep_dynamic_array_index +; CHECK: %0 = mul i32 %idx0, 9 +; CHECK: %1 = add i32 %idx1, %0 +; CHECK: %2 = getelementptr [2304 x float], [2304 x float] addrspace(3)* @ArrayOfArray.1dim, i32 0, i32 %1 +; CHECK: %3 = addrspacecast float addrspace(3)* %2 to float* +; CHECK: load float, float* %3 +define void @merge_gep_dynamic_array_index(i32 %idx0, i32 %idx1) { +entry: + %gep0 = getelementptr inbounds [256 x [9 x float]], [256 x [9 x float]] addrspace(3)* @ArrayOfArray, i32 0, i32 %idx0 + %asc = addrspacecast [9 x float] addrspace(3)* %gep0 to [9 x float]* + %gep1 = getelementptr inbounds [9 x float], [9 x float]* %asc, i32 0, i32 %idx1 + %load = load float, float* %gep1 + ret void +} + +; Test that we compute the correct index when there are multiple +; geps after the addrspacecast. This also exercises the case +; where one of the outer geps ends in an array which hits +; an early return in MergeGEP. +; CHECK-LABEL: @merge_gep_multi_level_end_in_sequential_with_addrspace +; CHECK: %0 = mul i32 %idx0, 9 +; CHECK: %1 = add i32 %idx1, %0 +; CHECK: %2 = getelementptr [2304 x float], [2304 x float] addrspace(3)* @ArrayOfArray.1dim, i32 0, i32 %1 +; CHECK: %3 = addrspacecast float addrspace(3)* %2 to float* +; CHECK: load float, float* %3 +define void @merge_gep_multi_level_end_in_sequential_with_addrspace(i32 %idx0, i32 %idx1) { +entry: + %gep0 = getelementptr inbounds [256 x [9 x float]], [256 x [9 x float]] addrspace(3)* @ArrayOfArray, i32 0 + %asc = addrspacecast [256 x [9 x float]] addrspace(3)* %gep0 to [256 x [9 x float]]* + %gep1 = getelementptr inbounds [256 x [9 x float]], [256 x [9 x float]]* %asc, i32 0, i32 %idx0 + %gep2 = getelementptr inbounds [9 x float], [9 x float]* %gep1, i32 0, i32 %idx1 + %load = load float, float* %gep2 + ret void +} + +; Test that we compute the correct index when there are three levels of geps. +; This also exercises the case where one of the outer geps ends in an +; array which hits an early return in MergeGEP. +; CHECK-LABEL: @merge_gep_multi_level_end_in_sequential +; CHECK: %0 = mul i32 %idx0, 9 +; CHECK: %1 = add i32 %idx1, %0 +; CHECK: %2 = getelementptr [2304 x float], [2304 x float] addrspace(3)* @ArrayOfArray.1dim, i32 0, i32 %1 +; CHECK: load float, float addrspace(3)* %2 +define void @merge_gep_multi_level_end_in_sequential(i32 %idx0, i32 %idx1) { +entry: + %gep0 = getelementptr inbounds [256 x [9 x float]], [256 x [9 x float]] addrspace(3)* @ArrayOfArray, i32 0 + %gep1 = getelementptr inbounds [256 x [9 x float]], [256 x [9 x float]] addrspace(3)* %gep0, i32 0, i32 %idx0 + %gep2 = getelementptr inbounds [9 x float], [9 x float] addrspace(3)* %gep1, i32 0, i32 %idx1 + %load = load float, float addrspace(3)* %gep2 + ret void +} + +; Test that we compute the correct index when the global has 3 levels of +; nested arrays and an addrspacecast. +; CHECK-LABEL: @merge_gep_multi_level_with_addrspace +; CHECK: %0 = mul i32 %idx0, 9 +; CHECK: %1 = add i32 %idx1, %0 +; CHECK: %2 = mul i32 %1, 3 +; CHECK: %3 = add i32 %idx2, %2 +; CHECK: %4 = getelementptr [6912 x float], [6912 x float] addrspace(3)* @ArrayOfArrayOfArray.1dim, i32 0, i32 %3 +; CHECK: %5 = addrspacecast float addrspace(3)* %4 to float* +; CHECK: load float, float* %5 +define void @merge_gep_multi_level_with_addrspace(i32 %idx0, i32 %idx1, i32 %idx2) { +entry: + %gep0 = getelementptr inbounds [256 x [9 x [3 x float]]], [256 x [9 x [3 x float]]] addrspace(3)* @ArrayOfArrayOfArray, i32 0, i32 %idx0 + %asc = addrspacecast [9 x [3 x float]] addrspace(3)* %gep0 to [9 x [3 x float]]* + %gep1 = getelementptr inbounds [9 x [3 x float]], [9 x [3 x float]]* %asc, i32 0, i32 %idx1 + %gep2 = getelementptr inbounds [3 x float], [3 x float]* %gep1, i32 0, i32 %idx2 + %load = load float, float* %gep2 + ret void +} + +; Test that we compute the correct index when the global has 3 levels of +; nested arrays. +; CHECK-LABEL: @merge_gep_multi_level +; CHECK: %0 = mul i32 %idx0, 9 +; CHECK: %1 = add i32 %idx1, %0 +; CHECK: %2 = mul i32 %1, 3 +; CHECK: %3 = add i32 %idx2, %2 +; CHECK: %4 = getelementptr [6912 x float], [6912 x float] addrspace(3)* @ArrayOfArrayOfArray.1dim, i32 0, i32 %3 +; CHECK: load float, float addrspace(3)* %4 +define void @merge_gep_multi_level(i32 %idx0, i32 %idx1, i32 %idx2) { +entry: + %gep0 = getelementptr inbounds [256 x [9 x [3 x float]]], [256 x [9 x [3 x float]]] addrspace(3)* @ArrayOfArrayOfArray, i32 0, i32 %idx0 + %gep1 = getelementptr inbounds [9 x [3 x float]], [9 x [3 x float]] addrspace(3)* %gep0, i32 0, i32 %idx1 + %gep2 = getelementptr inbounds [3 x float], [3 x float] addrspace(3)* %gep1, i32 0, i32 %idx2 + %load = load float, float addrspace(3)* %gep2 + ret void +} + +; Test that we compute the correct index when the addrspacecast includes both a +; change in address space and a change in the underlying type. I did not see +; this pattern in IR generated from hlsl, but we can handle this case so I am +; adding a test for it anyway. +; CHECK-LABEL: addrspace_cast_new_type +; CHECK: %0 = mul i32 %idx0, 9 +; CHECK: %1 = add i32 %idx1, %0 +; CHECK: %2 = getelementptr [2304 x float], [2304 x float] addrspace(3)* @ArrayOfArray.1dim, i32 0, i32 %1 +; CHECK: %3 = addrspacecast float addrspace(3)* %2 to i32* +; CHECK: load i32, i32* %3 +define void @addrspace_cast_new_type(i32 %idx0, i32 %idx1) { +entry: + %gep0 = getelementptr inbounds [256 x [9 x float]], [256 x [9 x float]] addrspace(3)* @ArrayOfArray, i32 0, i32 %idx0 + %asc = addrspacecast [9 x float] addrspace(3)* %gep0 to [3 x i32]* + %gep1 = getelementptr inbounds [3 x i32], [3 x i32]* %asc, i32 0, i32 %idx1 + %load = load i32, i32* %gep1 + ret void +} \ No newline at end of file diff --git a/test/Instrumentation/lit.local.cfg b/test/Instrumentation/lit.local.cfg index 72e1f98da1..bd4f075ebd 100644 --- a/test/Instrumentation/lit.local.cfg +++ b/test/Instrumentation/lit.local.cfg @@ -1,4 +1,4 @@ -config.unsupported = True # HLSL Change - Disable lit suites. +config.suffixes = [] # HLSL Change - Disable lit suites. # Failing Tests (86): # LLVM :: Instrumentation/AddressSanitizer/adaptive_global_redzones.ll diff --git a/test/Linker/lit.local.cfg b/test/Linker/lit.local.cfg index 2ba04d6911..fa8fea0342 100644 --- a/test/Linker/lit.local.cfg +++ b/test/Linker/lit.local.cfg @@ -1,4 +1,4 @@ -config.unsupported = True # HLSL Change - Disable lit suites. +config.suffixes = [] # HLSL Change - Disable lit suites. # Failing Tests (8): # LLVM :: Linker/pr21374.ll diff --git a/test/SymbolRewriter/lit.local.cfg b/test/SymbolRewriter/lit.local.cfg index 039670617e..76730bee2a 100644 --- a/test/SymbolRewriter/lit.local.cfg +++ b/test/SymbolRewriter/lit.local.cfg @@ -1 +1 @@ -config.unsupported = True # HLSL Change - Disable lit suites. +config.suffixes = [] # HLSL Change - Disable lit suites. diff --git a/test/Transforms/lit.local.cfg b/test/Transforms/lit.local.cfg index 784076f278..8ad744f7c2 100644 --- a/test/Transforms/lit.local.cfg +++ b/test/Transforms/lit.local.cfg @@ -1,4 +1,4 @@ -config.unsupported = True # HLSL Change - Disable lit suites. +config.suffixes = [] # HLSL Change - Disable lit suites. # If these are enabled, a duplicate test was created here which can be deleted: # tools/clang/test/HLSLFileCheck/passes/llvm/globalopt/alias-used.ll diff --git a/test/lit.cfg b/test/lit.cfg index fc040db31d..5f29b02034 100644 --- a/test/lit.cfg +++ b/test/lit.cfg @@ -42,7 +42,7 @@ config.test_format = lit.formats.ShTest(execute_external) # suffixes: A list of file extensions to treat as test files. This is overriden # by individual lit.local.cfg files in the test subdirectories. # HLSL Change Start - use just a subset of LLVM tests -config.suffixes = ['.txt', '.td', '.test'] +config.suffixes = ['.ll', '.txt', '.td', '.test'] #config.suffixes = ['.ll', '.c', '.cxx', '.test', '.txt', '.s'] # HLSL Change End - use just a subset of LLVM tests diff --git a/test/tools/dsymutil/lit.local.cfg b/test/tools/dsymutil/lit.local.cfg index 039670617e..76730bee2a 100644 --- a/test/tools/dsymutil/lit.local.cfg +++ b/test/tools/dsymutil/lit.local.cfg @@ -1 +1 @@ -config.unsupported = True # HLSL Change - Disable lit suites. +config.suffixes = [] # HLSL Change - Disable lit suites. diff --git a/test/tools/llvm-cxxdump/lit.local.cfg b/test/tools/llvm-cxxdump/lit.local.cfg index 039670617e..76730bee2a 100644 --- a/test/tools/llvm-cxxdump/lit.local.cfg +++ b/test/tools/llvm-cxxdump/lit.local.cfg @@ -1 +1 @@ -config.unsupported = True # HLSL Change - Disable lit suites. +config.suffixes = [] # HLSL Change - Disable lit suites. diff --git a/test/tools/llvm-mc/lit.local.cfg b/test/tools/llvm-mc/lit.local.cfg index 039670617e..76730bee2a 100644 --- a/test/tools/llvm-mc/lit.local.cfg +++ b/test/tools/llvm-mc/lit.local.cfg @@ -1 +1 @@ -config.unsupported = True # HLSL Change - Disable lit suites. +config.suffixes = [] # HLSL Change - Disable lit suites. diff --git a/test/tools/llvm-objdump/lit.local.cfg b/test/tools/llvm-objdump/lit.local.cfg index 039670617e..76730bee2a 100644 --- a/test/tools/llvm-objdump/lit.local.cfg +++ b/test/tools/llvm-objdump/lit.local.cfg @@ -1 +1 @@ -config.unsupported = True # HLSL Change - Disable lit suites. +config.suffixes = [] # HLSL Change - Disable lit suites. diff --git a/test/tools/llvm-symbolizer/lit.local.cfg b/test/tools/llvm-symbolizer/lit.local.cfg index 039670617e..76730bee2a 100644 --- a/test/tools/llvm-symbolizer/lit.local.cfg +++ b/test/tools/llvm-symbolizer/lit.local.cfg @@ -1 +1 @@ -config.unsupported = True # HLSL Change - Disable lit suites. +config.suffixes = [] # HLSL Change - Disable lit suites. diff --git a/test/tools/llvm-symbolizer/pdb/lit.local.cfg b/test/tools/llvm-symbolizer/pdb/lit.local.cfg index 039670617e..76730bee2a 100644 --- a/test/tools/llvm-symbolizer/pdb/lit.local.cfg +++ b/test/tools/llvm-symbolizer/pdb/lit.local.cfg @@ -1 +1 @@ -config.unsupported = True # HLSL Change - Disable lit suites. +config.suffixes = [] # HLSL Change - Disable lit suites. diff --git a/test/tools/lto/lit.local.cfg b/test/tools/lto/lit.local.cfg index 597a43fde1..5e981ec5b3 100644 --- a/test/tools/lto/lit.local.cfg +++ b/test/tools/lto/lit.local.cfg @@ -1,3 +1,3 @@ -config.unsupported = True # HLSL Change - Disable lit suites. +config.suffixes = [] # HLSL Change - Disable lit suites. if not 'ld64_plugin' in config.available_features: config.unsupported = True diff --git a/tools/clang/include/clang/Basic/Attr.td b/tools/clang/include/clang/Basic/Attr.td index f9cffe555e..e611d92d60 100644 --- a/tools/clang/include/clang/Basic/Attr.td +++ b/tools/clang/include/clang/Basic/Attr.td @@ -1142,6 +1142,14 @@ def VKExtensionExt : InheritableAttr { let Documentation = [Undocumented]; } +def VKSpvExecutionMode : InheritableAttr { + let Spellings = [CXX11<"vk", "spvexecutionmode">]; + let Subjects = SubjectList<[Function], ErrorDiag>; + let Args = [UnsignedArgument<"ExecutionMode">]; + let LangOpts = [SPIRV]; + let Documentation = [Undocumented]; +} + def VKStorageClassExt : InheritableAttr { let Spellings = [CXX11<"vk", "ext_storage_class">]; let Subjects = SubjectList<[Var, ParmVar], ErrorDiag>; diff --git a/tools/clang/include/clang/SPIRV/FeatureManager.h b/tools/clang/include/clang/SPIRV/FeatureManager.h index c9e8dab9ad..f5314d3312 100644 --- a/tools/clang/include/clang/SPIRV/FeatureManager.h +++ b/tools/clang/include/clang/SPIRV/FeatureManager.h @@ -49,7 +49,6 @@ enum class Extension { EXT_shader_viewport_index_layer, AMD_gpu_shader_half_float, AMD_shader_early_and_late_fragment_tests, - AMD_shader_explicit_vertex_parameter, GOOGLE_hlsl_functionality1, GOOGLE_user_type, NV_ray_tracing, @@ -58,6 +57,8 @@ enum class Extension { EXT_shader_image_int64, KHR_physical_storage_buffer, KHR_vulkan_memory_model, + NV_compute_shader_derivatives, + KHR_fragment_shader_barycentric, Unknown, }; diff --git a/tools/clang/include/clang/SPIRV/SpirvBuilder.h b/tools/clang/include/clang/SPIRV/SpirvBuilder.h index c9c7ac3321..cb47cee948 100644 --- a/tools/clang/include/clang/SPIRV/SpirvBuilder.h +++ b/tools/clang/include/clang/SPIRV/SpirvBuilder.h @@ -86,7 +86,8 @@ class SpirvBuilder { /// \brief Creates and registers a function parameter of the given pointer /// type in the current function and returns its pointer. SpirvFunctionParameter *addFnParam(QualType ptrType, bool isPrecise, - SourceLocation, llvm::StringRef name = ""); + bool isNointerp, SourceLocation, + llvm::StringRef name = ""); /// \brief Creates a local variable of the given type in the current /// function and returns it. @@ -95,6 +96,7 @@ class SpirvBuilder { /// this method for the variable itself. SpirvVariable *addFnVar(QualType valueType, SourceLocation, llvm::StringRef name = "", bool isPrecise = false, + bool isNointerp = false, SpirvInstruction *init = nullptr); /// \brief Ends building of the current function. All basic blocks constructed @@ -631,7 +633,7 @@ class SpirvBuilder { /// constructed in this method. SpirvVariable *addStageIOVar(QualType type, spv::StorageClass storageClass, llvm::StringRef name, bool isPrecise, - SourceLocation loc); + bool isNointerp, SourceLocation loc); /// \brief Adds a stage builtin variable whose value is of the given type. /// @@ -649,12 +651,12 @@ class SpirvBuilder { /// constructed in this method. SpirvVariable * addModuleVar(QualType valueType, spv::StorageClass storageClass, - bool isPrecise, llvm::StringRef name = "", + bool isPrecise, bool isNointerp, llvm::StringRef name = "", llvm::Optional init = llvm::None, SourceLocation loc = {}); SpirvVariable * addModuleVar(const SpirvType *valueType, spv::StorageClass storageClass, - bool isPrecise, llvm::StringRef name = "", + bool isPrecise, bool isNointerp, llvm::StringRef name = "", llvm::Optional init = llvm::None, SourceLocation loc = {}); @@ -714,6 +716,9 @@ class SpirvBuilder { void decoratePerTaskNV(SpirvInstruction *target, uint32_t offset, SourceLocation); + /// \brief Decorates the given target with PerVertexKHR + void decoratePerVertexKHR(SpirvInstruction *argInst, SourceLocation); + /// \brief Decorates the given target with Coherent void decorateCoherent(SpirvInstruction *target, SourceLocation); @@ -761,6 +766,13 @@ class SpirvBuilder { const SpirvPointerType * getPhysicalStorageBufferType(const SpirvType *pointee); + void setPerVertexInterpMode(bool b); + bool isPerVertexInterpMode(); + + void addPerVertexStgInputFuncVarEntry(SpirvInstruction *k, + SpirvInstruction *v); + SpirvInstruction *getPerVertexStgInput(SpirvInstruction *k); + public: std::vector takeModule(); @@ -866,6 +878,10 @@ class SpirvBuilder { /// clone variables. We need it to avoid multiple clone variables for the same /// CTBuffer. llvm::DenseMap fxcCTBufferToClone; + + /// Mapping of a temporary stage parameter variable to real stage input + /// variables, only when the declaration has attribute `nointerpolation` + llvm::DenseMap perVertexInputVarMap; }; void SpirvBuilder::requireCapability(spv::Capability cap, SourceLocation loc) { diff --git a/tools/clang/include/clang/SPIRV/SpirvFunction.h b/tools/clang/include/clang/SPIRV/SpirvFunction.h index acc28301c3..88542255f4 100644 --- a/tools/clang/include/clang/SPIRV/SpirvFunction.h +++ b/tools/clang/include/clang/SPIRV/SpirvFunction.h @@ -59,6 +59,9 @@ class SpirvFunction { return parameters; } + // Gets the vector of variables. + std::vector getVariables() { return variables; } + // Sets the SPIR-V type of the function void setFunctionType(SpirvType *type) { fnType = type; } // Returns the SPIR-V type of the function @@ -98,6 +101,21 @@ class SpirvFunction { basicBlocks[0]->addFirstInstruction(inst); } + /// Adds instructions to a cache array. + void addToInstructionCache(SpirvInstruction *inst) { + instructionsCache.push_back(inst); + } + + /// Adds cached instructions to the front of current function. + void addInstrCacheToFront() { + int cacheSize = instructionsCache.size(); + for (int i = 0; i < cacheSize; i++) { + auto *inst = instructionsCache.back(); + addFirstInstruction(inst); + instructionsCache.pop_back(); + } + instructionsCache.clear(); + } /// Legalization-specific code /// /// Note: the following methods are used for properly handling aliasing. @@ -122,6 +140,15 @@ class SpirvFunction { return parameters[0]->getDebugName() == "param.this"; } + /// Get or set a record for relationship between + /// a function parameter and variable within current function. + void addFuncParamVarEntry(SpirvInstruction *v, SpirvInstruction *p) { + funcVarParamMap[v] = p; + } + SpirvInstruction *getMappedFuncParam(SpirvInstruction *v) { + return funcVarParamMap.lookup(v); + } + private: uint32_t functionId; ///< This function's QualType astReturnType; ///< The return type @@ -130,6 +157,9 @@ class SpirvFunction { bool relaxedPrecision; ///< Whether the return type is at relaxed precision bool precise; ///< Whether the return value is 'precise' bool noInline; ///< The function is marked as no inline + ///< An instructions cache vector. Would be used to help insert instructions + ///< at the beginning of a function. + std::vector instructionsCache; /// Legalization-specific code /// @@ -164,6 +194,9 @@ class SpirvFunction { /// DebugDeclare instructions for parameters to this function. llvm::SmallVector debugDeclares; + + /// Record relationship between a function parameter and its mapped variable. + llvm::DenseMap funcVarParamMap; }; } // end namespace spirv diff --git a/tools/clang/include/clang/SPIRV/SpirvInstruction.h b/tools/clang/include/clang/SPIRV/SpirvInstruction.h index 9f0af77c7b..bc0e36dfef 100644 --- a/tools/clang/include/clang/SPIRV/SpirvInstruction.h +++ b/tools/clang/include/clang/SPIRV/SpirvInstruction.h @@ -172,6 +172,13 @@ class SpirvInstruction { // Invokes SPIR-V visitor on this instruction. virtual bool invokeVisitor(Visitor *) = 0; + // Replace operands with a function callable reference, and if needed, + // refresh instrunctions result type. If current visitor is in entry + // function wrapper, avoid refresh its AST result type. + virtual void replaceOperand( + llvm::function_ref remapOp, + bool inEntryFunctionWrapper){}; + Kind getKind() const { return kind; } spv::Op getopcode() const { return opcode; } QualType getAstResultType() const { return astResultType; } @@ -217,6 +224,9 @@ class SpirvInstruction { void setPrecise(bool p = true) { isPrecise_ = p; } bool isPrecise() const { return isPrecise_; } + void setNoninterpolated(bool ni = true) { isNoninterpolated_ = ni; } + bool isNoninterpolated() const { return isNoninterpolated_; } + void setBitfieldInfo(const BitfieldInfo &info) { bitfieldInfo = info; } llvm::Optional getBitfieldInfo() const { return bitfieldInfo; } @@ -265,6 +275,7 @@ class SpirvInstruction { bool isRelaxedPrecision_; bool isNonUniform_; bool isPrecise_; + bool isNoninterpolated_; llvm::Optional bitfieldInfo; bool isRasterizerOrdered_; }; @@ -540,10 +551,11 @@ class SpirvDecoration : public SpirvInstruction { class SpirvVariable : public SpirvInstruction { public: SpirvVariable(QualType resultType, SourceLocation loc, spv::StorageClass sc, - bool isPrecise, SpirvInstruction *initializerId = 0); + bool isPrecise, bool isNointerp, + SpirvInstruction *initializerId = 0); SpirvVariable(const SpirvType *spvType, SourceLocation loc, - spv::StorageClass sc, bool isPrecise, + spv::StorageClass sc, bool isPrecise, bool isNointerp, SpirvInstruction *initializerId = 0); DEFINE_RELEASE_MEMORY_FOR_CLASS(SpirvVariable) @@ -573,11 +585,11 @@ class SpirvVariable : public SpirvInstruction { class SpirvFunctionParameter : public SpirvInstruction { public: - SpirvFunctionParameter(QualType resultType, bool isPrecise, + SpirvFunctionParameter(QualType resultType, bool isPrecise, bool isNointerp, SourceLocation loc); SpirvFunctionParameter(const SpirvType *spvType, bool isPrecise, - SourceLocation loc); + bool isNointerp, SourceLocation loc); DEFINE_RELEASE_MEMORY_FOR_CLASS(SpirvFunctionParameter) @@ -753,6 +765,11 @@ class SpirvBranchConditional : public SpirvBranching { SpirvInstruction *getCondition() const { return condition; } SpirvBasicBlock *getTrueLabel() const { return trueLabel; } SpirvBasicBlock *getFalseLabel() const { return falseLabel; } + void replaceOperand( + llvm::function_ref remapOp, + bool inEntryFunctionWrapper) override { + condition = remapOp(condition); + } private: SpirvInstruction *condition; @@ -792,6 +809,11 @@ class SpirvReturn : public SpirvTerminator { bool hasReturnValue() const { return returnValue != 0; } SpirvInstruction *getReturnValue() const { return returnValue; } + void replaceOperand( + llvm::function_ref remapOp, + bool inEntryFunctionWrapper) override { + returnValue = remapOp(returnValue); + } private: SpirvInstruction *returnValue; @@ -823,6 +845,11 @@ class SpirvSwitch : public SpirvBranching { SpirvBasicBlock *getTargetLabelForLiteral(uint32_t) const; // Returns all possible branches that could be taken by the switch statement. llvm::ArrayRef getTargetBranches() const override; + void replaceOperand( + llvm::function_ref remapOp, + bool inEntryFunctionWrapper) override { + selector = remapOp(selector); + } private: SpirvInstruction *selector; @@ -867,6 +894,12 @@ class SpirvAccessChain : public SpirvInstruction { SpirvInstruction *getBase() const { return base; } llvm::ArrayRef getIndexes() const { return indices; } + void insertIndex(SpirvInstruction *i, uint32_t index) { + if (index < indices.size()) + indices.insert(&indices[index], i); + else if (index == indices.size()) + indices.push_back(i); + } private: SpirvInstruction *base; @@ -929,6 +962,14 @@ class SpirvAtomic : public SpirvInstruction { return memorySemanticUnequal; } + void replaceOperand( + llvm::function_ref remapOp, + bool inEntryFunctionWrapper) override { + pointer = remapOp(pointer); + value = remapOp(value); + comparator = remapOp(comparator); + } + private: SpirvInstruction *pointer; spv::Scope scope; @@ -1050,6 +1091,12 @@ class SpirvBinaryOp : public SpirvInstruction { bool isSpecConstantOp() const { return getopcode() == spv::Op::OpSpecConstantOp; } + void replaceOperand( + llvm::function_ref remapOp, + bool inEntryFunctionWrapper) override { + operand1 = remapOp(operand1); + operand2 = remapOp(operand2); + } private: SpirvInstruction *operand1; @@ -1071,6 +1118,13 @@ class SpirvBitField : public SpirvInstruction { virtual SpirvInstruction *getBase() const { return base; } virtual SpirvInstruction *getOffset() const { return offset; } virtual SpirvInstruction *getCount() const { return count; } + void replaceOperand( + llvm::function_ref remapOp, + bool inEntryFunctionWrapper) override { + count = remapOp(count); + offset = remapOp(offset); + base = remapOp(base); + } protected: SpirvBitField(Kind kind, spv::Op opcode, QualType resultType, @@ -1120,6 +1174,13 @@ class SpirvBitFieldInsert : public SpirvBitField { SpirvInstruction *getInsert() const { return insert; } + void replaceOperand( + llvm::function_ref remapOp, + bool inEntryFunctionWrapper) override { + SpirvBitField::replaceOperand(remapOp, inEntryFunctionWrapper); + insert = remapOp(insert); + } + private: SpirvInstruction *insert; }; @@ -1267,6 +1328,13 @@ class SpirvCompositeConstruct : public SpirvInstruction { return consituents; } + void replaceOperand( + llvm::function_ref remapOp, + bool inEntryFunctionWrapper) override { + for (size_t idx = 0; idx < consituents.size(); idx++) + consituents[idx] = remapOp(consituents[idx]); + } + private: llvm::SmallVector consituents; }; @@ -1290,6 +1358,12 @@ class SpirvCompositeExtract : public SpirvInstruction { SpirvInstruction *getComposite() const { return composite; } llvm::ArrayRef getIndexes() const { return indices; } + void insertIndex(uint32_t i, uint32_t index) { + if (index < indices.size()) + indices.insert(&indices[index], i); + else if (index == indices.size()) + indices.push_back(i); + } private: SpirvInstruction *composite; @@ -1316,6 +1390,12 @@ class SpirvCompositeInsert : public SpirvInstruction { SpirvInstruction *getComposite() const { return composite; } SpirvInstruction *getObject() const { return object; } llvm::ArrayRef getIndexes() const { return indices; } + void replaceOperand( + llvm::function_ref remapOp, + bool inEntryFunctionWrapper) override { + composite = remapOp(composite); + object = remapOp(object); + } private: SpirvInstruction *composite; @@ -1373,6 +1453,13 @@ class SpirvExtInst : public SpirvInstruction { uint32_t getInstruction() const { return instruction; } llvm::ArrayRef getOperands() const { return operands; } + void replaceOperand( + llvm::function_ref remapOp, + bool inEntryFunctionWrapper) override { + for (size_t idx = 0; idx < operands.size(); idx++) + operands[idx] = remapOp(operands[idx]); + } + private: SpirvExtInstImport *instructionSet; uint32_t instruction; @@ -1398,6 +1485,12 @@ class SpirvFunctionCall : public SpirvInstruction { SpirvFunction *getFunction() const { return function; } llvm::ArrayRef getArgs() const { return args; } + void replaceOperand( + llvm::function_ref remapOp, + bool inEntryFunctionWrapper) override { + for (size_t idx = 0; idx < args.size(); idx++) + args[idx] = remapOp(args[idx]); + } private: SpirvFunction *function; @@ -1441,6 +1534,12 @@ class SpirvNonUniformBinaryOp : public SpirvGroupNonUniformOp { SpirvInstruction *getArg1() const { return arg1; } SpirvInstruction *getArg2() const { return arg2; } + void replaceOperand( + llvm::function_ref remapOp, + bool inEntryFunctionWrapper) override { + arg1 = remapOp(arg1); + arg2 = remapOp(arg2); + } private: SpirvInstruction *arg1; @@ -1484,6 +1583,13 @@ class SpirvNonUniformUnaryOp : public SpirvGroupNonUniformOp { SpirvInstruction *getArg() const { return arg; } bool hasGroupOp() const { return groupOp.hasValue(); } spv::GroupOperation getGroupOp() const { return groupOp.getValue(); } + void replaceOperand( + llvm::function_ref remapOp, + bool inEntryFunctionWrapper) override { + arg = remapOp(arg); + if (inEntryFunctionWrapper) + setAstResultType(arg->getAstResultType()); + } private: SpirvInstruction *arg; @@ -1572,6 +1678,19 @@ class SpirvImageOp : public SpirvInstruction { SpirvInstruction *getMinLod() const { return minLod; } SpirvInstruction *getComponent() const { return component; } SpirvInstruction *getTexelToWrite() const { return texelToWrite; } + void replaceOperand( + llvm::function_ref remapOp, + bool inEntryFunctionWrapper) override { + coordinate = remapOp(coordinate); + dref = remapOp(dref); + bias = remapOp(bias); + lod = remapOp(lod); + gradDx = remapOp(gradDx); + gradDy = remapOp(gradDy); + offset = remapOp(offset); + minLod = remapOp(minLod); + component = remapOp(component); + } private: SpirvInstruction *image; @@ -1621,6 +1740,12 @@ class SpirvImageQuery : public SpirvInstruction { SpirvInstruction *getLod() const { return lod; } bool hasCoordinate() const { return coordinate != nullptr; } SpirvInstruction *getCoordinate() const { return coordinate; } + void replaceOperand( + llvm::function_ref remapOp, + bool inEntryFunctionWrapper) override { + lod = remapOp(lod); + coordinate = remapOp(coordinate); + } private: SpirvInstruction *image; @@ -1672,6 +1797,11 @@ class SpirvImageTexelPointer : public SpirvInstruction { SpirvInstruction *getImage() const { return image; } SpirvInstruction *getCoordinate() const { return coordinate; } SpirvInstruction *getSample() const { return sample; } + void replaceOperand( + llvm::function_ref remapOp, + bool inEntryFunctionWrapper) override { + coordinate = remapOp(coordinate); + } private: SpirvInstruction *image; @@ -1704,6 +1834,13 @@ class SpirvLoad : public SpirvInstruction { void setAlignment(uint32_t alignment); bool hasAlignment() const { return memoryAlignment.hasValue(); } uint32_t getAlignment() const { return memoryAlignment.getValue(); } + void replaceOperand( + llvm::function_ref remapOp, + bool inEntryFunctionWrapper) override { + pointer = remapOp(pointer); + if (inEntryFunctionWrapper) + setAstResultType(pointer->getAstResultType()); + } private: SpirvInstruction *pointer; @@ -1727,6 +1864,13 @@ class SpirvCopyObject : public SpirvInstruction { bool invokeVisitor(Visitor *v) override; SpirvInstruction *getPointer() const { return pointer; } + void replaceOperand( + llvm::function_ref remapOp, + bool inEntryFunctionWrapper) override { + pointer = remapOp(pointer); + if (inEntryFunctionWrapper) + setAstResultType(pointer->getAstResultType()); + } private: SpirvInstruction *pointer; @@ -1802,6 +1946,13 @@ class SpirvSelect : public SpirvInstruction { SpirvInstruction *getCondition() const { return condition; } SpirvInstruction *getTrueObject() const { return trueObject; } SpirvInstruction *getFalseObject() const { return falseObject; } + void replaceOperand( + llvm::function_ref remapOp, + bool inEntryFunctionWrapper) override { + condition = remapOp(condition); + trueObject = remapOp(trueObject); + falseObject = remapOp(falseObject); + } private: SpirvInstruction *condition; @@ -1885,6 +2036,17 @@ class SpirvStore : public SpirvInstruction { void setAlignment(uint32_t alignment); bool hasAlignment() const { return memoryAlignment.hasValue(); } uint32_t getAlignment() const { return memoryAlignment.getValue(); } + void replaceOperand( + llvm::function_ref remapOp, + bool inEntryFunctionWrapper) override { + pointer = remapOp(pointer); + object = remapOp(object); + if (inEntryFunctionWrapper && + object->getAstResultType() != pointer->getAstResultType() && + isa(pointer) && + pointer->getStorageClass() == spv::StorageClass::Output) + pointer->setAstResultType(object->getAstResultType()); + } private: SpirvInstruction *pointer; @@ -1971,6 +2133,11 @@ class SpirvUnaryOp : public SpirvInstruction { SpirvInstruction *getOperand() const { return operand; } bool isConversionOp() const; + void replaceOperand( + llvm::function_ref remapOp, + bool inEntryFunctionWrapper) override { + operand = remapOp(operand); + } private: SpirvInstruction *operand; @@ -1996,6 +2163,12 @@ class SpirvVectorShuffle : public SpirvInstruction { SpirvInstruction *getVec1() const { return vec1; } SpirvInstruction *getVec2() const { return vec2; } llvm::ArrayRef getComponents() const { return components; } + void replaceOperand( + llvm::function_ref remapOp, + bool inEntryFunctionWrapper) override { + vec1 = remapOp(vec1); + vec2 = remapOp(vec2); + } private: SpirvInstruction *vec1; @@ -2157,6 +2330,12 @@ class SpirvIntrinsicInstruction : public SpirvInstruction { llvm::ArrayRef getExtensions() const { return extensions; } SpirvExtInstImport *getInstructionSet() const { return instructionSet; } uint32_t getInstruction() const { return instruction; } + void replaceOperand( + llvm::function_ref remapOp, + bool inEntryFunctionWrapper) override { + for (size_t idx = 0; idx < operands.size(); idx++) + operands[idx] = remapOp(operands[idx]); + } private: uint32_t instruction; diff --git a/tools/clang/include/clang/SPIRV/SpirvModule.h b/tools/clang/include/clang/SPIRV/SpirvModule.h index 442bced065..86a02825ab 100644 --- a/tools/clang/include/clang/SPIRV/SpirvModule.h +++ b/tools/clang/include/clang/SPIRV/SpirvModule.h @@ -164,6 +164,10 @@ class SpirvModule { return entryPoints; } + void setPerVertexInterpMode(bool b) { perVertexInterp = b; } + + bool isPerVertexInterpMode() const { return perVertexInterp; } + private: // Use a set for storing capabilities. This will ensure there are no duplicate // capabilities. Although the set stores pointers, the provided @@ -209,6 +213,8 @@ class SpirvModule { // Keep all rich DebugInfo instructions. llvm::SmallVector debugInstructions; + // Whether current module is in pervertex interpolation mode. + bool perVertexInterp; }; } // end namespace spirv diff --git a/tools/clang/lib/CodeGen/CGBuilder.h b/tools/clang/lib/CodeGen/CGBuilder.h index 6610659131..9e440b6ffb 100644 --- a/tools/clang/lib/CodeGen/CGBuilder.h +++ b/tools/clang/lib/CodeGen/CGBuilder.h @@ -22,9 +22,9 @@ class CodeGenFunction; /// instructions. template class CGBuilderInserter - : protected llvm::IRBuilderDefaultInserter { + : protected llvm::IRBuilderDefaultInserter { public: - CGBuilderInserter() : CGF(nullptr) {} + CGBuilderInserter() = default; explicit CGBuilderInserter(CodeGenFunction *CGF) : CGF(CGF) {} protected: @@ -32,10 +32,9 @@ class CGBuilderInserter void InsertHelper(llvm::Instruction *I, const llvm::Twine &Name, llvm::BasicBlock *BB, llvm::BasicBlock::iterator InsertPt) const; -private: - void operator=(const CGBuilderInserter &) = delete; - CodeGenFunction *CGF; +private: + CodeGenFunction *CGF = nullptr; }; // Don't preserve names on values in an optimized build. diff --git a/tools/clang/lib/SPIRV/CMakeLists.txt b/tools/clang/lib/SPIRV/CMakeLists.txt index 422ef7c025..fd38d1690d 100644 --- a/tools/clang/lib/SPIRV/CMakeLists.txt +++ b/tools/clang/lib/SPIRV/CMakeLists.txt @@ -19,6 +19,7 @@ add_clang_library(clangSPIRV SortDebugInfoVisitor.cpp NonUniformVisitor.cpp PreciseVisitor.cpp + PervertexInputVisitor.cpp RawBufferMethods.cpp RelaxedPrecisionVisitor.cpp RemoveBufferBlockVisitor.cpp diff --git a/tools/clang/lib/SPIRV/CapabilityVisitor.cpp b/tools/clang/lib/SPIRV/CapabilityVisitor.cpp index 76ff5f7a71..5640868733 100644 --- a/tools/clang/lib/SPIRV/CapabilityVisitor.cpp +++ b/tools/clang/lib/SPIRV/CapabilityVisitor.cpp @@ -246,6 +246,12 @@ bool CapabilityVisitor::visit(SpirvDecoration *decor) { loc); break; } + case spv::Decoration::PerVertexKHR: { + addExtension(Extension::KHR_fragment_shader_barycentric, "PerVertexKHR", + loc); + addCapability(spv::Capability::FragmentBarycentricKHR); + break; + } // Capabilities needed for built-ins case spv::Decoration::BuiltIn: { AddVulkanMemoryModelForVolatile(decor, loc); @@ -359,15 +365,14 @@ bool CapabilityVisitor::visit(SpirvDecoration *decor) { addCapability(spv::Capability::CullDistance); break; } - case spv::BuiltIn::BaryCoordNoPerspAMD: - case spv::BuiltIn::BaryCoordNoPerspCentroidAMD: - case spv::BuiltIn::BaryCoordNoPerspSampleAMD: - case spv::BuiltIn::BaryCoordSmoothAMD: - case spv::BuiltIn::BaryCoordSmoothCentroidAMD: - case spv::BuiltIn::BaryCoordSmoothSampleAMD: - case spv::BuiltIn::BaryCoordPullModelAMD: { - addExtension(Extension::AMD_shader_explicit_vertex_parameter, + case spv::BuiltIn::BaryCoordKHR: + case spv::BuiltIn::BaryCoordNoPerspKHR: { + // SV_Barycentrics will have only two builtins + // But it is still allowed to decorate those two builtins with + // interpolation qualifier like centroid or sample. + addExtension(Extension::KHR_fragment_shader_barycentric, "SV_Barycentrics", loc); + addCapability(spv::Capability::FragmentBarycentricKHR); break; } case spv::BuiltIn::ShadingRateKHR: @@ -876,6 +881,13 @@ bool CapabilityVisitor::visit(SpirvModule *, Visitor::Phase phase) { spv::Capability::FragmentShaderShadingRateInterlockEXT, }); + addExtensionAndCapabilitiesIfEnabled( + Extension::NV_compute_shader_derivatives, + { + spv::Capability::ComputeDerivativeGroupQuadsNV, + spv::Capability::ComputeDerivativeGroupLinearNV, + }); + // AccelerationStructureType or RayQueryType can be provided by both // ray_tracing and ray_query extension. By default, we select ray_query to // provide it. This is an arbitrary decision. If the user wants avoid one diff --git a/tools/clang/lib/SPIRV/DeclResultIdMapper.cpp b/tools/clang/lib/SPIRV/DeclResultIdMapper.cpp index f19bfec4ab..516e69ba12 100644 --- a/tools/clang/lib/SPIRV/DeclResultIdMapper.cpp +++ b/tools/clang/lib/SPIRV/DeclResultIdMapper.cpp @@ -933,7 +933,8 @@ DeclResultIdMapper::createFnParam(const ParmVarDecl *param, const auto range = param->getSourceRange(); const auto name = param->getName(); SpirvFunctionParameter *fnParamInstr = spvBuilder.addFnParam( - type, param->hasAttr(), loc, param->getName()); + type, param->hasAttr(), + param->hasAttr(), loc, param->getName()); bool isAlias = false; (void)getTypeAndCreateCounterForPotentialAliasVar(param, &isAlias); fnParamInstr->setContainsAliasComponent(isAlias); @@ -977,8 +978,10 @@ DeclResultIdMapper::createFnVar(const VarDecl *var, const auto loc = var->getLocation(); const auto name = var->getName(); const bool isPrecise = var->hasAttr(); - SpirvVariable *varInstr = spvBuilder.addFnVar( - type, loc, name, isPrecise, init.hasValue() ? init.getValue() : nullptr); + const bool isNointerp = var->hasAttr(); + SpirvVariable *varInstr = + spvBuilder.addFnVar(type, loc, name, isPrecise, isNointerp, + init.hasValue() ? init.getValue() : nullptr); bool isAlias = false; (void)getTypeAndCreateCounterForPotentialAliasVar(var, &isAlias); @@ -1015,18 +1018,22 @@ SpirvDebugGlobalVariable *DeclResultIdMapper::createDebugGlobalVariable( SpirvVariable * DeclResultIdMapper::createFileVar(const VarDecl *var, llvm::Optional init) { + // In the case of template specialization, the same VarDecl node in the AST + // may be traversed more than once. + if (astDecls[var].instr != nullptr) { + return cast(astDecls[var].instr); + } + const auto type = getTypeOrFnRetType(var); const auto loc = var->getLocation(); const auto name = var->getName(); - SpirvVariable *varInstr = - spvBuilder.addModuleVar(type, spv::StorageClass::Private, - var->hasAttr(), name, init, loc); + SpirvVariable *varInstr = spvBuilder.addModuleVar( + type, spv::StorageClass::Private, var->hasAttr(), + var->hasAttr(), name, init, loc); bool isAlias = false; (void)getTypeAndCreateCounterForPotentialAliasVar(var, &isAlias); varInstr->setContainsAliasComponent(isAlias); - - assert(astDecls[var].instr == nullptr); astDecls[var].instr = varInstr; createDebugGlobalVariable(varInstr, type, loc, name); @@ -1096,8 +1103,8 @@ SpirvVariable *DeclResultIdMapper::createExternVar(const VarDecl *var) { const auto name = var->getName(); SpirvVariable *varInstr = spvBuilder.addModuleVar( - type, storageClass, var->hasAttr(), name, llvm::None, - loc); + type, storageClass, var->hasAttr(), + var->hasAttr(), name, llvm::None, loc); varInstr->setLayoutRule(rule); // If this variable has [[vk::combinedImageSampler]] and/or @@ -1260,8 +1267,8 @@ SpirvVariable *DeclResultIdMapper::createStructOrStructArrayVarOfExplicitLayout( // Create the variable for the whole struct / struct array. // The fields may be 'precise', but the structure itself is not. - SpirvVariable *var = - spvBuilder.addModuleVar(resultType, sc, /*isPrecise*/ false, varName); + SpirvVariable *var = spvBuilder.addModuleVar( + resultType, sc, /*isPrecise*/ false, /*isNoInterp*/ false, varName); const SpirvLayoutRule layoutRule = (forCBuffer || forGlobals) @@ -1290,7 +1297,7 @@ void DeclResultIdMapper::createEnumConstant(const EnumConstantDecl *decl) { const auto enumConstant = spvBuilder.getConstantInt(astContext.IntTy, decl->getInitVal()); SpirvVariable *varInstr = spvBuilder.addModuleVar( - astContext.IntTy, spv::StorageClass::Private, /*isPrecise*/ false, + astContext.IntTy, spv::StorageClass::Private, /*isPrecise*/ false, false, decl->getName(), enumConstant, decl->getLocation()); astDecls[valueDecl] = createDeclSpirvInfo(varInstr); } @@ -1617,7 +1624,7 @@ void DeclResultIdMapper::createCounterVar( } SpirvVariable *counterInstr = spvBuilder.addModuleVar( - counterType, sc, /*isPrecise*/ false, counterName); + counterType, sc, /*isPrecise*/ false, false, counterName); if (!isAlias) { // Non-alias counter variables should be put in to resourceVars so that @@ -2428,11 +2435,10 @@ bool DeclResultIdMapper::createStageVars( const hlsl::SigPoint *sigPoint, const NamedDecl *decl, bool asInput, QualType type, uint32_t arraySize, const llvm::StringRef namePrefix, llvm::Optional invocationId, SpirvInstruction **value, - bool noWriteBack, SemanticInfo *inheritSemantic) { + bool noWriteBack, SemanticInfo *inheritSemantic, bool asNoInterp) { // Look through references for stage variables. type = type.getNonReferenceType(); - assert(value); // invocationId should only be used for handling HS per-vertex output. if (invocationId.hasValue()) { @@ -2570,7 +2576,7 @@ bool DeclResultIdMapper::createStageVars( evalType = astContext.BoolTy; break; case hlsl::Semantic::Kind::Barycentrics: - evalType = astContext.getExtVectorType(astContext.FloatTy, 2); + evalType = astContext.getExtVectorType(astContext.FloatTy, 3); break; case hlsl::Semantic::Kind::DispatchThreadID: case hlsl::Semantic::Kind::GroupThreadID: @@ -2608,6 +2614,9 @@ bool DeclResultIdMapper::createStageVars( if (!varInstr) return false; + if (asNoInterp) + varInstr->setNoninterpolated(); + stageVar.setSpirvInstr(varInstr); stageVar.setLocationAttr(decl->getAttr()); stageVar.setIndexAttr(decl->getAttr()); @@ -2701,11 +2710,9 @@ bool DeclResultIdMapper::createStageVars( // Decorate with interpolation modes for pixel shader input variables // or vertex shader output variables. - if (((spvContext.isPS() && sigPoint->IsInput()) || - (spvContext.isVS() && sigPoint->IsOutput())) && - // BaryCoord*AMD buitins already encode the interpolation mode. - semanticKind != hlsl::Semantic::Kind::Barycentrics) - decorateInterpolationMode(decl, type, varInstr); + if ((spvContext.isPS() && sigPoint->IsInput()) || + (spvContext.isVS() && sigPoint->IsOutput())) + decorateInterpolationMode(decl, type, varInstr, *semanticToUse); if (asInput) { *value = spvBuilder.createLoad(evalType, varInstr, loc); @@ -2784,8 +2791,8 @@ bool DeclResultIdMapper::createStageVars( constOne, constZero, thisSemantic.loc); } // Special handling of SV_Barycentrics, which is a float3, but the - // underlying stage input variable is a float2 (only provides the first - // two components). Calculate the third element. + // The 3 values are NOT guaranteed to add up to floating-point 1.0 + // exactly. Calculate the third element here. else if (semanticKind == hlsl::Semantic::Kind::Barycentrics) { const auto x = spvBuilder.createCompositeExtract( astContext.FloatTy, *value, {0}, thisSemantic.loc); @@ -2919,7 +2926,9 @@ bool DeclResultIdMapper::createStageVars( spvBuilder.createStore(ptr, *value, thisSemantic.loc); } } - + if ((decl->hasAttr() || asNoInterp) && + sigPointKind == hlsl::SigPoint::Kind::PSIn) + spvBuilder.addPerVertexStgInputFuncVarEntry(varInstr, *value); return true; } @@ -2956,15 +2965,18 @@ bool DeclResultIdMapper::createStageVars( for (const auto *field : structDecl->fields()) { SpirvInstruction *subValue = nullptr; - if (!createStageVars(sigPoint, field, asInput, field->getType(), - arraySize, namePrefix, invocationId, &subValue, - noWriteBack, semanticToUse)) + if (!createStageVars( + sigPoint, field, asInput, field->getType(), arraySize, namePrefix, + invocationId, &subValue, noWriteBack, semanticToUse, + asNoInterp || field->hasAttr())) return false; subValues.push_back(subValue); } if (arraySize == 0) { *value = spvBuilder.createCompositeConstruct(evalType, subValues, loc); + for (auto *subInstr : subValues) + spvBuilder.addPerVertexStgInputFuncVarEntry(subInstr, *value); return true; } @@ -3042,14 +3054,19 @@ bool DeclResultIdMapper::createStageVars( for (const auto *field : structDecl->fields()) { const auto fieldType = field->getType(); SpirvInstruction *subValue = nullptr; - if (!noWriteBack) + if (!noWriteBack) { subValue = spvBuilder.createCompositeExtract( fieldType, *value, {getNumBaseClasses(type) + field->getFieldIndex()}, loc); + if (field->hasAttr() || + structDecl->hasAttr()) + subValue->setNoninterpolated(); + } - if (!createStageVars(sigPoint, field, asInput, field->getType(), - arraySize, namePrefix, invocationId, &subValue, - noWriteBack, semanticToUse)) + if (!createStageVars( + sigPoint, field, asInput, field->getType(), arraySize, namePrefix, + invocationId, &subValue, noWriteBack, semanticToUse, + asNoInterp || field->hasAttr())) return false; } } @@ -3074,8 +3091,8 @@ bool DeclResultIdMapper::createPayloadStageVars( StageVar stageVar(sigPoint, /*semaInfo=*/{}, /*builtinAttr=*/nullptr, type, getLocationAndComponentCount(astContext, type)); const auto name = namePrefix.str() + "." + decl->getNameAsString(); - SpirvVariable *varInstr = - spvBuilder.addStageIOVar(type, sc, name, /*isPrecise=*/false, loc); + SpirvVariable *varInstr = spvBuilder.addStageIOVar( + type, sc, name, /*isPrecise=*/false, /*isNointerp=*/false, loc); if (!varInstr) return false; @@ -3274,13 +3291,54 @@ DeclResultIdMapper::invertWIfRequested(SpirvInstruction *position, return position; } -void DeclResultIdMapper::decorateInterpolationMode(const NamedDecl *decl, - QualType type, - SpirvVariable *varInstr) { +void DeclResultIdMapper::decorateInterpolationMode( + const NamedDecl *decl, QualType type, SpirvVariable *varInstr, + const SemanticInfo semanticInfo) { if (varInstr->getStorageClass() != spv::StorageClass::Input && varInstr->getStorageClass() != spv::StorageClass::Output) { return; } + const bool isBaryCoord = + (semanticInfo.getKind() == hlsl::Semantic::Kind::Barycentrics); + uint32_t semanticIndex = semanticInfo.index; + + if (isBaryCoord) { + // BaryCentrics inputs cannot have attrib 'nointerpolation'. + if (decl->getAttr()) { + emitError( + "SV_BaryCentrics inputs cannot have attribute 'nointerpolation'.", + decl->getLocation()); + } + // SV_BaryCentrics could only have two index and apply to different inputs. + // The index should be 0 or 1, each index should be mapped to different + // interpolation type. + if (semanticIndex > 1) { + emitError("The index SV_BaryCentrics semantics could only be 1 or 0.", + decl->getLocation()); + } else if (noPerspBaryCentricsIndex < 2 && perspBaryCentricsIndex < 2) { + emitError( + "Cannot have more than 2 inputs with SV_BaryCentrics semantics.", + decl->getLocation()); + } else if (decl->getAttr()) { + if (noPerspBaryCentricsIndex == 2 && + perspBaryCentricsIndex != semanticIndex) { + noPerspBaryCentricsIndex = semanticIndex; + } else { + emitError("Cannot have more than 1 noperspective inputs with " + "SV_BaryCentrics semantics.", + decl->getLocation()); + } + } else { + if (perspBaryCentricsIndex == 2 && + noPerspBaryCentricsIndex != semanticIndex) { + perspBaryCentricsIndex = semanticIndex; + } else { + emitError("Cannot have more than 1 perspective-correct inputs with " + "SV_BaryCentrics semantics.", + decl->getLocation()); + } + } + } const auto loc = decl->getLocation(); if (isUintOrVecMatOfUintType(type) || isSintOrVecMatOfSintType(type) || @@ -3301,9 +3359,9 @@ void DeclResultIdMapper::decorateInterpolationMode(const NamedDecl *decl, // Attributes can be used together. So cannot use else if. if (decl->getAttr()) spvBuilder.decorateCentroid(varInstr, loc); - if (decl->getAttr()) + if (decl->getAttr() && !isBaryCoord) spvBuilder.decorateFlat(varInstr, loc); - if (decl->getAttr()) + if (decl->getAttr() && !isBaryCoord) spvBuilder.decorateNoPerspective(varInstr, loc); if (decl->getAttr()) { spvBuilder.decorateSample(varInstr, loc); @@ -3400,7 +3458,7 @@ SpirvVariable *DeclResultIdMapper::createSpirvStageVar( const auto sigPointKind = sigPoint->GetKind(); const auto type = stageVar->getAstType(); const auto isPrecise = decl->hasAttr(); - + auto isNointerp = decl->hasAttr(); spv::StorageClass sc = getStorageClassForSigPoint(sigPoint); if (sc == spv::StorageClass::Max) return 0; @@ -3453,7 +3511,8 @@ SpirvVariable *DeclResultIdMapper::createSpirvStageVar( case hlsl::SigPoint::Kind::VSIn: case hlsl::SigPoint::Kind::PCOut: case hlsl::SigPoint::Kind::DSIn: - return spvBuilder.addStageIOVar(type, sc, name.str(), isPrecise, srcLoc); + return spvBuilder.addStageIOVar(type, sc, name.str(), isPrecise, + isNointerp, srcLoc); case hlsl::SigPoint::Kind::VSOut: case hlsl::SigPoint::Kind::HSCPIn: case hlsl::SigPoint::Kind::HSCPOut: @@ -3499,7 +3558,8 @@ SpirvVariable *DeclResultIdMapper::createSpirvStageVar( case hlsl::SigPoint::Kind::GSVIn: case hlsl::SigPoint::Kind::GSOut: case hlsl::SigPoint::Kind::PSIn: - return spvBuilder.addStageIOVar(type, sc, name.str(), isPrecise, srcLoc); + return spvBuilder.addStageIOVar(type, sc, name.str(), isPrecise, + isNointerp, srcLoc); default: llvm_unreachable("invalid usage of SV_InstanceID sneaked in"); } @@ -3533,7 +3593,8 @@ SpirvVariable *DeclResultIdMapper::createSpirvStageVar( case hlsl::SigPoint::Kind::VSIn: case hlsl::SigPoint::Kind::PCOut: case hlsl::SigPoint::Kind::DSIn: - return spvBuilder.addStageIOVar(type, sc, name.str(), isPrecise, srcLoc); + return spvBuilder.addStageIOVar(type, sc, name.str(), isPrecise, + isNointerp, srcLoc); case hlsl::SigPoint::Kind::VSOut: case hlsl::SigPoint::Kind::HSCPIn: case hlsl::SigPoint::Kind::HSCPOut: @@ -3555,7 +3616,8 @@ SpirvVariable *DeclResultIdMapper::createSpirvStageVar( case hlsl::Semantic::Kind::IsFrontFace: { switch (sigPointKind) { case hlsl::SigPoint::Kind::GSOut: - return spvBuilder.addStageIOVar(type, sc, name.str(), isPrecise, srcLoc); + return spvBuilder.addStageIOVar(type, sc, name.str(), isPrecise, + isNointerp, srcLoc); case hlsl::SigPoint::Kind::PSIn: stageVar->setIsSpirvBuiltin(); return spvBuilder.addStageBuiltinVar(type, sc, BuiltIn::FrontFacing, @@ -3571,7 +3633,8 @@ SpirvVariable *DeclResultIdMapper::createSpirvStageVar( // An arbitrary semantic is defined by users. Generate normal Vulkan stage // input/output variables. case hlsl::Semantic::Kind::Arbitrary: { - return spvBuilder.addStageIOVar(type, sc, name.str(), isPrecise, srcLoc); + return spvBuilder.addStageIOVar(type, sc, name.str(), isPrecise, isNointerp, + srcLoc); // TODO: patch constant function in hull shader } // According to DXIL spec, the DispatchThreadID SV can only be used by CSIn. @@ -3675,21 +3738,9 @@ SpirvVariable *DeclResultIdMapper::createSpirvStageVar( // Selecting the correct builtin according to interpolation mode auto bi = BuiltIn::Max; if (decl->hasAttr()) { - if (decl->hasAttr()) { - bi = BuiltIn::BaryCoordNoPerspCentroidAMD; - } else if (decl->hasAttr()) { - bi = BuiltIn::BaryCoordNoPerspSampleAMD; - } else { - bi = BuiltIn::BaryCoordNoPerspAMD; - } + bi = BuiltIn::BaryCoordNoPerspKHR; } else { - if (decl->hasAttr()) { - bi = BuiltIn::BaryCoordSmoothCentroidAMD; - } else if (decl->hasAttr()) { - bi = BuiltIn::BaryCoordSmoothSampleAMD; - } else { - bi = BuiltIn::BaryCoordSmoothAMD; - } + bi = BuiltIn::BaryCoordKHR; } return spvBuilder.addStageBuiltinVar(type, sc, bi, isPrecise, srcLoc); @@ -3707,7 +3758,8 @@ SpirvVariable *DeclResultIdMapper::createSpirvStageVar( case hlsl::SigPoint::Kind::DSIn: case hlsl::SigPoint::Kind::DSCPIn: case hlsl::SigPoint::Kind::GSVIn: - return spvBuilder.addStageIOVar(type, sc, name.str(), isPrecise, srcLoc); + return spvBuilder.addStageIOVar(type, sc, name.str(), isPrecise, + isNointerp, srcLoc); case hlsl::SigPoint::Kind::VSOut: case hlsl::SigPoint::Kind::DSOut: stageVar->setIsSpirvBuiltin(); @@ -3736,7 +3788,8 @@ SpirvVariable *DeclResultIdMapper::createSpirvStageVar( case hlsl::SigPoint::Kind::DSIn: case hlsl::SigPoint::Kind::DSCPIn: case hlsl::SigPoint::Kind::GSVIn: - return spvBuilder.addStageIOVar(type, sc, name.str(), isPrecise, srcLoc); + return spvBuilder.addStageIOVar(type, sc, name.str(), isPrecise, + isNointerp, srcLoc); case hlsl::SigPoint::Kind::VSOut: case hlsl::SigPoint::Kind::DSOut: stageVar->setIsSpirvBuiltin(); @@ -4135,6 +4188,7 @@ DeclResultIdMapper::createRayTracingNVStageVar(spv::StorageClass sc, case spv::StorageClass::RayPayloadNV: case spv::StorageClass::CallableDataNV: retVal = spvBuilder.addModuleVar(type, sc, decl->hasAttr(), + decl->hasAttr(), name.str()); break; diff --git a/tools/clang/lib/SPIRV/DeclResultIdMapper.h b/tools/clang/lib/SPIRV/DeclResultIdMapper.h index 43d3de7e9d..b095d35c30 100644 --- a/tools/clang/lib/SPIRV/DeclResultIdMapper.h +++ b/tools/clang/lib/SPIRV/DeclResultIdMapper.h @@ -663,7 +663,7 @@ class DeclResultIdMapper { const llvm::StringRef namePrefix, llvm::Optional invocationId, SpirvInstruction **value, bool noWriteBack, - SemanticInfo *inheritSemantic); + SemanticInfo *inheritSemantic, bool asNoInterp = false); /// Creates the SPIR-V variable instruction for the given StageVar and returns /// the instruction. Also sets whether the StageVar is a SPIR-V builtin and @@ -711,7 +711,8 @@ class DeclResultIdMapper { /// Decorates varInstr of the given asType with proper interpolation modes /// considering the attributes on the given decl. void decorateInterpolationMode(const NamedDecl *decl, QualType asType, - SpirvVariable *varInstr); + SpirvVariable *varInstr, + const SemanticInfo semanticInfo); /// Returns the proper SPIR-V storage class (Input or Output) for the given /// SigPoint. @@ -902,6 +903,8 @@ class DeclResultIdMapper { /// an additional SPIR-V optimization pass to flatten such structures. bool needsFlatteningCompositeResources; + uint32_t perspBaryCentricsIndex, noPerspBaryCentricsIndex; + public: /// The gl_PerVertex structs for both input and output GlPerVertex glPerVertex; @@ -931,6 +934,7 @@ DeclResultIdMapper::DeclResultIdMapper(ASTContext &context, spirvOptions(options), astContext(context), spvContext(spirvContext), diags(context.getDiagnostics()), entryFunction(nullptr), needsLegalization(false), needsFlatteningCompositeResources(false), + perspBaryCentricsIndex(2), noPerspBaryCentricsIndex(2), glPerVertex(context, spirvContext, spirvBuilder) {} bool DeclResultIdMapper::decorateStageIOLocations() { diff --git a/tools/clang/lib/SPIRV/FeatureManager.cpp b/tools/clang/lib/SPIRV/FeatureManager.cpp index fba972d6cf..edaa1c43b5 100644 --- a/tools/clang/lib/SPIRV/FeatureManager.cpp +++ b/tools/clang/lib/SPIRV/FeatureManager.cpp @@ -183,8 +183,6 @@ Extension FeatureManager::getExtensionSymbol(llvm::StringRef name) { Extension::AMD_gpu_shader_half_float) .Case("SPV_AMD_shader_early_and_late_fragment_tests", Extension::AMD_shader_early_and_late_fragment_tests) - .Case("SPV_AMD_shader_explicit_vertex_parameter", - Extension::AMD_shader_explicit_vertex_parameter) .Case("SPV_GOOGLE_hlsl_functionality1", Extension::GOOGLE_hlsl_functionality1) .Case("SPV_GOOGLE_user_type", Extension::GOOGLE_user_type) @@ -199,6 +197,10 @@ Extension FeatureManager::getExtensionSymbol(llvm::StringRef name) { .Case("SPV_KHR_physical_storage_buffer", Extension::KHR_physical_storage_buffer) .Case("SPV_KHR_vulkan_memory_model", Extension::KHR_vulkan_memory_model) + .Case("SPV_NV_compute_shader_derivatives", + Extension::NV_compute_shader_derivatives) + .Case("SPV_KHR_fragment_shader_barycentric", + Extension::KHR_fragment_shader_barycentric) .Default(Extension::Unknown); } @@ -242,8 +244,6 @@ const char *FeatureManager::getExtensionName(Extension symbol) { return "SPV_AMD_gpu_shader_half_float"; case Extension::AMD_shader_early_and_late_fragment_tests: return "SPV_AMD_shader_early_and_late_fragment_tests"; - case Extension::AMD_shader_explicit_vertex_parameter: - return "SPV_AMD_shader_explicit_vertex_parameter"; case Extension::GOOGLE_hlsl_functionality1: return "SPV_GOOGLE_hlsl_functionality1"; case Extension::GOOGLE_user_type: @@ -262,6 +262,10 @@ const char *FeatureManager::getExtensionName(Extension symbol) { return "SPV_KHR_physical_storage_buffer"; case Extension::KHR_vulkan_memory_model: return "SPV_KHR_vulkan_memory_model"; + case Extension::NV_compute_shader_derivatives: + return "SPV_NV_compute_shader_derivatives"; + case Extension::KHR_fragment_shader_barycentric: + return "SPV_KHR_fragment_shader_barycentric"; default: break; } diff --git a/tools/clang/lib/SPIRV/InitListHandler.cpp b/tools/clang/lib/SPIRV/InitListHandler.cpp index 7f52abf8c3..a2a7c8a59a 100644 --- a/tools/clang/lib/SPIRV/InitListHandler.cpp +++ b/tools/clang/lib/SPIRV/InitListHandler.cpp @@ -80,7 +80,12 @@ void InitListHandler::flatten(const InitListExpr *expr) { init->IgnoreParenNoopCasts(theEmitter.getASTContext()))) { flatten(subInitList); } else { - initializers.push_back(theEmitter.loadIfGLValue(init)); + auto *initializer = theEmitter.loadIfGLValue(init); + if (!initializer) { + initializers.clear(); + return; + } + initializers.push_back(initializer); } } } @@ -253,6 +258,10 @@ InitListHandler::createInitForBuiltinType(QualType type, while (tryToSplitStruct() || tryToSplitConstantArray()) ; + if (initializers.empty()) { + return nullptr; + } + auto init = initializers.back(); initializers.pop_back(); @@ -385,7 +394,30 @@ InitListHandler::createInitForStructType(QualType type, SourceLocation srcLoc, } llvm::SmallVector fields; + + // Initialize base classes first. + llvm::SmallVector base_fields; const RecordDecl *structDecl = type->getAsStructureType()->getDecl(); + if (auto *cxxStructDecl = dyn_cast(structDecl)) { + for (CXXBaseSpecifier base : cxxStructDecl->bases()) { + QualType baseType = base.getType(); + const RecordType *baseStructType = baseType->getAsStructureType(); + if (baseStructType == nullptr) { + continue; + } + const RecordDecl *baseStructDecl = baseStructType->getDecl(); + for (const auto *field : baseStructDecl->fields()) { + base_fields.push_back( + createInitForType(field->getType(), field->getLocation(), range)); + if (!base_fields.back()) + return nullptr; + } + fields.push_back(spvBuilder.createCompositeConstruct( + baseType, base_fields, srcLoc, range)); + base_fields.clear(); + } + } + for (const auto *field : structDecl->fields()) { fields.push_back( createInitForType(field->getType(), field->getLocation(), range)); diff --git a/tools/clang/lib/SPIRV/PervertexInputVisitor.cpp b/tools/clang/lib/SPIRV/PervertexInputVisitor.cpp new file mode 100644 index 0000000000..a7a5b7a7ea --- /dev/null +++ b/tools/clang/lib/SPIRV/PervertexInputVisitor.cpp @@ -0,0 +1,319 @@ +//===--- PervertexInputVisitor.cpp ---- PerVertex Input Visitor --*- C++ -*-==// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "PervertexInputVisitor.h" +#include "clang/SPIRV/AstTypeProbe.h" +#include "clang/SPIRV/SpirvFunction.h" +#include "clang/SPIRV/SpirvType.h" + +#include + +namespace clang { +namespace spirv { + +///< For expanded variables, we need to decide where to add an extra index zero +///< for SpirvAccessChain and SpirvCompositeExtract. This comes to three access +///< cases : 1. array element. 2. structure member 3. vector channel. +int PervertexInputVisitor::appendIndexZeroAt( + QualType baseType, llvm::ArrayRef instIndexes) { + if (instIndexes.size() == 0) + return 0; + ///< 1. Array element + if (baseType.getTypePtr()->isArrayType()) { + int delta = + appendIndexZeroAt(baseType->getAsArrayTypeUnsafe()->getElementType(), + instIndexes.slice(1)); + if (delta == 0) + // swizzling at an array element in lowest level. + return 0; + else + // intermediate array/struct element access. + return 1 + delta; + } + ///< 2. structure member + if (baseType.getTypePtr()->isStructureType()) { + uint32_t idx = instIndexes[0]; + for (auto *f : baseType->getAs()->getDecl()->fields()) { + if (idx == 0) { + return 1 + appendIndexZeroAt(f->getType(), instIndexes.slice(1)); + break; + } + idx--; + } + } + ///< 3. vector channel. + return 0; +} + +///< Expand nointerpolation decorated variables/parameters. +///< If a variable/parameter is passed from a decorated inputs, it should be +///< treated as nointerpolated too. +bool PervertexInputVisitor::expandNointerpVarAndParam( + SpirvInstruction *spvInst) { + QualType type = spvInst->getAstResultType(); + bool isExpanded = false; + auto typePtr = type.getTypePtr(); + if (typePtr->isStructureType()) { + /// Structure + isExpanded = expandNointerpStructure(type, spvInst->isNoninterpolated()); + } else if (spvInst->isNoninterpolated()) { + /// Normal type + isExpanded = true; + type = astContext.getConstantArrayType(type, llvm::APInt(32, 3), + clang::ArrayType::Normal, 0); + spvInst->setAstResultType(type); + } + return isExpanded; +} + +bool PervertexInputVisitor::expandNointerpStructure(QualType type, + bool isVarDecoratedInterp) { + QualType currentType = type; + auto typePtr = type.getTypePtr(); + if (m_expandedStructureType.count(typePtr) > 0) + return true; + bool hasNoInterp = false; + if (typePtr->isStructureType()) { + const auto *structDecl = type->getAs()->getDecl(); + bool structTypeNoInterp = structDecl->hasAttr(); + uint32_t i = 0; + for (auto *field : structDecl->fields()) { + bool expandElem = (isVarDecoratedInterp || structTypeNoInterp || + field->hasAttr()); + if (field->getType().getTypePtr()->isStructureType()) + expandNointerpStructure(field->getType(), expandElem); + else if (expandElem) { + currentType = astContext.getConstantArrayType( + field->getType(), llvm::APInt(32, 3), clang::ArrayType::Normal, 0); + field->setType(currentType); + hasNoInterp = true; + } + i++; + } + } + if (hasNoInterp) + m_expandedStructureType.insert(typePtr); + return hasNoInterp; +} + +///< Get mapped operand used to replace original operand, if not exists, return +///< itself. +SpirvInstruction * +PervertexInputVisitor::getMappedReplaceInstr(SpirvInstruction *i) { + auto *replacedInstr = m_instrReplaceMap.lookup(i); + if (replacedInstr) + return replacedInstr; + else + return i; +} + +///< Add temp function variables, for operand replacement. An original usage to +///< a nointerpolated variable/parameter should be treated as an access to +///< its first element after expanding (data at first provoking vertex). +SpirvInstruction * +PervertexInputVisitor::createFirstPerVertexVar(SpirvInstruction *base, + llvm::StringRef varName) { + auto loc = base->getSourceLocation(); + auto *vtx = addFunctionTempVar(varName.str(), base->getAstResultType(), loc, + base->isPrecise()); + createVertexStore(vtx, createVertexLoad(base)); + return vtx; +} + +SpirvInstruction *PervertexInputVisitor::createProvokingVertexAccessChain( + SpirvInstruction *base, uint32_t index, QualType resultType) { + auto loc = base->getSourceLocation(); + auto range = base->getSourceRange(); + llvm::SmallVector indexes; + indexes.push_back(spirvBuilder.getConstantInt(astContext.UnsignedIntTy, + llvm::APInt(32, index))); + SpirvInstruction *instruction = + new (context) SpirvAccessChain(resultType, loc, base, indexes, range); + instruction->setStorageClass(spv::StorageClass::Function); + instruction->setLayoutRule(base->getLayoutRule()); + instruction->setContainsAliasComponent(base->containsAliasComponent()); + instruction->setNoninterpolated(false); + currentFunc->addToInstructionCache(instruction); + return instruction; +} + +SpirvVariable * +PervertexInputVisitor::addFunctionTempVar(llvm::StringRef varName, + QualType valueType, + SourceLocation loc, bool isPrecise) { + QualType varType = valueType; + if (varType.getTypePtr()->isPointerType()) + varType = varType.getTypePtr()->getPointeeType(); + SpirvVariable *var = new (context) SpirvVariable( + varType, loc, spv::StorageClass::Function, isPrecise, false, nullptr); + var->setDebugName(varName); + currentFunc->addVariable(var); + return var; +} + +///< When use temp variables within a function, we need to add load/store ops. +///< TIP: A nointerpolated input or function parameter will be treated as +///< input.vtx0 within current function, but would be treated as an array will +///< pass to a function call. +SpirvInstruction * +PervertexInputVisitor::createVertexLoad(SpirvInstruction *base) { + SpirvInstruction *loadPtr = new (context) + SpirvLoad(base->getAstResultType(), base->getSourceLocation(), base, + base->getSourceRange()); + loadPtr->setStorageClass(spv::StorageClass::Function); + loadPtr->setLayoutRule(base->getLayoutRule()); + loadPtr->setRValue(true); + currentFunc->addToInstructionCache(loadPtr); + return loadPtr; +} + +void PervertexInputVisitor::createVertexStore(SpirvInstruction *pt, + SpirvInstruction *obj) { + auto *storeInstr = new (context) SpirvStore(pt->getSourceLocation(), pt, obj); + currentFunc->addToInstructionCache(storeInstr); +} + +// Don't add extra index to a simple vector/matrix elem access when base is not +// expanded. Like: +// %99 = OpAccessChain %_ptr_Function_v3bool %input %int_2 %uint_0 +// %101 = OpAccessChain % _ptr_Function_bool % 99 % int_1 +bool PervertexInputVisitor::isNotExpandedVectorAccess(QualType baseType, + QualType resultType) { + QualType elemType = {}; + return (isVectorType(baseType, &elemType) || + isMxNMatrix(baseType, &elemType)) && + elemType == resultType && !baseType.getTypePtr()->isArrayType(); +} + +bool PervertexInputVisitor::visit(SpirvModule *m, Phase phase) { + if (!m->isPerVertexInterpMode()) + return false; + currentMod = m; + return true; +} + +bool PervertexInputVisitor::visit(SpirvEntryPoint *ep) { + // Add variable mapping here. First function would be main. + currentFunc = ep->getEntryPoint(); + /// Refine stage in/out variables + for (auto *var : currentMod->getVariables()) { + if (!var->isNoninterpolated() || + var->getStorageClass() != spv::StorageClass::Input) + continue; + auto *stgIOLoadPtr = spirvBuilder.getPerVertexStgInput(var); + if (!isa(stgIOLoadPtr)) { + stgIOLoadPtr->setAstResultType(var->getAstResultType()); + } + } + return true; +} + +bool PervertexInputVisitor::visit(SpirvFunction *sf, Phase phase) { + // Add variable mapping here. First function would be main. + currentFunc = sf; + inEntryFunctionWrapper = false; + if (sf->isEntryFunctionWrapper()) { + if (phase != Phase::Done) { + inEntryFunctionWrapper = true; + return true; + } + } + if (phase == Phase::Done) { + currentFunc->addInstrCacheToFront(); + } else { + // Refine variables and parameters. Add vtx0 for them. + // (Those param and var haven't been expanded at this point). + for (auto *var : currentFunc->getVariables()) { + if (!var->isNoninterpolated()) + continue; + auto *vtx0 = + createProvokingVertexAccessChain(var, 0, var->getAstResultType()); + m_instrReplaceMap[var] = vtx0; + } + for (auto *param : currentFunc->getParameters()) { + if (!param->isNoninterpolated()) + continue; + auto *vtx0 = + createProvokingVertexAccessChain(param, 0, param->getAstResultType()); + auto paramName = param->getDebugName().str() + "_perVertexParam0"; + m_instrReplaceMap[param] = createFirstPerVertexVar(vtx0, paramName); + } + } + return true; +} + +/// Spirv Instruction check and pointer replacement if needed. +bool PervertexInputVisitor::visit(SpirvVariable *inst) { + if (expandNointerpVarAndParam(inst) && + inst->getStorageClass() == spv::StorageClass::Input) + spirvBuilder.decoratePerVertexKHR(inst, inst->getSourceLocation()); + return true; +} + +bool PervertexInputVisitor::visit(SpirvFunctionParameter *inst) { + expandNointerpVarAndParam(inst); + return true; +} + +bool PervertexInputVisitor::visit(SpirvCompositeExtract *inst) { + if (inst->isNoninterpolated() && + !isNotExpandedVectorAccess(inst->getComposite()->getAstResultType(), + inst->getAstResultType())) { + int idx = appendIndexZeroAt(inst->getComposite()->getAstResultType(), + inst->getIndexes()); + inst->insertIndex(0, idx); + inst->setNoninterpolated(false); + } + return true; +} + +bool PervertexInputVisitor::visit(SpirvAccessChain *inst) { + llvm::SmallVector indexes; + SpirvInstruction *zero = + spirvBuilder.getConstantInt(astContext.UnsignedIntTy, llvm::APInt(32, 0)); + auto idx = dyn_cast(inst)->getIndexes(); + for (auto i : idx) { + if (isa(i)) { + indexes.push_back( + dyn_cast(i)->getValue().getZExtValue()); + } + } + + if (inst->isNoninterpolated() && + !isNotExpandedVectorAccess(inst->getBase()->getAstResultType(), + inst->getAstResultType())) { + // Not add extra index to a vector channel access. + int idx = appendIndexZeroAt(inst->getBase()->getAstResultType(), indexes); + inst->insertIndex(zero, idx); + inst->setNoninterpolated(false); + } + return true; +} + +// Only replace argument if not in entry function. +// If an expanded variable/parameter is passed to a function, +// recreate a pair of Store/Load instructions. +bool PervertexInputVisitor::visit(SpirvFunctionCall *inst) { + /// Replace each use of pervertex inputs with its vertex0 element within + /// functions. But pass it as an array if meet function call. + if (inEntryFunctionWrapper) + return true; + /// Load/Store instructions related to this argument may have been replaced + /// with other instructions, so we need to get its original mapped variables. + for (auto *arg : inst->getArgs()) + if (currentFunc->getMappedFuncParam(arg)) { + createVertexStore(arg, + createVertexLoad(currentFunc->getMappedFuncParam(arg))); + } + currentFunc->addInstrCacheToFront(); + return true; +} + +} // end namespace spirv +} // end namespace clang diff --git a/tools/clang/lib/SPIRV/PervertexInputVisitor.h b/tools/clang/lib/SPIRV/PervertexInputVisitor.h new file mode 100644 index 0000000000..89c074c59a --- /dev/null +++ b/tools/clang/lib/SPIRV/PervertexInputVisitor.h @@ -0,0 +1,135 @@ +//===--- PervertexInputVisitor.h ---- PerVertex Input Visitor ----------------// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_LIB_SPIRV_PERVERTEXINPUTVISITOR_H +#define LLVM_CLANG_LIB_SPIRV_PERVERTEXINPUTVISITOR_H + +#include "clang/AST/ASTContext.h" +#include "clang/SPIRV/SpirvBuilder.h" +#include "clang/SPIRV/SpirvContext.h" +#include "clang/SPIRV/SpirvModule.h" +#include "clang/SPIRV/SpirvVisitor.h" + +namespace clang { +namespace spirv { + +class PervertexInputVisitor : public Visitor { +public: + PervertexInputVisitor(SpirvBuilder &spvBuilder, ASTContext &astCtx, + SpirvContext &spvCtx, const SpirvCodeGenOptions &opts) + : Visitor(opts, spvCtx), inEntryFunctionWrapper(false), + spirvBuilder(spvBuilder), astContext(astCtx), currentMod(nullptr), + currentFunc(nullptr) {} + + ///< Don't add extra index to a simple vector/matrix elem access when base is + ///< not expanded. + bool isNotExpandedVectorAccess(QualType baseType, QualType resultType); + + ///< Expand nointerpolation decorated variables/parameters. + ///< If a variable/parameter is passed from a decorated inputs, it should be + ///< treated as nointerpolated too. + bool expandNointerpVarAndParam(SpirvInstruction *spvInst); + + bool expandNointerpStructure(QualType qtype, bool isVarDecoratedInterp); + + ///< Add temp function variables, for operand replacement. An original usage + ///< to a nointerpolated variable/parameter should be treated as an access to + ///< its first element after expanding (data at first provoking vertex). + SpirvInstruction *createFirstPerVertexVar(SpirvInstruction *base, + llvm::StringRef varName); + + SpirvVariable *addFunctionTempVar(llvm::StringRef name, QualType valueType, + SourceLocation loc, bool isPrecise); + + SpirvInstruction *createProvokingVertexAccessChain(SpirvInstruction *base, + uint32_t index, + QualType resultType); + + ///< Get mapped operand used to replace original operand, if not exists, + ///< return itself. + SpirvInstruction *getMappedReplaceInstr(SpirvInstruction *i); + + ///< For expanded variables, we need to decide where to add an extra index + ///< zero for SpirvAccessChain and SpirvCompositeExtract. This comes to + ///< three access cases : 1. array element. 2. structure member 3. vector + ///< channel. + int appendIndexZeroAt(QualType base, llvm::ArrayRef index); + + ///< When use temp variables within a function, we need to add load/store ops. + ///< TIP: A nointerpolated input or function parameter will be treated as + ///< input.vtx0 within current function, but would be treated as an array will + ///< pass to a function call. + SpirvInstruction *createVertexLoad(SpirvInstruction *base); + + void createVertexStore(SpirvInstruction *pt, SpirvInstruction *obj); + + ///< Visit different SPIR-V constructs for emitting. + using Visitor::visit; + bool visit(SpirvModule *, Phase phase) override; + bool visit(SpirvFunction *, Phase phase) override; + bool visit(SpirvEntryPoint *) override; + bool visit(SpirvVariable *) override; + bool visit(SpirvFunctionParameter *) override; + bool visit(SpirvAccessChain *) override; + bool visit(SpirvCompositeExtract *) override; + bool visit(SpirvFunctionCall *) override; + +#define REMAP_FUNC_OP(CLASS) \ + bool visit(Spirv##CLASS *op) override { \ + op->replaceOperand( \ + [this](SpirvInstruction *inst) { \ + return getMappedReplaceInstr(inst); \ + }, \ + inEntryFunctionWrapper); \ + return true; \ + } + + REMAP_FUNC_OP(ImageQuery) + REMAP_FUNC_OP(ImageOp) + REMAP_FUNC_OP(ExtInst) + REMAP_FUNC_OP(Atomic) + REMAP_FUNC_OP(NonUniformBinaryOp) + REMAP_FUNC_OP(BitFieldInsert) + REMAP_FUNC_OP(BitFieldExtract) + REMAP_FUNC_OP(IntrinsicInstruction) + REMAP_FUNC_OP(VectorShuffle) + REMAP_FUNC_OP(CompositeConstruct) + REMAP_FUNC_OP(BinaryOp) + REMAP_FUNC_OP(Store) + REMAP_FUNC_OP(Load) + REMAP_FUNC_OP(UnaryOp) + REMAP_FUNC_OP(CompositeInsert) + REMAP_FUNC_OP(BranchConditional) + REMAP_FUNC_OP(Return) + REMAP_FUNC_OP(ImageTexelPointer) + REMAP_FUNC_OP(Select) + REMAP_FUNC_OP(Switch) + REMAP_FUNC_OP(CopyObject) + REMAP_FUNC_OP(NonUniformUnaryOp) + +private: + ///< Whether in entry function wrapper, which will influence replace steps. + bool inEntryFunctionWrapper; + ///< Instruction replacement mapper. + ///< For AccessChain and CompositeExtract, will only add extra index. + llvm::DenseMap m_instrReplaceMap; + ///< Global declared structure type is special, + ///< we won't redeclare/expand it more than once. + llvm::SmallSet m_expandedStructureType; + ///< Context related helpers, will use to modify spv instruction stream. + SpirvBuilder &spirvBuilder; + ASTContext &astContext; + SpirvModule *currentMod; + SpirvFunction *currentFunc; +}; + +} // end namespace spirv +} // end namespace clang + +#endif // LLVM_CLANG_LIB_SPIRV_PERVERTEXINPUTVISITOR_H diff --git a/tools/clang/lib/SPIRV/SpirvBuilder.cpp b/tools/clang/lib/SPIRV/SpirvBuilder.cpp index ef16a75b5d..2b15d157e1 100644 --- a/tools/clang/lib/SPIRV/SpirvBuilder.cpp +++ b/tools/clang/lib/SPIRV/SpirvBuilder.cpp @@ -14,6 +14,7 @@ #include "LiteralTypeVisitor.h" #include "LowerTypeVisitor.h" #include "NonUniformVisitor.h" +#include "PervertexInputVisitor.h" #include "PreciseVisitor.h" #include "RelaxedPrecisionVisitor.h" #include "RemoveBufferBlockVisitor.h" @@ -65,10 +66,9 @@ SpirvFunction *SpirvBuilder::beginFunction(QualType returnType, return function; } -SpirvFunctionParameter *SpirvBuilder::addFnParam(QualType ptrType, - bool isPrecise, - SourceLocation loc, - llvm::StringRef name) { +SpirvFunctionParameter * +SpirvBuilder::addFnParam(QualType ptrType, bool isPrecise, bool isNointerp, + SourceLocation loc, llvm::StringRef name) { assert(function && "found detached parameter"); SpirvFunctionParameter *param = nullptr; if (isBindlessOpaqueArray(ptrType)) { @@ -76,9 +76,10 @@ SpirvFunctionParameter *SpirvBuilder::addFnParam(QualType ptrType, // a pointer to a pointer of the runtime array. param = new (context) SpirvFunctionParameter( context.getPointerType(ptrType, spv::StorageClass::UniformConstant), - isPrecise, loc); + isPrecise, isNointerp, loc); } else { - param = new (context) SpirvFunctionParameter(ptrType, isPrecise, loc); + param = new (context) + SpirvFunctionParameter(ptrType, isPrecise, isNointerp, loc); } param->setStorageClass(spv::StorageClass::Function); param->setDebugName(name); @@ -88,7 +89,7 @@ SpirvFunctionParameter *SpirvBuilder::addFnParam(QualType ptrType, SpirvVariable *SpirvBuilder::addFnVar(QualType valueType, SourceLocation loc, llvm::StringRef name, bool isPrecise, - SpirvInstruction *init) { + bool isNointerp, SpirvInstruction *init) { assert(function && "found detached local variable"); SpirvVariable *var = nullptr; if (isBindlessOpaqueArray(valueType)) { @@ -96,10 +97,11 @@ SpirvVariable *SpirvBuilder::addFnVar(QualType valueType, SourceLocation loc, // a pointer to a pointer of the runtime array. var = new (context) SpirvVariable( context.getPointerType(valueType, spv::StorageClass::UniformConstant), - loc, spv::StorageClass::Function, isPrecise, init); + loc, spv::StorageClass::Function, isPrecise, isNointerp, init); } else { - var = new (context) SpirvVariable( - valueType, loc, spv::StorageClass::Function, isPrecise, init); + var = + new (context) SpirvVariable(valueType, loc, spv::StorageClass::Function, + isPrecise, isNointerp, init); } var->setDebugName(name); function->addVariable(var); @@ -330,6 +332,11 @@ SpirvStore *SpirvBuilder::createStore(SpirvInstruction *address, createEndInvocationInterlockEXT(loc, range); } + if (isa(value) && isa(address)) { + if (isa(dyn_cast(value)->getPointer())) + function->addFuncParamVarEntry(address, + dyn_cast(value)->getPointer()); + } return instruction; } @@ -1279,9 +1286,9 @@ SpirvVariable *SpirvBuilder::createCloneVarForFxcCTBuffer( QualType astType, const SpirvType *spvType, SpirvInstruction *var) { SpirvVariable *clone = nullptr; if (astType != QualType({})) { - clone = - addModuleVar(astType, spv::StorageClass::Private, var->isPrecise(), - var->getDebugName(), llvm::None, var->getSourceLocation()); + clone = addModuleVar(astType, spv::StorageClass::Private, var->isPrecise(), + var->isNoninterpolated(), var->getDebugName(), + llvm::None, var->getSourceLocation()); } else { if (const auto *ty = dyn_cast(spvType)) { spvType = context.getStructType(ty->getFields(), ty->getName(), @@ -1292,9 +1299,9 @@ SpirvVariable *SpirvBuilder::createCloneVarForFxcCTBuffer( ty->getFields(), ty->getName(), ty->isReadOnly(), StructInterfaceType::InternalStorage); } - clone = - addModuleVar(spvType, spv::StorageClass::Private, var->isPrecise(), - var->getDebugName(), llvm::None, var->getSourceLocation()); + clone = addModuleVar(spvType, spv::StorageClass::Private, var->isPrecise(), + var->isNoninterpolated(), var->getDebugName(), + llvm::None, var->getSourceLocation()); } clone->setLayoutRule(SpirvLayoutRule::Void); return clone; @@ -1363,9 +1370,11 @@ SpirvExtInstImport *SpirvBuilder::getDebugInfoExtInstSet(bool vulkanDebugInfo) { SpirvVariable *SpirvBuilder::addStageIOVar(QualType type, spv::StorageClass storageClass, llvm::StringRef name, bool isPrecise, + bool isNointerp, SourceLocation loc) { // Note: We store the underlying type in the variable, *not* the pointer type. - auto *var = new (context) SpirvVariable(type, loc, storageClass, isPrecise); + auto *var = new (context) + SpirvVariable(type, loc, storageClass, isPrecise, isNointerp); var->setDebugName(name); mod->addVariable(var); return var; @@ -1375,7 +1384,7 @@ SpirvVariable *SpirvBuilder::addVarForHelperInvocation(QualType type, bool isPrecise, SourceLocation loc) { SpirvVariable *var = addModuleVar(type, spv::StorageClass::Private, isPrecise, - "HelperInvocation", llvm::None, loc); + false, "HelperInvocation", llvm::None, loc); auto *oldInsertPoint = insertPoint; switchInsertPointToModuleInit(); @@ -1404,7 +1413,8 @@ SpirvVariable *SpirvBuilder::addStageBuiltinVar(QualType type, } // Note: We store the underlying type in the variable, *not* the pointer type. - auto *var = new (context) SpirvVariable(type, loc, storageClass, isPrecise); + auto *var = + new (context) SpirvVariable(type, loc, storageClass, isPrecise, false); mod->addVariable(var); // Decorate with the specified Builtin @@ -1418,16 +1428,15 @@ SpirvVariable *SpirvBuilder::addStageBuiltinVar(QualType type, return var; } -SpirvVariable * -SpirvBuilder::addModuleVar(QualType type, spv::StorageClass storageClass, - bool isPrecise, llvm::StringRef name, - llvm::Optional init, - SourceLocation loc) { +SpirvVariable *SpirvBuilder::addModuleVar( + QualType type, spv::StorageClass storageClass, bool isPrecise, + bool isNointerp, llvm::StringRef name, + llvm::Optional init, SourceLocation loc) { assert(storageClass != spv::StorageClass::Function); // Note: We store the underlying type in the variable, *not* the pointer type. - auto *var = - new (context) SpirvVariable(type, loc, storageClass, isPrecise, - init.hasValue() ? init.getValue() : nullptr); + auto *var = new (context) + SpirvVariable(type, loc, storageClass, isPrecise, isNointerp, + init.hasValue() ? init.getValue() : nullptr); var->setDebugName(name); mod->addVariable(var); return var; @@ -1435,13 +1444,13 @@ SpirvBuilder::addModuleVar(QualType type, spv::StorageClass storageClass, SpirvVariable *SpirvBuilder::addModuleVar( const SpirvType *type, spv::StorageClass storageClass, bool isPrecise, - llvm::StringRef name, llvm::Optional init, - SourceLocation loc) { + bool isNointerp, llvm::StringRef name, + llvm::Optional init, SourceLocation loc) { assert(storageClass != spv::StorageClass::Function); // Note: We store the underlying type in the variable, *not* the pointer type. - auto *var = - new (context) SpirvVariable(/*QualType*/ {}, loc, storageClass, isPrecise, - init.hasValue() ? init.getValue() : nullptr); + auto *var = new (context) + SpirvVariable(type, loc, storageClass, isPrecise, isNointerp, + init.hasValue() ? init.getValue() : nullptr); var->setResultType(type); var->setDebugName(name); mod->addVariable(var); @@ -1598,6 +1607,13 @@ void SpirvBuilder::decoratePerTaskNV(SpirvInstruction *target, uint32_t offset, mod->addDecoration(decor); } +void SpirvBuilder::decoratePerVertexKHR(SpirvInstruction *target, + SourceLocation srcLoc) { + auto *decor = new (context) + SpirvDecoration(srcLoc, target, spv::Decoration::PerVertexKHR); + mod->addDecoration(decor); +} + void SpirvBuilder::decorateCoherent(SpirvInstruction *target, SourceLocation srcLoc) { auto *decor = @@ -1751,6 +1767,23 @@ void SpirvBuilder::addModuleInitCallToEntryPoints() { } } +void SpirvBuilder::setPerVertexInterpMode(bool b) { + mod->setPerVertexInterpMode(b); +} + +bool SpirvBuilder::isPerVertexInterpMode() { + return mod->isPerVertexInterpMode(); +} + +void SpirvBuilder::addPerVertexStgInputFuncVarEntry(SpirvInstruction *k, + SpirvInstruction *v) { + perVertexInputVarMap[k] = v; +} + +SpirvInstruction *SpirvBuilder::getPerVertexStgInput(SpirvInstruction *k) { + return perVertexInputVarMap.lookup(k); +} + void SpirvBuilder::endModuleInitFunction() { if (moduleInitInsertPoint == nullptr || moduleInitInsertPoint->hasTerminator()) { @@ -1780,6 +1813,11 @@ std::vector SpirvBuilder::takeModule() { RemoveBufferBlockVisitor removeBufferBlockVisitor( astContext, context, spirvOptions, featureManager); EmitVisitor emitVisitor(astContext, context, spirvOptions, featureManager); + PervertexInputVisitor pervertexInputVisitor(*this, astContext, context, + spirvOptions); + + // pervertex inputs refine + mod->invokeVisitor(&pervertexInputVisitor); mod->invokeVisitor(&literalTypeVisitor, true); diff --git a/tools/clang/lib/SPIRV/SpirvEmitter.cpp b/tools/clang/lib/SPIRV/SpirvEmitter.cpp index 0bcd3f7ce6..5fb53c7c53 100644 --- a/tools/clang/lib/SPIRV/SpirvEmitter.cpp +++ b/tools/clang/lib/SPIRV/SpirvEmitter.cpp @@ -1455,7 +1455,8 @@ void SpirvEmitter::doFunctionDecl(const FunctionDecl *decl) { // Remember the parameter for the 'this' object so later we can handle // CXXThisExpr correctly. curThis = spvBuilder.addFnParam(valueType, /*isPrecise*/ false, - decl->getLocStart(), "param.this"); + /*isNoInterp*/ false, decl->getLocStart(), + "param.this"); if (isOrContainsAKindOfStructuredOrByteBuffer(valueType)) { curThis->setContainsAliasComponent(true); needsLegalization = true; @@ -2688,18 +2689,24 @@ SpirvInstruction * SpirvEmitter::doArraySubscriptExpr(const ArraySubscriptExpr *expr, SourceRange rangeOverride) { llvm::SmallVector indices; - const auto *base = collectArrayStructIndices( - expr, /*rawIndex*/ false, /*rawIndices*/ nullptr, &indices); + bool isNoInterp = false; + const auto *base = collectArrayStructIndices(expr, /*rawIndex*/ false, + /*rawIndices*/ nullptr, &indices, + nullptr, &isNoInterp); auto *info = loadIfAliasVarRef(base); SourceRange range = (rangeOverride != SourceRange()) ? rangeOverride : expr->getSourceRange(); - if (indices.empty()) { + if (!info || indices.empty()) { return info; } - return derefOrCreatePointerToValue(base->getType(), info, expr->getType(), - indices, base->getExprLoc(), range); + SpirvInstruction *loadVal = + derefOrCreatePointerToValue(base->getType(), info, expr->getType(), + indices, base->getExprLoc(), range); + if (!loadVal->isNoninterpolated()) + loadVal->setNoninterpolated(isNoInterp); + return loadVal; } SpirvInstruction *SpirvEmitter::doBinaryOperator(const BinaryOperator *expr) { @@ -2962,9 +2969,10 @@ SpirvInstruction *SpirvEmitter::processCall(const CallExpr *callExpr) { // inside the function, not the variables at the call sites. Therefore, we // do not need to mark the "param.var.*" variables as precise. const bool isPrecise = false; + const bool isNoInterp = param->hasAttr(); - auto *tempVar = - spvBuilder.addFnVar(varType, arg->getLocStart(), varName, isPrecise); + auto *tempVar = spvBuilder.addFnVar(varType, arg->getLocStart(), varName, + isPrecise, isNoInterp); vars.push_back(tempVar); isTempVar.push_back(true); @@ -4063,6 +4071,9 @@ SpirvEmitter::processTextureLevelOfDetail(const CXXMemberCallExpr *expr, spvBuilder.createImageQuery(spv::Op::OpImageQueryLod, queryResultType, expr->getExprLoc(), sampledImage, coordinate); + if (spvContext.isCS()) { + addDerivativeGroupExecutionMode(); + } // The first component of the float2 contains the mipmap array layer. // The second component of the float2 represents the unclamped lod. return spvBuilder.createCompositeExtract(astContext.FloatTy, query, @@ -5284,9 +5295,10 @@ SpirvInstruction *SpirvEmitter::createImageSample( // Otherwise we use implicit-lod instructions. const bool isExplicit = lod || (grad.first && grad.second); - // Implicit-lod instructions are only allowed in pixel shader. - if (!spvContext.isPS() && !isExplicit) - emitError("sampling with implicit lod is only allowed in fragment shaders", + // Implicit-lod instructions are only allowed in pixel and compute shaders. + if (!spvContext.isPS() && !spvContext.isCS() && !isExplicit) + emitError("sampling with implicit lod is only allowed in fragment and " + "compute shaders", loc); auto *retVal = spvBuilder.createImageSample( @@ -5363,6 +5375,9 @@ SpirvEmitter::processTextureSampleGather(const CXXMemberCallExpr *expr, const auto retType = expr->getDirectCallee()->getReturnType(); if (isSample) { + if (spvContext.isCS()) { + addDerivativeGroupExecutionMode(); + } return createImageSample(retType, imageType, image, sampler, coordinate, /*compareVal*/ nullptr, /*bias*/ nullptr, /*lod*/ nullptr, std::make_pair(nullptr, nullptr), @@ -5450,6 +5465,9 @@ SpirvEmitter::processTextureSampleBiasLevel(const CXXMemberCallExpr *expr, const auto retType = expr->getDirectCallee()->getReturnType(); + if (!lod && spvContext.isCS()) { + addDerivativeGroupExecutionMode(); + } return createImageSample( retType, imageType, image, sampler, coordinate, /*compareVal*/ nullptr, bias, lod, std::make_pair(nullptr, nullptr), @@ -5599,6 +5617,10 @@ SpirvEmitter::processTextureSampleCmpCmpLevelZero(const CXXMemberCallExpr *expr, const auto retType = expr->getDirectCallee()->getReturnType(); const auto imageType = imageExpr->getType(); + if (!lod && spvContext.isCS()) { + addDerivativeGroupExecutionMode(); + } + return createImageSample( retType, imageType, image, sampler, coordinate, compareVal, /*bias*/ nullptr, lod, std::make_pair(nullptr, nullptr), constOffset, @@ -5983,6 +6005,20 @@ SpirvInstruction *SpirvEmitter::doInitListExpr(const InitListExpr *expr, return result; } +bool SpirvEmitter::isNoInterpMemberExpr(const MemberExpr *expr) { + bool ret = false; + FieldDecl *D = dyn_cast(expr->getMemberDecl()); + while (D != nullptr) { + if (D->hasAttr() || + D->getParent()->hasAttr()) { + ret = true; + } + D = dyn_cast(D->getParent()); + } + auto *base = dyn_cast(expr->getBase()); + return ret || (base != nullptr && isNoInterpMemberExpr(base)); +} + SpirvInstruction *SpirvEmitter::doMemberExpr(const MemberExpr *expr, SourceRange rangeOverride) { llvm::SmallVector indices; @@ -5999,8 +6035,11 @@ SpirvInstruction *SpirvEmitter::doMemberExpr(const MemberExpr *expr, const auto *fieldDecl = dyn_cast(expr->getMemberDecl()); if (!fieldDecl || !fieldDecl->isBitField()) { - return derefOrCreatePointerToValue(base->getType(), instr, expr->getType(), - indices, loc, range); + SpirvInstruction *retInstr = derefOrCreatePointerToValue( + base->getType(), instr, expr->getType(), indices, loc, range); + if (isNoInterpMemberExpr(expr)) + retInstr->setNoninterpolated(); + return retInstr; } auto baseType = expr->getBase()->getType(); @@ -6809,7 +6848,7 @@ void SpirvEmitter::initOnce(QualType varType, std::string varName, // Create a file/module visible variable to hold the initialization state. SpirvVariable *initDoneVar = spvBuilder.addModuleVar( - astContext.BoolTy, spv::StorageClass::Private, /*isPrecise*/ false, + astContext.BoolTy, spv::StorageClass::Private, /*isPrecise*/ false, false, varName, spvBuilder.getConstantBool(false)); auto *condition = spvBuilder.createLoad(astContext.BoolTy, initDoneVar, loc); @@ -7864,8 +7903,8 @@ SpirvEmitter::processMatrixBinaryOp(const Expr *lhs, const Expr *rhs, const Expr *SpirvEmitter::collectArrayStructIndices( const Expr *expr, bool rawIndex, llvm::SmallVectorImpl *rawIndices, - llvm::SmallVectorImpl *indices, - bool *isMSOutAttribute) { + llvm::SmallVectorImpl *indices, bool *isMSOutAttribute, + bool *isNointerp) { assert((rawIndex && rawIndices) || (!rawIndex && indices)); if (const auto *indexing = dyn_cast(expr)) { @@ -7878,6 +7917,9 @@ const Expr *SpirvEmitter::collectArrayStructIndices( /*RefersToEnclosingVariableOrCapture=*/false, SourceLocation(), varDecl->getType(), VK_LValue); + if (isNointerp) + *isNointerp = *isNointerp || isNoInterpMemberExpr(indexing); + const Expr *base = collectArrayStructIndices( indexing->getBase(), rawIndex, rawIndices, indices, isMSOutAttribute); @@ -7924,8 +7966,8 @@ const Expr *SpirvEmitter::collectArrayStructIndices( // The base of an ArraySubscriptExpr has a wrapping LValueToRValue implicit // cast. We need to ingore it to avoid creating OpLoad. const Expr *thisBase = indexing->getBase()->IgnoreParenLValueCasts(); - const Expr *base = collectArrayStructIndices(thisBase, rawIndex, rawIndices, - indices, isMSOutAttribute); + const Expr *base = collectArrayStructIndices( + thisBase, rawIndex, rawIndices, indices, isMSOutAttribute, isNointerp); // The index into an array must be an integer number. const auto *idxExpr = indexing->getIdx(); const auto idxExprType = idxExpr->getType(); @@ -7967,6 +8009,12 @@ const Expr *SpirvEmitter::collectArrayStructIndices( indexing->getArg(0)->IgnoreParenNoopCasts(astContext); const auto thisBaseType = thisBase->getType(); + + // If the base type is user defined, return the call expr so that any + // user-defined overloads of operator[] are called. + if (hlsl::IsUserDefinedRecordType(thisBaseType)) + return expr; + const Expr *base = collectArrayStructIndices( thisBase, rawIndex, rawIndices, indices, isMSOutAttribute); @@ -8804,6 +8852,10 @@ SpirvEmitter::processIntrinsicCallExpr(const CallExpr *callExpr) { srcRange); break; } + case hlsl::IntrinsicOp::IOP_GetAttributeAtVertex: { + retVal = processGetAttributeAtVertex(callExpr); + break; + } case hlsl::IntrinsicOp::IOP_ufirstbithigh: { retVal = processIntrinsicFirstbit(callExpr, GLSLstd450::GLSLstd450FindUMsb); break; @@ -11124,8 +11176,14 @@ SpirvEmitter::processIntrinsicF32ToF16(const CallExpr *callExpr) { SpirvInstruction *SpirvEmitter::processIntrinsicUsingSpirvInst( const CallExpr *callExpr, spv::Op opcode, bool actPerRowForMatrices) { - // Certain opcodes are only allowed in pixel shader - if (!spvContext.isPS()) + // The derivative opcodes are only allowed in pixel shader, or in compute + // shaderers when the SPV_NV_compute_shader_derivatives is enabled. + if (!spvContext.isPS()) { + // For cases where the instructions are known to be invalid, we turn on + // legalization expecting the invalid use to be optimized away. For compute + // shaders, we add the execution mode to enable the derivatives. We legalize + // in this case as well because that is what we did before the extension was + // used, and we do not want to change previous behaviour too much. switch (opcode) { case spv::Op::OpDPdx: case spv::Op::OpDPdy: @@ -11136,13 +11194,15 @@ SpirvInstruction *SpirvEmitter::processIntrinsicUsingSpirvInst( case spv::Op::OpFwidth: case spv::Op::OpFwidthFine: case spv::Op::OpFwidthCoarse: + if (spvContext.isCS()) + addDerivativeGroupExecutionMode(); needsLegalization = true; break; default: - // Only the given opcodes need legalization. Anything else should preserve - // previous. + // Only the given opcodes need legalization and the execution mode. break; } + } const auto loc = callExpr->getExprLoc(); const auto range = callExpr->getSourceRange(); @@ -11878,6 +11938,53 @@ void SpirvEmitter::processMeshOutputCounts(const CallExpr *callExpr) { } } +SpirvInstruction * +SpirvEmitter::processGetAttributeAtVertex(const CallExpr *expr) { + // Implicit type conversion should bound to two things: + // 1. Function Parameter, and recursively redecl mapped function called's var + // types. + // 2. User defined structure types, which may be used in function local + // variables (AccessChain add index 0 at end) + const auto exprLoc = expr->getExprLoc(); + const auto exprRange = expr->getSourceRange(); + + // arg1 : vertexId + const auto *arg1BaseExpr = doExpr(expr->getArg(1)->IgnoreParenLValueCasts()); + const auto *arg1ConstExpr = dyn_cast(arg1BaseExpr); + const auto *vertexId = arg1ConstExpr->getValue().getRawData(); + + // arg0 : decorated input + // Tip : for input with boolean type, we need to ignore implicit cast first, + // to match surrounded workaround cast expr. + auto *arg0NoCast = expr->getArg(0)->IgnoreCasts(); + SpirvInstruction *paramDeclInstr = doExpr(arg0NoCast); + // Hans't be redeclared before + QualType elementType = paramDeclInstr->getAstResultType(); + + if (isBoolOrVecOfBoolType(elementType)) { + emitError("attribute evaluation can only be done " + "on values taken directly from inputs.", + {}); + } + // Change to access chain instr + SpirvInstruction *accessChainPtr = paramDeclInstr; + SpirvConstant *vtxId = spvBuilder.getConstantInt(astContext.UnsignedIntTy, + llvm::APInt(32, *vertexId)); + if (isa(accessChainPtr)) { + auto *accessInstr = dyn_cast(accessChainPtr); + accessInstr->insertIndex(vtxId, accessInstr->getIndexes().size()); + } else + accessChainPtr = spvBuilder.createAccessChain(elementType, accessChainPtr, + vtxId, exprLoc, exprRange); + dyn_cast(accessChainPtr)->setNoninterpolated(false); + auto *loadPtr = + spvBuilder.createLoad(elementType, accessChainPtr, exprLoc, exprRange); + // PerVertexKHR Decorator and type redecl will be done in later pervertex + // visitor. + spvBuilder.setPerVertexInterpMode(true); + return loadPtr; +} + SpirvConstant *SpirvEmitter::getValueZero(QualType type) { { QualType scalarType = {}; @@ -12189,6 +12296,19 @@ SpirvEmitter::getSpirvShaderStage(hlsl::ShaderModel::Kind smk, } } +void SpirvEmitter::processInlineSpirvAttributes(const FunctionDecl *decl) { + if (!decl->hasAttrs()) + return; + + for (auto &attr : decl->getAttrs()) { + if (auto *modeAttr = dyn_cast(attr)) { + spvBuilder.addExecutionMode( + entryFunction, spv::ExecutionMode(modeAttr->getExecutionMode()), {}, + modeAttr->getLocation()); + } + } +} + bool SpirvEmitter::processGeometryShaderAttributes(const FunctionDecl *decl, uint32_t *arraySize) { bool success = true; @@ -12515,7 +12635,8 @@ bool SpirvEmitter::emitEntryFunctionWrapperForRayTracing( std::string tempVarName = "param.var." + param->getNameAsString(); auto *tempVar = spvBuilder.addFnVar(paramType, param->getLocation(), tempVarName, - param->hasAttr()); + param->hasAttr(), + param->hasAttr()); SpirvVariable *curStageVar = nullptr; @@ -12783,6 +12904,8 @@ bool SpirvEmitter::emitEntryFunctionWrapper(const FunctionDecl *decl, assert(entryInfo->isEntryFunction); entryInfo->entryFunction = entryFunction; + processInlineSpirvAttributes(decl); + if (spvContext.isRay()) { return emitEntryFunctionWrapperForRayTracing(decl, entryFuncInstr, debugFunction); @@ -12897,7 +13020,8 @@ bool SpirvEmitter::emitEntryFunctionWrapper(const FunctionDecl *decl, std::string tempVarName = "param.var." + param->getNameAsString(); auto *tempVar = spvBuilder.addFnVar(paramType, param->getLocation(), tempVarName, - param->hasAttr()); + param->hasAttr(), + param->hasAttr()); params.push_back(tempVar); @@ -12920,6 +13044,10 @@ bool SpirvEmitter::emitEntryFunctionWrapper(const FunctionDecl *decl, // Only initialize the temporary variable if the parameter is indeed used. if (param->isUsed()) { spvBuilder.createStore(tempVar, loadedValue, param->getLocation()); + // param is mapped to store object. Coule be a componentConstruct or + // Load + if (spvContext.isPS()) + spvBuilder.addPerVertexStgInputFuncVarEntry(loadedValue, tempVar); } // Record the temporary variable holding SV_OutputControlPointID, @@ -13084,8 +13212,9 @@ bool SpirvEmitter::processHSEntryPointOutputAndPCF( const QualType type = param->getType(); std::string tempVarName = "param.var." + param->getNameAsString(); auto paramLoc = param->getLocation(); - auto *tempVar = spvBuilder.addFnVar(type, paramLoc, tempVarName, - param->hasAttr()); + auto *tempVar = spvBuilder.addFnVar( + type, paramLoc, tempVarName, param->hasAttr(), + param->hasAttr()); SpirvInstruction *loadedValue = nullptr; declIdMapper.createStageInputVar(param, &loadedValue, /*forPCF*/ true); spvBuilder.createStore(tempVar, loadedValue, paramLoc); @@ -14053,6 +14182,33 @@ bool SpirvEmitter::spirvToolsValidate(std::vector *mod, return tools.Validate(mod->data(), mod->size(), options); } +void SpirvEmitter::addDerivativeGroupExecutionMode() { + assert(spvContext.isCS()); + + SpirvExecutionMode *numThreadsEm = spvBuilder.getModule()->findExecutionMode( + entryFunction, spv::ExecutionMode::LocalSize); + auto numThreads = numThreadsEm->getParams(); + + // The layout of the quad is determined by the numer of threads in each + // dimention. From the HLSL spec + // (https://microsoft.github.io/DirectX-Specs/d3d/HLSL_SM_6_6_Derivatives.html): + // + // Where numthreads has an X value divisible by 4 and Y and Z are both 1, the + // quad layouts are determined according to 1D quad rules. Where numthreads X + // and Y values are divisible by 2, the quad layouts are determined according + // to 2D quad rules. Using derivative operations in any numthreads + // configuration not matching either of these is invalid and will produce an + // error. + spv::ExecutionMode em = spv::ExecutionMode::DerivativeGroupQuadsNV; + if (numThreads[0] % 4 == 0 && numThreads[1] == 1 && numThreads[2] == 1) { + em = spv::ExecutionMode::DerivativeGroupLinearNV; + } else { + assert(numThreads[0] % 2 == 0 && numThreads[1] % 2 == 0); + } + + spvBuilder.addExecutionMode(entryFunction, em, {}, SourceLocation()); +} + bool SpirvEmitter::spirvToolsTrimCapabilities(std::vector *mod, std::string *messages) { spvtools::Optimizer optimizer(featureManager.getTargetEnv()); diff --git a/tools/clang/lib/SPIRV/SpirvEmitter.h b/tools/clang/lib/SPIRV/SpirvEmitter.h index 2502465488..84e3ac2526 100644 --- a/tools/clang/lib/SPIRV/SpirvEmitter.h +++ b/tools/clang/lib/SPIRV/SpirvEmitter.h @@ -186,6 +186,10 @@ class SpirvEmitter : public ASTConsumer { SpirvInstruction **aliasVarInstr, SourceRange rangeOverride = {}); + /// Check whether a member value has a nointerpolation qualifier in its type + /// declaration or any parents' type declaration recursively. + bool isNoInterpMemberExpr(const MemberExpr *expr); + private: /// Translates the given frontend binary operator into its SPIR-V equivalent /// taking consideration of the operand type. @@ -391,7 +395,8 @@ class SpirvEmitter : public ASTConsumer { collectArrayStructIndices(const Expr *expr, bool rawIndex, llvm::SmallVectorImpl *rawIndices, llvm::SmallVectorImpl *indices, - bool *isMSOutAttribute = nullptr); + bool *isMSOutAttribute = nullptr, + bool *isNointerp = nullptr); /// For L-values, creates an access chain to index into the given SPIR-V /// evaluation result and returns the new SPIR-V evaluation result. @@ -679,6 +684,9 @@ class SpirvEmitter : public ASTConsumer { /// Process mesh shader intrinsics. void processMeshOutputCounts(const CallExpr *callExpr); + /// Process GetAttributeAtVertex for barycentrics. + SpirvInstruction *processGetAttributeAtVertex(const CallExpr *expr); + /// Process ray query traceinline intrinsics. SpirvInstruction *processTraceRayInline(const CXXMemberCallExpr *expr); @@ -812,6 +820,9 @@ class SpirvEmitter : public ASTConsumer { static spv::ExecutionModel getSpirvShaderStage(hlsl::ShaderModel::Kind smk, bool); + /// \brief Handle inline SPIR-V attributes for the entry function. + void processInlineSpirvAttributes(const FunctionDecl *entryFunction); + /// \brief Adds necessary execution modes for the hull/domain shaders based on /// the HLSL attributes of the entry point function. /// In the case of hull shaders, also writes the number of output control @@ -1231,6 +1242,13 @@ class SpirvEmitter : public ASTConsumer { /// Returns true on success and false otherwise. bool spirvToolsValidate(std::vector *mod, std::string *messages); + /// Adds the appropriate derivative group execution mode to the entry point. + /// The entry point must already have a LocalSize execution mode, which will + /// be used to determine which execution mode (quad or linear) is required. + /// This decision is made according to the rules in + /// https://microsoft.github.io/DirectX-Specs/d3d/HLSL_SM_6_6_Derivatives.html. + void addDerivativeGroupExecutionMode(); + public: /// \brief Wrapper method to create a fatal error message and report it /// in the diagnostic engine associated with this consumer. diff --git a/tools/clang/lib/SPIRV/SpirvInstruction.cpp b/tools/clang/lib/SPIRV/SpirvInstruction.cpp index 4418f9298d..2e3288db48 100644 --- a/tools/clang/lib/SPIRV/SpirvInstruction.cpp +++ b/tools/clang/lib/SPIRV/SpirvInstruction.cpp @@ -124,7 +124,7 @@ SpirvInstruction::SpirvInstruction(Kind k, spv::Op op, QualType astType, layoutRule(SpirvLayoutRule::Void), containsAlias(false), storageClass(spv::StorageClass::Function), isRValue_(false), isRelaxedPrecision_(false), isNonUniform_(false), isPrecise_(false), - isRasterizerOrdered_(false) {} + isNoninterpolated_(false), isRasterizerOrdered_(false) {} bool SpirvInstruction::isArithmeticInstruction() const { switch (opcode) { @@ -293,40 +293,44 @@ bool SpirvDecoration::operator==(const SpirvDecoration &that) const { SpirvVariable::SpirvVariable(QualType resultType, SourceLocation loc, spv::StorageClass sc, bool precise, - SpirvInstruction *initializerInst) + bool isNointerp, SpirvInstruction *initializerInst) : SpirvInstruction(IK_Variable, spv::Op::OpVariable, resultType, loc), initializer(initializerInst), descriptorSet(-1), binding(-1), hlslUserType("") { setStorageClass(sc); setPrecise(precise); + setNoninterpolated(isNointerp); } SpirvVariable::SpirvVariable(const SpirvType *spvType, SourceLocation loc, spv::StorageClass sc, bool precise, - SpirvInstruction *initializerInst) + bool isNointerp, SpirvInstruction *initializerInst) : SpirvInstruction(IK_Variable, spv::Op::OpVariable, QualType(), loc), initializer(initializerInst), descriptorSet(-1), binding(-1), hlslUserType("") { setResultType(spvType); setStorageClass(sc); setPrecise(precise); + setNoninterpolated(isNointerp); } SpirvFunctionParameter::SpirvFunctionParameter(QualType resultType, - bool isPrecise, + bool isPrecise, bool isNointerp, SourceLocation loc) : SpirvInstruction(IK_FunctionParameter, spv::Op::OpFunctionParameter, resultType, loc) { setPrecise(isPrecise); + setNoninterpolated(isNointerp); } SpirvFunctionParameter::SpirvFunctionParameter(const SpirvType *spvType, - bool isPrecise, + bool isPrecise, bool isNointerp, SourceLocation loc) : SpirvInstruction(IK_FunctionParameter, spv::Op::OpFunctionParameter, QualType(), loc) { setResultType(spvType); setPrecise(isPrecise); + setNoninterpolated(isNointerp); } SpirvMerge::SpirvMerge(Kind kind, spv::Op op, SourceLocation loc, @@ -410,7 +414,10 @@ SpirvAccessChain::SpirvAccessChain(QualType resultType, SourceLocation loc, SourceRange range) : SpirvInstruction(IK_AccessChain, spv::Op::OpAccessChain, resultType, loc, range), - base(baseInst), indices(indexVec.begin(), indexVec.end()) {} + base(baseInst), indices(indexVec.begin(), indexVec.end()) { + if (baseInst && baseInst->isNoninterpolated()) + setNoninterpolated(); +} SpirvAtomic::SpirvAtomic(spv::Op op, QualType resultType, SourceLocation loc, SpirvInstruction *pointerInst, spv::Scope s, @@ -581,7 +588,10 @@ SpirvCompositeExtract::SpirvCompositeExtract(QualType resultType, SourceRange range) : SpirvInstruction(IK_CompositeExtract, spv::Op::OpCompositeExtract, resultType, loc, range), - composite(compositeInst), indices(indexVec.begin(), indexVec.end()) {} + composite(compositeInst), indices(indexVec.begin(), indexVec.end()) { + if (compositeInst && compositeInst->isNoninterpolated()) + setNoninterpolated(); +} SpirvCompositeInsert::SpirvCompositeInsert(QualType resultType, SourceLocation loc, diff --git a/tools/clang/lib/SPIRV/SpirvModule.cpp b/tools/clang/lib/SPIRV/SpirvModule.cpp index d5b79c5dfb..b8ae6c218a 100644 --- a/tools/clang/lib/SPIRV/SpirvModule.cpp +++ b/tools/clang/lib/SPIRV/SpirvModule.cpp @@ -17,7 +17,8 @@ namespace spirv { SpirvModule::SpirvModule() : capabilities({}), extensions({}), extInstSets({}), memoryModel(nullptr), entryPoints({}), executionModes({}), moduleProcesses({}), decorations({}), - constants({}), variables({}), functions({}), debugInstructions({}) {} + constants({}), variables({}), functions({}), debugInstructions({}), + perVertexInterp(false) {} SpirvModule::~SpirvModule() { for (auto *cap : capabilities) diff --git a/tools/clang/lib/Sema/SemaHLSL.cpp b/tools/clang/lib/Sema/SemaHLSL.cpp index 7953b83f3e..c6a27183a6 100644 --- a/tools/clang/lib/Sema/SemaHLSL.cpp +++ b/tools/clang/lib/Sema/SemaHLSL.cpp @@ -5879,6 +5879,12 @@ bool HLSLExternalSource::IsValidObjectElement(LPCSTR tableName, return true; // 6.7 adds UINT sampler support if (IS_BASIC_UINT(kind) || IS_BASIC_SINT(kind)) { + bool IsSampleC = (op == IntrinsicOp::MOP_SampleCmp || + op == IntrinsicOp::MOP_SampleCmpLevel || + op == IntrinsicOp::MOP_SampleCmpLevelZero); + // SampleCmp* cannot support integer resource. + if (IsSampleC) + return false; const auto *SM = hlsl::ShaderModel::GetByName( m_sema->getLangOpts().HLSLProfile.c_str()); return SM->IsSM67Plus(); @@ -12558,6 +12564,11 @@ void hlsl::HandleDeclAttributeForHLSL(Sema &S, Decl *D, const AttributeList &A, A.getRange(), S.Context, ValidateAttributeStringArg(S, A, nullptr), A.getAttributeSpellingListIndex()); break; + case AttributeList::AT_VKSpvExecutionMode: + declAttr = ::new (S.Context) VKSpvExecutionModeAttr( + A.getRange(), S.Context, ValidateAttributeIntArg(S, A), + A.getAttributeSpellingListIndex()); + break; case AttributeList::AT_VKInstructionExt: declAttr = ::new (S.Context) VKInstructionExtAttr( A.getRange(), S.Context, ValidateAttributeIntArg(S, A), diff --git a/tools/clang/test/CXX/lit.local.cfg b/tools/clang/test/CXX/lit.local.cfg index 039670617e..76730bee2a 100644 --- a/tools/clang/test/CXX/lit.local.cfg +++ b/tools/clang/test/CXX/lit.local.cfg @@ -1 +1 @@ -config.unsupported = True # HLSL Change - Disable lit suites. +config.suffixes = [] # HLSL Change - Disable lit suites. diff --git a/tools/clang/test/CodeCompletion/lit.local.cfg b/tools/clang/test/CodeCompletion/lit.local.cfg index 039670617e..76730bee2a 100644 --- a/tools/clang/test/CodeCompletion/lit.local.cfg +++ b/tools/clang/test/CodeCompletion/lit.local.cfg @@ -1 +1 @@ -config.unsupported = True # HLSL Change - Disable lit suites. +config.suffixes = [] # HLSL Change - Disable lit suites. diff --git a/tools/clang/test/CodeGenCUDA/lit.local.cfg b/tools/clang/test/CodeGenCUDA/lit.local.cfg index 039670617e..76730bee2a 100644 --- a/tools/clang/test/CodeGenCUDA/lit.local.cfg +++ b/tools/clang/test/CodeGenCUDA/lit.local.cfg @@ -1 +1 @@ -config.unsupported = True # HLSL Change - Disable lit suites. +config.suffixes = [] # HLSL Change - Disable lit suites. diff --git a/tools/clang/test/CodeGenDXIL/ByteAddressBuffer/store_groupshared_struct_with_array.hlsl b/tools/clang/test/CodeGenDXIL/ByteAddressBuffer/store_groupshared_struct_with_array.hlsl new file mode 100644 index 0000000000..5affc5e673 --- /dev/null +++ b/tools/clang/test/CodeGenDXIL/ByteAddressBuffer/store_groupshared_struct_with_array.hlsl @@ -0,0 +1,57 @@ +// This is a regression test for a shader that crashed the compiler. The crash +// occured because we failed to flatten the multi-level gep into a single-level +// gep which caused a crash in the multi-dimension global flattening pass. +// +// The shader is compiled with three different index values (two different +// constants and a dynamic index value). Each of these crashed in different +// places in the compiler as I was developing a fix. Originally, the /Od +// version crashed with index 0 or 1 and the /O3 version crashed with +// index 1. + +// RUN: dxc /Tcs_6_0 /DINDEX=0 %s | FileCheck %s +// RUN: dxc /Tcs_6_0 /Od /DINDEX=0 %s | FileCheck %s +// RUN: dxc /Tcs_6_0 /DINDEX=1 %s | FileCheck %s +// RUN: dxc /Tcs_6_0 /Od /DINDEX=1 %s | FileCheck %s +// RUN: dxc /Tcs_6_0 /DINDEX=idx %s | FileCheck %s +// RUN: dxc /Tcs_6_0 /Od /DINDEX=idx %s | FileCheck %s + + +// CHECK: @main +// CHECK-DAG: [[ELEM_0:%[0-9]+]] = load float, float addrspace(3)* +// CHECK-DAG: call void @dx.op.bufferStore.f32({{.*}}, float [[ELEM_0]] + +// CHECK-DAG: [[ELEM_1:%[0-9]+]] = load float, float addrspace(3)* +// CHECK-DAG: call void @dx.op.bufferStore.f32({{.*}}, float [[ELEM_1]] + +// CHECK-DAG: [[ELEM_2:%[0-9]+]] = load float, float addrspace(3)* +// CHECK-DAG: call void @dx.op.bufferStore.f32({{.*}}, float [[ELEM_2]] + +// CHECK-DAG: [[ELEM_3:%[0-9]+]] = load float, float addrspace(3)* +// CHECK-DAG: call void @dx.op.bufferStore.f32({{.*}}, float [[ELEM_3]] + +// CHECK-DAG: [[ELEM_4:%[0-9]+]] = load float, float addrspace(3)* +// CHECK-DAG: call void @dx.op.bufferStore.f32({{.*}}, float [[ELEM_4]] + +// CHECK-DAG: [[ELEM_5:%[0-9]+]] = load float, float addrspace(3)* +// CHECK-DAG: call void @dx.op.bufferStore.f32({{.*}}, float [[ELEM_5]] + +// CHECK-DAG: [[ELEM_6:%[0-9]+]] = load float, float addrspace(3)* +// CHECK-DAG: call void @dx.op.bufferStore.f32({{.*}}, float [[ELEM_6]] + +// CHECK-DAG: [[ELEM_7:%[0-9]+]] = load float, float addrspace(3)* +// CHECK-DAG: call void @dx.op.bufferStore.f32({{.*}}, float [[ELEM_7]] + +// CHECK-DAG: [[ELEM_8:%[0-9]+]] = load float, float addrspace(3)* +// CHECK-DAG: call void @dx.op.bufferStore.f32({{.*}}, float [[ELEM_8]] + +struct Vec9 { float data[9]; }; +groupshared Vec9 A[256]; + +RWByteAddressBuffer buf; + +[numthreads(1,1,1)] +[RootSignature("DescriptorTable(SRV(t0, numDescriptors=10), UAV(u0,numDescriptors=10))")] +void main(uint idx : SV_GroupID) +{ + buf.Store(idx, A[INDEX]); +} diff --git a/tools/clang/test/CodeGenSPIRV/decoration.no-contraction.struct.hlsl b/tools/clang/test/CodeGenSPIRV/decoration.no-contraction.struct.hlsl deleted file mode 100644 index 3b4ec0b745..0000000000 --- a/tools/clang/test/CodeGenSPIRV/decoration.no-contraction.struct.hlsl +++ /dev/null @@ -1,174 +0,0 @@ -// RUN: %dxc -T ps_6_0 -E main - -struct S { - float4 a; - precise float4 ap; - int b[5]; - precise int bp[5]; - int2x3 c[6][7][8]; - precise int2x3 cp[6][7][8]; - float3x4 d; - precise float3x4 dp; -}; - -struct T { - precise S sub1; // all members of sub1 should be precise. - S sub2; // only some members of sub2 are precise. -}; - - -// CHECK: OpName %w "w" -// CHECK-NOT: OpDecorate [[x_mul_x_1]] NoContraction -// CHECK-NOT: OpDecorate [[xx_plus_y_1]] NoContraction -// CHECK-NEXT: OpDecorate [[x_mul_x_2:%\d+]] NoContraction -// CHECK-NEXT: OpDecorate [[xx_plus_y_2:%\d+]] NoContraction - -// CHECK-NOT: OpDecorate [[z2_mul_z3_1]] NoContraction -// CHECK-NOT: OpDecorate [[z2z3_plus_z4_1]] NoContraction -// CHECK-NEXT: OpDecorate [[z2_mul_z3_2:%\d+]] NoContraction -// CHECK-NEXT: OpDecorate [[z2z3_plus_z4_2:%\d+]] NoContraction - -// CHECK-NOT: OpDecorate [[uu_row0_1]] NoContraction -// CHECK-NOT: OpDecorate [[uu_row1_1]] NoContraction -// CHECK-NEXT: OpDecorate [[uu_row0_2:%\d+]] NoContraction -// CHECK-NEXT: OpDecorate [[uu_row1_2:%\d+]] NoContraction - -// CHECK-NOT: OpDecorate [[ww_row0_1]] NoContraction -// CHECK-NOT: OpDecorate [[ww_row1_1]] NoContraction -// CHECK-NOT: OpDecorate [[ww_row2_1]] NoContraction -// CHECK-NOT: OpDecorate [[ww_plus_w_row0_1]] NoContraction -// CHECK-NOT: OpDecorate [[ww_plus_w_row1_1]] NoContraction -// CHECK-NOT: OpDecorate [[ww_plus_w_row2_1]] NoContraction -// CHECK-NEXT: OpDecorate [[ww_row0_2:%\d+]] NoContraction -// CHECK-NEXT: OpDecorate [[ww_row1_2:%\d+]] NoContraction -// CHECK-NEXT: OpDecorate [[ww_row2_2:%\d+]] NoContraction -// CHECK-NEXT: OpDecorate [[ww_plus_w_row0_2:%\d+]] NoContraction -// CHECK-NEXT: OpDecorate [[ww_plus_w_row1_2:%\d+]] NoContraction -// CHECK-NEXT: OpDecorate [[ww_plus_w_row2_2:%\d+]] NoContraction - -// CHECK-NEXT: OpDecorate [[x_mul_x_3:%\d+]] NoContraction -// CHECK-NEXT: OpDecorate [[xx_plus_y_3:%\d+]] NoContraction -// CHECK-NEXT: OpDecorate [[x_mul_x_4:%\d+]] NoContraction -// CHECK-NEXT: OpDecorate [[xx_plus_y_4:%\d+]] NoContraction -// CHECK-NEXT: OpDecorate [[z2_mul_z3_3:%\d+]] NoContraction -// CHECK-NEXT: OpDecorate [[z2z3_plus_z4_3:%\d+]] NoContraction -// CHECK-NEXT: OpDecorate [[z2_mul_z3_4:%\d+]] NoContraction -// CHECK-NEXT: OpDecorate [[z2z3_plus_z4_4:%\d+]] NoContraction -// CHECK-NEXT: OpDecorate [[uu_row0_3:%\d+]] NoContraction -// CHECK-NEXT: OpDecorate [[uu_row1_3:%\d+]] NoContraction -// CHECK-NEXT: OpDecorate [[uu_row0_4:%\d+]] NoContraction -// CHECK-NEXT: OpDecorate [[uu_row1_4:%\d+]] NoContraction -// CHECK-NEXT: OpDecorate [[ww_row0_3:%\d+]] NoContraction -// CHECK-NEXT: OpDecorate [[ww_row1_3:%\d+]] NoContraction -// CHECK-NEXT: OpDecorate [[ww_row2_3:%\d+]] NoContraction -// CHECK-NEXT: OpDecorate [[ww_plus_w_row0_3:%\d+]] NoContraction -// CHECK-NEXT: OpDecorate [[ww_plus_w_row1_3:%\d+]] NoContraction -// CHECK-NEXT: OpDecorate [[ww_plus_w_row2_3:%\d+]] NoContraction -// CHECK-NEXT: OpDecorate [[ww_row0_4:%\d+]] NoContraction -// CHECK-NEXT: OpDecorate [[ww_row1_4:%\d+]] NoContraction -// CHECK-NEXT: OpDecorate [[ww_row2_4:%\d+]] NoContraction -// CHECK-NEXT: OpDecorate [[ww_plus_w_row0_4:%\d+]] NoContraction -// CHECK-NEXT: OpDecorate [[ww_plus_w_row1_4:%\d+]] NoContraction -// CHECK-NEXT: OpDecorate [[ww_plus_w_row2_4:%\d+]] NoContraction - -void main() { - T t; - float4 x,y; - int z[5]; - int2x3 u; - float3x4 w; - - -// 'a' is NOT precise. -// -// CHECK: [[x_mul_x_1:%\d+]] = OpFMul %v4float -// CHECK: [[xx_plus_y_1:%\d+]] = OpFAdd %v4float - t.sub2.a = x * x + y; - -// 'ap' is precise. -// -// CHECK: [[x_mul_x_2]] = OpFMul %v4float -// CHECK: [[xx_plus_y_2]] = OpFAdd %v4float - t.sub2.ap = x * x + y; - -// 'b' is NOT precise. -// -// CHECK: [[z2_mul_z3_1:%\d+]] = OpIMul %int -// CHECK: [[z2z3_plus_z4_1:%\d+]] = OpIAdd %int - t.sub2.b[1] = z[2] * z[3] + z[4]; - -// 'bp' is precise. -// -// CHECK: [[z2_mul_z3_2]] = OpIMul %int -// CHECK: [[z2z3_plus_z4_2]] = OpIAdd %int - t.sub2.bp[1] = z[2] * z[3] + z[4]; - -// 'c' is NOT precise. -// -// CHECK: [[uu_row0_1:%\d+]] = OpIMul %v3int -// CHECK: [[uu_row1_1:%\d+]] = OpIMul %v3int - t.sub2.c[0][1][2] = u * u; - -// 'cp' is precise. -// -// CHECK: [[uu_row0_2]] = OpIMul %v3int -// CHECK: [[uu_row1_2]] = OpIMul %v3int - t.sub2.cp[0][1][2] = u * u; - -// 'd' is NOT precise. -// -// CHECK: [[ww_row0_1:%\d+]] = OpFMul %v4float -// CHECK: [[ww_row1_1:%\d+]] = OpFMul %v4float -// CHECK: [[ww_row2_1:%\d+]] = OpFMul %v4float -// CHECK: [[ww_plus_w_row0_1:%\d+]] = OpFAdd %v4float -// CHECK: [[ww_plus_w_row1_1:%\d+]] = OpFAdd %v4float -// CHECK: [[ww_plus_w_row2_1:%\d+]] = OpFAdd %v4float - t.sub2.d = w * w + w; - -// 'dp' is precise. -// -// CHECK: [[ww_row0_2]] = OpFMul %v4float -// CHECK: [[ww_row1_2]] = OpFMul %v4float -// CHECK: [[ww_row2_2]] = OpFMul %v4float -// CHECK: [[ww_plus_w_row0_2]] = OpFAdd %v4float -// CHECK: [[ww_plus_w_row1_2]] = OpFAdd %v4float -// CHECK: [[ww_plus_w_row2_2]] = OpFAdd %v4float - t.sub2.dp = w * w + w; - -// *ALL* members of sub1 are precise. So this operation should be precise. -// -// -// CHECK: [[x_mul_x_3]] = OpFMul %v4float -// CHECK: [[xx_plus_y_3]] = OpFAdd %v4float - t.sub1.a = x * x + y; -// CHECK: [[x_mul_x_4]] = OpFMul %v4float -// CHECK: [[xx_plus_y_4]] = OpFAdd %v4float - t.sub1.ap = x * x + y; -// CHECK: [[z2_mul_z3_3]] = OpIMul %int -// CHECK: [[z2z3_plus_z4_3]] = OpIAdd %int - t.sub1.b[1] = z[2] * z[3] + z[4]; -// CHECK: [[z2_mul_z3_4]] = OpIMul %int -// CHECK: [[z2z3_plus_z4_4]] = OpIAdd %int - t.sub1.bp[1] = z[2] * z[3] + z[4]; -// CHECK: [[uu_row0_3]] = OpIMul %v3int -// CHECK: [[uu_row1_3]] = OpIMul %v3int - t.sub1.c[0][1][2] = u * u; -// CHECK: [[uu_row0_4]] = OpIMul %v3int -// CHECK: [[uu_row1_4]] = OpIMul %v3int - t.sub1.cp[0][1][2] = u * u; -// CHECK: [[ww_row0_3]] = OpFMul %v4float -// CHECK: [[ww_row1_3]] = OpFMul %v4float -// CHECK: [[ww_row2_3]] = OpFMul %v4float -// CHECK: [[ww_plus_w_row0_3]] = OpFAdd %v4float -// CHECK: [[ww_plus_w_row1_3]] = OpFAdd %v4float -// CHECK: [[ww_plus_w_row2_3]] = OpFAdd %v4float - t.sub1.d = w * w + w; -// CHECK: [[ww_row0_4]] = OpFMul %v4float -// CHECK: [[ww_row1_4]] = OpFMul %v4float -// CHECK: [[ww_row2_4]] = OpFMul %v4float -// CHECK: [[ww_plus_w_row0_4]] = OpFAdd %v4float -// CHECK: [[ww_plus_w_row1_4]] = OpFAdd %v4float -// CHECK: [[ww_plus_w_row2_4]] = OpFAdd %v4float - t.sub1.dp = w * w + w; -} - diff --git a/tools/clang/test/CodeGenSPIRV/decoration.relaxed-precision.array.hlsl b/tools/clang/test/CodeGenSPIRV/decoration.relaxed-precision.array.hlsl deleted file mode 100644 index ddec47153c..0000000000 --- a/tools/clang/test/CodeGenSPIRV/decoration.relaxed-precision.array.hlsl +++ /dev/null @@ -1,46 +0,0 @@ -// RUN: %dxc -T cs_6_0 -E main - -// CHECK: OpDecorate %testShared RelaxedPrecision -// CHECK-NEXT: OpDecorate %test RelaxedPrecision -// CHECK-NEXT: OpDecorate %testTypedef RelaxedPrecision -// CHECK-NOT: OpDecorate %notMin16 RelaxedPrecision -// CHECK-NEXT: OpDecorate %a RelaxedPrecision -// CHECK-NEXT: OpDecorate [[compositeConstr1:%\d+]] RelaxedPrecision -// CHECK-NEXT: OpDecorate [[compositeConstr2:%\d+]] RelaxedPrecision -// CHECK-NEXT: OpDecorate [[loadFromTest1:%\d+]] RelaxedPrecision -// CHECK-NEXT: OpDecorate [[loadFromTest2:%\d+]] RelaxedPrecision -// CHECK-NEXT: OpDecorate [[loadFromTestTypedef:%\d+]] RelaxedPrecision -// CHECK-NEXT: OpDecorate [[multiply1:%\d+]] RelaxedPrecision -// CHECK-NEXT: OpDecorate [[loadVariable1:%\d+]] RelaxedPrecision -// CHECK-NEXT: OpDecorate [[multiply2:%\d+]] RelaxedPrecision -// CHECK-NEXT: OpDecorate [[loadFromShared:%\d+]] RelaxedPrecision -// CHECK-NEXT: OpDecorate [[loadVariable2:%\d+]] RelaxedPrecision -// CHECK-NEXT: OpDecorate [[multiply3:%\d+]] RelaxedPrecision - -typedef min16float ArrayOfMin16Float0[2]; -typedef ArrayOfMin16Float0 ArrayOfMin16Float; - -groupshared min16float testShared[2]; - -[numthreads(1, 1, 1)] void main() -{ -// CHECK: [[compositeConstr2:%\d+]] = OpCompositeConstruct %_arr_v2float_uint_2 {{%\d+}} {{%\d+}} - min16float2 test[2] = { float2(1.0, 1.0), float2(1.0, 1.0) }; -// CHECK: [[compositeConstr1:%\d+]] = OpCompositeConstruct %_arr_float_uint_2 %float_1 %float_1 - ArrayOfMin16Float testTypedef = { 1.0, 1.0 }; - float notMin16[2] = { 1.0, 1.0 }; -// CHECK: [[loadFromTest1:%\d+]] = OpLoad %float {{%\d+}} - testShared[0] = test[0].x; - - min16float a = 1.0; -// CHECK: [[loadFromTest2:%\d+]] = OpLoad %float {{%\d+}} -// CHECK: [[loadFromTestTypedef:%\d+]] = OpLoad %float {{%\d+}} -// CHECK: [[multiply1:%\d+]] = OpFMul %float {{%\d+}} {{%\d+}} -// CHECK: [[loadVariable1:%\d+]] = OpLoad %float %a -// CHECK: [[multiply2:%\d+]] = OpFMul %float {{%\d+}} {{%\d+}} - a *= (test[0].x * testTypedef[0]); -// CHECK: [[loadFromShared:%\d+]] = OpLoad %float {{%\d+}} -// CHECK: [[loadVariable2:%\d+]] = OpLoad %float %a -// CHECK: [[multiply3:%\d+]] = OpFMul %float {{%\d+}} {{%\d+}} - a *= testShared[0]; -} diff --git a/tools/clang/test/CodeGenSPIRV/reduce.load.size.hlsl b/tools/clang/test/CodeGenSPIRV/reduce.load.size.hlsl deleted file mode 100644 index ce0d905220..0000000000 --- a/tools/clang/test/CodeGenSPIRV/reduce.load.size.hlsl +++ /dev/null @@ -1,32 +0,0 @@ -// RUN: %dxc -T cs_6_0 -E main -fspv-reduce-load-size -O0 - -struct S { - uint f; -}; - -cbuffer gBuffer { uint a[6]; }; - -RWStructuredBuffer gRWSBuffer; - -// CHECK-NOT: OpCompositeExtract - -// CHECK: [[p0:%\w+]] = OpAccessChain %_ptr_Uniform_uint {{%\w+}} %uint_0 -// CHECK: OpLoad %uint [[p0]] -// CHECK: [[p1:%\w+]] = OpAccessChain %_ptr_Uniform_uint {{%\w+}} %uint_1 -// CHECK: OpLoad %uint [[p1]] -// CHECK: [[p2:%\w+]] = OpAccessChain %_ptr_Uniform_uint {{%\w+}} %uint_2 -// CHECK: OpLoad %uint [[p2]] -// CHECK: [[p3:%\w+]] = OpAccessChain %_ptr_Uniform_uint {{%\w+}} %uint_3 -// CHECK: OpLoad %uint [[p3]] -// CHECK: [[p4:%\w+]] = OpAccessChain %_ptr_Uniform_uint {{%\w+}} %uint_4 -// CHECK: OpLoad %uint [[p4]] -// CHECK: [[p5:%\w+]] = OpAccessChain %_ptr_Uniform_uint {{%\w+}} %uint_5 -// CHECK: OpLoad %uint [[p5]] -uint foo(uint p[6]) { - return p[0] + p[1] + p[2] + p[3] + p[4] + p[5]; -} - -[numthreads(1,1,1)] -void main() { - gRWSBuffer[0].f = foo(a); -} diff --git a/tools/clang/test/CodeGenSPIRV/semantic.barycentrics.ps.np-c.hlsl b/tools/clang/test/CodeGenSPIRV/semantic.barycentrics.ps.np-c.hlsl deleted file mode 100644 index b26b1f61f2..0000000000 --- a/tools/clang/test/CodeGenSPIRV/semantic.barycentrics.ps.np-c.hlsl +++ /dev/null @@ -1,22 +0,0 @@ -// RUN: %dxc -T ps_6_1 -E main - -// CHECK: OpExtension "SPV_AMD_shader_explicit_vertex_parameter" - -// CHECK: OpEntryPoint Fragment -// CHECK-SAME: [[bary:%\d+]] - -// CHECK: OpDecorate [[bary]] BuiltIn BaryCoordNoPerspCentroidAMD - -// CHECK: [[bary]] = OpVariable %_ptr_Input_v2float Input - -float4 main(noperspective centroid float3 bary : SV_Barycentrics) : SV_Target { - return float4(bary, 1.0); -// CHECK: %param_var_bary = OpVariable %_ptr_Function_v3float Function -// CHECK-NEXT: [[c2:%\d+]] = OpLoad %v2float [[bary]] -// CHECK-NEXT: [[x:%\d+]] = OpCompositeExtract %float [[c2]] 0 -// CHECK-NEXT: [[y:%\d+]] = OpCompositeExtract %float [[c2]] 1 -// CHECK-NEXT: [[xy:%\d+]] = OpFAdd %float [[x]] [[y]] -// CHECK-NEXT: [[z:%\d+]] = OpFSub %float %float_1 [[xy]] -// CHECK-NEXT: [[c3:%\d+]] = OpCompositeConstruct %v3float [[x]] [[y]] [[z]] -// CHECK-NEXT: OpStore %param_var_bary [[c3]] -} diff --git a/tools/clang/test/CodeGenSPIRV/semantic.barycentrics.ps.np-s.hlsl b/tools/clang/test/CodeGenSPIRV/semantic.barycentrics.ps.np-s.hlsl deleted file mode 100644 index 798c7a3f85..0000000000 --- a/tools/clang/test/CodeGenSPIRV/semantic.barycentrics.ps.np-s.hlsl +++ /dev/null @@ -1,22 +0,0 @@ -// RUN: %dxc -T ps_6_1 -E main - -// CHECK: OpExtension "SPV_AMD_shader_explicit_vertex_parameter" - -// CHECK: OpEntryPoint Fragment -// CHECK-SAME: [[bary:%\d+]] - -// CHECK: OpDecorate [[bary]] BuiltIn BaryCoordNoPerspSampleAMD - -// CHECK: [[bary]] = OpVariable %_ptr_Input_v2float Input - -float4 main(noperspective sample float3 bary : SV_Barycentrics) : SV_Target { - return float4(bary, 1.0); -// CHECK: %param_var_bary = OpVariable %_ptr_Function_v3float Function -// CHECK-NEXT: [[c2:%\d+]] = OpLoad %v2float [[bary]] -// CHECK-NEXT: [[x:%\d+]] = OpCompositeExtract %float [[c2]] 0 -// CHECK-NEXT: [[y:%\d+]] = OpCompositeExtract %float [[c2]] 1 -// CHECK-NEXT: [[xy:%\d+]] = OpFAdd %float [[x]] [[y]] -// CHECK-NEXT: [[z:%\d+]] = OpFSub %float %float_1 [[xy]] -// CHECK-NEXT: [[c3:%\d+]] = OpCompositeConstruct %v3float [[x]] [[y]] [[z]] -// CHECK-NEXT: OpStore %param_var_bary [[c3]] -} diff --git a/tools/clang/test/CodeGenSPIRV/semantic.barycentrics.ps.np.hlsl b/tools/clang/test/CodeGenSPIRV/semantic.barycentrics.ps.np.hlsl deleted file mode 100644 index 85f4c564ac..0000000000 --- a/tools/clang/test/CodeGenSPIRV/semantic.barycentrics.ps.np.hlsl +++ /dev/null @@ -1,22 +0,0 @@ -// RUN: %dxc -T ps_6_1 -E main - -// CHECK: OpExtension "SPV_AMD_shader_explicit_vertex_parameter" - -// CHECK: OpEntryPoint Fragment -// CHECK-SAME: [[bary:%\d+]] - -// CHECK: OpDecorate [[bary]] BuiltIn BaryCoordNoPerspAMD - -// CHECK: [[bary]] = OpVariable %_ptr_Input_v2float Input - -float4 main(noperspective float3 bary : SV_Barycentrics) : SV_Target { - return float4(bary, 1.0); -// CHECK: %param_var_bary = OpVariable %_ptr_Function_v3float Function -// CHECK-NEXT: [[c2:%\d+]] = OpLoad %v2float [[bary]] -// CHECK-NEXT: [[x:%\d+]] = OpCompositeExtract %float [[c2]] 0 -// CHECK-NEXT: [[y:%\d+]] = OpCompositeExtract %float [[c2]] 1 -// CHECK-NEXT: [[xy:%\d+]] = OpFAdd %float [[x]] [[y]] -// CHECK-NEXT: [[z:%\d+]] = OpFSub %float %float_1 [[xy]] -// CHECK-NEXT: [[c3:%\d+]] = OpCompositeConstruct %v3float [[x]] [[y]] [[z]] -// CHECK-NEXT: OpStore %param_var_bary [[c3]] -} diff --git a/tools/clang/test/CodeGenSPIRV/semantic.barycentrics.ps.s-c.hlsl b/tools/clang/test/CodeGenSPIRV/semantic.barycentrics.ps.s-c.hlsl deleted file mode 100644 index 750047db21..0000000000 --- a/tools/clang/test/CodeGenSPIRV/semantic.barycentrics.ps.s-c.hlsl +++ /dev/null @@ -1,22 +0,0 @@ -// RUN: %dxc -T ps_6_1 -E main - -// CHECK: OpExtension "SPV_AMD_shader_explicit_vertex_parameter" - -// CHECK: OpEntryPoint Fragment -// CHECK-SAME: [[bary:%\d+]] - -// CHECK: OpDecorate [[bary]] BuiltIn BaryCoordSmoothCentroidAMD - -// CHECK: [[bary]] = OpVariable %_ptr_Input_v2float Input - -float4 main(centroid float3 bary : SV_Barycentrics) : SV_Target { - return float4(bary, 1.0); -// CHECK: %param_var_bary = OpVariable %_ptr_Function_v3float Function -// CHECK-NEXT: [[c2:%\d+]] = OpLoad %v2float [[bary]] -// CHECK-NEXT: [[x:%\d+]] = OpCompositeExtract %float [[c2]] 0 -// CHECK-NEXT: [[y:%\d+]] = OpCompositeExtract %float [[c2]] 1 -// CHECK-NEXT: [[xy:%\d+]] = OpFAdd %float [[x]] [[y]] -// CHECK-NEXT: [[z:%\d+]] = OpFSub %float %float_1 [[xy]] -// CHECK-NEXT: [[c3:%\d+]] = OpCompositeConstruct %v3float [[x]] [[y]] [[z]] -// CHECK-NEXT: OpStore %param_var_bary [[c3]] -} diff --git a/tools/clang/test/CodeGenSPIRV/semantic.barycentrics.ps.s-s.hlsl b/tools/clang/test/CodeGenSPIRV/semantic.barycentrics.ps.s-s.hlsl deleted file mode 100644 index 85ef3ecc76..0000000000 --- a/tools/clang/test/CodeGenSPIRV/semantic.barycentrics.ps.s-s.hlsl +++ /dev/null @@ -1,22 +0,0 @@ -// RUN: %dxc -T ps_6_1 -E main - -// CHECK: OpExtension "SPV_AMD_shader_explicit_vertex_parameter" - -// CHECK: OpEntryPoint Fragment -// CHECK-SAME: [[bary:%\d+]] - -// CHECK: OpDecorate [[bary]] BuiltIn BaryCoordSmoothSampleAMD - -// CHECK: [[bary]] = OpVariable %_ptr_Input_v2float Input - -float4 main(sample float3 bary : SV_Barycentrics) : SV_Target { - return float4(bary, 1.0); -// CHECK: %param_var_bary = OpVariable %_ptr_Function_v3float Function -// CHECK-NEXT: [[c2:%\d+]] = OpLoad %v2float [[bary]] -// CHECK-NEXT: [[x:%\d+]] = OpCompositeExtract %float [[c2]] 0 -// CHECK-NEXT: [[y:%\d+]] = OpCompositeExtract %float [[c2]] 1 -// CHECK-NEXT: [[xy:%\d+]] = OpFAdd %float [[x]] [[y]] -// CHECK-NEXT: [[z:%\d+]] = OpFSub %float %float_1 [[xy]] -// CHECK-NEXT: [[c3:%\d+]] = OpCompositeConstruct %v3float [[x]] [[y]] [[z]] -// CHECK-NEXT: OpStore %param_var_bary [[c3]] -} diff --git a/tools/clang/test/CodeGenSPIRV/semantic.barycentrics.ps.s.hlsl b/tools/clang/test/CodeGenSPIRV/semantic.barycentrics.ps.s.hlsl deleted file mode 100644 index 74168306d4..0000000000 --- a/tools/clang/test/CodeGenSPIRV/semantic.barycentrics.ps.s.hlsl +++ /dev/null @@ -1,22 +0,0 @@ -// RUN: %dxc -T ps_6_1 -E main - -// CHECK: OpExtension "SPV_AMD_shader_explicit_vertex_parameter" - -// CHECK: OpEntryPoint Fragment -// CHECK-SAME: [[bary:%\d+]] - -// CHECK: OpDecorate [[bary]] BuiltIn BaryCoordSmoothAMD - -// CHECK: [[bary]] = OpVariable %_ptr_Input_v2float Input - -float4 main(float3 bary : SV_Barycentrics) : SV_Target { - return float4(bary, 1.0); -// CHECK: %param_var_bary = OpVariable %_ptr_Function_v3float Function -// CHECK-NEXT: [[c2:%\d+]] = OpLoad %v2float [[bary]] -// CHECK-NEXT: [[x:%\d+]] = OpCompositeExtract %float [[c2]] 0 -// CHECK-NEXT: [[y:%\d+]] = OpCompositeExtract %float [[c2]] 1 -// CHECK-NEXT: [[xy:%\d+]] = OpFAdd %float [[x]] [[y]] -// CHECK-NEXT: [[z:%\d+]] = OpFSub %float %float_1 [[xy]] -// CHECK-NEXT: [[c3:%\d+]] = OpCompositeConstruct %v3float [[x]] [[y]] [[z]] -// CHECK-NEXT: OpStore %param_var_bary [[c3]] -} diff --git a/tools/clang/test/CodeGenSPIRV/spirv.legal.cbuffer.hlsl b/tools/clang/test/CodeGenSPIRV/spirv.legal.cbuffer.hlsl deleted file mode 100644 index b74f433f42..0000000000 --- a/tools/clang/test/CodeGenSPIRV/spirv.legal.cbuffer.hlsl +++ /dev/null @@ -1,76 +0,0 @@ -// RUN: %dxc -T ps_6_0 -E main - -// %type_ConstantBuffer_S is the type for myCBuffer. With layout decoration. -// %S is the type for myASBuffer elements. With layout decoration. -// %S_0 is the type for function local variables. Without layout decoration. - -// CHECK: OpMemberDecorate %type_ConstantBuffer_S 0 Offset 0 -// CHECK: OpMemberDecorate %S 0 Offset 0 -// CHECK-NOT: OpMemberDecorate %S_0 0 Offset 0 - -// CHECK: %type_ConstantBuffer_S = OpTypeStruct %v4float -// CHECK: %S = OpTypeStruct %v4float -// CHECK: %S_0 = OpTypeStruct %v4float -struct S { - float4 f; -}; - -// CHECK: %myCBuffer = OpVariable %_ptr_Uniform_type_ConstantBuffer_S Uniform -ConstantBuffer myCBuffer; -AppendStructuredBuffer myASBuffer; - -S retStuff(); - -float4 doStuff(S buffer) { - return buffer.f; -} - -float4 main(in float4 pos : SV_Position) : SV_Target -{ -// Initializing a T with a ConstantBuffer is a copy -// CHECK: [[val:%\d+]] = OpLoad %type_ConstantBuffer_S %myCBuffer -// CHECK-NEXT: [[vec:%\d+]] = OpCompositeExtract %v4float [[val]] 0 -// CHECK-NEXT: [[tmp:%\d+]] = OpCompositeConstruct %S_0 [[vec]] -// CHECK-NEXT: OpStore %buffer1 [[tmp]] - S buffer1 = myCBuffer; - -// Assigning a ConstantBuffer to a T is a copy -// CHECK: [[val:%\d+]] = OpLoad %type_ConstantBuffer_S %myCBuffer -// CHECK-NEXT: [[vec:%\d+]] = OpCompositeExtract %v4float [[val]] 0 -// CHECK-NEXT: [[tmp:%\d+]] = OpCompositeConstruct %S_0 [[vec]] -// CHECK-NEXT: OpStore %buffer2 [[tmp]] - S buffer2; - buffer2 = myCBuffer; - -// We have the same struct type here -// CHECK: [[val:%\d+]] = OpFunctionCall %S_0 %retStuff -// CHECK-NEXT: OpStore %buffer3 [[val]] - S buffer3; - buffer3 = retStuff(); - -// Write out each component recursively -// CHECK: [[ptr:%\d+]] = OpAccessChain %_ptr_Uniform_S %myASBuffer %uint_0 {{%\d+}} -// CHECK-NEXT: [[val:%\d+]] = OpLoad %type_ConstantBuffer_S %myCBuffer -// CHECK-NEXT: [[vec:%\d+]] = OpCompositeExtract %v4float [[val]] 0 -// CHECK-NEXT: [[tmp:%\d+]] = OpCompositeConstruct %S_0 [[vec]] -// CHECK-NEXT: [[vec:%\d+]] = OpCompositeExtract %v4float [[tmp]] 0 -// CHECK-NEXT: [[tmp:%\d+]] = OpCompositeConstruct %S [[vec]] -// CHECK-NEXT: OpStore [[ptr]] [[tmp]] - myASBuffer.Append(myCBuffer); - -// Passing a ConstantBuffer to a T parameter is a copy -// CHECK: [[val:%\d+]] = OpLoad %type_ConstantBuffer_S %myCBuffer -// CHECK-NEXT: [[vec:%\d+]] = OpCompositeExtract %v4float [[val]] 0 -// CHECK-NEXT: [[tmp:%\d+]] = OpCompositeConstruct %S_0 [[vec]] -// CHECK-NEXT: OpStore %param_var_buffer [[tmp]] - return doStuff(myCBuffer); -} - -S retStuff() { -// Returning a ConstantBuffer as a T is a copy -// CHECK: [[val:%\d+]] = OpLoad %type_ConstantBuffer_S %myCBuffer -// CHECK-NEXT: [[vec:%\d+]] = OpCompositeExtract %v4float [[val]] 0 -// CHECK-NEXT: [[ret:%\d+]] = OpCompositeConstruct %S_0 [[vec]] -// CHECK-NEXT: OpReturnValue [[ret]] - return myCBuffer; -} diff --git a/tools/clang/test/CodeGenSPIRV/spirv.legal.tbuffer.hlsl b/tools/clang/test/CodeGenSPIRV/spirv.legal.tbuffer.hlsl deleted file mode 100644 index 3ad2eaabb3..0000000000 --- a/tools/clang/test/CodeGenSPIRV/spirv.legal.tbuffer.hlsl +++ /dev/null @@ -1,81 +0,0 @@ -// RUN: %dxc -T ps_6_0 -E main - -// Note: The following is invalid SPIR-V code. -// -// * The assignment ignores storage class (and thus layout) difference. - -// %type_TextureBuffer_S is the type for myTBuffer. With layout decoration. -// %S is the type for myASBuffer elements. With layout decoration. -// %S_0 is the type for function local variables. Without layout decoration. - -// CHECK: OpMemberDecorate %type_TextureBuffer_S 0 Offset 0 -// CHECK: OpMemberDecorate %S 0 Offset 0 -// CHECK-NOT: OpMemberDecorate %S_0 0 Offset 0 - -// CHECK: %type_TextureBuffer_S = OpTypeStruct %v4float -// CHECK: %S = OpTypeStruct %v4float -// CHECK: %S_0 = OpTypeStruct %v4float -struct S { - float4 f; -}; - -// CHECK: %myTBuffer = OpVariable %_ptr_Uniform_type_TextureBuffer_S Uniform -TextureBuffer myTBuffer; -AppendStructuredBuffer myASBuffer; - -S retStuff(); - -float4 doStuff(S buffer) { - return buffer.f; -} - -float4 main(in float4 pos : SV_Position) : SV_Target -{ -// Initializing a T with a TextureBuffer is a copy -// CHECK: [[val:%\d+]] = OpLoad %type_TextureBuffer_S %myTBuffer -// CHECK-NEXT: [[vec:%\d+]] = OpCompositeExtract %v4float [[val]] 0 -// CHECK-NEXT: [[tmp:%\d+]] = OpCompositeConstruct %S_0 [[vec]] -// CHECK-NEXT: OpStore %buffer1 [[tmp]] - S buffer1 = myTBuffer; - -// Assigning a TextureBuffer to a T is a copy -// CHECK: [[val:%\d+]] = OpLoad %type_TextureBuffer_S %myTBuffer -// CHECK-NEXT: [[vec:%\d+]] = OpCompositeExtract %v4float [[val]] 0 -// CHECK-NEXT: [[tmp:%\d+]] = OpCompositeConstruct %S_0 [[vec]] -// CHECK-NEXT: OpStore %buffer2 [[tmp]] - S buffer2; - buffer2 = myTBuffer; - -// We have the same struct type here -// CHECK: [[val:%\d+]] = OpFunctionCall %S_0 %retStuff -// CHECK-NEXT: OpStore %buffer3 [[val]] - S buffer3; - buffer3 = retStuff(); - -// TODO: The underlying struct type has the same layout but %type_TextureBuffer_S -// has an additional BufferBlock decoration. So this causes an validation error. -// CHECK: [[ptr:%\d+]] = OpAccessChain %_ptr_Uniform_S %myASBuffer %uint_0 {{%\d+}} -// CHECK-NEXT: [[tb:%\d+]] = OpLoad %type_TextureBuffer_S %myTBuffer -// CHECK-NEXT: [[vec:%\d+]] = OpCompositeExtract %v4float [[tb]] 0 -// CHECK-NEXT: [[loc:%\d+]] = OpCompositeConstruct %S_0 [[vec]] -// CHECK-NEXT: [[vec:%\d+]] = OpCompositeExtract %v4float [[loc]] 0 -// CHECK-NEXT: [[val:%\d+]] = OpCompositeConstruct %S [[vec]] -// CHECK-NEXT: OpStore [[ptr]] [[val]] - myASBuffer.Append(myTBuffer); - -// Passing a TextureBuffer to a T parameter is a copy -// CHECK: [[val:%\d+]] = OpLoad %type_TextureBuffer_S %myTBuffer -// CHECK-NEXT: [[vec:%\d+]] = OpCompositeExtract %v4float [[val]] 0 -// CHECK-NEXT: [[tmp:%\d+]] = OpCompositeConstruct %S_0 [[vec]] -// CHECK-NEXT: OpStore %param_var_buffer [[tmp]] - return doStuff(myTBuffer); -} - -S retStuff() { -// Returning a TextureBuffer as a T is a copy -// CHECK: [[val:%\d+]] = OpLoad %type_TextureBuffer_S %myTBuffer -// CHECK-NEXT: [[vec:%\d+]] = OpCompositeExtract %v4float [[val]] 0 -// CHECK-NEXT: [[ret:%\d+]] = OpCompositeConstruct %S_0 [[vec]] -// CHECK-NEXT: OpReturnValue [[ret]] - return myTBuffer; -} diff --git a/tools/clang/test/CodeGenSPIRV/var.init.struct.hlsl b/tools/clang/test/CodeGenSPIRV/var.init.struct.hlsl deleted file mode 100644 index 8a12e2667a..0000000000 --- a/tools/clang/test/CodeGenSPIRV/var.init.struct.hlsl +++ /dev/null @@ -1,96 +0,0 @@ -// RUN: %dxc -T vs_6_0 -E main - -struct S { - int3 a; - uint b; - float2x2 c; -}; - -struct T { - // Same fields as S - int3 h; - uint i; - float2x2 j; - - // Additional field - bool2 k; - - // Embedded S - S l; - - // Similar to S but need some casts - float3 m; - int n; - float2x2 o; -}; - -struct O { - int x; -}; - -struct P { - O y; - float z; -}; - -struct W { - float4 color; -}; - -void main() { -// CHECK-LABEL: %bb_entry = OpLabel - - // Flat initializer list -// CHECK: [[a:%\d+]] = OpCompositeConstruct %v3int %int_1 %int_2 %int_3 -// CHECK-NEXT: [[c0:%\d+]] = OpCompositeConstruct %v2float %float_1 %float_2 -// CHECK-NEXT: [[c1:%\d+]] = OpCompositeConstruct %v2float %float_3 %float_4 -// CHECK-NEXT: [[c:%\d+]] = OpCompositeConstruct %mat2v2float [[c0]] [[c1]] -// CHECK-NEXT: [[s1:%\d+]] = OpCompositeConstruct %S [[a]] %uint_42 [[c]] -// CHECK-NEXT: OpStore %s1 [[s1]] - S s1 = {1, 2, 3, 42, 1., 2., 3., 4.}; - - // Random parentheses -// CHECK: [[a:%\d+]] = OpCompositeConstruct %v3int %int_1 %int_2 %int_3 -// CHECK-NEXT: [[c0:%\d+]] = OpCompositeConstruct %v2float %float_1 %float_2 -// CHECK-NEXT: [[c1:%\d+]] = OpCompositeConstruct %v2float %float_3 %float_4 -// CHECK-NEXT: [[c:%\d+]] = OpCompositeConstruct %mat2v2float [[c0]] [[c1]] -// CHECK-NEXT: [[s2:%\d+]] = OpCompositeConstruct %S [[a]] %uint_42 [[c]] -// CHECK-NEXT: OpStore %s2 [[s2]] - S s2 = {{1, 2}, 3, {{42}, {{1.}}}, {2., {3., 4.}}}; - - // Flat initalizer list for nested structs -// CHECK: [[y:%\d+]] = OpCompositeConstruct %O %int_1 -// CHECK-NEXT: [[p:%\d+]] = OpCompositeConstruct %P [[y]] %float_2 -// CHECK-NEXT: OpStore %p [[p]] - P p = {1, 2.}; - - // Mixed case: use struct as a whole, decomposing struct, type casting - -// CHECK-NEXT: [[s1_val:%\d+]] = OpLoad %S %s1 -// CHECK-NEXT: [[l:%\d+]] = OpLoad %S %s2 -// CHECK-NEXT: [[s2_val:%\d+]] = OpLoad %S %s2 -// CHECK-NEXT: [[h:%\d+]] = OpCompositeExtract %v3int [[s1_val]] 0 -// CHECK-NEXT: [[i:%\d+]] = OpCompositeExtract %uint [[s1_val]] 1 -// CHECK-NEXT: [[j:%\d+]] = OpCompositeExtract %mat2v2float [[s1_val]] 2 - -// CHECK-NEXT: [[k:%\d+]] = OpCompositeConstruct %v2bool %true %false - -// CHECK-NEXT: [[s2av:%\d+]] = OpCompositeExtract %v3int [[s2_val]] 0 -// CHECK-NEXT: [[s2bv:%\d+]] = OpCompositeExtract %uint [[s2_val]] 1 -// CHECK-NEXT: [[o:%\d+]] = OpCompositeExtract %mat2v2float [[s2_val]] 2 -// CHECK-NEXT: [[m:%\d+]] = OpConvertSToF %v3float [[s2av]] -// CHECK-NEXT: [[n:%\d+]] = OpBitcast %int [[s2bv]] -// CHECK-NEXT: [[t:%\d+]] = OpCompositeConstruct %T [[h]] [[i]] [[j]] [[k]] [[l]] [[m]] [[n]] [[o]] -// CHECK-NEXT: OpStore %t [[t]] - T t = {s1, // Decomposing struct - true, false, // constructing field from scalar - s2, // Embedded struct - s2 // Decomposing struct + type casting - }; - - // Using InitListExpr -// CHECK: [[int4_zero:%\d+]] = OpCompositeConstruct %v4int %int_0 %int_0 %int_0 %int_0 -// CHECK-NEXT: [[float4_zero:%\d+]] = OpConvertSToF %v4float [[int4_zero]] -// CHECK-NEXT: {{%\d+}} = OpCompositeConstruct %W [[float4_zero]] - W w = { (0).xxxx }; -} diff --git a/tools/clang/test/CodeGenSPIRV/vk.cloption.invert-w.ps.hlsl b/tools/clang/test/CodeGenSPIRV/vk.cloption.invert-w.ps.hlsl deleted file mode 100644 index 0249c74777..0000000000 --- a/tools/clang/test/CodeGenSPIRV/vk.cloption.invert-w.ps.hlsl +++ /dev/null @@ -1,12 +0,0 @@ -// RUN: %dxc -T ps_6_0 -E main -fvk-use-dx-position-w - -float4 main(float4 pos: SV_Position) : SV_Target { - return pos; -} - -// CHECK: [[old:%\d+]] = OpLoad %v4float %gl_FragCoord -// CHECK-NEXT: [[oldW:%\d+]] = OpCompositeExtract %float [[old]] 3 -// CHECK-NEXT: [[newW:%\d+]] = OpFDiv %float %float_1 [[oldW]] -// CHECK-NEXT: [[new:%\d+]] = OpCompositeInsert %v4float [[newW]] [[old]] 3 -// CHECK-NEXT: OpStore %param_var_pos [[new]] -// CHECK-NEXT: OpFunctionCall %v4float %src_main %param_var_pos diff --git a/tools/clang/test/CodeGenSPIRV/vk.cloption.invert-y.vs.hlsl b/tools/clang/test/CodeGenSPIRV/vk.cloption.invert-y.vs.hlsl deleted file mode 100644 index 5d2eebe8df..0000000000 --- a/tools/clang/test/CodeGenSPIRV/vk.cloption.invert-y.vs.hlsl +++ /dev/null @@ -1,11 +0,0 @@ -// RUN: %dxc -T vs_6_0 -E main -fvk-invert-y - -float4 main(float4 a : A) : SV_Position { - return a; -} - -// CHECK: [[a:%\d+]] = OpFunctionCall %v4float %src_main %param_var_a -// CHECK-NEXT: [[oldY:%\d+]] = OpCompositeExtract %float [[a]] 1 -// CHECK-NEXT: [[newY:%\d+]] = OpFNegate %float [[oldY]] -// CHECK-NEXT: [[pos:%\d+]] = OpCompositeInsert %v4float [[newY]] [[a]] 1 -// CHECK-NEXT: OpStore %gl_Position [[pos]] diff --git a/tools/clang/test/CodeGenSPIRV/vk.layout.cbuffer.boolean.hlsl b/tools/clang/test/CodeGenSPIRV/vk.layout.cbuffer.boolean.hlsl deleted file mode 100644 index 5f429fcacf..0000000000 --- a/tools/clang/test/CodeGenSPIRV/vk.layout.cbuffer.boolean.hlsl +++ /dev/null @@ -1,162 +0,0 @@ -// RUN: %dxc -T ps_6_0 -HV 2018 -E main - -// CHECK: OpDecorate %_arr_v3uint_uint_2 ArrayStride 16 -// CHECK: OpMemberDecorate %FrameConstants 0 Offset 0 -// CHECK: OpMemberDecorate %FrameConstants 1 Offset 4 -// CHECK: OpMemberDecorate %FrameConstants 2 Offset 16 -// CHECK: OpMemberDecorate %type_CONSTANTS 0 Offset 0 -// CHECK: OpDecorate %type_CONSTANTS Block - -// CHECK: [[v3uint0:%\d+]] = OpConstantComposite %v3uint %uint_0 %uint_0 %uint_0 -// CHECK: [[v2uint0:%\d+]] = OpConstantComposite %v2uint %uint_0 %uint_0 - -// CHECK: %T = OpTypeStruct %_arr_uint_uint_1 -struct T { - bool boolArray[1]; -}; - -// CHECK: %FrameConstants = OpTypeStruct %uint %v3uint %_arr_v3uint_uint_2 %T -struct FrameConstants -{ - bool boolScalar; - bool3 boolVec; - row_major bool2x3 boolMat; - T t; -}; - -[[vk::binding(0, 0)]] -cbuffer CONSTANTS -{ - FrameConstants frameConstants; -}; - -// These are the types that hold SPIR-V booleans, rather than Uints. -// CHECK: %T_0 = OpTypeStruct %_arr_bool_uint_1 -// CHECK: %FrameConstants_0 = OpTypeStruct %bool %v3bool %_arr_v3bool_uint_2 %T_0 - -float4 main(in float4 texcoords : TEXCOORD0) : SV_TARGET -{ -// CHECK: [[FrameConstants:%\d+]] = OpAccessChain %_ptr_Uniform_FrameConstants %CONSTANTS %int_0 -// CHECK-NEXT: [[uintVecPtr:%\d+]] = OpAccessChain %_ptr_Uniform_v3uint [[FrameConstants]] %int_1 -// CHECK-NEXT: [[uintVec:%\d+]] = OpLoad %v3uint [[uintVecPtr]] -// CHECK-NEXT: [[boolVec:%\d+]] = OpINotEqual %v3bool [[uintVec]] [[v3uint0]] -// CHECK-NEXT: OpStore %a [[boolVec]] - bool3 a = frameConstants.boolVec; - -// CHECK: [[FrameConstants:%\d+]] = OpAccessChain %_ptr_Uniform_FrameConstants %CONSTANTS %int_0 -// CHECK-NEXT: [[uintPtr:%\d+]] = OpAccessChain %_ptr_Uniform_uint [[FrameConstants]] %int_1 %uint_0 -// CHECK-NEXT: [[uint:%\d+]] = OpLoad %uint [[uintPtr]] -// CHECK-NEXT: [[bool:%\d+]] = OpINotEqual %bool [[uint]] %uint_0 -// CHECK-NEXT: OpStore %b [[bool]] - bool b = frameConstants.boolVec[0]; - -// CHECK: [[FrameConstants:%\d+]] = OpAccessChain %_ptr_Uniform_FrameConstants %CONSTANTS %int_0 -// CHECK-NEXT: [[uintPtr:%\d+]] = OpAccessChain %_ptr_Uniform_uint [[FrameConstants]] %int_0 -// CHECK-NEXT: [[uint:%\d+]] = OpLoad %uint [[uintPtr]] -// CHECK-NEXT: [[bool:%\d+]] = OpINotEqual %bool [[uint]] %uint_0 -// CHECK-NEXT: OpStore %c [[bool]] - bool c = frameConstants.boolScalar; - -// CHECK: [[FrameConstants:%\d+]] = OpAccessChain %_ptr_Uniform_FrameConstants %CONSTANTS %int_0 -// CHECK-NEXT: [[uintMatPtr:%\d+]] = OpAccessChain %_ptr_Uniform__arr_v3uint_uint_2 [[FrameConstants]] %int_2 -// CHECK-NEXT: [[uintMat:%\d+]] = OpLoad %_arr_v3uint_uint_2 [[uintMatPtr]] -// CHECK-NEXT: [[uintVec1:%\d+]] = OpCompositeExtract %v3uint [[uintMat]] 0 -// CHECK-NEXT: [[boolVec1:%\d+]] = OpINotEqual %v3bool [[uintVec1]] [[v3uint0]] -// CHECK-NEXT: [[uintVec2:%\d+]] = OpCompositeExtract %v3uint [[uintMat]] 1 -// CHECK-NEXT: [[boolVec2:%\d+]] = OpINotEqual %v3bool [[uintVec2]] [[v3uint0]] -// CHECK-NEXT: [[boolMat:%\d+]] = OpCompositeConstruct %_arr_v3bool_uint_2 [[boolVec1]] [[boolVec2]] -// CHECK-NEXT: OpStore %d [[boolMat]] - bool2x3 d = frameConstants.boolMat; - -// CHECK: [[FrameConstants:%\d+]] = OpAccessChain %_ptr_Uniform_FrameConstants %CONSTANTS %int_0 -// CHECK-NEXT: [[uintVecPtr:%\d+]] = OpAccessChain %_ptr_Uniform_v3uint [[FrameConstants]] %int_2 %uint_0 -// CHECK-NEXT: [[uintVec:%\d+]] = OpLoad %v3uint [[uintVecPtr]] -// CHECK-NEXT: [[boolVec:%\d+]] = OpINotEqual %v3bool [[uintVec]] [[v3uint0]] -// CHECK-NEXT: OpStore %e [[boolVec]] - bool3 e = frameConstants.boolMat[0]; - -// CHECK: [[FrameConstants:%\d+]] = OpAccessChain %_ptr_Uniform_FrameConstants %CONSTANTS %int_0 -// CHECK-NEXT: [[uintPtr:%\d+]] = OpAccessChain %_ptr_Uniform_uint [[FrameConstants]] %int_2 %uint_1 %uint_2 -// CHECK-NEXT: [[uint:%\d+]] = OpLoad %uint [[uintPtr]] -// CHECK-NEXT: [[bool:%\d+]] = OpINotEqual %bool [[uint]] %uint_0 -// CHECK-NEXT: OpStore %f [[bool]] - bool f = frameConstants.boolMat[1][2]; - -// Swizzle Vector: out of order -// CHECK: [[FrameConstants:%\d+]] = OpAccessChain %_ptr_Uniform_FrameConstants %CONSTANTS %int_0 -// CHECK-NEXT: [[uintVecPtr:%\d+]] = OpAccessChain %_ptr_Uniform_v3uint [[FrameConstants]] %int_1 -// CHECK-NEXT: [[uintVec:%\d+]] = OpLoad %v3uint [[uintVecPtr]] -// CHECK-NEXT: [[boolVec:%\d+]] = OpINotEqual %v3bool [[uintVec]] [[v3uint0]] -// CHECK-NEXT: [[swizzle:%\d+]] = OpVectorShuffle %v2bool [[boolVec]] [[boolVec]] 1 0 -// CHECK-NEXT: OpStore %g [[swizzle]] - bool2 g = frameConstants.boolVec.yx; - -// Swizzle Vector: one element only. -// CHECK: [[FrameConstants:%\d+]] = OpAccessChain %_ptr_Uniform_FrameConstants %CONSTANTS %int_0 -// CHECK-NEXT: [[uintVecPtr:%\d+]] = OpAccessChain %_ptr_Uniform_v3uint [[FrameConstants]] %int_1 -// CHECK-NEXT: [[uintPtr:%\d+]] = OpAccessChain %_ptr_Uniform_uint [[uintVecPtr]] %int_0 -// CHECK-NEXT: [[uint:%\d+]] = OpLoad %uint [[uintPtr]] -// CHECK-NEXT: [[bool:%\d+]] = OpINotEqual %bool [[uint]] %uint_0 -// CHECK-NEXT: OpStore %h [[bool]] - bool h = frameConstants.boolVec.x; - -// Swizzle Vector: original indeces. -// CHECK: [[FrameConstants:%\d+]] = OpAccessChain %_ptr_Uniform_FrameConstants %CONSTANTS %int_0 -// CHECK-NEXT: [[uintVecPtr:%\d+]] = OpAccessChain %_ptr_Uniform_v3uint [[FrameConstants]] %int_1 -// CHECK-NEXT: [[uintVec:%\d+]] = OpLoad %v3uint [[uintVecPtr]] -// CHECK-NEXT: [[boolVec:%\d+]] = OpINotEqual %v3bool [[uintVec]] [[v3uint0]] -// CHECK-NEXT: OpStore %i [[boolVec]] - bool3 i = frameConstants.boolVec.xyz; - -// Swizzle Vector: on temporary value (rvalue) -// CHECK: [[uintVec1:%\d+]] = OpLoad %v3uint {{%\d+}} -// CHECK-NEXT: [[boolVec1:%\d+]] = OpINotEqual %v3bool [[uintVec1]] [[v3uint0]] -// CHECK: [[uintVec2:%\d+]] = OpLoad %v3uint {{%\d+}} -// CHECK-NEXT: [[boolVec2:%\d+]] = OpINotEqual %v3bool [[uintVec2]] [[v3uint0]] -// CHECK-NEXT: [[temporary:%\d+]] = OpLogicalAnd %v3bool [[boolVec1]] [[boolVec2]] -// CHECK-NEXT: [[bool:%\d+]] = OpCompositeExtract %bool [[temporary]] 0 -// CHECK-NEXT: OpStore %j [[bool]] - bool j = (frameConstants.boolVec && frameConstants.boolVec).x; - -// CHECK: [[FrameConstants:%\d+]] = OpAccessChain %_ptr_Uniform_FrameConstants %CONSTANTS %int_0 -// CHECK-NEXT: [[uintMatPtr:%\d+]] = OpAccessChain %_ptr_Uniform__arr_v3uint_uint_2 [[FrameConstants]] %int_2 -// CHECK-NEXT: [[uintPtr:%\d+]] = OpAccessChain %_ptr_Uniform_uint [[uintMatPtr]] %int_1 %int_2 -// CHECK-NEXT: [[uint0:%\d+]] = OpLoad %uint [[uintPtr]] -// CHECK-NEXT: [[uintPtr:%\d+]] = OpAccessChain %_ptr_Uniform_uint [[uintMatPtr]] %int_0 %int_1 -// CHECK-NEXT: [[uint1:%\d+]] = OpLoad %uint [[uintPtr]] -// CHECK-NEXT: [[uintVec:%\d+]] = OpCompositeConstruct %v2uint [[uint0]] [[uint1]] -// CHECK-NEXT: [[boolVec:%\d+]] = OpINotEqual %v2bool [[uintVec]] [[v2uint0]] -// CHECK-NEXT: OpStore %k [[boolVec]] - bool2 k = frameConstants.boolMat._m12_m01; - -// CHECK: [[FrameConstants:%\d+]] = OpAccessChain %_ptr_Uniform_FrameConstants %CONSTANTS %int_0 -// CHECK-NEXT: [[ptr:%\d+]] = OpAccessChain %_ptr_Uniform_uint [[FrameConstants]] %int_3 %int_0 %int_2 -// CHECK-NEXT: [[uint:%\d+]] = OpLoad %uint [[ptr]] -// CHECK-NEXT: [[bool:%\d+]] = OpINotEqual %bool [[uint]] %uint_0 -// CHECK-NEXT: OpStore %l [[bool]] - bool l = frameConstants.t.boolArray[2]; - -// CHECK: [[FrameConstantsPtr:%\d+]] = OpAccessChain %_ptr_Uniform_FrameConstants %CONSTANTS %int_0 -// CHECK-NEXT: [[FrameConstants:%\d+]] = OpLoad %FrameConstants [[FrameConstantsPtr]] -// CHECK-NEXT: [[fc_0_uint:%\d+]] = OpCompositeExtract %uint [[FrameConstants]] 0 -// CHECK-NEXT: [[fc_0_bool:%\d+]] = OpINotEqual %bool [[fc_0_uint]] %uint_0 -// CHECK-NEXT: [[fc_1_uint3:%\d+]] = OpCompositeExtract %v3uint [[FrameConstants]] 1 -// CHECK-NEXT: [[fc_1_bool3:%\d+]] = OpINotEqual %v3bool [[fc_1_uint3]] [[v3uint0]] -// CHECK-NEXT: [[fc_2_uintMat:%\d+]] = OpCompositeExtract %_arr_v3uint_uint_2 [[FrameConstants]] 2 -// CHECK-NEXT: [[fc_2_uintMat_row0_uint:%\d+]] = OpCompositeExtract %v3uint [[fc_2_uintMat]] 0 -// CHECK-NEXT: [[fc_2_uintMat_row0_bool:%\d+]] = OpINotEqual %v3bool [[fc_2_uintMat_row0_uint]] [[v3uint0]] -// CHECK-NEXT: [[fc_2_uintMat_row1_uint:%\d+]] = OpCompositeExtract %v3uint [[fc_2_uintMat]] 1 -// CHECK-NEXT: [[fc_2_uintMat_row1_bool:%\d+]] = OpINotEqual %v3bool [[fc_2_uintMat_row1_uint]] [[v3uint0]] -// CHECK-NEXT: [[fc_2_boolMat:%\d+]] = OpCompositeConstruct %_arr_v3bool_uint_2 [[fc_2_uintMat_row0_bool]] [[fc_2_uintMat_row1_bool]] -// CHECK-NEXT: [[fc_3_T:%\d+]] = OpCompositeExtract %T [[FrameConstants]] 3 -// CHECK-NEXT: [[fc_3_T_0_uint_arr:%\d+]] = OpCompositeExtract %_arr_uint_uint_1 [[fc_3_T]] 0 -// CHECK-NEXT: [[fc_3_T_0_0_uint:%\d+]] = OpCompositeExtract %uint [[fc_3_T_0_uint_arr]] 0 -// CHECK-NEXT: [[fc_3_T_0_0_bool:%\d+]] = OpINotEqual %bool [[fc_3_T_0_0_uint]] %uint_0 -// CHECK-NEXT: [[fc_3_T_0_bool_arr:%\d+]] = OpCompositeConstruct %_arr_bool_uint_1 [[fc_3_T_0_0_bool]] -// CHECK-NEXT: [[fc_3_T_bool:%\d+]] = OpCompositeConstruct %T_0 [[fc_3_T_0_bool_arr]] -// CHECK-NEXT: [[fc:%\d+]] = OpCompositeConstruct %FrameConstants_0 [[fc_0_bool]] [[fc_1_bool3]] [[fc_2_boolMat]] [[fc_3_T_bool]] -// CHECK-NEXT: OpStore %fc [[fc]] - FrameConstants fc = frameConstants; - - return (1.0).xxxx; -} diff --git a/tools/clang/test/CodeGenSPIRV/vk.layout.cbuffer.zpr.hlsl b/tools/clang/test/CodeGenSPIRV/vk.layout.cbuffer.zpr.hlsl deleted file mode 100644 index 7db872c85a..0000000000 --- a/tools/clang/test/CodeGenSPIRV/vk.layout.cbuffer.zpr.hlsl +++ /dev/null @@ -1,52 +0,0 @@ -// RUN: %dxc -T vs_6_0 -E main -Zpr - -// CHECK: OpDecorate %_arr_mat2v3float_uint_5 ArrayStride 32 -// CHECK: OpDecorate %_arr_mat2v3float_uint_5_0 ArrayStride 48 - -// CHECK: OpDecorate %_arr_v3int_uint_2 ArrayStride 16 -// CHECK: OpDecorate %_arr__arr_v3int_uint_2_uint_5 ArrayStride 32 - -// CHECK: OpMemberDecorate %type_MyCBuffer 0 ColMajor -// CHECK: OpMemberDecorate %type_MyCBuffer 1 RowMajor -// CHECK: OpMemberDecorate %type_MyCBuffer 2 ColMajor - -// CHECK: %type_MyCBuffer = OpTypeStruct %_arr_mat2v3float_uint_5 %_arr_mat2v3float_uint_5_0 %_arr_mat2v3float_uint_5 -cbuffer MyCBuffer { - row_major float2x3 matrices1[5]; - column_major float2x3 matrices2[5]; - float2x3 matrices3[5]; - - row_major int2x3 matrices4[5]; - int2x3 matrices5[5]; -} - -void main() { - // Check that the result types for access chains are correct -// CHECK: {{%\d+}} = OpAccessChain %_ptr_Uniform__arr_mat2v3float_uint_5 %MyCBuffer %int_0 -// CHECK: {{%\d+}} = OpAccessChain %_ptr_Uniform__arr_mat2v3float_uint_5_0 %MyCBuffer %int_1 -// CHECK: {{%\d+}} = OpAccessChain %_ptr_Uniform__arr_mat2v3float_uint_5 %MyCBuffer %int_2 - float2x3 m1 = matrices1[1]; - float2x3 m2 = matrices2[2]; - float2x3 m3 = matrices3[3]; - - // Note: Since non-fp matrices are represented as arrays of vectors, and - // due to layout decoration on the rhs of the assignments below, - // a load and store is performed for each vector. - -// CHECK: [[ptr_matrices4:%\d+]] = OpAccessChain %_ptr_Uniform__arr__arr_v3int_uint_2_uint_5 %MyCBuffer %int_3 -// CHECK-NEXT: [[ptr_matrices4_1:%\d+]] = OpAccessChain %_ptr_Uniform__arr_v3int_uint_2 [[ptr_matrices4]] %int_1 -// CHECK-NEXT: [[matrices4_1:%\d+]] = OpLoad %_arr_v3int_uint_2 [[ptr_matrices4_1]] -// CHECK-NEXT: [[matrices4_1_row0:%\d+]] = OpCompositeExtract %v3int [[matrices4_1]] 0 -// CHECK-NEXT: [[matrices4_1_row1:%\d+]] = OpCompositeExtract %v3int [[matrices4_1]] 1 -// CHECK-NEXT: [[tmp:%\d+]] = OpCompositeConstruct %_arr_v3int_uint_2_0 [[matrices4_1_row0]] [[matrices4_1_row1]] -// CHECK-NEXT: OpStore %m4 [[tmp]] - int2x3 m4 = matrices4[1]; -// CHECK: [[ptr_matrices5:%\d+]] = OpAccessChain %_ptr_Uniform__arr__arr_v3int_uint_2_uint_5 %MyCBuffer %int_4 -// CHECK-NEXT: [[ptr_matrices5_2:%\d+]] = OpAccessChain %_ptr_Uniform__arr_v3int_uint_2 [[ptr_matrices5]] %int_2 -// CHECK-NEXT: [[matrices5_2:%\d+]] = OpLoad %_arr_v3int_uint_2 [[ptr_matrices5_2]] -// CHECK-NEXT: [[matrices_5_2_row0:%\d+]] = OpCompositeExtract %v3int [[matrices5_2]] 0 -// CHECK-NEXT: [[matrices_5_2_row1:%\d+]] = OpCompositeExtract %v3int [[matrices5_2]] 1 -// CHECK-NEXT: [[tmp:%\d+]] = OpCompositeConstruct %_arr_v3int_uint_2_0 [[matrices_5_2_row0]] [[matrices_5_2_row1]] -// CHECK-NEXT: OpStore %m5 [[tmp]] - int2x3 m5 = matrices5[2]; -} diff --git a/tools/clang/test/CodeGenSPIRV/vk.layout.rwstructuredbuffer.boolean.hlsl b/tools/clang/test/CodeGenSPIRV/vk.layout.rwstructuredbuffer.boolean.hlsl deleted file mode 100644 index 9435878a49..0000000000 --- a/tools/clang/test/CodeGenSPIRV/vk.layout.rwstructuredbuffer.boolean.hlsl +++ /dev/null @@ -1,91 +0,0 @@ -// RUN: %dxc -T vs_6_0 -E main - -// CHECK: [[v3uint1:%\d+]] = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1 -// CHECK: [[v3uint0:%\d+]] = OpConstantComposite %v3uint %uint_0 %uint_0 %uint_0 - -// CHECK: %T = OpTypeStruct %_arr_uint_uint_1 -struct T { - bool boolArray[1]; -}; - -// CHECK: %S = OpTypeStruct %uint %v3uint %_arr_v3uint_uint_2 %T -struct S -{ - bool boolScalar; - bool3 boolVec; - row_major bool2x3 boolMat; - T t; -}; - -RWStructuredBuffer values; - -// These are the types that hold SPIR-V booleans, rather than Uints. -// CHECK: %T_0 = OpTypeStruct %_arr_bool_uint_1 -// CHECK: %S_0 = OpTypeStruct %bool %v3bool %_arr_v3bool_uint_2 %T_0 - -void main() -{ - bool3 boolVecVar; - bool2 boolVecVar2; - row_major bool2x3 boolMatVar; - -// CHECK: [[uintPtr:%\d+]] = OpAccessChain %_ptr_Uniform_uint %values %int_0 %uint_0 %int_0 -// CHECK-NEXT: [[convertTrueToUint:%\d+]] = OpSelect %uint %true %uint_1 %uint_0 -// CHECK-NEXT: OpStore [[uintPtr]] [[convertTrueToUint]] - values[0].boolScalar = true; - -// CHECK: [[boolVecVar:%\d+]] = OpLoad %v3bool %boolVecVar -// CHECK-NEXT: [[uintVecPtr:%\d+]] = OpAccessChain %_ptr_Uniform_v3uint %values %int_0 %uint_1 %int_1 -// CHECK-NEXT: [[uintVecVar:%\d+]] = OpSelect %v3uint [[boolVecVar]] [[v3uint1]] [[v3uint0]] -// CHECK-NEXT: OpStore [[uintVecPtr]] [[uintVecVar]] - values[1].boolVec = boolVecVar; - - // TODO: In the following cases, OpAccessChain runs into type mismatch issues due to decoration differences. - // values[2].boolMat = boolMatVar; - // values[0].boolVec.yzx = boolVecVar; - // values[0].boolMat._m12_m11 = boolVecVar2; - -// CHECK: [[sPtr:%\d+]] = OpAccessChain %_ptr_Uniform_S %values %int_0 %uint_0 -// CHECK-NEXT: [[s:%\d+]] = OpLoad %S [[sPtr]] -// CHECK-NEXT: [[s0:%\d+]] = OpCompositeExtract %uint [[s]] 0 -// CHECK-NEXT: [[s0_bool:%\d+]] = OpINotEqual %bool [[s0]] %uint_0 -// CHECK-NEXT: [[s1:%\d+]] = OpCompositeExtract %v3uint [[s]] 1 -// CHECK-NEXT: [[s1_bool:%\d+]] = OpINotEqual %v3bool [[s1]] [[v3uint0]] -// CHECK-NEXT: [[s2:%\d+]] = OpCompositeExtract %_arr_v3uint_uint_2 [[s]] 2 -// CHECK-NEXT: [[s2_row0:%\d+]] = OpCompositeExtract %v3uint [[s2]] 0 -// CHECK-NEXT: [[s2_row0_bool:%\d+]] = OpINotEqual %v3bool [[s2_row0]] [[v3uint0]] -// CHECK-NEXT: [[s2_row1:%\d+]] = OpCompositeExtract %v3uint [[s2]] 1 -// CHECK-NEXT: [[s2_row1_bool:%\d+]] = OpINotEqual %v3bool [[s2_row1]] [[v3uint0]] -// CHECK-NEXT: [[s2_bool:%\d+]] = OpCompositeConstruct %_arr_v3bool_uint_2 [[s2_row0_bool]] [[s2_row1_bool]] -// CHECK-NEXT: [[t:%\d+]] = OpCompositeExtract %T [[s]] 3 -// CHECK-NEXT: [[t0_uint_arr:%\d+]] = OpCompositeExtract %_arr_uint_uint_1 [[t]] 0 -// CHECK-NEXT: [[t0_0_uint:%\d+]] = OpCompositeExtract %uint [[t0_uint_arr]] 0 -// CHECK-NEXT: [[t0_0_bool:%\d+]] = OpINotEqual %bool [[t0_0_uint]] %uint_0 -// CHECK-NEXT: [[t0_bool:%\d+]] = OpCompositeConstruct %_arr_bool_uint_1 [[t0_0_bool]] -// CHECK-NEXT: [[t_bool:%\d+]] = OpCompositeConstruct %T_0 [[t0_bool]] -// CHECK-NEXT: [[s_bool:%\d+]] = OpCompositeConstruct %S_0 [[s0_bool]] [[s1_bool]] [[s2_bool]] [[t_bool]] -// CHECK-NEXT: OpStore %s [[s_bool]] - S s = values[0]; - -// CHECK: [[s:%\d+]] = OpLoad %S_0 %s -// CHECK-NEXT: [[resultPtr:%\d+]] = OpAccessChain %_ptr_Uniform_S %values %int_0 %uint_1 -// CHECK-NEXT: [[s0_bool:%\d+]] = OpCompositeExtract %bool [[s]] 0 -// CHECK-NEXT: [[s0_uint:%\d+]] = OpSelect %uint [[s0_bool]] %uint_1 %uint_0 -// CHECK-NEXT: [[s1_boolVec:%\d+]] = OpCompositeExtract %v3bool [[s]] 1 -// CHECK-NEXT: [[s1_uintVec:%\d+]] = OpSelect %v3uint [[s1_boolVec]] -// CHECK-NEXT: [[s2_boolMat:%\d+]] = OpCompositeExtract %_arr_v3bool_uint_2 [[s]] 2 -// CHECK-NEXT: [[s2_boolMat_row0:%\d+]] = OpCompositeExtract %v3bool [[s2_boolMat]] 0 -// CHECK-NEXT: [[s2_boolMat_row0_uint:%\d+]] = OpSelect %v3uint [[s2_boolMat_row0]] -// CHECK-NEXT: [[s2_boolMat_row1:%\d+]] = OpCompositeExtract %v3bool [[s2_boolMat]] 1 -// CHECK-NEXT: [[s2_boolMat_row1_uint:%\d+]] = OpSelect %v3uint [[s2_boolMat_row1]] -// CHECK-NEXT: [[s2_uintMat:%\d+]] = OpCompositeConstruct %_arr_v3uint_uint_2 [[s2_boolMat_row0_uint]] [[s2_boolMat_row1_uint]] -// CHECK-NEXT: [[t:%\d+]] = OpCompositeExtract %T_0 [[s]] 3 -// CHECK-NEXT: [[t0_bool_arr:%\d+]] = OpCompositeExtract %_arr_bool_uint_1 [[t]] 0 -// CHECK-NEXT: [[t0_bool_arr_0:%\d+]] = OpCompositeExtract %bool [[t0_bool_arr]] 0 -// CHECK-NEXT: [[t0_bool_arr_0_uint:%\d+]] = OpSelect %uint [[t0_bool_arr_0]] %uint_1 %uint_0 -// CHECK-NEXT: [[t0_uint_arr:%\d+]] = OpCompositeConstruct %_arr_uint_uint_1 [[t0_bool_arr_0_uint]] -// CHECK-NEXT: [[t_uint:%\d+]] = OpCompositeConstruct %T [[t0_uint_arr]] -// CHECK-NEXT: [[s_uint:%\d+]] = OpCompositeConstruct %S [[s0_uint]] [[s1_uintVec]] [[s2_uintMat]] [[t_uint]] -// CHECK-NEXT: OpStore [[resultPtr:%\d+]] [[s_uint]] - values[1] = s; -} diff --git a/tools/clang/test/CodeGenSPIRV/vk.layout.struct.bitfield.assignment.hlsl b/tools/clang/test/CodeGenSPIRV/vk.layout.struct.bitfield.assignment.hlsl deleted file mode 100644 index 02cd5d3505..0000000000 --- a/tools/clang/test/CodeGenSPIRV/vk.layout.struct.bitfield.assignment.hlsl +++ /dev/null @@ -1,78 +0,0 @@ -// RUN: %dxc -T vs_6_0 -E main -HV 2021 - -// Sanity check. -struct S1 { - uint f1 : 1; -}; - -struct S2 { - uint f1 : 1; - uint f2 : 3; - uint f3 : 8; - uint f4 : 1; -}; - -struct S3 { - uint f1 : 1; - int f2 : 1; - uint f3 : 1; -}; - -void main() : A { - S1 s1; -// CHECK: [[ptr:%\d+]] = OpAccessChain %_ptr_Function_uint %s1 %int_0 -// CHECK: [[load:%\d+]] = OpLoad %uint [[ptr]] -// CHECK: [[insert:%\d+]] = OpBitFieldInsert %uint [[load]] %uint_1 %uint_0 %uint_1 -// CHECK: OpStore [[ptr]] [[insert]] - s1.f1 = 1; - - S2 s2; -// CHECK: [[ptr:%\d+]] = OpAccessChain %_ptr_Function_uint %s2 %int_0 -// CHECK: [[load:%\d+]] = OpLoad %uint [[ptr]] -// CHECK: [[insert:%\d+]] = OpBitFieldInsert %uint [[load]] %uint_1 %uint_0 %uint_1 -// CHECK: OpStore [[ptr]] [[insert]] - s2.f1 = 1; -// CHECK: [[ptr:%\d+]] = OpAccessChain %_ptr_Function_uint %s2 %int_0 -// CHECK: [[load:%\d+]] = OpLoad %uint [[ptr]] -// CHECK: [[insert:%\d+]] = OpBitFieldInsert %uint [[load]] %uint_5 %uint_1 %uint_3 -// CHECK: OpStore [[ptr]] [[insert]] - s2.f2 = 5; -// CHECK: [[ptr:%\d+]] = OpAccessChain %_ptr_Function_uint %s2 %int_0 -// CHECK: [[load:%\d+]] = OpLoad %uint [[ptr]] -// CHECK: [[insert:%\d+]] = OpBitFieldInsert %uint [[load]] %uint_2 %uint_4 %uint_8 -// CHECK: OpStore [[ptr]] [[insert]] - s2.f3 = 2; - -// CHECK: [[ptr:%\d+]] = OpAccessChain %_ptr_Function_uint %s2 %int_0 -// CHECK: [[load:%\d+]] = OpLoad %uint [[ptr]] -// CHECK: [[insert:%\d+]] = OpBitFieldInsert %uint [[load]] %uint_1 %uint_12 %uint_1 -// CHECK: OpStore [[ptr]] [[insert]] - s2.f4 = 1; - - S3 s3; -// CHECK: [[ptr:%\d+]] = OpAccessChain %_ptr_Function_uint %s3 %int_0 -// CHECK: [[load:%\d+]] = OpLoad %uint [[ptr]] -// CHECK: [[insert:%\d+]] = OpBitFieldInsert %uint [[load]] %uint_1 %uint_0 %uint_1 -// CHECK: OpStore [[ptr]] [[insert]] - s3.f1 = 1; -// CHECK: [[ptr:%\d+]] = OpAccessChain %_ptr_Function_int %s3 %int_1 -// CHECK: [[load:%\d+]] = OpLoad %int [[ptr]] -// CHECK: [[insert:%\d+]] = OpBitFieldInsert %int [[load]] %int_0 %uint_0 %uint_1 -// CHECK: OpStore [[ptr]] [[insert]] - s3.f2 = 0; -// CHECK: [[ptr:%\d+]] = OpAccessChain %_ptr_Function_uint %s3 %int_2 -// CHECK: [[load:%\d+]] = OpLoad %uint [[ptr]] -// CHECK: [[insert:%\d+]] = OpBitFieldInsert %uint [[load]] %uint_1 %uint_0 %uint_1 -// CHECK: OpStore [[ptr]] [[insert]] - s3.f3 = 1; - -// CHECK: [[ptr:%\d+]] = OpAccessChain %_ptr_Function_uint %s2 %int_0 -// CHECK: [[load:%\d+]] = OpLoad %uint [[ptr]] -// CHECK: [[s2f4_extract:%\d+]] = OpBitFieldUExtract %uint [[load]] %uint_12 %uint_1 -// CHECK: [[s2f4_sext:%\d+]] = OpBitcast %int [[s2f4_extract]] -// CHECK: [[ptr:%\d+]] = OpAccessChain %_ptr_Function_int %s3 %int_1 -// CHECK: [[load:%\d+]] = OpLoad %int [[ptr]] -// CHECK: [[insert:%\d+]] = OpBitFieldInsert %int [[load]] [[s2f4_sext]] %uint_0 %uint_1 -// CHECK: OpStore [[ptr]] [[insert]] - s3.f2 = s2.f4; -} diff --git a/tools/clang/test/CodeGenSPIRV/vk.shading-rate.vs.hlsl b/tools/clang/test/CodeGenSPIRV/vk.shading-rate.vs.hlsl deleted file mode 100644 index db8456369a..0000000000 --- a/tools/clang/test/CodeGenSPIRV/vk.shading-rate.vs.hlsl +++ /dev/null @@ -1,9 +0,0 @@ -// RUN: %dxc -T vs_6_4 -E main - -void main(out uint rate : SV_ShadingRate) { -// CHECK: OpCapability FragmentShadingRateKHR -// CHECK: OpExtension "SPV_KHR_fragment_shading_rate" -// CHECK: OpDecorate [[r:%\d+]] BuiltIn PrimitiveShadingRateKHR -// CHECK: [[r:%\d+]] = OpVariable %_ptr_Output_uint Output - rate = 0; -} diff --git a/tools/clang/test/CodeGenSPIRV/capability.unique.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/capability.unique.hlsl similarity index 75% rename from tools/clang/test/CodeGenSPIRV/capability.unique.hlsl rename to tools/clang/test/CodeGenSPIRV_Lit/capability.unique.hlsl index 601c0cd920..d721198d8a 100644 --- a/tools/clang/test/CodeGenSPIRV/capability.unique.hlsl +++ b/tools/clang/test/CodeGenSPIRV_Lit/capability.unique.hlsl @@ -1,4 +1,4 @@ -// RUN: %dxc -T ps_6_2 -E main +// RUN: %dxc -T ps_6_2 -E main -fcgl %s -spirv | FileCheck %s // Make sure the same capability is not applied twice. // diff --git a/tools/clang/test/CodeGenSPIRV/cs.groupshared.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/cs.groupshared.hlsl similarity index 76% rename from tools/clang/test/CodeGenSPIRV/cs.groupshared.hlsl rename to tools/clang/test/CodeGenSPIRV_Lit/cs.groupshared.hlsl index cb2951d644..c8e5351c6c 100644 --- a/tools/clang/test/CodeGenSPIRV/cs.groupshared.hlsl +++ b/tools/clang/test/CodeGenSPIRV_Lit/cs.groupshared.hlsl @@ -1,4 +1,4 @@ -// RUN: %dxc -T cs_6_0 -E main +// RUN: %dxc -T cs_6_0 -E main -fcgl %s -spirv | FileCheck %s struct S { float f1; @@ -25,8 +25,8 @@ groupshared S s; [numthreads(8, 8, 8)] void main(uint3 tid : SV_DispatchThreadID, uint2 gid : SV_GroupID) { // Make sure pointers have the correct storage class -// CHECK: {{%\d+}} = OpAccessChain %_ptr_Workgroup_float %s %int_0 -// CHECK: [[d0:%\d+]] = OpAccessChain %_ptr_Workgroup_v2float %d %int_0 -// CHECK: {{%\d+}} = OpAccessChain %_ptr_Workgroup_float [[d0]] %int_1 +// CHECK: {{%[0-9]+}} = OpAccessChain %_ptr_Workgroup_float %s %int_0 +// CHECK: [[d0:%[0-9]+]] = OpAccessChain %_ptr_Workgroup_v2float %d %int_0 +// CHECK: {{%[0-9]+}} = OpAccessChain %_ptr_Workgroup_float [[d0]] %int_1 d[0].y = s.f1; } diff --git a/tools/clang/test/CodeGenSPIRV/cs.groupshared.not-in-globals.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/cs.groupshared.not-in-globals.hlsl similarity index 95% rename from tools/clang/test/CodeGenSPIRV/cs.groupshared.not-in-globals.hlsl rename to tools/clang/test/CodeGenSPIRV_Lit/cs.groupshared.not-in-globals.hlsl index 3adbb9e396..b36a04a968 100644 --- a/tools/clang/test/CodeGenSPIRV/cs.groupshared.not-in-globals.hlsl +++ b/tools/clang/test/CodeGenSPIRV_Lit/cs.groupshared.not-in-globals.hlsl @@ -1,4 +1,4 @@ -// RUN: %dxc -T cs_6_0 -E main +// RUN: %dxc -T cs_6_0 -E main -fcgl %s -spirv | FileCheck %s // A and B are groupshared, and should not be placed in the $Globals cbuffer. // myGlobalInteger is a global variable and is placed in $Globals cbuffer. diff --git a/tools/clang/test/CodeGenSPIRV_Lit/ddx.compute.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/ddx.compute.hlsl new file mode 100644 index 0000000000..2cb9fd2bcd --- /dev/null +++ b/tools/clang/test/CodeGenSPIRV_Lit/ddx.compute.hlsl @@ -0,0 +1,29 @@ +// RUN: %dxc -T cs_6_6 -E main -fspv-extension=SPV_NV_compute_shader_derivatives -fcgl %s -spirv 2>&1 | FileCheck %s + +// CHECK: OpCapability ComputeDerivativeGroupQuadsNV +// CHECK: OpExtension "SPV_NV_compute_shader_derivatives" +// CHECK: OpExecutionMode %main DerivativeGroupQuadsNV + + +SamplerState ss : register(s2); +SamplerComparisonState scs; + +RWStructuredBuffer o; +Texture1D t1; + +[numthreads(2,2,1)] +void main(uint3 id : SV_GroupThreadID) +{ + // CHECK: OpDPdx %float %float_0_5 + o[0] = ddx(0.5); + // CHECK: OpDPdxCoarse %float %float_0_5 + o[1] = ddx_coarse(0.5); + // CHECK: OpDPdy %float %float_0_5 + o[2] = ddy(0.5); + // CHECK: OpDPdyCoarse %float %float_0_5 + o[3] = ddy_coarse(0.5); + // CHECK: OpDPdxFine %float %float_0_5 + o[4] = ddx_fine(0.5); + // CHECK: OpDPdyFine %float %float_0_5 + o[5] = ddy_fine(0.5); +} \ No newline at end of file diff --git a/tools/clang/test/CodeGenSPIRV/decoration.coherent.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/decoration.coherent.hlsl similarity index 85% rename from tools/clang/test/CodeGenSPIRV/decoration.coherent.hlsl rename to tools/clang/test/CodeGenSPIRV_Lit/decoration.coherent.hlsl index 749f1d113e..dc369206c9 100644 --- a/tools/clang/test/CodeGenSPIRV/decoration.coherent.hlsl +++ b/tools/clang/test/CodeGenSPIRV_Lit/decoration.coherent.hlsl @@ -1,4 +1,4 @@ -// RUN: %dxc -T ps_6_0 -E main +// RUN: %dxc -T ps_6_0 -E main -fcgl %s -spirv | FileCheck %s struct StructA { diff --git a/tools/clang/test/CodeGenSPIRV/decoration.no-contraction.stage-vars.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/decoration.no-contraction.stage-vars.hlsl similarity index 66% rename from tools/clang/test/CodeGenSPIRV/decoration.no-contraction.stage-vars.hlsl rename to tools/clang/test/CodeGenSPIRV_Lit/decoration.no-contraction.stage-vars.hlsl index 74a82735e7..c9bc64ee21 100644 --- a/tools/clang/test/CodeGenSPIRV/decoration.no-contraction.stage-vars.hlsl +++ b/tools/clang/test/CodeGenSPIRV_Lit/decoration.no-contraction.stage-vars.hlsl @@ -1,31 +1,27 @@ -// RUN: %dxc -T vs_6_0 -E main -fspv-reflect +// RUN: %dxc -T vs_6_0 -E main -fspv-reflect -fcgl %s -spirv | FileCheck %s --implicit-check-not "OpDecorate {{%[0-9]+}} NoContraction" -// CHECK: OpDecorate [[aa_1:%\d+]] NoContraction -// CHECK-NEXT: OpDecorate [[aa_plus_b_1:%\d+]] NoContraction +// The --implicit-check-not option above checks that there are no `OpDecorate ... NoContraction` instructions other than those CHECKed below. -// CHECK-NEXT: OpDecorate [[aa_2:%\d+]] NoContraction -// CHECK-NEXT: OpDecorate [[aa_plus_b_2:%\d+]] NoContraction +// CHECK: OpDecorate [[aa_1:%[0-9]+]] NoContraction +// CHECK-NEXT: OpDecorate [[aa_plus_b_1:%[0-9]+]] NoContraction -// CHECK-NEXT: OpDecorate [[ee:%\d+]] NoContraction -// CHECK-NEXT: OpDecorate [[ee_plus_f:%\d+]] NoContraction +// CHECK-NEXT: OpDecorate [[aa_2:%[0-9]+]] NoContraction +// CHECK-NEXT: OpDecorate [[aa_plus_b_2:%[0-9]+]] NoContraction -// CHECK-NEXT: OpDecorate [[cc_1:%\d+]] NoContraction -// CHECK-NEXT: OpDecorate [[cc_plus_d_1:%\d+]] NoContraction +// CHECK-NEXT: OpDecorate [[ee:%[0-9]+]] NoContraction +// CHECK-NEXT: OpDecorate [[ee_plus_f:%[0-9]+]] NoContraction -// CHECK-NEXT: OpDecorate [[cc_2:%\d+]] NoContraction -// CHECK-NEXT: OpDecorate [[cc_plus_d_2:%\d+]] NoContraction +// CHECK-NEXT: OpDecorate [[cc_1:%[0-9]+]] NoContraction +// CHECK-NEXT: OpDecorate [[cc_plus_d_1:%[0-9]+]] NoContraction -// CHECK-NEXT: OpDecorate [[cxcy_1:%\d+]] NoContraction -// CHECK-NEXT: OpDecorate [[cxcy_plus_dz_1:%\d+]] NoContraction +// CHECK-NEXT: OpDecorate [[cc_2:%[0-9]+]] NoContraction +// CHECK-NEXT: OpDecorate [[cc_plus_d_2:%[0-9]+]] NoContraction -// CHECK-NOT: OpDecorate [[cxcy_2]] NoContraction -// CHECK-NOT: OpDecorate [[cxcy_plus_dz_2]] NoContraction +// CHECK-NEXT: OpDecorate [[cxcy_1:%[0-9]+]] NoContraction +// CHECK-NEXT: OpDecorate [[cxcy_plus_dz_1:%[0-9]+]] NoContraction -// CHECK-NOT: OpDecorate [[cxcy_3]] NoContraction -// CHECK-NOT: OpDecorate [[cxcy_plus_dz_3]] NoContraction - -// CHECK-NEXT: OpDecorate [[aa_3:%\d+]] NoContraction -// CHECK-NEXT: OpDecorate [[aa_plus_b_3:%\d+]] NoContraction +// CHECK-NEXT: OpDecorate [[aa_3:%[0-9]+]] NoContraction +// CHECK-NEXT: OpDecorate [[aa_plus_b_3:%[0-9]+]] NoContraction struct InnerInnerStruct { precise float4 position : SV_Position; // -> BuiltIn Position in gl_Pervertex @@ -95,14 +91,14 @@ float main(out VSOut vsOut, // Output CullDistance builtin. culldis3 is NOT precise. // -// CHECK: [[cxcy_2:%\d+]] = OpFMul %float -// CHECK: [[cxcy_plus_dz_2:%\d+]] = OpFAdd %float +// CHECK: [[cxcy_2:%[0-9]+]] = OpFMul %float +// CHECK: [[cxcy_plus_dz_2:%[0-9]+]] = OpFAdd %float culldis3 = c.x * c.y + d.z; // Output CullDistance builtin. clipdis6 is NOT precise. // -// CHECK: [[cxcy_3:%\d+]] = OpFMul %float -// CHECK: [[cxcy_plus_dz_3:%\d+]] = OpFAdd %float +// CHECK: [[cxcy_3:%[0-9]+]] = OpFMul %float +// CHECK: [[cxcy_plus_dz_3:%[0-9]+]] = OpFAdd %float clipdis6 = c.x * c.y + d.z; // Position builtin is precise. diff --git a/tools/clang/test/CodeGenSPIRV_Lit/decoration.no-contraction.struct.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/decoration.no-contraction.struct.hlsl new file mode 100644 index 0000000000..df01a5de51 --- /dev/null +++ b/tools/clang/test/CodeGenSPIRV_Lit/decoration.no-contraction.struct.hlsl @@ -0,0 +1,164 @@ +// RUN: %dxc -T ps_6_0 -E main -fcgl %s -spirv | FileCheck %s --implicit-check-not "OpDecorate {{%[0-9]+}} NoContraction" + +// The --implicit-check-not option above checks that there are no `OpDecorate ... NoContraction` instructions other than those CHECKed below. + +struct S { + float4 a; + precise float4 ap; + int b[5]; + precise int bp[5]; + int2x3 c[6][7][8]; + precise int2x3 cp[6][7][8]; + float3x4 d; + precise float3x4 dp; +}; + +struct T { + precise S sub1; // all members of sub1 should be precise. + S sub2; // only some members of sub2 are precise. +}; + + +// CHECK: OpName %w "w" +// CHECK-NEXT: OpDecorate [[x_mul_x_2:%[0-9]+]] NoContraction +// CHECK-NEXT: OpDecorate [[xx_plus_y_2:%[0-9]+]] NoContraction + +// CHECK-NEXT: OpDecorate [[z2_mul_z3_2:%[0-9]+]] NoContraction +// CHECK-NEXT: OpDecorate [[z2z3_plus_z4_2:%[0-9]+]] NoContraction + +// CHECK-NEXT: OpDecorate [[uu_row0_2:%[0-9]+]] NoContraction +// CHECK-NEXT: OpDecorate [[uu_row1_2:%[0-9]+]] NoContraction + +// CHECK-NEXT: OpDecorate [[ww_row0_2:%[0-9]+]] NoContraction +// CHECK-NEXT: OpDecorate [[ww_row1_2:%[0-9]+]] NoContraction +// CHECK-NEXT: OpDecorate [[ww_row2_2:%[0-9]+]] NoContraction +// CHECK-NEXT: OpDecorate [[ww_plus_w_row0_2:%[0-9]+]] NoContraction +// CHECK-NEXT: OpDecorate [[ww_plus_w_row1_2:%[0-9]+]] NoContraction +// CHECK-NEXT: OpDecorate [[ww_plus_w_row2_2:%[0-9]+]] NoContraction + +// CHECK-NEXT: OpDecorate [[x_mul_x_3:%[0-9]+]] NoContraction +// CHECK-NEXT: OpDecorate [[xx_plus_y_3:%[0-9]+]] NoContraction +// CHECK-NEXT: OpDecorate [[x_mul_x_4:%[0-9]+]] NoContraction +// CHECK-NEXT: OpDecorate [[xx_plus_y_4:%[0-9]+]] NoContraction +// CHECK-NEXT: OpDecorate [[z2_mul_z3_3:%[0-9]+]] NoContraction +// CHECK-NEXT: OpDecorate [[z2z3_plus_z4_3:%[0-9]+]] NoContraction +// CHECK-NEXT: OpDecorate [[z2_mul_z3_4:%[0-9]+]] NoContraction +// CHECK-NEXT: OpDecorate [[z2z3_plus_z4_4:%[0-9]+]] NoContraction +// CHECK-NEXT: OpDecorate [[uu_row0_3:%[0-9]+]] NoContraction +// CHECK-NEXT: OpDecorate [[uu_row1_3:%[0-9]+]] NoContraction +// CHECK-NEXT: OpDecorate [[uu_row0_4:%[0-9]+]] NoContraction +// CHECK-NEXT: OpDecorate [[uu_row1_4:%[0-9]+]] NoContraction +// CHECK-NEXT: OpDecorate [[ww_row0_3:%[0-9]+]] NoContraction +// CHECK-NEXT: OpDecorate [[ww_row1_3:%[0-9]+]] NoContraction +// CHECK-NEXT: OpDecorate [[ww_row2_3:%[0-9]+]] NoContraction +// CHECK-NEXT: OpDecorate [[ww_plus_w_row0_3:%[0-9]+]] NoContraction +// CHECK-NEXT: OpDecorate [[ww_plus_w_row1_3:%[0-9]+]] NoContraction +// CHECK-NEXT: OpDecorate [[ww_plus_w_row2_3:%[0-9]+]] NoContraction +// CHECK-NEXT: OpDecorate [[ww_row0_4:%[0-9]+]] NoContraction +// CHECK-NEXT: OpDecorate [[ww_row1_4:%[0-9]+]] NoContraction +// CHECK-NEXT: OpDecorate [[ww_row2_4:%[0-9]+]] NoContraction +// CHECK-NEXT: OpDecorate [[ww_plus_w_row0_4:%[0-9]+]] NoContraction +// CHECK-NEXT: OpDecorate [[ww_plus_w_row1_4:%[0-9]+]] NoContraction +// CHECK-NEXT: OpDecorate [[ww_plus_w_row2_4:%[0-9]+]] NoContraction + +void main() { + T t; + float4 x,y; + int z[5]; + int2x3 u; + float3x4 w; + + +// 'a' is NOT precise. +// +// CHECK: [[x_mul_x_1:%[0-9]+]] = OpFMul %v4float +// CHECK: [[xx_plus_y_1:%[0-9]+]] = OpFAdd %v4float + t.sub2.a = x * x + y; + +// 'ap' is precise. +// +// CHECK: [[x_mul_x_2]] = OpFMul %v4float +// CHECK: [[xx_plus_y_2]] = OpFAdd %v4float + t.sub2.ap = x * x + y; + +// 'b' is NOT precise. +// +// CHECK: [[z2_mul_z3_1:%[0-9]+]] = OpIMul %int +// CHECK: [[z2z3_plus_z4_1:%[0-9]+]] = OpIAdd %int + t.sub2.b[1] = z[2] * z[3] + z[4]; + +// 'bp' is precise. +// +// CHECK: [[z2_mul_z3_2]] = OpIMul %int +// CHECK: [[z2z3_plus_z4_2]] = OpIAdd %int + t.sub2.bp[1] = z[2] * z[3] + z[4]; + +// 'c' is NOT precise. +// +// CHECK: [[uu_row0_1:%[0-9]+]] = OpIMul %v3int +// CHECK: [[uu_row1_1:%[0-9]+]] = OpIMul %v3int + t.sub2.c[0][1][2] = u * u; + +// 'cp' is precise. +// +// CHECK: [[uu_row0_2]] = OpIMul %v3int +// CHECK: [[uu_row1_2]] = OpIMul %v3int + t.sub2.cp[0][1][2] = u * u; + +// 'd' is NOT precise. +// +// CHECK: [[ww_row0_1:%[0-9]+]] = OpFMul %v4float +// CHECK: [[ww_row1_1:%[0-9]+]] = OpFMul %v4float +// CHECK: [[ww_row2_1:%[0-9]+]] = OpFMul %v4float +// CHECK: [[ww_plus_w_row0_1:%[0-9]+]] = OpFAdd %v4float +// CHECK: [[ww_plus_w_row1_1:%[0-9]+]] = OpFAdd %v4float +// CHECK: [[ww_plus_w_row2_1:%[0-9]+]] = OpFAdd %v4float + t.sub2.d = w * w + w; + +// 'dp' is precise. +// +// CHECK: [[ww_row0_2]] = OpFMul %v4float +// CHECK: [[ww_row1_2]] = OpFMul %v4float +// CHECK: [[ww_row2_2]] = OpFMul %v4float +// CHECK: [[ww_plus_w_row0_2]] = OpFAdd %v4float +// CHECK: [[ww_plus_w_row1_2]] = OpFAdd %v4float +// CHECK: [[ww_plus_w_row2_2]] = OpFAdd %v4float + t.sub2.dp = w * w + w; + +// *ALL* members of sub1 are precise. So this operation should be precise. +// +// +// CHECK: [[x_mul_x_3]] = OpFMul %v4float +// CHECK: [[xx_plus_y_3]] = OpFAdd %v4float + t.sub1.a = x * x + y; +// CHECK: [[x_mul_x_4]] = OpFMul %v4float +// CHECK: [[xx_plus_y_4]] = OpFAdd %v4float + t.sub1.ap = x * x + y; +// CHECK: [[z2_mul_z3_3]] = OpIMul %int +// CHECK: [[z2z3_plus_z4_3]] = OpIAdd %int + t.sub1.b[1] = z[2] * z[3] + z[4]; +// CHECK: [[z2_mul_z3_4]] = OpIMul %int +// CHECK: [[z2z3_plus_z4_4]] = OpIAdd %int + t.sub1.bp[1] = z[2] * z[3] + z[4]; +// CHECK: [[uu_row0_3]] = OpIMul %v3int +// CHECK: [[uu_row1_3]] = OpIMul %v3int + t.sub1.c[0][1][2] = u * u; +// CHECK: [[uu_row0_4]] = OpIMul %v3int +// CHECK: [[uu_row1_4]] = OpIMul %v3int + t.sub1.cp[0][1][2] = u * u; +// CHECK: [[ww_row0_3]] = OpFMul %v4float +// CHECK: [[ww_row1_3]] = OpFMul %v4float +// CHECK: [[ww_row2_3]] = OpFMul %v4float +// CHECK: [[ww_plus_w_row0_3]] = OpFAdd %v4float +// CHECK: [[ww_plus_w_row1_3]] = OpFAdd %v4float +// CHECK: [[ww_plus_w_row2_3]] = OpFAdd %v4float + t.sub1.d = w * w + w; +// CHECK: [[ww_row0_4]] = OpFMul %v4float +// CHECK: [[ww_row1_4]] = OpFMul %v4float +// CHECK: [[ww_row2_4]] = OpFMul %v4float +// CHECK: [[ww_plus_w_row0_4]] = OpFAdd %v4float +// CHECK: [[ww_plus_w_row1_4]] = OpFAdd %v4float +// CHECK: [[ww_plus_w_row2_4]] = OpFAdd %v4float + t.sub1.dp = w * w + w; +} + diff --git a/tools/clang/test/CodeGenSPIRV/decoration.no-contraction.variable-reuse.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/decoration.no-contraction.variable-reuse.hlsl similarity index 75% rename from tools/clang/test/CodeGenSPIRV/decoration.no-contraction.variable-reuse.hlsl rename to tools/clang/test/CodeGenSPIRV_Lit/decoration.no-contraction.variable-reuse.hlsl index 40a33f5b19..7ee18c45c8 100644 --- a/tools/clang/test/CodeGenSPIRV/decoration.no-contraction.variable-reuse.hlsl +++ b/tools/clang/test/CodeGenSPIRV_Lit/decoration.no-contraction.variable-reuse.hlsl @@ -1,7 +1,7 @@ -// RUN: %dxc -T ps_6_0 -E main +// RUN: %dxc -T ps_6_0 -E main -fcgl %s -spirv | FileCheck %s --implicit-check-not "OpDecorate {{%[0-9]+}} NoContraction" // The purpose of this test is to make sure non-precise computations are *not* -// decorated with NoContraction. +// decorated with NoContraction. Note the --implicit-check-not flag above. // // To this end, we will perform the same computation twice, once when it // affects a precise variable, and once when it doesn't. @@ -9,15 +9,11 @@ void foo(float p) { p = p + 1; } // CHECK: OpName %bb_entry_0 "bb.entry" -// CHECK-NEXT: OpDecorate [[first_b_plus_c:%\d+]] NoContraction -// CHECK-NOT: OpDecorate [[first_a_mul_b]] NoContraction -// CHECK-NOT: OpDecorate [[ax_mul_bx]] NoContraction -// CHECK-NEXT: OpDecorate [[second_a_mul_b:%\d+]] NoContraction -// CHECK-NOT: OpDecorate [[second_a_plus_b]] NoContraction -// CHECK-NEXT: OpDecorate [[first_d_plus_e:%\d+]] NoContraction -// CHECK-NEXT: OpDecorate [[c_mul_d:%\d+]] NoContraction -// CHECK-NOT: OpDecorate [[second_d_plus_e]] NoContraction -// CHECK-NEXT: OpDecorate [[r_plus_s:%\d+]] NoContraction +// CHECK-NEXT: OpDecorate [[first_b_plus_c:%[0-9]+]] NoContraction +// CHECK-NEXT: OpDecorate [[second_a_mul_b:%[0-9]+]] NoContraction +// CHECK-NEXT: OpDecorate [[first_d_plus_e:%[0-9]+]] NoContraction +// CHECK-NEXT: OpDecorate [[c_mul_d:%[0-9]+]] NoContraction +// CHECK-NEXT: OpDecorate [[r_plus_s:%[0-9]+]] NoContraction void main() { float4 a, b, c, d, e; @@ -35,13 +31,13 @@ void main() { // Even though this looks like the statement on line 52: // This changes "u", which does not affect "v" in any way. Not Precise. // -// CHECK: [[first_a_mul_b:%\d+]] = OpFMul %v3float +// CHECK: [[first_a_mul_b:%[0-9]+]] = OpFMul %v3float // CHECK-NEXT: OpStore %u u = float3((float3)a * (float3)b); // Does not affect the value of "v". Not Precise. // -// CHECK: [[ax_mul_bx:%\d+]] = OpFMul %float +// CHECK: [[ax_mul_bx:%[0-9]+]] = OpFMul %float // CHECK-NEXT: OpStore %param_var_p foo(a.x * b.x); @@ -54,7 +50,7 @@ void main() { // Even though this looks identical to "a = b + c" above: // This can change the value of "a", BUT, this change will not affect "v". Not Precise. // -// CHECK: [[second_a_plus_b:%\d+]] = OpFAdd %v4float +// CHECK: [[second_a_plus_b:%[0-9]+]] = OpFAdd %v4float // CHECK-NEXT: OpStore %a %61 a = b + c; @@ -77,7 +73,7 @@ void main() { // // CHECK: OpLoad %v4float %d // CHECK-NEXT: OpLoad %v4float %e -// CHECK-NEXT: [[second_d_plus_e:%\d+]] = OpFAdd %v4float +// CHECK-NEXT: [[second_d_plus_e:%[0-9]+]] = OpFAdd %v4float // CHECK-NEXT: OpStore %c c = d + e; diff --git a/tools/clang/test/CodeGenSPIRV_Lit/decoration.relaxed-precision.array.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/decoration.relaxed-precision.array.hlsl new file mode 100644 index 0000000000..878eb5fe4f --- /dev/null +++ b/tools/clang/test/CodeGenSPIRV_Lit/decoration.relaxed-precision.array.hlsl @@ -0,0 +1,46 @@ +// RUN: %dxc -T cs_6_0 -E main -fcgl %s -spirv | FileCheck %s + +// CHECK: OpDecorate %testShared RelaxedPrecision +// CHECK-NEXT: OpDecorate %test RelaxedPrecision +// CHECK-NEXT: OpDecorate %testTypedef RelaxedPrecision +// CHECK-NOT: OpDecorate %notMin16 RelaxedPrecision +// CHECK-NEXT: OpDecorate %a RelaxedPrecision +// CHECK-NEXT: OpDecorate [[compositeConstr1:%[0-9]+]] RelaxedPrecision +// CHECK-NEXT: OpDecorate [[compositeConstr2:%[0-9]+]] RelaxedPrecision +// CHECK-NEXT: OpDecorate [[loadFromTest1:%[0-9]+]] RelaxedPrecision +// CHECK-NEXT: OpDecorate [[loadFromTest2:%[0-9]+]] RelaxedPrecision +// CHECK-NEXT: OpDecorate [[loadFromTestTypedef:%[0-9]+]] RelaxedPrecision +// CHECK-NEXT: OpDecorate [[multiply1:%[0-9]+]] RelaxedPrecision +// CHECK-NEXT: OpDecorate [[loadVariable1:%[0-9]+]] RelaxedPrecision +// CHECK-NEXT: OpDecorate [[multiply2:%[0-9]+]] RelaxedPrecision +// CHECK-NEXT: OpDecorate [[loadFromShared:%[0-9]+]] RelaxedPrecision +// CHECK-NEXT: OpDecorate [[loadVariable2:%[0-9]+]] RelaxedPrecision +// CHECK-NEXT: OpDecorate [[multiply3:%[0-9]+]] RelaxedPrecision + +typedef min16float ArrayOfMin16Float0[2]; +typedef ArrayOfMin16Float0 ArrayOfMin16Float; + +groupshared min16float testShared[2]; + +[numthreads(1, 1, 1)] void main() +{ +// CHECK: [[compositeConstr2_0:%[0-9]+]] = OpCompositeConstruct %_arr_v2float_uint_2 {{%[0-9]+}} {{%[0-9]+}} + min16float2 test[2] = { float2(1.0, 1.0), float2(1.0, 1.0) }; +// CHECK: [[compositeConstr1_0:%[0-9]+]] = OpCompositeConstruct %_arr_float_uint_2 %float_1 %float_1 + ArrayOfMin16Float testTypedef = { 1.0, 1.0 }; + float notMin16[2] = { 1.0, 1.0 }; +// CHECK: [[loadFromTest1_0:%[0-9]+]] = OpLoad %float {{%[0-9]+}} + testShared[0] = test[0].x; + + min16float a = 1.0; +// CHECK: [[loadFromTest2_0:%[0-9]+]] = OpLoad %float {{%[0-9]+}} +// CHECK: [[loadFromTestTypedef_0:%[0-9]+]] = OpLoad %float {{%[0-9]+}} +// CHECK: [[multiply1_0:%[0-9]+]] = OpFMul %float {{%[0-9]+}} {{%[0-9]+}} +// CHECK: [[loadVariable1_0:%[0-9]+]] = OpLoad %float %a +// CHECK: [[multiply2_0:%[0-9]+]] = OpFMul %float {{%[0-9]+}} {{%[0-9]+}} + a *= (test[0].x * testTypedef[0]); +// CHECK: [[loadFromShared_0:%[0-9]+]] = OpLoad %float {{%[0-9]+}} +// CHECK: [[loadVariable2_0:%[0-9]+]] = OpLoad %float %a +// CHECK: [[multiply3_0:%[0-9]+]] = OpFMul %float {{%[0-9]+}} {{%[0-9]+}} + a *= testShared[0]; +} diff --git a/tools/clang/test/CodeGenSPIRV/decoration.relaxed-precision.basic.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/decoration.relaxed-precision.basic.hlsl similarity index 62% rename from tools/clang/test/CodeGenSPIRV/decoration.relaxed-precision.basic.hlsl rename to tools/clang/test/CodeGenSPIRV_Lit/decoration.relaxed-precision.basic.hlsl index 4be065fea2..4a5df3d679 100644 --- a/tools/clang/test/CodeGenSPIRV/decoration.relaxed-precision.basic.hlsl +++ b/tools/clang/test/CodeGenSPIRV_Lit/decoration.relaxed-precision.basic.hlsl @@ -1,22 +1,22 @@ -// RUN: %dxc -T ps_6_0 -E main +// RUN: %dxc -T ps_6_0 -E main -fcgl %s -spirv | FileCheck %s // CHECK: OpDecorate %in_var_TEXCOORD0 RelaxedPrecision // CHECK-NEXT: OpDecorate %out_var_SV_Target RelaxedPrecision // CHECK-NEXT: OpDecorate %param_var_x RelaxedPrecision -// CHECK-NEXT: OpDecorate [[coordValue:%\d+]] RelaxedPrecision -// CHECK-NEXT: OpDecorate [[mainResult:%\d+]] RelaxedPrecision +// CHECK-NEXT: OpDecorate [[coordValue:%[0-9]+]] RelaxedPrecision +// CHECK-NEXT: OpDecorate [[mainResult:%[0-9]+]] RelaxedPrecision // CHECK-NEXT: OpDecorate %src_main RelaxedPrecision // CHECK-NEXT: OpDecorate %x RelaxedPrecision // CHECK-NEXT: OpDecorate %y RelaxedPrecision -// CHECK-NEXT: OpDecorate [[xValue1:%\d+]] RelaxedPrecision -// CHECK-NEXT: OpDecorate [[comparison:%\d+]] RelaxedPrecision -// CHECK-NEXT: OpDecorate [[xValue2:%\d+]] RelaxedPrecision -// CHECK-NEXT: OpDecorate [[xValue3:%\d+]] RelaxedPrecision -// CHECK-NEXT: OpDecorate [[xMulx:%\d+]] RelaxedPrecision -// CHECK-NEXT: OpDecorate [[xValue4:%\d+]] RelaxedPrecision -// CHECK-NEXT: OpDecorate [[yValue1:%\d+]] RelaxedPrecision -// CHECK-NEXT: OpDecorate [[yValue2:%\d+]] RelaxedPrecision -// CHECK-NEXT: OpDecorate [[yMuly:%\d+]] RelaxedPrecision +// CHECK-NEXT: OpDecorate [[xValue1:%[0-9]+]] RelaxedPrecision +// CHECK-NEXT: OpDecorate [[comparison:%[0-9]+]] RelaxedPrecision +// CHECK-NEXT: OpDecorate [[xValue2:%[0-9]+]] RelaxedPrecision +// CHECK-NEXT: OpDecorate [[xValue3:%[0-9]+]] RelaxedPrecision +// CHECK-NEXT: OpDecorate [[xMulx:%[0-9]+]] RelaxedPrecision +// CHECK-NEXT: OpDecorate [[xValue4:%[0-9]+]] RelaxedPrecision +// CHECK-NEXT: OpDecorate [[yValue1:%[0-9]+]] RelaxedPrecision +// CHECK-NEXT: OpDecorate [[yValue2:%[0-9]+]] RelaxedPrecision +// CHECK-NEXT: OpDecorate [[yMuly:%[0-9]+]] RelaxedPrecision // CHECK: %in_var_TEXCOORD0 = OpVariable %_ptr_Input_float Input // CHECK: %out_var_SV_Target = OpVariable %_ptr_Output_float Output @@ -25,7 +25,7 @@ // CHECK: [[coordValue]] = OpLoad %float %in_var_TEXCOORD0 // CHECK: [[mainResult]] = OpFunctionCall %float %src_main %param_var_x min16float main(min16float x : TEXCOORD0) : SV_Target { -// CHECK: %src_main = OpFunction %float None {{%\d+}} +// CHECK: %src_main = OpFunction %float None {{%[0-9]+}} // CHECK: %x = OpFunctionParameter %_ptr_Function_float // CHECK: %y = OpVariable %_ptr_Function_float Function // CHECK: [[xValue1]] = OpLoad %float %x diff --git a/tools/clang/test/CodeGenSPIRV/decoration.relaxed-precision.bool.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/decoration.relaxed-precision.bool.hlsl similarity index 71% rename from tools/clang/test/CodeGenSPIRV/decoration.relaxed-precision.bool.hlsl rename to tools/clang/test/CodeGenSPIRV_Lit/decoration.relaxed-precision.bool.hlsl index 9d318731c0..38339d6d8c 100644 --- a/tools/clang/test/CodeGenSPIRV/decoration.relaxed-precision.bool.hlsl +++ b/tools/clang/test/CodeGenSPIRV_Lit/decoration.relaxed-precision.bool.hlsl @@ -1,4 +1,4 @@ -// RUN: %dxc -T cs_6_0 -HV 2018 -E main +// RUN: %dxc -T cs_6_0 -HV 2018 -E main -fcgl %s -spirv | FileCheck %s // According to the SPIR-V spec (2.14. Relaxed Precision): // The RelaxedPrecision decoration can be applied to: @@ -13,22 +13,22 @@ // CHECK: OpDecorate %a RelaxedPrecision // CHECK: OpDecorate %b RelaxedPrecision -// CHECK: OpDecorate [[a:%\d+]] RelaxedPrecision -// CHECK: OpDecorate [[compare_op:%\d+]] RelaxedPrecision -// CHECK: OpDecorate [[b:%\d+]] RelaxedPrecision -// CHECK: OpDecorate [[compare_op_2:%\d+]] RelaxedPrecision +// CHECK: OpDecorate [[a:%[0-9]+]] RelaxedPrecision +// CHECK: OpDecorate [[compare_op:%[0-9]+]] RelaxedPrecision +// CHECK: OpDecorate [[b:%[0-9]+]] RelaxedPrecision +// CHECK: OpDecorate [[compare_op_2:%[0-9]+]] RelaxedPrecision // // We should NOT have a decoration for the 'any' operation. // We should NOT have a decoration for the '||' operation. // -// CHECK-NOT: OpDecorate {{%\d+}} RelaxedPrecision +// CHECK-NOT: OpDecorate {{%[0-9]+}} RelaxedPrecision // CHECK: [[a]] = OpLoad %float %a // CHECK: [[compare_op]] = OpFOrdGreaterThan %bool [[a]] %float_0 // CHECK: [[b]] = OpLoad %v2float %b -// CHECK: [[compare_op_2]] = OpFOrdGreaterThan %v2bool [[b]] {{%\d+}} -// CHECK: [[any_op:%\d+]] = OpAny %bool %26 -// CHECK: [[or_op:%\d+]] = OpLogicalOr %bool +// CHECK: [[compare_op_2]] = OpFOrdGreaterThan %v2bool [[b]] {{%[0-9]+}} +// CHECK: [[any_op:%[0-9]+]] = OpAny %bool %26 +// CHECK: [[or_op:%[0-9]+]] = OpLogicalOr %bool RWBuffer Buf; diff --git a/tools/clang/test/CodeGenSPIRV/decoration.relaxed-precision.image.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/decoration.relaxed-precision.image.hlsl similarity index 67% rename from tools/clang/test/CodeGenSPIRV/decoration.relaxed-precision.image.hlsl rename to tools/clang/test/CodeGenSPIRV_Lit/decoration.relaxed-precision.image.hlsl index eacf071f04..88a204543a 100644 --- a/tools/clang/test/CodeGenSPIRV/decoration.relaxed-precision.image.hlsl +++ b/tools/clang/test/CodeGenSPIRV_Lit/decoration.relaxed-precision.image.hlsl @@ -1,4 +1,4 @@ -// RUN: %dxc -T ps_6_0 -E main +// RUN: %dxc -T ps_6_0 -E main -fcgl %s -spirv | FileCheck %s SamplerState gSampler : register(s4); SamplerComparisonState gCompareSampler : register(s5); @@ -6,14 +6,14 @@ SamplerComparisonState gCompareSampler : register(s5); // CHECK: OpDecorate %t2f4 RelaxedPrecision // CHECK-NEXT: OpDecorate %t2i4 RelaxedPrecision // CHECK-NEXT: OpDecorate %t2f RelaxedPrecision -// CHECK-NEXT: OpDecorate [[t2f4_val:%\d+]] RelaxedPrecision -// CHECK-NEXT: OpDecorate [[image_op_1:%\d+]] RelaxedPrecision -// CHECK-NEXT: OpDecorate [[t2i4_val:%\d+]] RelaxedPrecision -// CHECK-NEXT: OpDecorate [[image_op_2:%\d+]] RelaxedPrecision -// CHECK: OpDecorate [[t2f_val:%\d+]] RelaxedPrecision -// CHECK: OpDecorate [[imgSampleExplicit:%\d+]] RelaxedPrecision -// CHECK: OpDecorate [[t2f_val_again:%\d+]] RelaxedPrecision -// CHECK: OpDecorate [[imgSampleImplicit:%\d+]] RelaxedPrecision +// CHECK-NEXT: OpDecorate [[t2f4_val:%[0-9]+]] RelaxedPrecision +// CHECK-NEXT: OpDecorate [[image_op_1:%[0-9]+]] RelaxedPrecision +// CHECK-NEXT: OpDecorate [[t2i4_val:%[0-9]+]] RelaxedPrecision +// CHECK-NEXT: OpDecorate [[image_op_2:%[0-9]+]] RelaxedPrecision +// CHECK: OpDecorate [[t2f_val:%[0-9]+]] RelaxedPrecision +// CHECK: OpDecorate [[imgSampleExplicit:%[0-9]+]] RelaxedPrecision +// CHECK: OpDecorate [[t2f_val_again:%[0-9]+]] RelaxedPrecision +// CHECK: OpDecorate [[imgSampleImplicit:%[0-9]+]] RelaxedPrecision // CHECK: %t2f4 = OpVariable %_ptr_UniformConstant_type_2d_image_array UniformConstant // CHECK: %t2i4 = OpVariable %_ptr_UniformConstant_type_2d_image UniformConstant diff --git a/tools/clang/test/CodeGenSPIRV/decoration.relaxed-precision.resource.in.struct.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/decoration.relaxed-precision.resource.in.struct.hlsl similarity index 88% rename from tools/clang/test/CodeGenSPIRV/decoration.relaxed-precision.resource.in.struct.hlsl rename to tools/clang/test/CodeGenSPIRV_Lit/decoration.relaxed-precision.resource.in.struct.hlsl index 71219d449b..7e699162ac 100644 --- a/tools/clang/test/CodeGenSPIRV/decoration.relaxed-precision.resource.in.struct.hlsl +++ b/tools/clang/test/CodeGenSPIRV_Lit/decoration.relaxed-precision.resource.in.struct.hlsl @@ -1,4 +1,4 @@ -// RUN: %dxc -T ps_6_0 -E main -O0 +// RUN: %dxc -T ps_6_0 -E main -O0 %s -spirv | FileCheck %s //CHECK: OpDecorate %foo_x DescriptorSet 0 //CHECK: OpDecorate %foo_x Binding 0 diff --git a/tools/clang/test/CodeGenSPIRV/decoration.relaxed-precision.struct.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/decoration.relaxed-precision.struct.hlsl similarity index 58% rename from tools/clang/test/CodeGenSPIRV/decoration.relaxed-precision.struct.hlsl rename to tools/clang/test/CodeGenSPIRV_Lit/decoration.relaxed-precision.struct.hlsl index a539db0064..17908f9704 100644 --- a/tools/clang/test/CodeGenSPIRV/decoration.relaxed-precision.struct.hlsl +++ b/tools/clang/test/CodeGenSPIRV_Lit/decoration.relaxed-precision.struct.hlsl @@ -1,4 +1,4 @@ -// RUN: %dxc -T ps_6_0 -E main +// RUN: %dxc -T ps_6_0 -E main -fcgl %s -spirv | FileCheck %s min16uint foo(min12int param); @@ -20,21 +20,21 @@ void main() { // CHECK-NEXT: OpDecorate %i RelaxedPrecision // CHECK-NEXT: OpDecorate %j RelaxedPrecision // CHECK-NEXT: OpDecorate %param_var_param RelaxedPrecision -// CHECK-NEXT: OpDecorate [[sb:%\d+]] RelaxedPrecision +// CHECK-NEXT: OpDecorate [[sb:%[0-9]+]] RelaxedPrecision // Note: Decoration is missing for sa_plus_sb. -// CHECK-NEXT: OpDecorate [[sb2:%\d+]] RelaxedPrecision -// CHECK-NEXT: OpDecorate [[sb2_int:%\d+]] RelaxedPrecision -// CHECK-NEXT: OpDecorate [[sc:%\d+]] RelaxedPrecision -// CHECK-NEXT: OpDecorate [[sb_plus_sc:%\d+]] RelaxedPrecision -// CHECK-NEXT: OpDecorate [[sd:%\d+]] RelaxedPrecision -// CHECK-NEXT: OpDecorate [[se:%\d+]] RelaxedPrecision -// CHECK-NEXT: OpDecorate [[sd_plus_se:%\d+]] RelaxedPrecision -// CHECK-NEXT: OpDecorate [[sb3:%\d+]] RelaxedPrecision -// CHECK-NEXT: OpDecorate [[foo_result:%\d+]] RelaxedPrecision +// CHECK-NEXT: OpDecorate [[sb2:%[0-9]+]] RelaxedPrecision +// CHECK-NEXT: OpDecorate [[sb2_int:%[0-9]+]] RelaxedPrecision +// CHECK-NEXT: OpDecorate [[sc:%[0-9]+]] RelaxedPrecision +// CHECK-NEXT: OpDecorate [[sb_plus_sc:%[0-9]+]] RelaxedPrecision +// CHECK-NEXT: OpDecorate [[sd:%[0-9]+]] RelaxedPrecision +// CHECK-NEXT: OpDecorate [[se:%[0-9]+]] RelaxedPrecision +// CHECK-NEXT: OpDecorate [[sd_plus_se:%[0-9]+]] RelaxedPrecision +// CHECK-NEXT: OpDecorate [[sb3:%[0-9]+]] RelaxedPrecision +// CHECK-NEXT: OpDecorate [[foo_result:%[0-9]+]] RelaxedPrecision // CHECK-NEXT: OpDecorate %foo RelaxedPrecision // CHECK-NEXT: OpDecorate %param RelaxedPrecision -// CHECK-NEXT: OpDecorate [[param_value:%\d+]] RelaxedPrecision -// CHECK-NEXT: OpDecorate [[param_plus_1:%\d+]] RelaxedPrecision +// CHECK-NEXT: OpDecorate [[param_value:%[0-9]+]] RelaxedPrecision +// CHECK-NEXT: OpDecorate [[param_plus_1:%[0-9]+]] RelaxedPrecision // CHECK: %S = OpTypeStruct %int %int %int %float %float %float S s; @@ -44,30 +44,30 @@ void main() { // CHECK: %j = OpVariable %_ptr_Function_uint Function // CHECK: param_var_param = OpVariable %_ptr_Function_int Function -// CHECK: [[s1ptr:%\d+]] = OpAccessChain %_ptr_Function_int %s %int_1 +// CHECK: [[s1ptr:%[0-9]+]] = OpAccessChain %_ptr_Function_int %s %int_1 // CHECK: [[sb]] = OpLoad %int [[s1ptr]] -// CHECK: [[sa_plus_sb:%\d+]] = OpIAdd %int +// CHECK: [[sa_plus_sb:%[0-9]+]] = OpIAdd %int // While s.b is RelaxedPrecision (min12int), s.a is not (int). // We can only annotate the OpIAdd as RelaxedPrecision if both were. int g = s.a + s.b; -// CHECK: [[s1ptr:%\d+]] = OpAccessChain %_ptr_Function_int %s %int_1 -// CHECK: [[sb2]] = OpLoad %int [[s1ptr]] +// CHECK: [[s1ptr_0:%[0-9]+]] = OpAccessChain %_ptr_Function_int %s %int_1 +// CHECK: [[sb2]] = OpLoad %int [[s1ptr_0]] // CHECK: [[sb2_int]] = OpBitcast %int [[sb2]] -// CHECK: [[s2ptr:%\d+]] = OpAccessChain %_ptr_Function_int %s %int_2 +// CHECK: [[s2ptr:%[0-9]+]] = OpAccessChain %_ptr_Function_int %s %int_2 // CHECK: [[sc]] = OpLoad %int [[s2ptr]] // CHECK: [[sb_plus_sc]] = OpIAdd %int [[sb2_int]] [[sc]] min16int h = s.b + s.c; -// CHECK: [[s3ptr:%\d+]] = OpAccessChain %_ptr_Function_float %s %int_3 +// CHECK: [[s3ptr:%[0-9]+]] = OpAccessChain %_ptr_Function_float %s %int_3 // CHECK: [[sd]] = OpLoad %float [[s3ptr]] -// CHECK: [[s4ptr:%\d+]] = OpAccessChain %_ptr_Function_float %s %int_4 +// CHECK: [[s4ptr:%[0-9]+]] = OpAccessChain %_ptr_Function_float %s %int_4 // CHECK: [[se]] = OpLoad %float [[s4ptr]] // CHECK: [[sd_plus_se]] = OpFAdd %float [[sd]] [[se]] min16float i = s.d + s.e; -// CHECK: [[s1ptr:%\d+]] = OpAccessChain %_ptr_Function_int %s %int_1 -// CHECK: [[sb3]] = OpLoad %int [[s1ptr]] +// CHECK: [[s1ptr_1:%[0-9]+]] = OpAccessChain %_ptr_Function_int %s %int_1 +// CHECK: [[sb3]] = OpLoad %int [[s1ptr_1]] // CHECK: [[foo_result]] = OpFunctionCall %uint %foo %param_var_param min16uint j = foo(s.b); } diff --git a/tools/clang/test/CodeGenSPIRV/decoration.unique.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/decoration.unique.hlsl similarity index 79% rename from tools/clang/test/CodeGenSPIRV/decoration.unique.hlsl rename to tools/clang/test/CodeGenSPIRV_Lit/decoration.unique.hlsl index 3818225954..895bacd0d1 100644 --- a/tools/clang/test/CodeGenSPIRV/decoration.unique.hlsl +++ b/tools/clang/test/CodeGenSPIRV_Lit/decoration.unique.hlsl @@ -1,4 +1,4 @@ -// RUN: %dxc -T ps_6_2 -E main -fspv-reflect +// RUN: %dxc -T ps_6_2 -E main -fspv-reflect -fcgl %s -spirv | FileCheck %s // Make sure the same decoration is not applied twice. // diff --git a/tools/clang/test/CodeGenSPIRV/decoration.user-type.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/decoration.user-type.hlsl similarity index 98% rename from tools/clang/test/CodeGenSPIRV/decoration.user-type.hlsl rename to tools/clang/test/CodeGenSPIRV_Lit/decoration.user-type.hlsl index 4f558bd123..2c10943883 100644 --- a/tools/clang/test/CodeGenSPIRV/decoration.user-type.hlsl +++ b/tools/clang/test/CodeGenSPIRV_Lit/decoration.user-type.hlsl @@ -1,4 +1,4 @@ -// RUN: %dxc -T ps_6_0 -E main -fspv-reflect +// RUN: %dxc -T ps_6_0 -E main -fspv-reflect -fcgl %s -spirv | FileCheck %s // CHECK: OpExtension "SPV_GOOGLE_hlsl_functionality1" // CHECK: OpExtension "SPV_GOOGLE_user_type" diff --git a/tools/clang/test/CodeGenSPIRV/extension.unique.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/extension.unique.hlsl similarity index 76% rename from tools/clang/test/CodeGenSPIRV/extension.unique.hlsl rename to tools/clang/test/CodeGenSPIRV_Lit/extension.unique.hlsl index d5856da7a0..20d59ecc75 100644 --- a/tools/clang/test/CodeGenSPIRV/extension.unique.hlsl +++ b/tools/clang/test/CodeGenSPIRV_Lit/extension.unique.hlsl @@ -1,4 +1,4 @@ -// RUN: %dxc -T ps_6_2 -E main -enable-16bit-types +// RUN: %dxc -T ps_6_2 -E main -enable-16bit-types -fcgl %s -spirv | FileCheck %s // Make sure the same decoration is not applied twice. // diff --git a/tools/clang/test/CodeGenSPIRV/fspv-entrypoint-name.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/fspv-entrypoint-name.hlsl similarity index 62% rename from tools/clang/test/CodeGenSPIRV/fspv-entrypoint-name.hlsl rename to tools/clang/test/CodeGenSPIRV_Lit/fspv-entrypoint-name.hlsl index 131f4ee23a..757920eddc 100644 --- a/tools/clang/test/CodeGenSPIRV/fspv-entrypoint-name.hlsl +++ b/tools/clang/test/CodeGenSPIRV_Lit/fspv-entrypoint-name.hlsl @@ -1,4 +1,4 @@ -// RUN: %dxc -T ps_6_0 -E PSMain -fspv-entrypoint-name=main +// RUN: %dxc -T ps_6_0 -E PSMain -fspv-entrypoint-name=main -fcgl %s -spirv | FileCheck %s // CHECK: OpEntryPoint Fragment %PSMain "main" %in_var_COLOR %out_var_SV_TARGET float4 PSMain(float4 color : COLOR) : SV_TARGET diff --git a/tools/clang/test/CodeGenSPIRV/fspv-print-all.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/fspv-print-all.hlsl similarity index 81% rename from tools/clang/test/CodeGenSPIRV/fspv-print-all.hlsl rename to tools/clang/test/CodeGenSPIRV_Lit/fspv-print-all.hlsl index 69ae860f7f..052797a98f 100644 --- a/tools/clang/test/CodeGenSPIRV/fspv-print-all.hlsl +++ b/tools/clang/test/CodeGenSPIRV_Lit/fspv-print-all.hlsl @@ -1,4 +1,4 @@ -// RUN: %dxc -T ps_6_0 -E main -spirv -fspv-print-all +// RUN: %dxc -T ps_6_0 -E main -spirv -fspv-print-all -fcgl %s -spirv | FileCheck %s // We expect the whole module to be printed multiple times, but we cannot check // that here as stderr contents do not appear as test diagnostics. Instead, diff --git a/tools/clang/test/CodeGenSPIRV/gs.emit.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/gs.emit.hlsl similarity index 51% rename from tools/clang/test/CodeGenSPIRV/gs.emit.hlsl rename to tools/clang/test/CodeGenSPIRV_Lit/gs.emit.hlsl index 3202671f44..bef55d4261 100644 --- a/tools/clang/test/CodeGenSPIRV/gs.emit.hlsl +++ b/tools/clang/test/CodeGenSPIRV_Lit/gs.emit.hlsl @@ -1,4 +1,4 @@ -// RUN: %dxc -T gs_6_0 -E main +// RUN: %dxc -T gs_6_0 -E main -fcgl %s -spirv | FileCheck %s struct GsInnerOut { float2 bar : BAR; @@ -10,7 +10,7 @@ struct GsPerVertexOut { GsInnerOut s; }; -// CHECK: [[null:%\d+]] = OpConstantNull %GsPerVertexOut +// CHECK: [[null:%[0-9]+]] = OpConstantNull %GsPerVertexOut [maxvertexcount(2)] void main(in line float2 foo[2] : FOO, @@ -26,27 +26,27 @@ void main(in line float2 foo[2] : FOO, vertex = (GsPerVertexOut)0; // Write back to stage output variables -// CHECK-NEXT: [[vertex:%\d+]] = OpLoad %GsPerVertexOut %vertex -// CHECK-NEXT: [[pos:%\d+]] = OpCompositeExtract %v4float [[vertex]] 0 +// CHECK-NEXT: [[vertex:%[0-9]+]] = OpLoad %GsPerVertexOut %vertex +// CHECK-NEXT: [[pos:%[0-9]+]] = OpCompositeExtract %v4float [[vertex]] 0 // CHECK-NEXT: OpStore %gl_Position_0 [[pos]] -// CHECK-NEXT: [[foo:%\d+]] = OpCompositeExtract %v3float [[vertex]] 1 +// CHECK-NEXT: [[foo:%[0-9]+]] = OpCompositeExtract %v3float [[vertex]] 1 // CHECK-NEXT: OpStore %out_var_FOO [[foo]] -// CHECK-NEXT: [[s:%\d+]] = OpCompositeExtract %GsInnerOut [[vertex]] 2 -// CHECK-NEXT: [[bar:%\d+]] = OpCompositeExtract %v2float [[s]] 0 +// CHECK-NEXT: [[s:%[0-9]+]] = OpCompositeExtract %GsInnerOut [[vertex]] 2 +// CHECK-NEXT: [[bar:%[0-9]+]] = OpCompositeExtract %v2float [[s]] 0 // CHECK-NEXT: OpStore %out_var_BAR [[bar]] // CHECK-NEXT: OpEmitVertex outData.Append(vertex); // Write back to stage output variables -// CHECK-NEXT: [[vertex:%\d+]] = OpLoad %GsPerVertexOut %vertex -// CHECK-NEXT: [[pos:%\d+]] = OpCompositeExtract %v4float [[vertex]] 0 -// CHECK-NEXT: OpStore %gl_Position_0 [[pos]] -// CHECK-NEXT: [[foo:%\d+]] = OpCompositeExtract %v3float [[vertex]] 1 -// CHECK-NEXT: OpStore %out_var_FOO [[foo]] -// CHECK-NEXT: [[s:%\d+]] = OpCompositeExtract %GsInnerOut [[vertex]] 2 -// CHECK-NEXT: [[bar:%\d+]] = OpCompositeExtract %v2float [[s]] 0 -// CHECK-NEXT: OpStore %out_var_BAR [[bar]] +// CHECK-NEXT: [[vertex_0:%[0-9]+]] = OpLoad %GsPerVertexOut %vertex +// CHECK-NEXT: [[pos_0:%[0-9]+]] = OpCompositeExtract %v4float [[vertex_0]] 0 +// CHECK-NEXT: OpStore %gl_Position_0 [[pos_0]] +// CHECK-NEXT: [[foo_0:%[0-9]+]] = OpCompositeExtract %v3float [[vertex_0]] 1 +// CHECK-NEXT: OpStore %out_var_FOO [[foo_0]] +// CHECK-NEXT: [[s_0:%[0-9]+]] = OpCompositeExtract %GsInnerOut [[vertex_0]] 2 +// CHECK-NEXT: [[bar_0:%[0-9]+]] = OpCompositeExtract %v2float [[s_0]] 0 +// CHECK-NEXT: OpStore %out_var_BAR [[bar_0]] // CHECK-NEXT: OpEmitVertex outData.Append(vertex); diff --git a/tools/clang/test/CodeGenSPIRV/hs.const.output-patch.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/hs.const.output-patch.hlsl similarity index 64% rename from tools/clang/test/CodeGenSPIRV/hs.const.output-patch.hlsl rename to tools/clang/test/CodeGenSPIRV_Lit/hs.const.output-patch.hlsl index 939aed22bc..d14be7934a 100644 --- a/tools/clang/test/CodeGenSPIRV/hs.const.output-patch.hlsl +++ b/tools/clang/test/CodeGenSPIRV_Lit/hs.const.output-patch.hlsl @@ -1,4 +1,4 @@ -// RUN: %dxc -T hs_6_0 -E main +// RUN: %dxc -T hs_6_0 -E main -fcgl %s -spirv | FileCheck %s struct HSCtrlPt { float4 ctrlPt : CONTROLPOINT; @@ -17,13 +17,13 @@ HSPatchConstData HSPatchConstantFunc(const OutputPatch input) { // CHECK: %input = OpFunctionParameter %_ptr_Function__arr_HSCtrlPt_uint_3 -// CHECK: [[OutCtrl0:%\d+]] = OpAccessChain %_ptr_Function_v4float %input %uint_0 %int_0 -// CHECK: [[input0:%\d+]] = OpLoad %v4float [[OutCtrl0]] -// CHECK: [[OutCtrl1:%\d+]] = OpAccessChain %_ptr_Function_v4float %input %uint_1 %int_0 -// CHECK: [[input1:%\d+]] = OpLoad %v4float [[OutCtrl1]] -// CHECK: [[add:%\d+]] = OpFAdd %v4float [[input0]] [[input1]] -// CHECK: [[OutCtrl2:%\d+]] = OpAccessChain %_ptr_Function_v4float %input %uint_2 %int_0 -// CHECK: [[input2:%\d+]] = OpLoad %v4float [[OutCtrl2]] +// CHECK: [[OutCtrl0:%[0-9]+]] = OpAccessChain %_ptr_Function_v4float %input %uint_0 %int_0 +// CHECK: [[input0:%[0-9]+]] = OpLoad %v4float [[OutCtrl0]] +// CHECK: [[OutCtrl1:%[0-9]+]] = OpAccessChain %_ptr_Function_v4float %input %uint_1 %int_0 +// CHECK: [[input1:%[0-9]+]] = OpLoad %v4float [[OutCtrl1]] +// CHECK: [[add:%[0-9]+]] = OpFAdd %v4float [[input0]] [[input1]] +// CHECK: [[OutCtrl2:%[0-9]+]] = OpAccessChain %_ptr_Function_v4float %input %uint_2 %int_0 +// CHECK: [[input2:%[0-9]+]] = OpLoad %v4float [[OutCtrl2]] // CHECK: OpFAdd %v4float [[add]] [[input2]] data.constData = input[0].ctrlPt + input[1].ctrlPt + input[2].ctrlPt; diff --git a/tools/clang/test/CodeGenSPIRV/hs.pcf.view-id.1.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/hs.pcf.view-id.1.hlsl similarity index 76% rename from tools/clang/test/CodeGenSPIRV/hs.pcf.view-id.1.hlsl rename to tools/clang/test/CodeGenSPIRV_Lit/hs.pcf.view-id.1.hlsl index bc179cfd62..51169ebccb 100644 --- a/tools/clang/test/CodeGenSPIRV/hs.pcf.view-id.1.hlsl +++ b/tools/clang/test/CodeGenSPIRV_Lit/hs.pcf.view-id.1.hlsl @@ -1,4 +1,4 @@ -// RUN: %dxc -T hs_6_1 -E main +// RUN: %dxc -T hs_6_1 -E main -fcgl %s -spirv | FileCheck %s // Test: Both entry point and PCF Takes ViewID @@ -6,11 +6,11 @@ // CHECK: OpExtension "SPV_KHR_multiview" // CHECK: OpEntryPoint TessellationControl -// CHECK-SAME: [[viewindex:%\d+]] +// CHECK-SAME: [[viewindex:%[0-9]+]] // CHECK: OpDecorate [[viewindex]] BuiltIn ViewIndex -// CHECK: [[pcfType:%\d+]] = OpTypeFunction %HsPcfOut %_ptr_Function_uint +// CHECK: [[pcfType:%[0-9]+]] = OpTypeFunction %HsPcfOut %_ptr_Function_uint // CHECK: [[viewindex]] = OpVariable %_ptr_Input_uint Input #define NumOutPoints 2 @@ -46,12 +46,12 @@ HsCpOut main(InputPatch patch, HsCpOut output; output.bar = viewid; return output; -// CHECK: %main = OpFunction %void None {{%\d+}} +// CHECK: %main = OpFunction %void None {{%[0-9]+}} // CHECK: %param_var_viewid = OpVariable %_ptr_Function_uint Function -// CHECK: [[val:%\d+]] = OpLoad %uint [[viewindex]] +// CHECK: [[val:%[0-9]+]] = OpLoad %uint [[viewindex]] // CHECK: OpStore %param_var_viewid [[val]] -// CHECK: {{%\d+}} = OpFunctionCall %HsPcfOut %pcf %param_var_viewid +// CHECK: {{%[0-9]+}} = OpFunctionCall %HsPcfOut %pcf %param_var_viewid // CHECK: %pcf = OpFunction %HsPcfOut None [[pcfType]] // CHECK: %viewid = OpFunctionParameter %_ptr_Function_uint diff --git a/tools/clang/test/CodeGenSPIRV/hs.pcf.view-id.2.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/hs.pcf.view-id.2.hlsl similarity index 76% rename from tools/clang/test/CodeGenSPIRV/hs.pcf.view-id.2.hlsl rename to tools/clang/test/CodeGenSPIRV_Lit/hs.pcf.view-id.2.hlsl index f9b1947c75..6dc5b6e7ac 100644 --- a/tools/clang/test/CodeGenSPIRV/hs.pcf.view-id.2.hlsl +++ b/tools/clang/test/CodeGenSPIRV_Lit/hs.pcf.view-id.2.hlsl @@ -1,4 +1,4 @@ -// RUN: %dxc -T hs_6_1 -E main +// RUN: %dxc -T hs_6_1 -E main -fcgl %s -spirv | FileCheck %s // Test: Both entry point and PCF Takes ViewID @@ -6,11 +6,11 @@ // CHECK: OpExtension "SPV_KHR_multiview" // CHECK: OpEntryPoint TessellationControl -// CHECK-SAME: [[viewindex:%\d+]] +// CHECK-SAME: [[viewindex:%[0-9]+]] // CHECK: OpDecorate [[viewindex]] BuiltIn ViewIndex -// CHECK: [[pcfType:%\d+]] = OpTypeFunction %HsPcfOut %_ptr_Function_uint +// CHECK: [[pcfType:%[0-9]+]] = OpTypeFunction %HsPcfOut %_ptr_Function_uint // CHECK: [[viewindex]] = OpVariable %_ptr_Input_uint Input #define NumOutPoints 2 @@ -45,12 +45,12 @@ HsCpOut main(InputPatch patch, HsCpOut output; output = (HsCpOut)0; return output; -// CHECK: %main = OpFunction %void None {{%\d+}} +// CHECK: %main = OpFunction %void None {{%[0-9]+}} // CHECK: %param_var_viewid = OpVariable %_ptr_Function_uint Function -// CHECK: [[val:%\d+]] = OpLoad %uint [[viewindex]] +// CHECK: [[val:%[0-9]+]] = OpLoad %uint [[viewindex]] // CHECK: OpStore %param_var_viewid [[val]] -// CHECK: {{%\d+}} = OpFunctionCall %HsPcfOut %pcf %param_var_viewid +// CHECK: {{%[0-9]+}} = OpFunctionCall %HsPcfOut %pcf %param_var_viewid // CHECK: %pcf = OpFunction %HsPcfOut None [[pcfType]] // CHECK: %viewid = OpFunctionParameter %_ptr_Function_uint diff --git a/tools/clang/test/CodeGenSPIRV_Lit/intrinsics.get-attribute-at-vertex.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/intrinsics.get-attribute-at-vertex.hlsl deleted file mode 100644 index 4b07d022a0..0000000000 --- a/tools/clang/test/CodeGenSPIRV_Lit/intrinsics.get-attribute-at-vertex.hlsl +++ /dev/null @@ -1,25 +0,0 @@ -// RUN: not %dxc -T ps_6_1 -E main -fcgl %s -spirv 2>&1 | FileCheck %s - -struct PSInput { - float4 position : SV_POSITION; - nointerpolation float3 color : COLOR; -}; - -cbuffer constants : register(b0) { - float4 g_constants; -} - -float4 main(PSInput input) : SV_TARGET { - uint cmp = (uint)(g_constants[0]); - - // CHECK: 16:21: error: GetAttributeAtVertex intrinsic function unimplemented - float colorAtV0 = GetAttributeAtVertex(input.color, 0)[cmp]; - - // CHECK: 19:21: error: GetAttributeAtVertex intrinsic function unimplemented - float colorAtV1 = GetAttributeAtVertex(input.color, 1)[cmp]; - - // CHECK: 22:21: error: GetAttributeAtVertex intrinsic function unimplemented - float colorAtV2 = GetAttributeAtVertex(input.color, 2)[cmp]; - - return float4(colorAtV0, colorAtV1, colorAtV2, 0); -} diff --git a/tools/clang/test/CodeGenSPIRV_Lit/intrinsics.get-attribute-at-vertex.n.bool.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/intrinsics.get-attribute-at-vertex.n.bool.hlsl new file mode 100644 index 0000000000..84f953051d --- /dev/null +++ b/tools/clang/test/CodeGenSPIRV_Lit/intrinsics.get-attribute-at-vertex.n.bool.hlsl @@ -0,0 +1,21 @@ +// RUN: not %dxc -T ps_6_1 -E main %s -spirv 2>&1 | FileCheck %s + +enum VertexID { + FIRST = 0, + SECOND = 1, + THIRD = 2 +}; + +bool3 main( + float4 position : SV_POSITION, + nointerpolation bool3 color1 : COLOR1, + nointerpolation bool3 color2 : COLOR2) : SV_Target +{ + bool3 vColor0 = color1; + bool3 vColor1 = GetAttributeAtVertex( color1, VertexID::SECOND ); + bool3 vColor2 = color2; + bool3 vColor3 = GetAttributeAtVertex( color2, VertexID::THIRD ); + return and(and(and(vColor0 ,vColor1), vColor2), vColor3); +} +// CHECK: error: attribute evaluation can only be done on values taken directly from inputs. +// CHECK: error: attribute evaluation can only be done on values taken directly from inputs. \ No newline at end of file diff --git a/tools/clang/test/CodeGenSPIRV_Lit/intrinsics.get-attribute-at-vertex.n.callChain.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/intrinsics.get-attribute-at-vertex.n.callChain.hlsl new file mode 100644 index 0000000000..11e55e309e --- /dev/null +++ b/tools/clang/test/CodeGenSPIRV_Lit/intrinsics.get-attribute-at-vertex.n.callChain.hlsl @@ -0,0 +1,40 @@ +// RUN: %dxc -T ps_6_1 -E main -spirv -Od %s 2>&1 | FileCheck %s + +enum VertexID { + FIRST = 0, + SECOND = 1, + THIRD = 2 +}; + + +float3 func1(nointerpolation float3 func1Color){ + float3 func1Ret = GetAttributeAtVertex(func1Color, 1) + func1Color; + return func1Ret; +} + +float3 func0(nointerpolation float3 func0Color){ + return func1(func0Color); +} + +// CHECK: OpCapability FragmentBarycentricKHR +// CHECK: OpExtension "SPV_KHR_fragment_shader_barycentric" +// CHECK: OpDecorate %in_var_COLOR Location 0 +// CHECK: OpDecorate %in_var_COLOR PerVertexKHR +// CHECK: %in_var_COLOR = OpVariable %_ptr_Input__arr_v3float_uint_3 Input +float3 main(nointerpolation float3 inputColor : COLOR) : SV_Target +{ + float3 mainRet = func0(inputColor); + return mainRet; +} +// CHECK: [[param_var_inputColor:%[a-zA-Z0-9_]+]] = OpVariable %_ptr_Function__arr_v3float_uint_3 Function +// CHECK: [[param_var_func0Color:%[a-zA-Z0-9_]+]] = OpVariable %_ptr_Function__arr_v3float_uint_3 Function +// CHECK: [[inputColor_perVertexParam0:%[a-zA-Z0-9_]+]] = OpVariable %_ptr_Function_v3float Function +// CHECK: [[inst36:%[0-9]+]] = OpAccessChain %_ptr_Function_v3float [[param_var_func0Color]] %uint_0 +// CHECK: [[inst37:%[0-9]+]] = OpAccessChain %_ptr_Function_v3float [[inputColor:%[a-zA-Z0-9_]+]] %uint_0 +// CHECK: [[inst38:%[0-9]+]] = OpLoad %v3float [[inst37]] +// CHECK: OpStore [[inputColor_perVertexParam0]] [[inst38]] +// CHECK: [[func1Color:%[a-zA-Z0-9_]+]] = OpFunctionParameter %_ptr_Function__arr_v3float_uint_3 +// CHECK: [[func1Color_perVertexParam0:%[a-zA-Z0-9_]+]] = OpVariable %_ptr_Function_v3float Function +// CHECK: [[inst59:%[0-9]+]] = OpAccessChain %_ptr_Function_v3float [[func1Color]] %uint_0 +// CHECK: [[inst60:%[0-9]+]] = OpLoad %v3float [[inst59]] +// CHECK: OpStore [[func1Color_perVertexParam0]] [[inst60]] \ No newline at end of file diff --git a/tools/clang/test/CodeGenSPIRV_Lit/intrinsics.get-attribute-at-vertex.n.channel.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/intrinsics.get-attribute-at-vertex.n.channel.hlsl new file mode 100644 index 0000000000..e30573edee --- /dev/null +++ b/tools/clang/test/CodeGenSPIRV_Lit/intrinsics.get-attribute-at-vertex.n.channel.hlsl @@ -0,0 +1,42 @@ +// RUN: %dxc -T ps_6_1 -E main -spirv -Od %s 2>&1 | FileCheck %s + +enum VertexID { + FIRST = 0, + SECOND = 1, + THIRD = 2 +}; + +// CHECK: OpCapability FragmentBarycentricKHR +// CHECK: OpExtension "SPV_KHR_fragment_shader_barycentric" +// CHECK: OpDecorate [[in_var_COLOR0:%[a-zA-Z0-9_]+]] Location 0 +// CHECK: OpDecorate [[in_var_COLOR1:%[a-zA-Z0-9_]+]] Location 1 +// CHECK: OpDecorate [[in_var_COLOR2:%[a-zA-Z0-9_]+]] Location 2 +// CHECK: OpDecorate [[in_var_COLOR1]] PerVertexKHR +// CHECK: OpDecorate [[in_var_COLOR2]] PerVertexKHR +// CHECK: [[in_var_COLOR0]] = OpVariable %_ptr_Input_v3float Input +// CHECK: [[in_var_COLOR1]] = OpVariable %_ptr_Input__arr_v3float_uint_3 Input +// CHECK: [[in_var_COLOR2]] = OpVariable %_ptr_Input__arr_v3float_uint_3 Input +float3 main( + float3 color0 : COLOR0, + nointerpolation float3 color1 : COLOR1, + nointerpolation float3 color2 : COLOR2) : SV_Target +{ + float3 vColor0 = color0; + float3 vColor1 = color1; + float3 vColor2 = GetAttributeAtVertex( color1, VertexID::SECOND ); + float3 vColor3 = color1; + float3 vColor4 = float3(color2.y, color1.z, vColor2.y); + return vColor0 + vColor1 + vColor2 + vColor3 + vColor4; +} + +// CHECK: [[color0:%[a-zA-Z0-9_]+]] = OpFunctionParameter %_ptr_Function_v3float +// CHECK: [[color1:%[a-zA-Z0-9_]+]] = OpFunctionParameter %_ptr_Function__arr_v3float_uint_3 +// CHECK: [[color2:%[a-zA-Z0-9_]+]] = OpFunctionParameter %_ptr_Function__arr_v3float_uint_3 +// CHECK: [[inst104:%[0-9]+]] = OpAccessChain %_ptr_Function_float [[color2]] %uint_0 %int_1 +// CHECK: [[inst105:%[0-9]+]] = OpLoad %float [[inst104]] +// CHECK: [[inst106:%[0-9]+]] = OpAccessChain %_ptr_Function_float [[color1]] %uint_0 %int_2 +// CHECK: [[inst107:%[0-9]+]] = OpLoad %float [[inst106]] +// CHECK: [[inst108:%[0-9]+]] = OpAccessChain %_ptr_Function_float [[vColor2:%[a-zA-Z0-9_]+]] %int_1 +// CHECK: [[inst109:%[0-9]+]] = OpLoad %float [[inst108]] +// CHECK: [[inst110:%[0-9]+]] = OpCompositeConstruct %v3float [[inst105]] [[inst107]] [[inst109]] +// CHECK: OpStore [[vColor4:%[a-zA-Z0-9_]+]] [[inst110]] \ No newline at end of file diff --git a/tools/clang/test/CodeGenSPIRV_Lit/intrinsics.get-attribute-at-vertex.s.bool.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/intrinsics.get-attribute-at-vertex.s.bool.hlsl new file mode 100644 index 0000000000..678274e40f --- /dev/null +++ b/tools/clang/test/CodeGenSPIRV_Lit/intrinsics.get-attribute-at-vertex.s.bool.hlsl @@ -0,0 +1,25 @@ +// RUN: not %dxc -T ps_6_1 -E main %s -spirv 2>&1 | FileCheck %s + +enum VertexID { + FIRST = 0, + SECOND = 1, + THIRD = 2 +}; + +struct PSInput +{ + float4 position : SV_POSITION; + nointerpolation bool3 color1 : COLOR1; + nointerpolation bool3 color2 : COLOR2; +}; + +bool3 main(PSInput input ) : SV_Target +{ + bool3 vColor0 = input.color1; + bool3 vColor1 = GetAttributeAtVertex( input.color1, VertexID::SECOND ); + bool3 vColor2 = input.color2; + bool3 vColor3 = GetAttributeAtVertex( input.color2, VertexID::THIRD ); + return and(and(and(vColor0, vColor1), vColor2), vColor3); +} +// CHECK: error: attribute evaluation can only be done on values taken directly from inputs. +// CHECK: error: attribute evaluation can only be done on values taken directly from inputs. \ No newline at end of file diff --git a/tools/clang/test/CodeGenSPIRV_Lit/intrinsics.get-attribute-at-vertex.s.callChain.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/intrinsics.get-attribute-at-vertex.s.callChain.hlsl new file mode 100644 index 0000000000..fde0b24e6c --- /dev/null +++ b/tools/clang/test/CodeGenSPIRV_Lit/intrinsics.get-attribute-at-vertex.s.callChain.hlsl @@ -0,0 +1,63 @@ +// RUN: %dxc -T ps_6_1 -E main -spirv -Od %s 2>&1 | FileCheck %s + +enum VertexID { + FIRST = 0, + SECOND = 1, + THIRD = 2 +}; + + +struct PSInput +{ + int i : COLOR0; + nointerpolation float3 Color : COLOR1; +}; + +struct testStructure +{ + nointerpolation float3 Color : COLOR4; +}; + + +float3 func1(nointerpolation float3 func1Color){ + testStructure chainEndVal; + chainEndVal.Color = func1Color; + float3 func1Ret = GetAttributeAtVertex(func1Color, 1) + chainEndVal.Color; + return func1Ret; +} + +float3 func0(nointerpolation float3 func0Color){ + return func1(func0Color); +} + +// CHECK: OpCapability FragmentBarycentricKHR +// CHECK: OpExtension "SPV_KHR_fragment_shader_barycentric" +// CHECK: OpDecorate [[color:%[a-zA-Z0-9_]+]] Location 0 +// CHECK: OpDecorate [[color]] PerVertexKHR +// CHECK: [[param_var_inputColor:%[a-zA-Z0-9_]+]] = OpVariable %_ptr_Function__arr_v3float_uint_3 Function +// CHECK: [[inst26:%[0-9]+]] = OpLoad %_arr_v3float_uint_3 [[color]] +// CHECK: OpStore [[param_var_inputColor]] [[inst26]] +// CHECK: [[callMain:%[0-9]+]] = OpFunctionCall %v3float %src_main [[param_var_inputColor]] +float3 main(nointerpolation float3 inputColor : COLOR) : SV_Target +{ + float3 mainRet = func0(inputColor); + return mainRet; +} + +// CHECK: [[inputColor:%[a-zA-Z]+]] = OpFunctionParameter %_ptr_Function__arr_v3float_uint_3 +// CHECK: %inputColor_perVertexParam0 = OpVariable %_ptr_Function_v3float Function +// CHECK: [[inst39:%[0-9]+]] = OpAccessChain %_ptr_Function_v3float [[inputColor]] %uint_0 +// CHECK: [[inst40:%[0-9]+]] = OpLoad %v3float [[inst39]] +// CHECK: OpStore %inputColor_perVertexParam0 [[inst40]] +// CHECK: [[inst41:%[0-9]+]] = OpLoad %_arr_v3float_uint_3 [[inputColor]] +// CHECK: OpStore [[param_var_func0Color:%[a-zA-Z0-9_]+]] [[inst41]] +// CHECK: [[inst43:%[0-9]+]] = OpFunctionCall %v3float [[func0:%[a-zA-Z0-9_]+]] [[param_var_func0Color]] +// CHECK: [[chainEndVal:%[a-zA-Z0-9_]+]] = OpVariable %_ptr_Function_testStructure Function +// CHECK: [[func1Ret:%[a-zA-Z0-9_]+]] = OpVariable %_ptr_Function_v3float Function +// CHECK: %func1Color_perVertexParam0 = OpVariable %_ptr_Function_v3float Function +// CHECK: [[inst66:%[0-9]+]] = OpAccessChain %_ptr_Function_v3float [[func1Color:%[a-zA-Z0-9_]+]] %uint_0 +// CHECK: [[inst67:%[0-9]+]] = OpLoad %v3float [[inst66]] +// CHECK: OpStore %func1Color_perVertexParam0 [[inst67]] +// CHECK: [[inst68:%[0-9]+]] = OpLoad %v3float %func1Color_perVertexParam0 +// CHECK: [[inst69:%[0-9]+]] = OpAccessChain %_ptr_Function_v3float [[chainEndVal]] %int_0 %uint_0 +// CHECK: OpStore [[inst69]] [[inst68]] \ No newline at end of file diff --git a/tools/clang/test/CodeGenSPIRV_Lit/intrinsics.get-attribute-at-vertex.s.channel.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/intrinsics.get-attribute-at-vertex.s.channel.hlsl new file mode 100644 index 0000000000..031bec59b5 --- /dev/null +++ b/tools/clang/test/CodeGenSPIRV_Lit/intrinsics.get-attribute-at-vertex.s.channel.hlsl @@ -0,0 +1,40 @@ +// RUN: %dxc -T ps_6_1 -E main -spirv -Od %s 2>&1 | FileCheck %s + +enum VertexID { + FIRST = 0, + SECOND = 1, + THIRD = 2 +}; + +struct PSInput +{ + float3 color0 : COLOR0; + nointerpolation float3 color1 : COLOR1; + nointerpolation float3 color2 : COLOR2; +}; + +// CHECK: OpCapability FragmentBarycentricKHR +// CHECK: OpExtension "SPV_KHR_fragment_shader_barycentric" +// CHECK: OpDecorate [[color0:%[a-zA-Z0-9_]+]] Location 0 +// CHECK: OpDecorate [[color1:%[a-zA-Z0-9_]+]] Location 1 +// CHECK: OpDecorate [[color2:%[a-zA-Z0-9_]+]] Location 2 +// CHECK: OpDecorate [[color1]] PerVertexKHR +// CHECK: OpDecorate [[color2]] PerVertexKHR +// CHECK: [[PSInput:%[a-zA-Z0-9_]+]] = OpTypeStruct %v3float %_arr_v3float_uint_3 %_arr_v3float_uint_3 +// CHECK: [[color0]] = OpVariable %_ptr_Input_v3float Input +// CHECK: [[color1]] = OpVariable %_ptr_Input__arr_v3float_uint_3 Input +// CHECK: [[color2]] = OpVariable %_ptr_Input__arr_v3float_uint_3 Input +float3 main(PSInput input) : SV_Target +{ + float3 vColor0 = input.color0; + float3 vColor1 = input.color1; + float3 vColor2 = GetAttributeAtVertex(input.color1, VertexID::SECOND ); + float3 vColor3 = input.color1; + float3 vColor4 = float3(input.color2.y, input.color1.z, vColor2.y); + return vColor0 + vColor1 + vColor2 + vColor3 + vColor4; +} +// CHECK: [[input:%[a-zA-Z0-9_]+]] = OpFunctionParameter [[Ptr_PSInput:%[a-zA-Z0-9_]+]] +// CHECK: [[acInputColor2:%[0-9]+]] = OpAccessChain %_ptr_Function_v3float [[input]] %int_2 %uint_0 +// CHECK: [[color2Y:%[0-9]+]] = OpAccessChain %_ptr_Function_float [[acInputColor2]] %int_1 +// CHECK: [[loadc2y:%[0-9]+]] = OpLoad %float [[color2Y]] +// CHECK: [[result:%[0-9]+]] = OpCompositeConstruct %v3float [[loadc2y]] [[loadc1z:%[0-9]+]] [[vc2y:%[0-9]+]] \ No newline at end of file diff --git a/tools/clang/test/CodeGenSPIRV_Lit/intrinsics.get-attribute-at-vertex.s.nestedStruct.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/intrinsics.get-attribute-at-vertex.s.nestedStruct.hlsl new file mode 100644 index 0000000000..a43fa7bd7c --- /dev/null +++ b/tools/clang/test/CodeGenSPIRV_Lit/intrinsics.get-attribute-at-vertex.s.nestedStruct.hlsl @@ -0,0 +1,47 @@ +// RUN: %dxc -T ps_6_1 -E main -spirv -Od %s 2>&1 | FileCheck %s + +enum VertexID { + FIRST = 0, + SECOND = 1, + THIRD = 2 +}; +struct PSInput1 +{ + float3 color3: COLOR3; +}; + +struct PSInput +{ + float4 position : SV_POSITION; + nointerpolation float3 color1 : COLOR1; + nointerpolation PSInput1 pi : COLOR2; +}; + +// CHECK: OpCapability FragmentBarycentricKHR +// CHECK: OpExtension "SPV_KHR_fragment_shader_barycentric" +// CHECK: OpDecorate [[color1:%[a-zA-Z0-9_]+]] Location 0 +// CHECK: OpDecorate [[color2:%[a-zA-Z0-9_]+]] Location 1 +// CHECK: OpDecorate [[color1]] PerVertexKHR +// CHECK: OpDecorate [[color2]] PerVertexKHR +// CHECK: [[PSInput1:%[a-zA-Z0-9_]+]] = OpTypeStruct %_arr_v3float_uint_3 +// CHECK: [[PSInput:%[a-zA-Z0-9_]+]] = OpTypeStruct %v4float %_arr_v3float_uint_3 [[PSInput1]] +// CHECK: [[color1]] = OpVariable %_ptr_Input__arr_v3float_uint_3 Input +// CHECK: [[color2]] = OpVariable %_ptr_Input__arr_v3float_uint_3 Input +// CHECK: [[loadc1:%[0-9]+]] = OpLoad %_arr_v3float_uint_3 [[color1]] +// CHECK: [[loadc2:%[0-9]+]] = OpLoad %_arr_v3float_uint_3 [[color2]] +// CHECK: [[loadpi1:%[0-9]+]] = OpCompositeConstruct [[PSInput1]] [[loadc2]] +// CHECK: [[loadpi:%[0-9]+]] = OpCompositeConstruct [[PSInput]] [[frag:%[0-9]+]] [[loadc1]] [[loadpi1]] +float3 main( PSInput input ) : SV_Target +{ + float3 vColor0 = input.color1; + float3 vColor1 = GetAttributeAtVertex( input.color1, VertexID::SECOND ); + float3 vColor2 = input.pi.color3; + float3 vColor3 = GetAttributeAtVertex( input.pi.color3, VertexID::THIRD ); + return (vColor0 + vColor1 + vColor2 + vColor3); +} + +// CHECK: [[input:%[a-zA-Z0-9_]+]] = OpFunctionParameter %_ptr_Function_PSInput +// CHECK: %vColor2 = OpVariable %_ptr_Function_v3float Function +// CHECK: [[acColor3:%[0-9]+]] = OpAccessChain %_ptr_Function_v3float [[input]] %int_2 %int_0 %uint_0 +// CHECK: [[loadColor3:%[0-9]+]] = OpLoad %v3float [[acColor3]] +// CHECK: OpStore %vColor2 [[loadColor3]] \ No newline at end of file diff --git a/tools/clang/test/CodeGenSPIRV_Lit/intrinsics.get-attribute-at-vertex.s.retStruct.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/intrinsics.get-attribute-at-vertex.s.retStruct.hlsl new file mode 100644 index 0000000000..f961edfdb9 --- /dev/null +++ b/tools/clang/test/CodeGenSPIRV_Lit/intrinsics.get-attribute-at-vertex.s.retStruct.hlsl @@ -0,0 +1,48 @@ +// RUN: %dxc -T ps_6_1 -E main -spirv -Od %s 2>&1 | FileCheck %s + +enum VertexID { + FIRST = 0, + SECOND = 1, + THIRD = 2 +}; + + +struct PSInput +{ + nointerpolation float3 color0 : COLOR0; + nointerpolation float3 color1 : COLOR1; + nointerpolation float3 color2 : COLOR2; +}; + +// CHECK: OpCapability FragmentBarycentricKHR +// CHECK: OpExtension "SPV_KHR_fragment_shader_barycentric" +// CHECK: OpDecorate [[color0:%[a-zA-Z0-9_]+]] Location 0 +// CHECK: OpDecorate [[color1:%[a-zA-Z0-9_]+]] Location 1 +// CHECK: OpDecorate [[color2:%[a-zA-Z0-9_]+]] Location 2 +// CHECK: OpDecorate [[color0]] PerVertexKHR +// CHECK: OpDecorate [[color1]] PerVertexKHR +// CHECK: OpDecorate [[color2]] PerVertexKHR +// CHECK: [[PSInput:%[a-zA-Z0-9_]+]] = OpTypeStruct %_arr_v3float_uint_3 %_arr_v3float_uint_3 %_arr_v3float_uint_3 +// CHECK: [[color0]] = OpVariable %_ptr_Input__arr_v3float_uint_3 Input +// CHECK: [[color1]] = OpVariable %_ptr_Input__arr_v3float_uint_3 Input +// CHECK: [[color2]] = OpVariable %_ptr_Input__arr_v3float_uint_3 Input +// CHECK: [[outTarget0:%[a-zA-Z0-9_]+]] = OpVariable %_ptr_Output_v3float Output +// CHECK: [[outTarget1:%[a-zA-Z0-9_]+]] = OpVariable %_ptr_Output_v3float Output +// CHECK: [[outTarget2:%[a-zA-Z0-9_]+]] = OpVariable %_ptr_Output_v3float Output +PSInput main( PSInput input ) : SV_Target +{ + PSInput retVal; + retVal.color0 = 0.1; + retVal.color1 += input.color1; + retVal.color1 += GetAttributeAtVertex( input.color1, VertexID::SECOND ); + retVal.color2 = input.color2; + retVal.color2 = GetAttributeAtVertex( input.color2, VertexID::THIRD ); + return retVal; +} + +// CHECK: [[input:%[a-zA-Z0-9_]+]] = OpFunctionParameter [[Ptr_PSInput:%[a-zA-Z0-9_]+]] +// CHECK: [[retVal:%[a-zA-Z0-9_]+]] = OpVariable [[Ptr_PSInput]] Function +// CHECK: [[acInput2:%[0-9]+]] = OpAccessChain %_ptr_Function_v3float [[input]] %int_2 %uint_0 +// CHECK: [[loadInput2:%[0-9]+]] = OpLoad %v3float [[acInput2]] +// CHECK: [[storeRet:%[0-9]+]] = OpAccessChain %_ptr_Function_v3float [[retVal]] %int_2 %uint_0 +// CHECK: OpStore [[storeRet]] [[loadInput2]] \ No newline at end of file diff --git a/tools/clang/test/CodeGenSPIRV_Lit/intrinsics.get-attribute-at-vertex.s.tempStruct.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/intrinsics.get-attribute-at-vertex.s.tempStruct.hlsl new file mode 100644 index 0000000000..ee242e7d18 --- /dev/null +++ b/tools/clang/test/CodeGenSPIRV_Lit/intrinsics.get-attribute-at-vertex.s.tempStruct.hlsl @@ -0,0 +1,49 @@ +// RUN: %dxc -T ps_6_1 -E main -spirv -Od %s 2>&1 | FileCheck %s + +enum VertexID { + FIRST = 0, + SECOND = 1, + THIRD = 2 +}; + + +struct PSInput +{ + float2 m0 : COLOR0; + nointerpolation float3 m1 : COLOR1; + nointerpolation float3 m2 : COLOR2; +}; + +// CHECK: OpCapability FragmentBarycentricKHR +// CHECK: OpExtension "SPV_KHR_fragment_shader_barycentric" +// CHECK: OpDecorate [[color4:%[a-zA-Z0-9_]+]] Location 1 +// CHECK: OpDecorate [[color5:%[a-zA-Z0-9_]+]] Location 2 +// CHECK: OpDecorate [[color4]] PerVertexKHR +// CHECK: OpDecorate [[color5]] PerVertexKHR +// CHECK: [[PSInput:%[a-zA-Z0-9_]+]] = OpTypeStruct %v2float %_arr_v3float_uint_3 %_arr_v3float_uint_3 +// CHECK: [[color4]] = OpVariable %_ptr_Input__arr_v3float_uint_3 Input +// CHECK: [[color5]] = OpVariable %_ptr_Input__arr_v3float_uint_3 Input +// CHECK: [[outTarget1:%[a-zA-Z0-9_]+]] = OpVariable %_ptr_Output_v3float Output +// CHECK: [[outTarget2:%[a-zA-Z0-9_]+]] = OpVariable %_ptr_Output_v3float Output +PSInput main( float2 color0 : COLOR3, + nointerpolation float3 color1 : COLOR4, + nointerpolation float3 color2 : COLOR5) : SV_Target +{ + PSInput retVal; + retVal.m0 = color0; + retVal.m1 += color1; + retVal.m1 += GetAttributeAtVertex( color1, VertexID::SECOND ); + retVal.m2 = color2; + retVal.m2 = GetAttributeAtVertex( color2, VertexID::THIRD ); + return retVal; +} + +// CHECK: [[c1pvt0:%[a-zA-Z0-9_]+]] = OpVariable %_ptr_Function_v3float Function +// CHECK: [[c2pvt0:%[a-zA-Z0-9_]+]] = OpVariable %_ptr_Function_v3float Function +// CHECK: [[c1e0:%[0-9]+]] = OpAccessChain %_ptr_Function_v3float [[funcp1:%[a-zA-Z0-9_]+]] %uint_0 +// CHECK: [[c2e0:%[0-9]+]] = OpAccessChain %_ptr_Function_v3float [[funcp2:%[a-zA-Z0-9_]+]] %uint_0 +// CHECK: [[loadc2e0:%[0-9]+]] = OpLoad %v3float [[c2e0]] +// CHECK: OpStore [[c2pvt0]] [[loadc2e0]] +// CHECK: [[ldc2pvt0:%[0-9]+]] = OpLoad %v3float [[c2pvt0]] +// CHECK: [[acRetVal2:%[0-9]+]] = OpAccessChain %_ptr_Function_v3float [[retVal:%[a-zA-Z0-9_]+]] %int_2 %uint_0 +// CHECK: OpStore [[acRetVal2]] [[ldc2pvt0]] \ No newline at end of file diff --git a/tools/clang/test/CodeGenSPIRV/meshshading.ext.amplification.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/meshshading.ext.amplification.hlsl similarity index 77% rename from tools/clang/test/CodeGenSPIRV/meshshading.ext.amplification.hlsl rename to tools/clang/test/CodeGenSPIRV_Lit/meshshading.ext.amplification.hlsl index 1ca0b7011b..e7061aff41 100644 --- a/tools/clang/test/CodeGenSPIRV/meshshading.ext.amplification.hlsl +++ b/tools/clang/test/CodeGenSPIRV_Lit/meshshading.ext.amplification.hlsl @@ -1,7 +1,7 @@ -// RUN: %dxc -T as_6_5 -fspv-target-env=vulkan1.1spirv1.4 -E main +// RUN: %dxc -T as_6_5 -fspv-target-env=vulkan1.1spirv1.4 -E main -fcgl %s -spirv | FileCheck %s // CHECK: OpCapability MeshShadingEXT // CHECK: OpExtension "SPV_EXT_mesh_shader" -// CHECK: OpEntryPoint TaskEXT %main "main" [[drawid:%\d+]] %gl_LocalInvocationID %gl_WorkGroupID %gl_GlobalInvocationID %gl_LocalInvocationIndex %out_var_dummy %out_var_pos +// CHECK: OpEntryPoint TaskEXT %main "main" [[drawid:%[0-9]+]] %gl_LocalInvocationID %gl_WorkGroupID %gl_GlobalInvocationID %gl_LocalInvocationIndex %out_var_dummy %out_var_pos // CHECK: OpExecutionMode %main LocalSize 128 1 1 // CHECK: OpDecorate [[drawid]] BuiltIn DrawIndex @@ -47,20 +47,20 @@ void main( // CHECK: %tid = OpFunctionParameter %_ptr_Function_uint // CHECK: %tig = OpFunctionParameter %_ptr_Function_uint // -// CHECK: [[a:%\d+]] = OpAccessChain %_ptr_Workgroup_v4float %pld %int_1 -// CHECK: OpStore [[a]] {{%\d+}} +// CHECK: [[a:%[0-9]+]] = OpAccessChain %_ptr_Workgroup_v4float %pld %int_1 +// CHECK: OpStore [[a]] {{%[0-9]+}} pld.pos = float4(gtid.x, gid.y, tid, tig); // CHECK: OpControlBarrier %uint_2 %uint_2 %uint_264 -// CHECK: [[e:%\d+]] = OpLoad %MeshPayload %pld -// CHECK: [[f:%\d+]] = OpCompositeExtract %_arr_float_uint_10 [[e]] 0 +// CHECK: [[e:%[0-9]+]] = OpLoad %MeshPayload %pld +// CHECK: [[f:%[0-9]+]] = OpCompositeExtract %_arr_float_uint_10 [[e]] 0 // CHECK: OpStore %out_var_dummy [[f]] -// CHECK: [[g:%\d+]] = OpCompositeExtract %v4float [[e]] 1 +// CHECK: [[g:%[0-9]+]] = OpCompositeExtract %v4float [[e]] 1 // CHECK: OpStore %out_var_pos [[g]] -// CHECK: [[h:%\d+]] = OpLoad %int %drawId -// CHECK: [[i:%\d+]] = OpBitcast %uint [[h]] -// CHECK: [[j:%\d+]] = OpLoad %int %drawId -// CHECK: [[k:%\d+]] = OpBitcast %uint [[j]] +// CHECK: [[h:%[0-9]+]] = OpLoad %int %drawId +// CHECK: [[i:%[0-9]+]] = OpBitcast %uint [[h]] +// CHECK: [[j:%[0-9]+]] = OpLoad %int %drawId +// CHECK: [[k:%[0-9]+]] = OpBitcast %uint [[j]] // CHECK: OpEmitMeshTasksEXT %uint_128 [[i]] [[k]] DispatchMesh(NUM_THREADS, drawId, drawId, pld); } diff --git a/tools/clang/test/CodeGenSPIRV/meshshading.ext.triangle.mesh.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/meshshading.ext.triangle.mesh.hlsl similarity index 77% rename from tools/clang/test/CodeGenSPIRV/meshshading.ext.triangle.mesh.hlsl rename to tools/clang/test/CodeGenSPIRV_Lit/meshshading.ext.triangle.mesh.hlsl index 3dde06353c..2c0dcee65d 100644 --- a/tools/clang/test/CodeGenSPIRV/meshshading.ext.triangle.mesh.hlsl +++ b/tools/clang/test/CodeGenSPIRV_Lit/meshshading.ext.triangle.mesh.hlsl @@ -1,7 +1,7 @@ -// RUN: %dxc -T ms_6_5 -fspv-target-env=universal1.5 -E main +// RUN: %dxc -T ms_6_5 -fspv-target-env=universal1.5 -E main -fcgl %s -spirv | FileCheck %s // CHECK: OpCapability MeshShadingEXT // CHECK: OpExtension "SPV_EXT_mesh_shader" -// CHECK: OpEntryPoint MeshEXT %main "main" %gl_ClipDistance %gl_CullDistance %in_var_dummy %in_var_pos [[drawid:%\d+]] %gl_LocalInvocationID %gl_WorkGroupID %gl_GlobalInvocationID %gl_LocalInvocationIndex %gl_Position %gl_PointSize %out_var_USER %out_var_USER_ARR %out_var_USER_MAT [[primindices:%\d+]] %gl_PrimitiveID %gl_Layer %gl_ViewportIndex [[cullprim:%\d+]] [[primshadingrate:%\d+]] %out_var_PRIM_USER %out_var_PRIM_USER_ARR +// CHECK: OpEntryPoint MeshEXT %main "main" %gl_ClipDistance %gl_CullDistance %in_var_dummy %in_var_pos [[drawid:%[0-9]+]] %gl_LocalInvocationID %gl_WorkGroupID %gl_GlobalInvocationID %gl_LocalInvocationIndex %gl_Position %gl_PointSize %out_var_USER %out_var_USER_ARR %out_var_USER_MAT [[primindices:%[0-9]+]] %gl_PrimitiveID %gl_Layer %gl_ViewportIndex [[cullprim:%[0-9]+]] [[primshadingrate:%[0-9]+]] %out_var_PRIM_USER %out_var_PRIM_USER_ARR // CHECK: OpExecutionMode %main LocalSize 128 1 1 // CHECK: OpExecutionMode %main OutputTrianglesNV // CHECK: OpExecutionMode %main OutputVertices 64 @@ -113,63 +113,63 @@ void main( // Directly assign to per-vertex attribute object. -// CHECK: OpAccessChain %_ptr_Output_float %gl_Position {{%\d+}} %uint_0 -// CHECK: OpStore {{%\d+}} %float_11 +// CHECK: OpAccessChain %_ptr_Output_float %gl_Position {{%[0-9]+}} %uint_0 +// CHECK: OpStore {{%[0-9]+}} %float_11 verts[tid].position.x = 11.0; -// CHECK: OpAccessChain %_ptr_Output_float %gl_Position {{%\d+}} %uint_1 -// CHECK: OpStore {{%\d+}} {{%\d+}} -// CHECK: OpAccessChain %_ptr_Output_float %gl_Position {{%\d+}} %uint_3 -// CHECK: OpStore {{%\d+}} {{%\d+}} +// CHECK: OpAccessChain %_ptr_Output_float %gl_Position {{%[0-9]+}} %uint_1 +// CHECK: OpStore {{%[0-9]+}} {{%[0-9]+}} +// CHECK: OpAccessChain %_ptr_Output_float %gl_Position {{%[0-9]+}} %uint_3 +// CHECK: OpStore {{%[0-9]+}} {{%[0-9]+}} verts[tid].position.yw = float2(12.0,14.0); -// CHECK: OpAccessChain %_ptr_Output_float %gl_Position {{%\d+}} %uint_2 -// CHECK: OpStore {{%\d+}} %float_13 +// CHECK: OpAccessChain %_ptr_Output_float %gl_Position {{%[0-9]+}} %uint_2 +// CHECK: OpStore {{%[0-9]+}} %float_13 verts[tid].position[2] = 13.0; -// CHECK: OpAccessChain %_ptr_Output_float %gl_PointSize {{%\d+}} -// CHECK: OpStore {{%\d+}} %float_50 +// CHECK: OpAccessChain %_ptr_Output_float %gl_PointSize {{%[0-9]+}} +// CHECK: OpStore {{%[0-9]+}} %float_50 verts[tid].psize = 50.0; // CHECK: OpIAdd %uint %uint_1 %uint_2 -// CHECK: OpAccessChain %_ptr_Output_float %gl_ClipDistance {{%\d+}} {{%\d+}} -// CHECK: OpStore {{%\d+}} {{%\d+}} +// CHECK: OpAccessChain %_ptr_Output_float %gl_ClipDistance {{%[0-9]+}} {{%[0-9]+}} +// CHECK: OpStore {{%[0-9]+}} {{%[0-9]+}} // CHECK: OpIAdd %uint %uint_0 %uint_2 -// CHECK: OpAccessChain %_ptr_Output_float %gl_ClipDistance {{%\d+}} {{%\d+}} -// CHECK: OpStore {{%\d+}} {{%\d+}} +// CHECK: OpAccessChain %_ptr_Output_float %gl_ClipDistance {{%[0-9]+}} {{%[0-9]+}} +// CHECK: OpStore {{%[0-9]+}} {{%[0-9]+}} // CHECK: OpIAdd %uint %uint_2 %uint_2 -// CHECK: OpAccessChain %_ptr_Output_float %gl_ClipDistance {{%\d+}} {{%\d+}} -// CHECK: OpStore {{%\d+}} {{%\d+}} +// CHECK: OpAccessChain %_ptr_Output_float %gl_ClipDistance {{%[0-9]+}} {{%[0-9]+}} +// CHECK: OpStore {{%[0-9]+}} {{%[0-9]+}} verts[tid].clipdis4.yxz = float3(0.0,1.0,2.0); // CHECK: OpIAdd %uint %uint_0 %uint_2 -// CHECK: OpAccessChain %_ptr_Output_float %gl_ClipDistance {{%\d+}} {{%\d+}} -// CHECK: OpStore {{%\d+}} %float_10 +// CHECK: OpAccessChain %_ptr_Output_float %gl_ClipDistance {{%[0-9]+}} {{%[0-9]+}} +// CHECK: OpStore {{%[0-9]+}} %float_10 verts[tid].clipdis4[0] = 10.0; -// CHECK: OpAccessChain %_ptr_Output_float %gl_CullDistance {{%\d+}} %uint_0 -// CHECK: OpStore {{%\d+}} %float_5 +// CHECK: OpAccessChain %_ptr_Output_float %gl_CullDistance {{%[0-9]+}} %uint_0 +// CHECK: OpStore {{%[0-9]+}} %float_5 verts[tid].culldis5 = 5.0; // CHECK: OpIAdd %uint %uint_0 %uint_0 -// CHECK: OpAccessChain %_ptr_Output_float %gl_ClipDistance {{%\d+}} {{%\d+}} -// CHECK: OpStore {{%\d+}} {{%\d+}} +// CHECK: OpAccessChain %_ptr_Output_float %gl_ClipDistance {{%[0-9]+}} {{%[0-9]+}} +// CHECK: OpStore {{%[0-9]+}} {{%[0-9]+}} // CHECK: OpIAdd %uint %uint_0 %uint_1 -// CHECK: OpAccessChain %_ptr_Output_float %gl_ClipDistance {{%\d+}} {{%\d+}} -// CHECK: OpStore {{%\d+}} {{%\d+}} +// CHECK: OpAccessChain %_ptr_Output_float %gl_ClipDistance {{%[0-9]+}} {{%[0-9]+}} +// CHECK: OpStore {{%[0-9]+}} {{%[0-9]+}} verts[tid].clipdis3 = float2(11.0,12.0); // CHECK: OpIAdd %uint %uint_0 %uint_1 -// CHECK: OpAccessChain %_ptr_Output_float %gl_CullDistance {{%\d+}} {{%\d+}} -// CHECK: OpStore {{%\d+}} %float_13 +// CHECK: OpAccessChain %_ptr_Output_float %gl_CullDistance {{%[0-9]+}} {{%[0-9]+}} +// CHECK: OpStore {{%[0-9]+}} %float_13 verts[tid].culldis6[0] = 13.0; // CHECK: OpIAdd %uint %uint_1 %uint_1 -// CHECK: OpAccessChain %_ptr_Output_float %gl_CullDistance {{%\d+}} {{%\d+}} -// CHECK: OpStore {{%\d+}} %float_14 +// CHECK: OpAccessChain %_ptr_Output_float %gl_CullDistance {{%[0-9]+}} {{%[0-9]+}} +// CHECK: OpStore {{%[0-9]+}} %float_14 verts[tid].culldis6.y = 14.0; -// CHECK: OpAccessChain %_ptr_Output_v2float %out_var_USER {{%\d+}} -// CHECK: OpStore {{%\d+}} {{%\d+}} +// CHECK: OpAccessChain %_ptr_Output_v2float %out_var_USER {{%[0-9]+}} +// CHECK: OpStore {{%[0-9]+}} {{%[0-9]+}} verts[tid].userVertAttr = float2(9.0, 10.0); -// CHECK: OpAccessChain %_ptr_Output_v4float %out_var_USER_ARR {{%\d+}} %int_0 -// CHECK: OpStore {{%\d+}} {{%\d+}} +// CHECK: OpAccessChain %_ptr_Output_v4float %out_var_USER_ARR {{%[0-9]+}} %int_0 +// CHECK: OpStore {{%[0-9]+}} {{%[0-9]+}} verts[tid].userVertAttrArr[0] = float4(17.0, 18.0, 19.0, 20.0); -// CHECK: OpAccessChain %_ptr_Output_v4float %out_var_USER_ARR {{%\d+}} %int_1 -// CHECK: OpStore {{%\d+}} {{%\d+}} +// CHECK: OpAccessChain %_ptr_Output_v4float %out_var_USER_ARR {{%[0-9]+}} %int_1 +// CHECK: OpStore {{%[0-9]+}} {{%[0-9]+}} verts[tid].userVertAttrArr[1] = float4(27.0, 28.0, 29.0, 30.0); -// CHECK: OpAccessChain %_ptr_Output_v4float %out_var_USER_MAT {{%\d+}} %uint_3 -// CHECK: OpStore {{%\d+}} {{%\d+}} +// CHECK: OpAccessChain %_ptr_Output_v4float %out_var_USER_MAT {{%[0-9]+}} %uint_3 +// CHECK: OpStore {{%[0-9]+}} {{%[0-9]+}} verts[tid].userVertAttrMat[3] = float4(7.0, 8.0, 9.0, 10.0); // Indirectly assign to per-vertex attribute object. @@ -190,30 +190,30 @@ void main( // Directly assign to per-vertex attribute object. -// CHECK: OpAccessChain %_ptr_Output_int %gl_PrimitiveID {{%\d+}} -// CHECK: OpStore {{%\d+}} %int_10 +// CHECK: OpAccessChain %_ptr_Output_int %gl_PrimitiveID {{%[0-9]+}} +// CHECK: OpStore {{%[0-9]+}} %int_10 prims[tig].primId = 10; -// CHECK: OpAccessChain %_ptr_Output_int %gl_Layer {{%\d+}} -// CHECK: OpStore {{%\d+}} %int_11 +// CHECK: OpAccessChain %_ptr_Output_int %gl_Layer {{%[0-9]+}} +// CHECK: OpStore {{%[0-9]+}} %int_11 prims[tig].layer = 11; -// CHECK: OpAccessChain %_ptr_Output_int %gl_ViewportIndex {{%\d+}} -// CHECK: OpStore {{%\d+}} %int_12 +// CHECK: OpAccessChain %_ptr_Output_int %gl_ViewportIndex {{%[0-9]+}} +// CHECK: OpStore {{%[0-9]+}} %int_12 prims[tig].vpIdx = 12; -// CHECK: OpAccessChain %_ptr_Output_int [[cullprim]] {{%\d+}} -// CHECK: OpStore {{%\d+}} %int_13 +// CHECK: OpAccessChain %_ptr_Output_int [[cullprim]] {{%[0-9]+}} +// CHECK: OpStore {{%[0-9]+}} %int_13 prims[tig].cullPrim = 13; -// CHECK: OpAccessChain %_ptr_Output_uint [[primshadingrate]] {{%\d+}} -// CHECK: OpStore {{%\d+}} %uint_14 +// CHECK: OpAccessChain %_ptr_Output_uint [[primshadingrate]] {{%[0-9]+}} +// CHECK: OpStore {{%[0-9]+}} %uint_14 prims[tig].shadingRate = 14; -// CHECK: OpAccessChain %_ptr_Output_v4float %out_var_PRIM_USER_ARR {{%\d+}} %int_0 -// CHECK: OpStore {{%\d+}} {{%\d+}} +// CHECK: OpAccessChain %_ptr_Output_v4float %out_var_PRIM_USER_ARR {{%[0-9]+}} %int_0 +// CHECK: OpStore {{%[0-9]+}} {{%[0-9]+}} prims[tig].userPrimAttrArr[0] = float4(4.0,5.0,6.0,7.0); -// CHECK: OpAccessChain %_ptr_Output_v4float %out_var_PRIM_USER_ARR {{%\d+}} %int_1 -// CHECK: OpStore {{%\d+}} {{%\d+}} +// CHECK: OpAccessChain %_ptr_Output_v4float %out_var_PRIM_USER_ARR {{%[0-9]+}} %int_1 +// CHECK: OpStore {{%[0-9]+}} {{%[0-9]+}} prims[tig].userPrimAttrArr[1] = float4(8.0,9.0,10.0,11.0); -// CHECK: OpAccessChain %_ptr_Output_v3float %out_var_PRIM_USER {{%\d+}} -// CHECK: OpStore {{%\d+}} {{%\d+}} +// CHECK: OpAccessChain %_ptr_Output_v3float %out_var_PRIM_USER {{%[0-9]+}} +// CHECK: OpStore {{%[0-9]+}} {{%[0-9]+}} prims[tig].userPrimAttr = float3(14.0,15.0,16.0); // Indirectly assign to per-vertex attribute object. @@ -231,23 +231,23 @@ void main( // Assign primitive indices. // CHECK: OpAccessChain %_ptr_Output_uint [[primindices]] %int_4 %uint_0 -// CHECK: OpStore {{%\d+}} %uint_1 +// CHECK: OpStore {{%[0-9]+}} %uint_1 primitiveInd[4].x = 1; -// CHECK: OpCompositeExtract %uint {{%\d+}} 0 +// CHECK: OpCompositeExtract %uint {{%[0-9]+}} 0 // CHECK: OpAccessChain %_ptr_Output_uint [[primindices]] %int_4 %uint_1 -// CHECK: OpStore {{%\d+}} {{%\d+}} -// CHECK: OpCompositeExtract %uint {{%\d+}} 1 +// CHECK: OpStore {{%[0-9]+}} {{%[0-9]+}} +// CHECK: OpCompositeExtract %uint {{%[0-9]+}} 1 // CHECK: OpAccessChain %_ptr_Output_uint [[primindices]] %int_4 %uint_2 -// CHECK: OpStore {{%\d+}} {{%\d+}} +// CHECK: OpStore {{%[0-9]+}} {{%[0-9]+}} primitiveInd[4].yz = uint2(2,3); // CHECK: OpAccessChain %_ptr_Output_uint [[primindices]] %int_2 %uint_1 -// CHECK: OpStore {{%\d+}} %uint_2 +// CHECK: OpStore {{%[0-9]+}} %uint_2 primitiveInd[2].y = 2; // CHECK: OpAccessChain %_ptr_Output_uint [[primindices]] %int_2 %uint_2 -// CHECK: OpStore {{%\d+}} %uint_1 +// CHECK: OpStore {{%[0-9]+}} %uint_1 primitiveInd[2][2] = 1; // CHECK: OpLoad %uint %tid -// CHECK: OpAccessChain %_ptr_Output_v3uint [[primindices]] {{%\d+}} -// CHECK: OpStore {{%\d+}} {{%\d+}} +// CHECK: OpAccessChain %_ptr_Output_v3uint [[primindices]] {{%[0-9]+}} +// CHECK: OpStore {{%[0-9]+}} {{%[0-9]+}} primitiveInd[tid] = uint3(11,12,13); } diff --git a/tools/clang/test/CodeGenSPIRV/meshshading.nv.amplification.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/meshshading.nv.amplification.hlsl similarity index 74% rename from tools/clang/test/CodeGenSPIRV/meshshading.nv.amplification.hlsl rename to tools/clang/test/CodeGenSPIRV_Lit/meshshading.nv.amplification.hlsl index 4f411d6cbb..a2cb37f052 100644 --- a/tools/clang/test/CodeGenSPIRV/meshshading.nv.amplification.hlsl +++ b/tools/clang/test/CodeGenSPIRV_Lit/meshshading.nv.amplification.hlsl @@ -1,7 +1,7 @@ -// RUN: %dxc -T as_6_5 -E main +// RUN: %dxc -T as_6_5 -E main -fcgl %s -spirv | FileCheck %s // CHECK: OpCapability MeshShadingNV // CHECK: OpExtension "SPV_NV_mesh_shader" -// CHECK: OpEntryPoint TaskNV %main "main" [[drawid:%\d+]] %gl_LocalInvocationID %gl_WorkGroupID %gl_GlobalInvocationID %gl_LocalInvocationIndex %out_var_dummy %out_var_pos [[taskcount:%\d+]] +// CHECK: OpEntryPoint TaskNV %main "main" [[drawid:%[0-9]+]] %gl_LocalInvocationID %gl_WorkGroupID %gl_GlobalInvocationID %gl_LocalInvocationIndex %out_var_dummy %out_var_pos [[taskcount:%[0-9]+]] // CHECK: OpExecutionMode %main LocalSize 128 1 1 // CHECK: OpDecorate [[drawid]] BuiltIn DrawIndex @@ -52,22 +52,22 @@ void main( // CHECK: %tid = OpFunctionParameter %_ptr_Function_uint // CHECK: %tig = OpFunctionParameter %_ptr_Function_uint -// CHECK: [[b:%\d+]] = OpAccessChain %_ptr_Workgroup_v4float %pld %int_1 -// CHECK: OpStore [[b]] {{%\d+}} +// CHECK: [[b:%[0-9]+]] = OpAccessChain %_ptr_Workgroup_v4float %pld %int_1 +// CHECK: OpStore [[b]] {{%[0-9]+}} pld.pos = float4(gtid.x, gid.y, tid, tig); // CHECK: OpControlBarrier %uint_2 %uint_2 %uint_264 -// CHECK: [[c:%\d+]] = OpLoad %MeshPayload %pld -// CHECK: [[d:%\d+]] = OpCompositeExtract %_arr_float_uint_10 [[c]] 0 +// CHECK: [[c:%[0-9]+]] = OpLoad %MeshPayload %pld +// CHECK: [[d:%[0-9]+]] = OpCompositeExtract %_arr_float_uint_10 [[c]] 0 // CHECK: OpStore %out_var_dummy [[d]] -// CHECK: [[e:%\d+]] = OpCompositeExtract %v4float [[c]] 1 +// CHECK: [[e:%[0-9]+]] = OpCompositeExtract %v4float [[c]] 1 // CHECK: OpStore %out_var_pos [[e]] -// CHECK: [[f:%\d+]] = OpLoad %int %drawId -// CHECK: [[g:%\d+]] = OpBitcast %uint [[f]] -// CHECK: [[h:%\d+]] = OpLoad %int %drawId -// CHECK: [[i:%\d+]] = OpBitcast %uint [[h]] -// CHECK: [[j:%\d+]] = OpIMul %uint [[g]] [[i]] -// CHECK: [[k:%\d+]] = OpIMul %uint %uint_128 [[j]] +// CHECK: [[f:%[0-9]+]] = OpLoad %int %drawId +// CHECK: [[g:%[0-9]+]] = OpBitcast %uint [[f]] +// CHECK: [[h:%[0-9]+]] = OpLoad %int %drawId +// CHECK: [[i:%[0-9]+]] = OpBitcast %uint [[h]] +// CHECK: [[j:%[0-9]+]] = OpIMul %uint [[g]] [[i]] +// CHECK: [[k:%[0-9]+]] = OpIMul %uint %uint_128 [[j]] // CHECK: OpStore [[taskcount]] [[k]] DispatchMesh(NUM_THREADS, drawId, drawId, pld); } diff --git a/tools/clang/test/CodeGenSPIRV/meshshading.nv.buffer.mesh.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/meshshading.nv.buffer.mesh.hlsl similarity index 96% rename from tools/clang/test/CodeGenSPIRV/meshshading.nv.buffer.mesh.hlsl rename to tools/clang/test/CodeGenSPIRV_Lit/meshshading.nv.buffer.mesh.hlsl index a55844ec4b..4ba254c474 100644 --- a/tools/clang/test/CodeGenSPIRV/meshshading.nv.buffer.mesh.hlsl +++ b/tools/clang/test/CodeGenSPIRV_Lit/meshshading.nv.buffer.mesh.hlsl @@ -1,4 +1,4 @@ -// RUN: %dxc -T ms_6_5 -E main +// RUN: %dxc -T ms_6_5 -E main -fcgl %s -spirv | FileCheck %s // CHECK: OpCapability MeshShadingNV // CHECK: OpExtension "SPV_NV_mesh_shader" @@ -155,8 +155,8 @@ void main( { uint task = taskmem.submeshID[gid]; // CHECK: %submesh = OpVariable %_ptr_Function_SubMesh_0 Function -// CHECK: OpAccessChain %_ptr_Uniform_SubMesh %submeshes %int_0 [[task:%\d+]] -// CHECK: OpStore %submesh [[submeshVal:%\d+]] +// CHECK: OpAccessChain %_ptr_Uniform_SubMesh %submeshes %int_0 [[task:%[0-9]+]] +// CHECK: OpStore %submesh [[submeshVal:%[0-9]+]] SubMesh submesh = submeshes[task]; // CHECK: OpAccessChain %_ptr_Function_uint %submesh %int_0 uint numPackedVertices = submesh.vertexCount; @@ -170,11 +170,11 @@ void main( // CHECK: OpAccessChain %_ptr_Function_uint %submesh %int_1 uint svid = vid + submesh.vertexOffset; if (vid >= numPackedVertices) continue; -// CHECK: OpAccessChain %_ptr_Uniform_v2float %userVertices %int_0 [[svid_1:%\d+]] %int_1 +// CHECK: OpAccessChain %_ptr_Uniform_v2float %userVertices %int_0 [[svid_1:%[0-9]+]] %int_1 verts[vid].texcoord = userVertices[svid].texcoord; -// CHECK: OpAccessChain %_ptr_Uniform_v3float %userVertices %int_0 [[svid_2:%\d+]] %int_2 +// CHECK: OpAccessChain %_ptr_Uniform_v3float %userVertices %int_0 [[svid_2:%[0-9]+]] %int_2 verts[vid].color = userVertices[svid].color; -// CHECK: OpAccessChain %_ptr_Uniform_v3float %userVertices %int_0 [[svid_0:%\d+]] %int_0 +// CHECK: OpAccessChain %_ptr_Uniform_v3float %userVertices %int_0 [[svid_0:%[0-9]+]] %int_0 float3 position = userVertices[svid].position; // CHECK: OpAccessChain %_ptr_Uniform_mat4v4float %UBO %int_0 verts[vid].position = mul(mvp, float4(position, 1.0)); @@ -188,14 +188,14 @@ void main( // CHECK: OpAccessChain %_ptr_Function_uint %submesh %int_3 uint sidxoff = submesh.indexOffset + didxoff; if (pid >= numPackedPrimitives) continue; -// CHECK: OpAccessChain %_ptr_Uniform_uint %userIndices %int_0 [[sidxoff_0:%\d+]] -// CHECK: OpAccessChain %_ptr_Uniform_uint %userIndices %int_0 [[sidxoff_1:%\d+]] -// CHECK: OpAccessChain %_ptr_Uniform_uint %userIndices %int_0 [[sidxoff_2:%\d+]] +// CHECK: OpAccessChain %_ptr_Uniform_uint %userIndices %int_0 [[sidxoff_0:%[0-9]+]] +// CHECK: OpAccessChain %_ptr_Uniform_uint %userIndices %int_0 [[sidxoff_1:%[0-9]+]] +// CHECK: OpAccessChain %_ptr_Uniform_uint %userIndices %int_0 [[sidxoff_2:%[0-9]+]] primIndices[pid] = uint3(userIndices[sidxoff], userIndices[sidxoff+1], userIndices[sidxoff+2]); // CHECK: OpAccessChain %_ptr_Function_uint %submesh %int_1 -// CHECK: OpAccessChain %_ptr_Uniform_uint %userIndices %int_0 [[ind:%\d+]] +// CHECK: OpAccessChain %_ptr_Uniform_uint %userIndices %int_0 [[ind:%[0-9]+]] uint providx = submesh.vertexOffset + userIndices[sidxoff + vertsPerPrim - 1U]; -// CHECK: OpAccessChain %_ptr_Uniform_v3float %userVertices %int_0 [[providx:%\d+]] %int_2 +// CHECK: OpAccessChain %_ptr_Uniform_v3float %userVertices %int_0 [[providx:%[0-9]+]] %int_2 prims[pid].primcolor = float4(userVertices[providx].color, 1.0); } } diff --git a/tools/clang/test/CodeGenSPIRV/meshshading.nv.fncall.amplification.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/meshshading.nv.fncall.amplification.hlsl similarity index 88% rename from tools/clang/test/CodeGenSPIRV/meshshading.nv.fncall.amplification.hlsl rename to tools/clang/test/CodeGenSPIRV_Lit/meshshading.nv.fncall.amplification.hlsl index 8f69e7dec9..660bf2a3b3 100644 --- a/tools/clang/test/CodeGenSPIRV/meshshading.nv.fncall.amplification.hlsl +++ b/tools/clang/test/CodeGenSPIRV_Lit/meshshading.nv.fncall.amplification.hlsl @@ -1,4 +1,4 @@ -// RUN: %dxc -T as_6_5 -E main -fspv-target-env=vulkan1.1 +// RUN: %dxc -T as_6_5 -E main -fspv-target-env=vulkan1.1 -fcgl %s -spirv | FileCheck %s // CHECK: OpCapability MeshShadingNV // CHECK: OpExtension "SPV_NV_mesh_shader" @@ -50,7 +50,7 @@ groupshared SubMeshes sharedSubMeshes; // CHECK: %_arr_v4float_uint_8_0 = OpTypeArray %v4float %uint_8 // CHECK: %SubMesh_0 = OpTypeStruct %uint %uint %uint %uint %_arr_v4float_uint_8_0 // CHECK: %_ptr_Function_SubMesh_0 = OpTypePointer Function %SubMesh_0 -// CHECK: [[funcType:%\d+]] = OpTypeFunction %bool %_ptr_Function_SubMesh_0 +// CHECK: [[funcType:%[0-9]+]] = OpTypeFunction %bool %_ptr_Function_SubMesh_0 bool TestSubmesh(SubMesh submesh) { uint clip = 0x0U; @@ -87,10 +87,10 @@ void main( SubMesh submesh = submeshes[smid]; bool passed = true; -// CHECK: [[submeshValue:%\d+]] = OpLoad %SubMesh_0 %submesh +// CHECK: [[submeshValue:%[0-9]+]] = OpLoad %SubMesh_0 %submesh // CHECK: OpStore %param_var_submesh [[submeshValue]] -// CHECK: [[rv:%\d+]] = OpFunctionCall %bool %TestSubmesh %param_var_submesh -// CHECK: [[cond:%\d+]] = OpLogicalNot %bool [[rv]] +// CHECK: [[rv:%[0-9]+]] = OpFunctionCall %bool %TestSubmesh %param_var_submesh +// CHECK: [[cond:%[0-9]+]] = OpLogicalNot %bool [[rv]] // CHECK: OpSelectionMerge %if_merge_0 None // CHECK: OpBranchConditional [[cond]] %if_true_0 %if_merge_0 // CHECK: %if_true_0 = OpLabel @@ -129,7 +129,7 @@ void main( // CHECK: %for_body_0 = OpLabel // CHECK: %for_merge_0 = OpLabel -// CHECK: [[clipValue:%\d+]] = OpLoad %uint %clip -// CHECK: [[retValue:%\d+]] = OpIEqual %bool [[clipValue]] %uint_63 +// CHECK: [[clipValue:%[0-9]+]] = OpLoad %uint %clip +// CHECK: [[retValue:%[0-9]+]] = OpIEqual %bool [[clipValue]] %uint_63 // CHECK: OpReturnValue [[retValue]] // CHECK: OpFunctionEnd diff --git a/tools/clang/test/CodeGenSPIRV/meshshading.nv.line.mesh.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/meshshading.nv.line.mesh.hlsl similarity index 71% rename from tools/clang/test/CodeGenSPIRV/meshshading.nv.line.mesh.hlsl rename to tools/clang/test/CodeGenSPIRV_Lit/meshshading.nv.line.mesh.hlsl index ad880139ab..75f74947de 100644 --- a/tools/clang/test/CodeGenSPIRV/meshshading.nv.line.mesh.hlsl +++ b/tools/clang/test/CodeGenSPIRV_Lit/meshshading.nv.line.mesh.hlsl @@ -1,7 +1,7 @@ -// RUN: %dxc -T ms_6_5 -E main +// RUN: %dxc -T ms_6_5 -E main -fcgl %s -spirv | FileCheck %s // CHECK: OpCapability MeshShadingNV // CHECK: OpExtension "SPV_NV_mesh_shader" -// CHECK: OpEntryPoint MeshNV %main "main" %gl_GlobalInvocationID %gl_Position [[primind:%\d+]] [[primcount:%\d+]] +// CHECK: OpEntryPoint MeshNV %main "main" %gl_GlobalInvocationID %gl_Position [[primind:%[0-9]+]] [[primcount:%[0-9]+]] // CHECK: OpExecutionMode %main LocalSize 128 1 1 // CHECK: OpExecutionMode %main OutputLinesNV // CHECK: OpExecutionMode %main OutputVertices 256 @@ -36,17 +36,17 @@ void main(out vertices MeshPerVertex verts[MAX_VERT], SetMeshOutputCounts(MAX_VERT, MAX_PRIM); // CHECK: OpLoad %uint %tid -// CHECK: OpAccessChain %_ptr_Output_v4float %gl_Position {{%\d+}} -// CHECK: OpStore {{%\d+}} {{%\d+}} +// CHECK: OpAccessChain %_ptr_Output_v4float %gl_Position {{%[0-9]+}} +// CHECK: OpStore {{%[0-9]+}} {{%[0-9]+}} verts[tid].position = float4(4.0,5.0,6.0,7.0); // CHECK: OpIMul %uint %uint_6 %uint_2 -// CHECK: OpAccessChain %_ptr_Output_uint [[primind]] {{%\d+}} -// CHECK: OpCompositeExtract %uint {{%\d+}} 0 -// CHECK: OpStore {{%\d+}} {{%\d+}} -// CHECK: OpIAdd %uint {{%\d+}} %uint_1 -// CHECK: OpAccessChain %_ptr_Output_uint [[primind]] {{%\d+}} -// CHECK: OpCompositeExtract %uint {{%\d+}} 1 -// CHECK: OpStore {{%\d+}} {{%\d+}} +// CHECK: OpAccessChain %_ptr_Output_uint [[primind]] {{%[0-9]+}} +// CHECK: OpCompositeExtract %uint {{%[0-9]+}} 0 +// CHECK: OpStore {{%[0-9]+}} {{%[0-9]+}} +// CHECK: OpIAdd %uint {{%[0-9]+}} %uint_1 +// CHECK: OpAccessChain %_ptr_Output_uint [[primind]] {{%[0-9]+}} +// CHECK: OpCompositeExtract %uint {{%[0-9]+}} 1 +// CHECK: OpStore {{%[0-9]+}} {{%[0-9]+}} primitiveInd[6] = uint2(1,2); } diff --git a/tools/clang/test/CodeGenSPIRV/meshshading.nv.point.mesh.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/meshshading.nv.point.mesh.hlsl similarity index 84% rename from tools/clang/test/CodeGenSPIRV/meshshading.nv.point.mesh.hlsl rename to tools/clang/test/CodeGenSPIRV_Lit/meshshading.nv.point.mesh.hlsl index ed2d6d42b0..b17f6c3ca8 100644 --- a/tools/clang/test/CodeGenSPIRV/meshshading.nv.point.mesh.hlsl +++ b/tools/clang/test/CodeGenSPIRV_Lit/meshshading.nv.point.mesh.hlsl @@ -1,7 +1,7 @@ -// RUN: %dxc -T ms_6_5 -E main +// RUN: %dxc -T ms_6_5 -E main -fcgl %s -spirv | FileCheck %s // CHECK: OpCapability MeshShadingNV // CHECK: OpExtension "SPV_NV_mesh_shader" -// CHECK: OpEntryPoint MeshNV %main "main" %gl_GlobalInvocationID %gl_Position [[primind:%\d+]] [[primcount:%\d+]] +// CHECK: OpEntryPoint MeshNV %main "main" %gl_GlobalInvocationID %gl_Position [[primind:%[0-9]+]] [[primcount:%[0-9]+]] // CHECK: OpExecutionMode %main LocalSize 128 1 1 // CHECK: OpExecutionMode %main OutputPoints // CHECK: OpExecutionMode %main OutputVertices 256 @@ -36,12 +36,12 @@ void main(out vertices MeshPerVertex verts[MAX_VERT], SetMeshOutputCounts(MAX_VERT, MAX_PRIM); // CHECK: OpLoad %uint %tid -// CHECK: OpAccessChain %_ptr_Output_v4float %gl_Position {{%\d+}} -// CHECK: OpStore {{%\d+}} {{%\d+}} +// CHECK: OpAccessChain %_ptr_Output_v4float %gl_Position {{%[0-9]+}} +// CHECK: OpStore {{%[0-9]+}} {{%[0-9]+}} verts[tid].position = float4(4.0,5.0,6.0,7.0); // CHECK: OpAccessChain %_ptr_Output_uint [[primind]] %int_6 -// CHECK: OpStore {{%\d+}} %uint_2 +// CHECK: OpStore {{%[0-9]+}} %uint_2 primitiveInd[6] = 2; } diff --git a/tools/clang/test/CodeGenSPIRV/meshshading.nv.triangle.mesh.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/meshshading.nv.triangle.mesh.hlsl similarity index 71% rename from tools/clang/test/CodeGenSPIRV/meshshading.nv.triangle.mesh.hlsl rename to tools/clang/test/CodeGenSPIRV_Lit/meshshading.nv.triangle.mesh.hlsl index 5e65d22a4a..50b0dd7e82 100644 --- a/tools/clang/test/CodeGenSPIRV/meshshading.nv.triangle.mesh.hlsl +++ b/tools/clang/test/CodeGenSPIRV_Lit/meshshading.nv.triangle.mesh.hlsl @@ -1,7 +1,7 @@ -// RUN: %dxc -T ms_6_5 -E main +// RUN: %dxc -T ms_6_5 -E main -fcgl %s -spirv | FileCheck %s // CHECK: OpCapability MeshShadingNV // CHECK: OpExtension "SPV_NV_mesh_shader" -// CHECK: OpEntryPoint MeshNV %main "main" %gl_ClipDistance %gl_CullDistance %in_var_dummy %in_var_pos [[drawid:%\d+]] %gl_LocalInvocationID %gl_WorkGroupID %gl_GlobalInvocationID %gl_LocalInvocationIndex %gl_Position %gl_PointSize %out_var_USER %out_var_USER_ARR %out_var_USER_MAT [[primind:%\d+]] %gl_PrimitiveID %gl_Layer %gl_ViewportIndex [[vmask:%\d+]] %out_var_PRIM_USER %out_var_PRIM_USER_ARR [[primcount:%\d+]] +// CHECK: OpEntryPoint MeshNV %main "main" %gl_ClipDistance %gl_CullDistance %in_var_dummy %in_var_pos [[drawid:%[0-9]+]] %gl_LocalInvocationID %gl_WorkGroupID %gl_GlobalInvocationID %gl_LocalInvocationIndex %gl_Position %gl_PointSize %out_var_USER %out_var_USER_ARR %out_var_USER_MAT [[primind:%[0-9]+]] %gl_PrimitiveID %gl_Layer %gl_ViewportIndex [[vmask:%[0-9]+]] %out_var_PRIM_USER %out_var_PRIM_USER_ARR [[primcount:%[0-9]+]] // CHECK: OpExecutionMode %main LocalSize 128 1 1 // CHECK: OpExecutionMode %main OutputTrianglesNV // CHECK: OpExecutionMode %main OutputVertices 64 @@ -115,63 +115,63 @@ void main( // Directly assign to per-vertex attribute object. -// CHECK: OpAccessChain %_ptr_Output_float %gl_Position {{%\d+}} %uint_0 -// CHECK: OpStore {{%\d+}} %float_11 +// CHECK: OpAccessChain %_ptr_Output_float %gl_Position {{%[0-9]+}} %uint_0 +// CHECK: OpStore {{%[0-9]+}} %float_11 verts[tid].position.x = 11.0; -// CHECK: OpAccessChain %_ptr_Output_float %gl_Position {{%\d+}} %uint_1 -// CHECK: OpStore {{%\d+}} {{%\d+}} -// CHECK: OpAccessChain %_ptr_Output_float %gl_Position {{%\d+}} %uint_3 -// CHECK: OpStore {{%\d+}} {{%\d+}} +// CHECK: OpAccessChain %_ptr_Output_float %gl_Position {{%[0-9]+}} %uint_1 +// CHECK: OpStore {{%[0-9]+}} {{%[0-9]+}} +// CHECK: OpAccessChain %_ptr_Output_float %gl_Position {{%[0-9]+}} %uint_3 +// CHECK: OpStore {{%[0-9]+}} {{%[0-9]+}} verts[tid].position.yw = float2(12.0,14.0); -// CHECK: OpAccessChain %_ptr_Output_float %gl_Position {{%\d+}} %uint_2 -// CHECK: OpStore {{%\d+}} %float_13 +// CHECK: OpAccessChain %_ptr_Output_float %gl_Position {{%[0-9]+}} %uint_2 +// CHECK: OpStore {{%[0-9]+}} %float_13 verts[tid].position[2] = 13.0; -// CHECK: OpAccessChain %_ptr_Output_float %gl_PointSize {{%\d+}} -// CHECK: OpStore {{%\d+}} %float_50 +// CHECK: OpAccessChain %_ptr_Output_float %gl_PointSize {{%[0-9]+}} +// CHECK: OpStore {{%[0-9]+}} %float_50 verts[tid].psize = 50.0; // CHECK: OpIAdd %uint %uint_1 %uint_2 -// CHECK: OpAccessChain %_ptr_Output_float %gl_ClipDistance {{%\d+}} {{%\d+}} -// CHECK: OpStore {{%\d+}} {{%\d+}} +// CHECK: OpAccessChain %_ptr_Output_float %gl_ClipDistance {{%[0-9]+}} {{%[0-9]+}} +// CHECK: OpStore {{%[0-9]+}} {{%[0-9]+}} // CHECK: OpIAdd %uint %uint_0 %uint_2 -// CHECK: OpAccessChain %_ptr_Output_float %gl_ClipDistance {{%\d+}} {{%\d+}} -// CHECK: OpStore {{%\d+}} {{%\d+}} +// CHECK: OpAccessChain %_ptr_Output_float %gl_ClipDistance {{%[0-9]+}} {{%[0-9]+}} +// CHECK: OpStore {{%[0-9]+}} {{%[0-9]+}} // CHECK: OpIAdd %uint %uint_2 %uint_2 -// CHECK: OpAccessChain %_ptr_Output_float %gl_ClipDistance {{%\d+}} {{%\d+}} -// CHECK: OpStore {{%\d+}} {{%\d+}} +// CHECK: OpAccessChain %_ptr_Output_float %gl_ClipDistance {{%[0-9]+}} {{%[0-9]+}} +// CHECK: OpStore {{%[0-9]+}} {{%[0-9]+}} verts[tid].clipdis4.yxz = float3(0.0,1.0,2.0); // CHECK: OpIAdd %uint %uint_0 %uint_2 -// CHECK: OpAccessChain %_ptr_Output_float %gl_ClipDistance {{%\d+}} {{%\d+}} -// CHECK: OpStore {{%\d+}} %float_10 +// CHECK: OpAccessChain %_ptr_Output_float %gl_ClipDistance {{%[0-9]+}} {{%[0-9]+}} +// CHECK: OpStore {{%[0-9]+}} %float_10 verts[tid].clipdis4[0] = 10.0; -// CHECK: OpAccessChain %_ptr_Output_float %gl_CullDistance {{%\d+}} %uint_0 -// CHECK: OpStore {{%\d+}} %float_5 +// CHECK: OpAccessChain %_ptr_Output_float %gl_CullDistance {{%[0-9]+}} %uint_0 +// CHECK: OpStore {{%[0-9]+}} %float_5 verts[tid].culldis5 = 5.0; // CHECK: OpIAdd %uint %uint_0 %uint_0 -// CHECK: OpAccessChain %_ptr_Output_float %gl_ClipDistance {{%\d+}} {{%\d+}} -// CHECK: OpStore {{%\d+}} {{%\d+}} +// CHECK: OpAccessChain %_ptr_Output_float %gl_ClipDistance {{%[0-9]+}} {{%[0-9]+}} +// CHECK: OpStore {{%[0-9]+}} {{%[0-9]+}} // CHECK: OpIAdd %uint %uint_0 %uint_1 -// CHECK: OpAccessChain %_ptr_Output_float %gl_ClipDistance {{%\d+}} {{%\d+}} -// CHECK: OpStore {{%\d+}} {{%\d+}} +// CHECK: OpAccessChain %_ptr_Output_float %gl_ClipDistance {{%[0-9]+}} {{%[0-9]+}} +// CHECK: OpStore {{%[0-9]+}} {{%[0-9]+}} verts[tid].clipdis3 = float2(11.0,12.0); // CHECK: OpIAdd %uint %uint_0 %uint_1 -// CHECK: OpAccessChain %_ptr_Output_float %gl_CullDistance {{%\d+}} {{%\d+}} -// CHECK: OpStore {{%\d+}} %float_13 +// CHECK: OpAccessChain %_ptr_Output_float %gl_CullDistance {{%[0-9]+}} {{%[0-9]+}} +// CHECK: OpStore {{%[0-9]+}} %float_13 verts[tid].culldis6[0] = 13.0; // CHECK: OpIAdd %uint %uint_1 %uint_1 -// CHECK: OpAccessChain %_ptr_Output_float %gl_CullDistance {{%\d+}} {{%\d+}} -// CHECK: OpStore {{%\d+}} %float_14 +// CHECK: OpAccessChain %_ptr_Output_float %gl_CullDistance {{%[0-9]+}} {{%[0-9]+}} +// CHECK: OpStore {{%[0-9]+}} %float_14 verts[tid].culldis6.y = 14.0; -// CHECK: OpAccessChain %_ptr_Output_v2float %out_var_USER {{%\d+}} -// CHECK: OpStore {{%\d+}} {{%\d+}} +// CHECK: OpAccessChain %_ptr_Output_v2float %out_var_USER {{%[0-9]+}} +// CHECK: OpStore {{%[0-9]+}} {{%[0-9]+}} verts[tid].userVertAttr = float2(9.0, 10.0); -// CHECK: OpAccessChain %_ptr_Output_v4float %out_var_USER_ARR {{%\d+}} %int_0 -// CHECK: OpStore {{%\d+}} {{%\d+}} +// CHECK: OpAccessChain %_ptr_Output_v4float %out_var_USER_ARR {{%[0-9]+}} %int_0 +// CHECK: OpStore {{%[0-9]+}} {{%[0-9]+}} verts[tid].userVertAttrArr[0] = float4(17.0, 18.0, 19.0, 20.0); -// CHECK: OpAccessChain %_ptr_Output_v4float %out_var_USER_ARR {{%\d+}} %int_1 -// CHECK: OpStore {{%\d+}} {{%\d+}} +// CHECK: OpAccessChain %_ptr_Output_v4float %out_var_USER_ARR {{%[0-9]+}} %int_1 +// CHECK: OpStore {{%[0-9]+}} {{%[0-9]+}} verts[tid].userVertAttrArr[1] = float4(27.0, 28.0, 29.0, 30.0); -// CHECK: OpAccessChain %_ptr_Output_v4float %out_var_USER_MAT {{%\d+}} %uint_3 -// CHECK: OpStore {{%\d+}} {{%\d+}} +// CHECK: OpAccessChain %_ptr_Output_v4float %out_var_USER_MAT {{%[0-9]+}} %uint_3 +// CHECK: OpStore {{%[0-9]+}} {{%[0-9]+}} verts[tid].userVertAttrMat[3] = float4(7.0, 8.0, 9.0, 10.0); // Indirectly assign to per-vertex attribute object. @@ -192,26 +192,26 @@ void main( // Directly assign to per-vertex attribute object. -// CHECK: OpAccessChain %_ptr_Output_int %gl_PrimitiveID {{%\d+}} -// CHECK: OpStore {{%\d+}} %int_10 +// CHECK: OpAccessChain %_ptr_Output_int %gl_PrimitiveID {{%[0-9]+}} +// CHECK: OpStore {{%[0-9]+}} %int_10 prims[tig].primId = 10; -// CHECK: OpAccessChain %_ptr_Output_int %gl_Layer {{%\d+}} -// CHECK: OpStore {{%\d+}} %int_11 +// CHECK: OpAccessChain %_ptr_Output_int %gl_Layer {{%[0-9]+}} +// CHECK: OpStore {{%[0-9]+}} %int_11 prims[tig].layer = 11; -// CHECK: OpAccessChain %_ptr_Output_int %gl_ViewportIndex {{%\d+}} -// CHECK: OpStore {{%\d+}} %int_12 +// CHECK: OpAccessChain %_ptr_Output_int %gl_ViewportIndex {{%[0-9]+}} +// CHECK: OpStore {{%[0-9]+}} %int_12 prims[tig].vpIdx = 12; -// CHECK: OpAccessChain %_ptr_Output_int [[vmask]] {{%\d+}} %int_0 -// CHECK: OpStore {{%\d+}} %int_32 +// CHECK: OpAccessChain %_ptr_Output_int [[vmask]] {{%[0-9]+}} %int_0 +// CHECK: OpStore {{%[0-9]+}} %int_32 prims[tig].vmask[0] = 32; -// CHECK: OpAccessChain %_ptr_Output_v4float %out_var_PRIM_USER_ARR {{%\d+}} %int_0 -// CHECK: OpStore {{%\d+}} {{%\d+}} +// CHECK: OpAccessChain %_ptr_Output_v4float %out_var_PRIM_USER_ARR {{%[0-9]+}} %int_0 +// CHECK: OpStore {{%[0-9]+}} {{%[0-9]+}} prims[tig].userPrimAttrArr[0] = float4(4.0,5.0,6.0,7.0); -// CHECK: OpAccessChain %_ptr_Output_v4float %out_var_PRIM_USER_ARR {{%\d+}} %int_1 -// CHECK: OpStore {{%\d+}} {{%\d+}} +// CHECK: OpAccessChain %_ptr_Output_v4float %out_var_PRIM_USER_ARR {{%[0-9]+}} %int_1 +// CHECK: OpStore {{%[0-9]+}} {{%[0-9]+}} prims[tig].userPrimAttrArr[1] = float4(8.0,9.0,10.0,11.0); -// CHECK: OpAccessChain %_ptr_Output_v3float %out_var_PRIM_USER {{%\d+}} -// CHECK: OpStore {{%\d+}} {{%\d+}} +// CHECK: OpAccessChain %_ptr_Output_v3float %out_var_PRIM_USER {{%[0-9]+}} +// CHECK: OpStore {{%[0-9]+}} {{%[0-9]+}} prims[tig].userPrimAttr = float3(14.0,15.0,16.0); // Indirectly assign to per-vertex attribute object. @@ -228,43 +228,43 @@ void main( // Assign primitive indices. // CHECK: OpIMul %uint %uint_4 %uint_3 -// CHECK: OpIAdd %uint {{%\d+}} %uint_0 -// CHECK: OpAccessChain %_ptr_Output_uint [[primind]] {{%\d+}} -// CHECK: OpStore {{%\d+}} %uint_1 +// CHECK: OpIAdd %uint {{%[0-9]+}} %uint_0 +// CHECK: OpAccessChain %_ptr_Output_uint [[primind]] {{%[0-9]+}} +// CHECK: OpStore {{%[0-9]+}} %uint_1 primitiveInd[4].x = 1; -// CHECK: OpCompositeExtract %uint {{%\d+}} 0 +// CHECK: OpCompositeExtract %uint {{%[0-9]+}} 0 // CHECK: OpIMul %uint %uint_4 %uint_3 -// CHECK: OpIAdd %uint {{%\d+}} %uint_1 -// CHECK: OpAccessChain %_ptr_Output_uint [[primind]] {{%\d+}} -// CHECK: OpStore {{%\d+}} {{%\d+}} -// CHECK: OpCompositeExtract %uint {{%\d+}} 1 +// CHECK: OpIAdd %uint {{%[0-9]+}} %uint_1 +// CHECK: OpAccessChain %_ptr_Output_uint [[primind]] {{%[0-9]+}} +// CHECK: OpStore {{%[0-9]+}} {{%[0-9]+}} +// CHECK: OpCompositeExtract %uint {{%[0-9]+}} 1 // CHECK: OpIMul %uint %uint_4 %uint_3 -// CHECK: OpIAdd %uint {{%\d+}} %uint_2 -// CHECK: OpAccessChain %_ptr_Output_uint [[primind]] {{%\d+}} -// CHECK: OpStore {{%\d+}} {{%\d+}} +// CHECK: OpIAdd %uint {{%[0-9]+}} %uint_2 +// CHECK: OpAccessChain %_ptr_Output_uint [[primind]] {{%[0-9]+}} +// CHECK: OpStore {{%[0-9]+}} {{%[0-9]+}} primitiveInd[4].yz = uint2(2,3); // CHECK: OpIMul %uint %uint_2 %uint_3 -// CHECK: OpIAdd %uint {{%\d+}} %uint_1 -// CHECK: OpAccessChain %_ptr_Output_uint [[primind]] {{%\d+}} -// CHECK: OpStore {{%\d+}} %uint_2 +// CHECK: OpIAdd %uint {{%[0-9]+}} %uint_1 +// CHECK: OpAccessChain %_ptr_Output_uint [[primind]] {{%[0-9]+}} +// CHECK: OpStore {{%[0-9]+}} %uint_2 primitiveInd[2].y = 2; // CHECK: OpIMul %uint %uint_2 %uint_3 -// CHECK: OpIAdd %uint {{%\d+}} %uint_2 -// CHECK: OpAccessChain %_ptr_Output_uint [[primind]] {{%\d+}} -// CHECK: OpStore {{%\d+}} %uint_1 +// CHECK: OpIAdd %uint {{%[0-9]+}} %uint_2 +// CHECK: OpAccessChain %_ptr_Output_uint [[primind]] {{%[0-9]+}} +// CHECK: OpStore {{%[0-9]+}} %uint_1 primitiveInd[2][2] = 1; // CHECK: OpLoad %uint %tid -// CHECK: OpIMul %uint {{%\d+}} %uint_3 -// CHECK: OpAccessChain %_ptr_Output_uint [[primind]] {{%\d+}} -// CHECK: OpCompositeExtract %uint {{%\d+}} 0 -// CHECK: OpStore {{%\d+}} {{%\d+}} -// CHECK: OpIAdd %uint {{%\d+}} %uint_1 -// CHECK: OpAccessChain %_ptr_Output_uint [[primind]] {{%\d+}} -// CHECK: OpCompositeExtract %uint {{%\d+}} 1 -// CHECK: OpStore {{%\d+}} {{%\d+}} -// CHECK: OpIAdd %uint {{%\d+}} %uint_2 -// CHECK: OpAccessChain %_ptr_Output_uint [[primind]] {{%\d+}} -// CHECK: OpCompositeExtract %uint {{%\d+}} 2 -// CHECK: OpStore {{%\d+}} {{%\d+}} +// CHECK: OpIMul %uint {{%[0-9]+}} %uint_3 +// CHECK: OpAccessChain %_ptr_Output_uint [[primind]] {{%[0-9]+}} +// CHECK: OpCompositeExtract %uint {{%[0-9]+}} 0 +// CHECK: OpStore {{%[0-9]+}} {{%[0-9]+}} +// CHECK: OpIAdd %uint {{%[0-9]+}} %uint_1 +// CHECK: OpAccessChain %_ptr_Output_uint [[primind]] {{%[0-9]+}} +// CHECK: OpCompositeExtract %uint {{%[0-9]+}} 1 +// CHECK: OpStore {{%[0-9]+}} {{%[0-9]+}} +// CHECK: OpIAdd %uint {{%[0-9]+}} %uint_2 +// CHECK: OpAccessChain %_ptr_Output_uint [[primind]] {{%[0-9]+}} +// CHECK: OpCompositeExtract %uint {{%[0-9]+}} 2 +// CHECK: OpStore {{%[0-9]+}} {{%[0-9]+}} primitiveInd[tid] = uint3(11,12,13); } diff --git a/tools/clang/test/CodeGenSPIRV/namespace.functions.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/namespace.functions.hlsl similarity index 68% rename from tools/clang/test/CodeGenSPIRV/namespace.functions.hlsl rename to tools/clang/test/CodeGenSPIRV_Lit/namespace.functions.hlsl index 9999aafaa8..36f37d44d0 100644 --- a/tools/clang/test/CodeGenSPIRV/namespace.functions.hlsl +++ b/tools/clang/test/CodeGenSPIRV_Lit/namespace.functions.hlsl @@ -1,4 +1,4 @@ -// RUN: %dxc -T ps_6_0 -E main +// RUN: %dxc -T ps_6_0 -E main -fcgl %s -spirv | FileCheck %s // CHECK: OpName %AddRed "AddRed" // CHECK: OpName %A__AddRed "A::AddRed" @@ -8,11 +8,11 @@ // CHECK: OpName %A__createMyStruct "A::createMyStruct" // CHECK: OpName %A__myStruct_add "A::myStruct.add" -// CHECK: [[v3f2:%\d+]] = OpConstantComposite %v3float %float_2 %float_2 %float_2 -// CHECK: [[v4f0:%\d+]] = OpConstantComposite %v4float %float_0 %float_0 %float_0 %float_0 -// CHECK: [[v3f0:%\d+]] = OpConstantComposite %v3float %float_0 %float_0 %float_0 -// CHECK: [[v3f1:%\d+]] = OpConstantComposite %v3float %float_1 %float_1 %float_1 -// CHECK: [[v3f3:%\d+]] = OpConstantComposite %v3float %float_3 %float_3 %float_3 +// CHECK: [[v3f2:%[0-9]+]] = OpConstantComposite %v3float %float_2 %float_2 %float_2 +// CHECK: [[v4f0:%[0-9]+]] = OpConstantComposite %v4float %float_0 %float_0 %float_0 %float_0 +// CHECK: [[v3f0:%[0-9]+]] = OpConstantComposite %v3float %float_0 %float_0 %float_0 +// CHECK: [[v3f1:%[0-9]+]] = OpConstantComposite %v3float %float_1 %float_1 %float_1 +// CHECK: [[v3f3:%[0-9]+]] = OpConstantComposite %v3float %float_3 %float_3 %float_3 namespace A { @@ -44,25 +44,25 @@ float3 AddRed() { return float3(2, 2, 2); } float4 main(float4 PosCS : SV_Position) : SV_Target { -// CHECK: {{%\d+}} = OpFunctionCall %v3float %AddRed +// CHECK: {{%[0-9]+}} = OpFunctionCall %v3float %AddRed float3 val_1 = AddRed(); -// CHECK: {{%\d+}} = OpFunctionCall %v3float %A__AddRed +// CHECK: {{%[0-9]+}} = OpFunctionCall %v3float %A__AddRed float3 val_2 = A::AddRed(); -// CHECK: {{%\d+}} = OpFunctionCall %v3float %A__B__AddRed +// CHECK: {{%[0-9]+}} = OpFunctionCall %v3float %A__B__AddRed float3 val_3 = A::B::AddRed(); -// CHECK: {{%\d+}} = OpFunctionCall %v3float %A__B__AddBlue +// CHECK: {{%[0-9]+}} = OpFunctionCall %v3float %A__B__AddBlue float3 val_4 = A::B::AddBlue(); -// CHECK: {{%\d+}} = OpFunctionCall %v3float %A__AddGreen +// CHECK: {{%[0-9]+}} = OpFunctionCall %v3float %A__AddGreen float3 val_5 = A::AddGreen(); // CHECK: OpStore %vec3f [[v3f2]] A::B::f3 vec3f = float3(2,2,2); -// CHECK: [[s:%\d+]] = OpFunctionCall %myStruct %A__createMyStruct +// CHECK: [[s:%[0-9]+]] = OpFunctionCall %myStruct %A__createMyStruct // CHECK: OpStore %s [[s]] A::myStruct s = A::createMyStruct(); -// CHECK: {{%\d+}} = OpFunctionCall %int %A__myStruct_add %s +// CHECK: {{%[0-9]+}} = OpFunctionCall %int %A__myStruct_add %s int val_6 = s.add(); return float4(0,0,0,0); diff --git a/tools/clang/test/CodeGenSPIRV/namespace.globals.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/namespace.globals.hlsl similarity index 91% rename from tools/clang/test/CodeGenSPIRV/namespace.globals.hlsl rename to tools/clang/test/CodeGenSPIRV_Lit/namespace.globals.hlsl index c0eb8bdd66..75c0d4cbb0 100644 --- a/tools/clang/test/CodeGenSPIRV/namespace.globals.hlsl +++ b/tools/clang/test/CodeGenSPIRV_Lit/namespace.globals.hlsl @@ -1,4 +1,4 @@ -// RUN: %dxc -T ps_6_0 -E main +// RUN: %dxc -T ps_6_0 -E main -fcgl %s -spirv | FileCheck %s // CHECK: OpMemberName %type__Globals 0 "a" // CHECK: OpMemberName %type__Globals 1 "b" diff --git a/tools/clang/test/CodeGenSPIRV/namespace.resources.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/namespace.resources.hlsl similarity index 94% rename from tools/clang/test/CodeGenSPIRV/namespace.resources.hlsl rename to tools/clang/test/CodeGenSPIRV_Lit/namespace.resources.hlsl index 390090c7f8..8e04b4aa24 100644 --- a/tools/clang/test/CodeGenSPIRV/namespace.resources.hlsl +++ b/tools/clang/test/CodeGenSPIRV_Lit/namespace.resources.hlsl @@ -1,4 +1,4 @@ -// RUN: %dxc -T ps_6_0 -E main +// RUN: %dxc -T ps_6_0 -E main -fcgl %s -spirv | FileCheck %s // CHECK: OpDecorate %rw1 DescriptorSet 0 // CHECK: OpDecorate %rw1 Binding 0 diff --git a/tools/clang/test/CodeGenSPIRV_Lit/operator.overloading.subscript.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/operator.overloading.subscript.hlsl new file mode 100644 index 0000000000..899281cce5 --- /dev/null +++ b/tools/clang/test/CodeGenSPIRV_Lit/operator.overloading.subscript.hlsl @@ -0,0 +1,28 @@ +// RUN: %dxc -T ps_6_0 -E main -fcgl %s -spirv | FileCheck %s + +struct s +{ + float field; +}; + +struct subscriptable +{ + s operator[](const uint64_t index) + { + return s(123.0); + } +}; + +float4 main() : SV_TARGET +{ + subscriptable o; + + float f; +// CHECK: %param_var_index = OpVariable %_ptr_Function_ulong Function +// CHECK: OpStore %param_var_index %ulong_123 +// CHECK: [[op_result:%[0-9]+]] = OpFunctionCall %s %subscriptable_operator_Subscript %o %param_var_index +// CHECK: OpStore %temp_var_s [[op_result]] +// CHECK: {{%[0-9]+}} = OpAccessChain %_ptr_Function_float %temp_var_s %int_0 + f = o[123].field; + return f; +} diff --git a/tools/clang/test/CodeGenSPIRV_Lit/partial.template.specialization.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/partial.template.specialization.hlsl new file mode 100644 index 0000000000..f54db4be84 --- /dev/null +++ b/tools/clang/test/CodeGenSPIRV_Lit/partial.template.specialization.hlsl @@ -0,0 +1,26 @@ +// RUN: %dxc -T cs_6_7 -E main -fcgl %s -spirv | FileCheck %s + +// CHECK: %bool_type = OpTypeStruct +template +struct bool_type +{ + static const bool value = val; +}; + +template<> +struct bool_type +{ + static const bool value = false; +}; + +[numthreads(1, 1, 1)] +void main(uint3 invocationID : SV_DispatchThreadID) +{ +// CHECK: OpStore %truthVal %true + bool_type trueType; + bool truthVal = trueType.value; + +// CHECK: OpStore %falseVal %false + bool_type falseType; + bool falseVal = falseType.value; +} diff --git a/tools/clang/test/CodeGenSPIRV/pragma.pack_matrix.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/pragma.pack_matrix.hlsl similarity index 96% rename from tools/clang/test/CodeGenSPIRV/pragma.pack_matrix.hlsl rename to tools/clang/test/CodeGenSPIRV_Lit/pragma.pack_matrix.hlsl index 245403639b..5533c20610 100644 --- a/tools/clang/test/CodeGenSPIRV/pragma.pack_matrix.hlsl +++ b/tools/clang/test/CodeGenSPIRV_Lit/pragma.pack_matrix.hlsl @@ -1,4 +1,4 @@ -// RUN: %dxc -T ps_6_0 -E main +// RUN: %dxc -T ps_6_0 -E main -fcgl %s -spirv | FileCheck %s // CHECK: OpMemberDecorate %type_StructuredBuffer_mat2v3float 0 ColMajor diff --git a/tools/clang/test/CodeGenSPIRV/rayquery_init_expr.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/rayquery_init_expr.hlsl similarity index 82% rename from tools/clang/test/CodeGenSPIRV/rayquery_init_expr.hlsl rename to tools/clang/test/CodeGenSPIRV_Lit/rayquery_init_expr.hlsl index 75be3c2731..b1762c8394 100644 --- a/tools/clang/test/CodeGenSPIRV/rayquery_init_expr.hlsl +++ b/tools/clang/test/CodeGenSPIRV_Lit/rayquery_init_expr.hlsl @@ -1,4 +1,4 @@ -// RUN: %dxc -T cs_6_3 -E main -fspv-target-env=vulkan1.2 +// RUN: %dxc -T cs_6_3 -E main -fspv-target-env=vulkan1.2 -fcgl %s -spirv | FileCheck %s // Ignore "init" Expr of RayQuery in the AST traversal. @@ -27,7 +27,7 @@ void main() { RayQuery<0> RayQ1 = RayQuery<0>(); // CHECK: %RayQ2 = OpVariable %_ptr_Function_rayQueryKHR Function -// CHECK: [[rayq0:%\w+]] = OpLoad {{%\w+}} %RayQ0 +// CHECK: [[rayq0:%[a-zA-Z0-9_]+]] = OpLoad {{%[a-zA-Z0-9_]+}} %RayQ0 // CHECK: OpStore %RayQ2 [[rayq0]] RayQuery<0> RayQ2 = RayQ0; diff --git a/tools/clang/test/CodeGenSPIRV/raytracing.acceleration-structure.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/raytracing.acceleration-structure.hlsl similarity index 71% rename from tools/clang/test/CodeGenSPIRV/raytracing.acceleration-structure.hlsl rename to tools/clang/test/CodeGenSPIRV_Lit/raytracing.acceleration-structure.hlsl index 1765057f8f..dc4daeee37 100644 --- a/tools/clang/test/CodeGenSPIRV/raytracing.acceleration-structure.hlsl +++ b/tools/clang/test/CodeGenSPIRV_Lit/raytracing.acceleration-structure.hlsl @@ -1,4 +1,4 @@ -// RUN: %dxc -E main -T cs_6_4 -fspv-target-env=vulkan1.2 +// RUN: %dxc -E main -T cs_6_4 -fspv-target-env=vulkan1.2 -fcgl %s -spirv | FileCheck %s // CHECK: OpCapability RayQueryKHR // CHECK: OpExtension "SPV_KHR_ray_query" diff --git a/tools/clang/test/CodeGenSPIRV/raytracing.khr.closesthit.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/raytracing.khr.closesthit.hlsl similarity index 61% rename from tools/clang/test/CodeGenSPIRV/raytracing.khr.closesthit.hlsl rename to tools/clang/test/CodeGenSPIRV_Lit/raytracing.khr.closesthit.hlsl index 4f764cc441..4ae0c71667 100644 --- a/tools/clang/test/CodeGenSPIRV/raytracing.khr.closesthit.hlsl +++ b/tools/clang/test/CodeGenSPIRV_Lit/raytracing.khr.closesthit.hlsl @@ -1,22 +1,25 @@ -// RUN: %dxc -T lib_6_3 -fspv-target-env=vulkan1.2 +// RUN: %dxc -T lib_6_3 -fspv-target-env=vulkan1.2 -fcgl %s -spirv | FileCheck %s // CHECK: OpCapability RayTracingKHR // CHECK: OpExtension "SPV_KHR_ray_tracing" -// CHECK: OpDecorate [[a:%\d+]] BuiltIn LaunchIdNV -// CHECK: OpDecorate [[b:%\d+]] BuiltIn LaunchSizeNV -// CHECK: OpDecorate [[c:%\d+]] BuiltIn WorldRayOriginNV -// CHECK: OpDecorate [[d:%\d+]] BuiltIn WorldRayDirectionNV -// CHECK: OpDecorate [[e:%\d+]] BuiltIn RayTminNV -// CHECK: OpDecorate [[f:%\d+]] BuiltIn IncomingRayFlagsNV +// CHECK: OpDecorate [[a:%[0-9]+]] BuiltIn LaunchIdNV +// CHECK: OpDecorate [[b:%[0-9]+]] BuiltIn LaunchSizeNV +// CHECK: OpDecorate [[c:%[0-9]+]] BuiltIn WorldRayOriginNV +// CHECK: OpDecorate [[d:%[0-9]+]] BuiltIn WorldRayDirectionNV +// CHECK: OpDecorate [[e:%[0-9]+]] BuiltIn RayTminNV +// CHECK: OpDecorate [[f:%[0-9]+]] BuiltIn IncomingRayFlagsNV // CHECK: OpDecorate %gl_InstanceID BuiltIn InstanceId -// CHECK: OpDecorate [[g:%\d+]] BuiltIn InstanceCustomIndexNV +// CHECK: OpDecorate [[g:%[0-9]+]] BuiltIn InstanceCustomIndexNV // CHECK: OpDecorate %gl_PrimitiveID BuiltIn PrimitiveId -// CHECK: OpDecorate [[h:%\d+]] BuiltIn ObjectRayOriginNV -// CHECK: OpDecorate [[i:%\d+]] BuiltIn ObjectRayDirectionNV -// CHECK: OpDecorate [[j:%\d+]] BuiltIn ObjectToWorldNV -// CHECK: OpDecorate [[k:%\d+]] BuiltIn WorldToObjectNV -// CHECK: OpDecorate [[l:%\d+]] BuiltIn HitKindNV -// CHECK: OpDecorate [[m:%\d+]] BuiltIn RayGeometryIndexKHR -// CHECK: OpDecorate [[n:%\d+]] BuiltIn RayTmaxNV +// CHECK: OpDecorate [[h:%[0-9]+]] BuiltIn ObjectRayOriginNV +// CHECK: OpDecorate [[i:%[0-9]+]] BuiltIn ObjectRayDirectionNV +// CHECK: OpDecorate [[j:%[0-9]+]] BuiltIn ObjectToWorldNV +// CHECK: OpDecorate [[k:%[0-9]+]] BuiltIn WorldToObjectNV +// CHECK: OpDecorate [[l:%[0-9]+]] BuiltIn HitKindNV +// CHECK: OpDecorate [[m:%[0-9]+]] BuiltIn RayGeometryIndexKHR +// CHECK: OpDecorate [[n:%[0-9]+]] BuiltIn RayTmaxNV + +// CHECK: %accelerationStructureNV = OpTypeAccelerationStructureKHR +// CHECK-NOT: OpTypeAccelerationStructureKHR // CHECK: OpTypePointer IncomingRayPayloadNV %Payload struct Payload @@ -34,7 +37,6 @@ struct Attribute float2 bary; }; -// CHECK-COUNT-1: [[rstype:%\d+]] = OpTypeAccelerationStructureNV RaytracingAccelerationStructure rs; [shader("closesthit")] @@ -62,12 +64,12 @@ void main(inout Payload MyPayload, in Attribute MyAttr) { float3 _10 = ObjectRayOrigin(); // CHECK: OpLoad %v3float [[i]] float3 _11 = ObjectRayDirection(); -// CHECK: [[matotw:%\d+]] = OpLoad %mat4v3float [[j]] +// CHECK: [[matotw:%[0-9]+]] = OpLoad %mat4v3float [[j]] // CHECK-NEXT: OpTranspose %mat3v4float [[matotw]] float3x4 _12 = ObjectToWorld3x4(); // CHECK: OpLoad %mat4v3float [[j]] float4x3 _13 = ObjectToWorld4x3(); -// CHECK: [[matwto:%\d+]] = OpLoad %mat4v3float [[k]] +// CHECK: [[matwto:%[0-9]+]] = OpLoad %mat4v3float [[k]] // CHECK-NEXT: OpTranspose %mat3v4float [[matwto]] float3x4 _14 = WorldToObject3x4(); // CHECK: OpLoad %mat4v3float [[k]] @@ -81,13 +83,13 @@ void main(inout Payload MyPayload, in Attribute MyAttr) { Payload myPayload = { float4(0.0f,0.0f,0.0f,0.0f) }; CallData myCallData = { float4(0.0f,0.0f,0.0f,0.0f) }; -// CHECK: OpStore %myPayload {{%\d+}} +// CHECK: OpStore %myPayload {{%[0-9]+}} RayDesc rayDesc; rayDesc.Origin = float3(0.0f, 0.0f, 0.0f); rayDesc.Direction = float3(0.0f, 0.0f, -1.0f); rayDesc.TMin = 0.0f; rayDesc.TMax = 1000.0f; -// CHECK: OpTraceRayKHR {{%\d+}} %uint_0 %uint_255 %uint_0 %uint_1 %uint_0 {{%\d+}} {{%\d+}} {{%\d+}} {{%\d+}} %myPayload +// CHECK: OpTraceRayKHR {{%[0-9]+}} %uint_0 %uint_255 %uint_0 %uint_1 %uint_0 {{%[0-9]+}} {{%[0-9]+}} {{%[0-9]+}} {{%[0-9]+}} %myPayload TraceRay(rs, 0x0, 0xff, 0, 1, 0, rayDesc, myPayload); // CHECK: OpExecuteCallableKHR %uint_0 %myCallData CallShader(0, myCallData); diff --git a/tools/clang/test/CodeGenSPIRV/raytracing.khr.closesthit.vulkan1.1spirv1.4.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/raytracing.khr.closesthit.vulkan1.1spirv1.4.hlsl similarity index 62% rename from tools/clang/test/CodeGenSPIRV/raytracing.khr.closesthit.vulkan1.1spirv1.4.hlsl rename to tools/clang/test/CodeGenSPIRV_Lit/raytracing.khr.closesthit.vulkan1.1spirv1.4.hlsl index 71661772dc..be70a426fd 100644 --- a/tools/clang/test/CodeGenSPIRV/raytracing.khr.closesthit.vulkan1.1spirv1.4.hlsl +++ b/tools/clang/test/CodeGenSPIRV_Lit/raytracing.khr.closesthit.vulkan1.1spirv1.4.hlsl @@ -1,25 +1,28 @@ -// RUN: %dxc -T lib_6_3 -fspv-target-env=vulkan1.1spirv1.4 +// RUN: %dxc -T lib_6_3 -fspv-target-env=vulkan1.1spirv1.4 -fcgl %s -spirv | FileCheck %s // CHECK: ; SPIR-V // CHECK-NEXT: ; Version: 1.4 // CHECK: OpCapability RayTracingKHR // CHECK: OpExtension "SPV_KHR_ray_tracing" -// CHECK: OpDecorate [[a:%\d+]] BuiltIn LaunchIdNV -// CHECK: OpDecorate [[b:%\d+]] BuiltIn LaunchSizeNV -// CHECK: OpDecorate [[c:%\d+]] BuiltIn WorldRayOriginNV -// CHECK: OpDecorate [[d:%\d+]] BuiltIn WorldRayDirectionNV -// CHECK: OpDecorate [[e:%\d+]] BuiltIn RayTminNV -// CHECK: OpDecorate [[f:%\d+]] BuiltIn IncomingRayFlagsNV +// CHECK: OpDecorate [[a:%[0-9]+]] BuiltIn LaunchIdNV +// CHECK: OpDecorate [[b:%[0-9]+]] BuiltIn LaunchSizeNV +// CHECK: OpDecorate [[c:%[0-9]+]] BuiltIn WorldRayOriginNV +// CHECK: OpDecorate [[d:%[0-9]+]] BuiltIn WorldRayDirectionNV +// CHECK: OpDecorate [[e:%[0-9]+]] BuiltIn RayTminNV +// CHECK: OpDecorate [[f:%[0-9]+]] BuiltIn IncomingRayFlagsNV // CHECK: OpDecorate %gl_InstanceID BuiltIn InstanceId -// CHECK: OpDecorate [[g:%\d+]] BuiltIn InstanceCustomIndexNV +// CHECK: OpDecorate [[g:%[0-9]+]] BuiltIn InstanceCustomIndexNV // CHECK: OpDecorate %gl_PrimitiveID BuiltIn PrimitiveId -// CHECK: OpDecorate [[h:%\d+]] BuiltIn ObjectRayOriginNV -// CHECK: OpDecorate [[i:%\d+]] BuiltIn ObjectRayDirectionNV -// CHECK: OpDecorate [[j:%\d+]] BuiltIn ObjectToWorldNV -// CHECK: OpDecorate [[k:%\d+]] BuiltIn WorldToObjectNV -// CHECK: OpDecorate [[l:%\d+]] BuiltIn HitKindNV -// CHECK: OpDecorate [[m:%\d+]] BuiltIn RayGeometryIndexKHR -// CHECK: OpDecorate [[n:%\d+]] BuiltIn RayTmaxNV +// CHECK: OpDecorate [[h:%[0-9]+]] BuiltIn ObjectRayOriginNV +// CHECK: OpDecorate [[i:%[0-9]+]] BuiltIn ObjectRayDirectionNV +// CHECK: OpDecorate [[j:%[0-9]+]] BuiltIn ObjectToWorldNV +// CHECK: OpDecorate [[k:%[0-9]+]] BuiltIn WorldToObjectNV +// CHECK: OpDecorate [[l:%[0-9]+]] BuiltIn HitKindNV +// CHECK: OpDecorate [[m:%[0-9]+]] BuiltIn RayGeometryIndexKHR +// CHECK: OpDecorate [[n:%[0-9]+]] BuiltIn RayTmaxNV + +// CHECK: %accelerationStructureNV = OpTypeAccelerationStructureKHR +// CHECK-NOT: OpTypeAccelerationStructureKHR // CHECK: OpTypePointer IncomingRayPayloadNV %Payload struct Payload @@ -37,7 +40,6 @@ struct Attribute float2 bary; }; -// CHECK-COUNT-1: [[rstype:%\d+]] = OpTypeAccelerationStructureNV RaytracingAccelerationStructure rs; [shader("closesthit")] @@ -65,12 +67,12 @@ void main(inout Payload MyPayload, in Attribute MyAttr) { float3 _10 = ObjectRayOrigin(); // CHECK: OpLoad %v3float [[i]] float3 _11 = ObjectRayDirection(); -// CHECK: [[matotw:%\d+]] = OpLoad %mat4v3float [[j]] +// CHECK: [[matotw:%[0-9]+]] = OpLoad %mat4v3float [[j]] // CHECK-NEXT: OpTranspose %mat3v4float [[matotw]] float3x4 _12 = ObjectToWorld3x4(); // CHECK: OpLoad %mat4v3float [[j]] float4x3 _13 = ObjectToWorld4x3(); -// CHECK: [[matwto:%\d+]] = OpLoad %mat4v3float [[k]] +// CHECK: [[matwto:%[0-9]+]] = OpLoad %mat4v3float [[k]] // CHECK-NEXT: OpTranspose %mat3v4float [[matwto]] float3x4 _14 = WorldToObject3x4(); // CHECK: OpLoad %mat4v3float [[k]] @@ -84,13 +86,13 @@ void main(inout Payload MyPayload, in Attribute MyAttr) { Payload myPayload = { float4(0.0f,0.0f,0.0f,0.0f) }; CallData myCallData = { float4(0.0f,0.0f,0.0f,0.0f) }; -// CHECK: OpStore %myPayload {{%\d+}} +// CHECK: OpStore %myPayload {{%[0-9]+}} RayDesc rayDesc; rayDesc.Origin = float3(0.0f, 0.0f, 0.0f); rayDesc.Direction = float3(0.0f, 0.0f, -1.0f); rayDesc.TMin = 0.0f; rayDesc.TMax = 1000.0f; -// CHECK: OpTraceRayKHR {{%\d+}} %uint_0 %uint_255 %uint_0 %uint_1 %uint_0 {{%\d+}} {{%\d+}} {{%\d+}} {{%\d+}} %myPayload +// CHECK: OpTraceRayKHR {{%[0-9]+}} %uint_0 %uint_255 %uint_0 %uint_1 %uint_0 {{%[0-9]+}} {{%[0-9]+}} {{%[0-9]+}} {{%[0-9]+}} %myPayload TraceRay(rs, 0x0, 0xff, 0, 1, 0, rayDesc, myPayload); // CHECK: OpExecuteCallableKHR %uint_0 %myCallData CallShader(0, myCallData); diff --git a/tools/clang/test/CodeGenSPIRV/raytracing.khr.terminate.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/raytracing.khr.terminate.hlsl similarity index 88% rename from tools/clang/test/CodeGenSPIRV/raytracing.khr.terminate.hlsl rename to tools/clang/test/CodeGenSPIRV_Lit/raytracing.khr.terminate.hlsl index eee9fbf82f..2ad31882fb 100644 --- a/tools/clang/test/CodeGenSPIRV/raytracing.khr.terminate.hlsl +++ b/tools/clang/test/CodeGenSPIRV_Lit/raytracing.khr.terminate.hlsl @@ -1,8 +1,8 @@ -// RUN: %dxc -T lib_6_3 -fspv-target-env=vulkan1.2 +// RUN: %dxc -T lib_6_3 -fspv-target-env=vulkan1.2 -fcgl %s -spirv | FileCheck %s // CHECK: OpCapability RayTracingKHR // CHECK: OpExtension "SPV_KHR_ray_tracing" -// CHECK: OpDecorate [[l:%\d+]] BuiltIn HitKindNV +// CHECK: OpDecorate [[l:%[0-9]+]] BuiltIn HitKindNV // CHECK: OpTypePointer IncomingRayPayloadNV %Payload struct Payload diff --git a/tools/clang/test/CodeGenSPIRV/raytracing.nv.anyhit.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/raytracing.nv.anyhit.hlsl similarity index 62% rename from tools/clang/test/CodeGenSPIRV/raytracing.nv.anyhit.hlsl rename to tools/clang/test/CodeGenSPIRV_Lit/raytracing.nv.anyhit.hlsl index 108435c63f..1770c6f64a 100644 --- a/tools/clang/test/CodeGenSPIRV/raytracing.nv.anyhit.hlsl +++ b/tools/clang/test/CodeGenSPIRV_Lit/raytracing.nv.anyhit.hlsl @@ -1,21 +1,24 @@ -// RUN: %dxc -T lib_6_3 -fspv-extension=SPV_NV_ray_tracing -fspv-extension=SPV_KHR_ray_query +// RUN: %dxc -T lib_6_3 -fspv-extension=SPV_NV_ray_tracing -fspv-extension=SPV_KHR_ray_query -fcgl %s -spirv | FileCheck %s // CHECK: OpCapability RayTracingNV // CHECK: OpExtension "SPV_NV_ray_tracing" -// CHECK: OpDecorate [[a:%\d+]] BuiltIn LaunchIdNV -// CHECK: OpDecorate [[b:%\d+]] BuiltIn LaunchSizeNV -// CHECK: OpDecorate [[c:%\d+]] BuiltIn WorldRayOriginNV -// CHECK: OpDecorate [[d:%\d+]] BuiltIn WorldRayDirectionNV -// CHECK: OpDecorate [[e:%\d+]] BuiltIn RayTminNV -// CHECK: OpDecorate [[f:%\d+]] BuiltIn IncomingRayFlagsNV +// CHECK: OpDecorate [[a:%[0-9]+]] BuiltIn LaunchIdNV +// CHECK: OpDecorate [[b:%[0-9]+]] BuiltIn LaunchSizeNV +// CHECK: OpDecorate [[c:%[0-9]+]] BuiltIn WorldRayOriginNV +// CHECK: OpDecorate [[d:%[0-9]+]] BuiltIn WorldRayDirectionNV +// CHECK: OpDecorate [[e:%[0-9]+]] BuiltIn RayTminNV +// CHECK: OpDecorate [[f:%[0-9]+]] BuiltIn IncomingRayFlagsNV // CHECK: OpDecorate %gl_InstanceID BuiltIn InstanceId -// CHECK: OpDecorate [[g:%\d+]] BuiltIn InstanceCustomIndexNV +// CHECK: OpDecorate [[g:%[0-9]+]] BuiltIn InstanceCustomIndexNV // CHECK: OpDecorate %gl_PrimitiveID BuiltIn PrimitiveId -// CHECK: OpDecorate [[h:%\d+]] BuiltIn ObjectRayOriginNV -// CHECK: OpDecorate [[i:%\d+]] BuiltIn ObjectRayDirectionNV -// CHECK: OpDecorate [[j:%\d+]] BuiltIn ObjectToWorldNV -// CHECK: OpDecorate [[k:%\d+]] BuiltIn WorldToObjectNV -// CHECK: OpDecorate [[l:%\d+]] BuiltIn HitKindNV -// CHECK: OpDecorate [[m:%\d+]] BuiltIn HitTNV +// CHECK: OpDecorate [[h:%[0-9]+]] BuiltIn ObjectRayOriginNV +// CHECK: OpDecorate [[i:%[0-9]+]] BuiltIn ObjectRayDirectionNV +// CHECK: OpDecorate [[j:%[0-9]+]] BuiltIn ObjectToWorldNV +// CHECK: OpDecorate [[k:%[0-9]+]] BuiltIn WorldToObjectNV +// CHECK: OpDecorate [[l:%[0-9]+]] BuiltIn HitKindNV +// CHECK: OpDecorate [[m:%[0-9]+]] BuiltIn HitTNV + +// CHECK: %accelerationStructureNV = OpTypeAccelerationStructureKHR +// CHECK-NOT: OpTypeAccelerationStructureKHR // CHECK: OpTypePointer IncomingRayPayloadNV %Payload struct Payload @@ -28,7 +31,6 @@ struct Attribute float2 bary; }; -// CHECK-COUNT-1: [[rstype:%\d+]] = OpTypeAccelerationStructureNV RaytracingAccelerationStructure rs; [shader("anyhit")] @@ -56,12 +58,12 @@ void main(inout Payload MyPayload, in Attribute MyAttr) { float3 _10 = ObjectRayOrigin(); // CHECK: OpLoad %v3float [[i]] float3 _11 = ObjectRayDirection(); -// CHECK: [[matotw:%\d+]] = OpLoad %mat4v3float [[j]] +// CHECK: [[matotw:%[0-9]+]] = OpLoad %mat4v3float [[j]] // CHECK-NEXT: OpTranspose %mat3v4float [[matotw]] float3x4 _12 = ObjectToWorld3x4(); // CHECK: OpLoad %mat4v3float [[j]] float4x3 _13 = ObjectToWorld4x3(); -// CHECK: [[matwto:%\d+]] = OpLoad %mat4v3float [[k]] +// CHECK: [[matwto:%[0-9]+]] = OpLoad %mat4v3float [[k]] // CHECK-NEXT: OpTranspose %mat3v4float [[matwto]] float3x4 _14 = WorldToObject3x4(); // CHECK: OpLoad %mat4v3float [[k]] @@ -72,12 +74,12 @@ void main(inout Payload MyPayload, in Attribute MyAttr) { uint _17 = RayTCurrent(); if (_16 == 1U) { -// CHECK: [[payloadread0:%\d+]] = OpLoad %Payload %MyPayload_0 +// CHECK: [[payloadread0:%[0-9]+]] = OpLoad %Payload %MyPayload_0 // CHECK-NEXT : OpStore %MyPayload [[payloadread0]] // CHECK-NEXT : OpIgnoreIntersectionNV IgnoreHit(); } else { -// CHECK: [[payloadread1:%\d+]] = OpLoad %Payload %MyPayload_0 +// CHECK: [[payloadread1:%[0-9]+]] = OpLoad %Payload %MyPayload_0 // CHECK-NEXT : OpStore %MyPayload [[payloadread1]] // CHECK-NEXT : OpTerminateRayNV AcceptHitAndEndSearch(); diff --git a/tools/clang/test/CodeGenSPIRV/raytracing.nv.callable.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/raytracing.nv.callable.hlsl similarity index 64% rename from tools/clang/test/CodeGenSPIRV/raytracing.nv.callable.hlsl rename to tools/clang/test/CodeGenSPIRV_Lit/raytracing.nv.callable.hlsl index cc16b879e6..68ccce22ee 100644 --- a/tools/clang/test/CodeGenSPIRV/raytracing.nv.callable.hlsl +++ b/tools/clang/test/CodeGenSPIRV_Lit/raytracing.nv.callable.hlsl @@ -1,8 +1,8 @@ -// RUN: %dxc -T lib_6_3 -fspv-extension=SPV_NV_ray_tracing +// RUN: %dxc -T lib_6_3 -fspv-extension=SPV_NV_ray_tracing -fcgl %s -spirv | FileCheck %s // CHECK: OpCapability RayTracingNV // CHECK: OpExtension "SPV_NV_ray_tracing" -// CHECK: OpDecorate [[a:%\d+]] BuiltIn LaunchIdNV -// CHECK: OpDecorate [[b:%\d+]] BuiltIn LaunchSizeNV +// CHECK: OpDecorate [[a:%[0-9]+]] BuiltIn LaunchIdNV +// CHECK: OpDecorate [[b:%[0-9]+]] BuiltIn LaunchSizeNV // CHECK: OpTypePointer IncomingCallableDataNV %CallData struct CallData diff --git a/tools/clang/test/CodeGenSPIRV/raytracing.nv.closesthit.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/raytracing.nv.closesthit.hlsl similarity index 62% rename from tools/clang/test/CodeGenSPIRV/raytracing.nv.closesthit.hlsl rename to tools/clang/test/CodeGenSPIRV_Lit/raytracing.nv.closesthit.hlsl index ad8acb28d2..f3463f5e73 100644 --- a/tools/clang/test/CodeGenSPIRV/raytracing.nv.closesthit.hlsl +++ b/tools/clang/test/CodeGenSPIRV_Lit/raytracing.nv.closesthit.hlsl @@ -1,21 +1,24 @@ -// RUN: %dxc -T lib_6_3 -fspv-extension=SPV_NV_ray_tracing -fspv-extension=SPV_KHR_ray_query +// RUN: %dxc -T lib_6_3 -fspv-extension=SPV_NV_ray_tracing -fspv-extension=SPV_KHR_ray_query -fcgl %s -spirv | FileCheck %s // CHECK: OpCapability RayTracingNV // CHECK: OpExtension "SPV_NV_ray_tracing" -// CHECK: OpDecorate [[a:%\d+]] BuiltIn LaunchIdNV -// CHECK: OpDecorate [[b:%\d+]] BuiltIn LaunchSizeNV -// CHECK: OpDecorate [[c:%\d+]] BuiltIn WorldRayOriginNV -// CHECK: OpDecorate [[d:%\d+]] BuiltIn WorldRayDirectionNV -// CHECK: OpDecorate [[e:%\d+]] BuiltIn RayTminNV -// CHECK: OpDecorate [[f:%\d+]] BuiltIn IncomingRayFlagsNV +// CHECK: OpDecorate [[a:%[0-9]+]] BuiltIn LaunchIdNV +// CHECK: OpDecorate [[b:%[0-9]+]] BuiltIn LaunchSizeNV +// CHECK: OpDecorate [[c:%[0-9]+]] BuiltIn WorldRayOriginNV +// CHECK: OpDecorate [[d:%[0-9]+]] BuiltIn WorldRayDirectionNV +// CHECK: OpDecorate [[e:%[0-9]+]] BuiltIn RayTminNV +// CHECK: OpDecorate [[f:%[0-9]+]] BuiltIn IncomingRayFlagsNV // CHECK: OpDecorate %gl_InstanceID BuiltIn InstanceId -// CHECK: OpDecorate [[g:%\d+]] BuiltIn InstanceCustomIndexNV +// CHECK: OpDecorate [[g:%[0-9]+]] BuiltIn InstanceCustomIndexNV // CHECK: OpDecorate %gl_PrimitiveID BuiltIn PrimitiveId -// CHECK: OpDecorate [[h:%\d+]] BuiltIn ObjectRayOriginNV -// CHECK: OpDecorate [[i:%\d+]] BuiltIn ObjectRayDirectionNV -// CHECK: OpDecorate [[j:%\d+]] BuiltIn ObjectToWorldNV -// CHECK: OpDecorate [[k:%\d+]] BuiltIn WorldToObjectNV -// CHECK: OpDecorate [[l:%\d+]] BuiltIn HitKindNV -// CHECK: OpDecorate [[m:%\d+]] BuiltIn HitTNV +// CHECK: OpDecorate [[h:%[0-9]+]] BuiltIn ObjectRayOriginNV +// CHECK: OpDecorate [[i:%[0-9]+]] BuiltIn ObjectRayDirectionNV +// CHECK: OpDecorate [[j:%[0-9]+]] BuiltIn ObjectToWorldNV +// CHECK: OpDecorate [[k:%[0-9]+]] BuiltIn WorldToObjectNV +// CHECK: OpDecorate [[l:%[0-9]+]] BuiltIn HitKindNV +// CHECK: OpDecorate [[m:%[0-9]+]] BuiltIn HitTNV + +// CHECK: %accelerationStructureNV = OpTypeAccelerationStructureKHR +// CHECK-NOT: OpTypeAccelerationStructureKHR // CHECK: OpTypePointer IncomingRayPayloadNV %Payload struct Payload @@ -28,7 +31,6 @@ struct Attribute float2 bary; }; -// CHECK-COUNT-1: [[rstype:%\d+]] = OpTypeAccelerationStructureNV RaytracingAccelerationStructure rs; [shader("closesthit")] @@ -56,12 +58,12 @@ void main(inout Payload MyPayload, in Attribute MyAttr) { float3 _10 = ObjectRayOrigin(); // CHECK: OpLoad %v3float [[i]] float3 _11 = ObjectRayDirection(); -// CHECK: [[matotw:%\d+]] = OpLoad %mat4v3float [[j]] +// CHECK: [[matotw:%[0-9]+]] = OpLoad %mat4v3float [[j]] // CHECK-NEXT: OpTranspose %mat3v4float [[matotw]] float3x4 _12 = ObjectToWorld3x4(); // CHECK: OpLoad %mat4v3float [[j]] float4x3 _13 = ObjectToWorld4x3(); -// CHECK: [[matwto:%\d+]] = OpLoad %mat4v3float [[k]] +// CHECK: [[matwto:%[0-9]+]] = OpLoad %mat4v3float [[k]] // CHECK-NEXT: OpTranspose %mat3v4float [[matwto]] float3x4 _14 = WorldToObject3x4(); // CHECK: OpLoad %mat4v3float [[k]] @@ -77,6 +79,6 @@ void main(inout Payload MyPayload, in Attribute MyAttr) { rayDesc.Direction = float3(0.0f, 0.0f, -1.0f); rayDesc.TMin = 0.0f; rayDesc.TMax = 1000.0f; -// CHECK: OpTraceNV {{%\d+}} %uint_0 %uint_255 %uint_0 %uint_1 %uint_0 {{%\d+}} {{%\d+}} {{%\d+}} {{%\d+}} %uint_0 +// CHECK: OpTraceNV {{%[0-9]+}} %uint_0 %uint_255 %uint_0 %uint_1 %uint_0 {{%[0-9]+}} {{%[0-9]+}} {{%[0-9]+}} {{%[0-9]+}} %uint_0 TraceRay(rs, 0x0, 0xff, 0, 1, 0, rayDesc, myPayload); } diff --git a/tools/clang/test/CodeGenSPIRV/raytracing.nv.enum.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/raytracing.nv.enum.hlsl similarity index 73% rename from tools/clang/test/CodeGenSPIRV/raytracing.nv.enum.hlsl rename to tools/clang/test/CodeGenSPIRV_Lit/raytracing.nv.enum.hlsl index be79ce124a..5c97b3356c 100644 --- a/tools/clang/test/CodeGenSPIRV/raytracing.nv.enum.hlsl +++ b/tools/clang/test/CodeGenSPIRV_Lit/raytracing.nv.enum.hlsl @@ -1,10 +1,11 @@ -// RUN: %dxc -T lib_6_3 -fspv-extension=SPV_NV_ray_tracing -fspv-extension=SPV_KHR_ray_query +// RUN: %dxc -T lib_6_3 -fspv-extension=SPV_NV_ray_tracing -fspv-extension=SPV_KHR_ray_query -fcgl %s -spirv | FileCheck %s // CHECK: OpCapability RayTracingNV // CHECK: OpExtension "SPV_NV_ray_tracing" -// CHECK: OpDecorate [[a:%\d+]] BuiltIn LaunchIdNV -// CHECK: OpDecorate [[b:%\d+]] BuiltIn LaunchSizeNV +// CHECK: OpDecorate [[a:%[0-9]+]] BuiltIn LaunchIdNV +// CHECK: OpDecorate [[b:%[0-9]+]] BuiltIn LaunchSizeNV -// CHECK-COUNT-1: [[rstype:%\d+]] = OpTypeAccelerationStructureNV +// CHECK: %accelerationStructureNV = OpTypeAccelerationStructureKHR +// CHECK-NOT: OpTypeAccelerationStructureKHR RaytracingAccelerationStructure rs; struct Payload @@ -23,13 +24,13 @@ enum Number { Second, }; -//CHECK: [[first:%\d+]] = OpLoad %int %First +//CHECK: [[first:%[0-9]+]] = OpLoad %int %First //CHECK-NEXT: OpStore %foo [[first]] static ::Number foo = First; [shader("raygeneration")] void main() { -//CHECK: [[second:%\d+]] = OpLoad %int %Second +//CHECK: [[second:%[0-9]+]] = OpLoad %int %Second //CHECK-NEXT: OpStore %bar [[second]] static ::Number bar = Second; diff --git a/tools/clang/test/CodeGenSPIRV/raytracing.nv.intersection.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/raytracing.nv.intersection.hlsl similarity index 62% rename from tools/clang/test/CodeGenSPIRV/raytracing.nv.intersection.hlsl rename to tools/clang/test/CodeGenSPIRV_Lit/raytracing.nv.intersection.hlsl index 62f2519478..7adf16a380 100644 --- a/tools/clang/test/CodeGenSPIRV/raytracing.nv.intersection.hlsl +++ b/tools/clang/test/CodeGenSPIRV_Lit/raytracing.nv.intersection.hlsl @@ -1,19 +1,19 @@ -// RUN: %dxc -T lib_6_3 -fspv-extension=SPV_NV_ray_tracing +// RUN: %dxc -T lib_6_3 -fspv-extension=SPV_NV_ray_tracing -fcgl %s -spirv | FileCheck %s // CHECK: OpCapability RayTracingNV // CHECK: OpExtension "SPV_NV_ray_tracing" -// CHECK: OpDecorate [[a:%\d+]] BuiltIn LaunchIdNV -// CHECK: OpDecorate [[b:%\d+]] BuiltIn LaunchSizeNV -// CHECK: OpDecorate [[c:%\d+]] BuiltIn WorldRayOriginNV -// CHECK: OpDecorate [[d:%\d+]] BuiltIn WorldRayDirectionNV -// CHECK: OpDecorate [[e:%\d+]] BuiltIn RayTminNV -// CHECK: OpDecorate [[f:%\d+]] BuiltIn IncomingRayFlagsNV +// CHECK: OpDecorate [[a:%[0-9]+]] BuiltIn LaunchIdNV +// CHECK: OpDecorate [[b:%[0-9]+]] BuiltIn LaunchSizeNV +// CHECK: OpDecorate [[c:%[0-9]+]] BuiltIn WorldRayOriginNV +// CHECK: OpDecorate [[d:%[0-9]+]] BuiltIn WorldRayDirectionNV +// CHECK: OpDecorate [[e:%[0-9]+]] BuiltIn RayTminNV +// CHECK: OpDecorate [[f:%[0-9]+]] BuiltIn IncomingRayFlagsNV // CHECK: OpDecorate %gl_InstanceID BuiltIn InstanceId -// CHECK: OpDecorate [[g:%\d+]] BuiltIn InstanceCustomIndexNV +// CHECK: OpDecorate [[g:%[0-9]+]] BuiltIn InstanceCustomIndexNV // CHECK: OpDecorate %gl_PrimitiveID BuiltIn PrimitiveId -// CHECK: OpDecorate [[h:%\d+]] BuiltIn ObjectRayOriginNV -// CHECK: OpDecorate [[i:%\d+]] BuiltIn ObjectRayDirectionNV -// CHECK: OpDecorate [[j:%\d+]] BuiltIn ObjectToWorldNV -// CHECK: OpDecorate [[k:%\d+]] BuiltIn WorldToObjectNV +// CHECK: OpDecorate [[h:%[0-9]+]] BuiltIn ObjectRayOriginNV +// CHECK: OpDecorate [[i:%[0-9]+]] BuiltIn ObjectRayDirectionNV +// CHECK: OpDecorate [[j:%[0-9]+]] BuiltIn ObjectToWorldNV +// CHECK: OpDecorate [[k:%[0-9]+]] BuiltIn WorldToObjectNV struct Attribute { @@ -45,12 +45,12 @@ void main() { float3 _10 = ObjectRayOrigin(); // CHECK: OpLoad %v3float [[i]] float3 _11 = ObjectRayDirection(); -// CHECK: [[matotw:%\d+]] = OpLoad %mat4v3float [[j]] +// CHECK: [[matotw:%[0-9]+]] = OpLoad %mat4v3float [[j]] // CHECK-NEXT: OpTranspose %mat3v4float [[matotw]] float3x4 _12 = ObjectToWorld3x4(); // CHECK: OpLoad %mat4v3float [[j]] float4x3 _13 = ObjectToWorld4x3(); -// CHECK: [[matwto:%\d+]] = OpLoad %mat4v3float [[k]] +// CHECK: [[matwto:%[0-9]+]] = OpLoad %mat4v3float [[k]] // CHECK-NEXT: OpTranspose %mat3v4float [[matwto]] float3x4 _14 = WorldToObject3x4(); // CHECK: OpLoad %mat4v3float [[k]] diff --git a/tools/clang/test/CodeGenSPIRV/raytracing.nv.library.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/raytracing.nv.library.hlsl similarity index 66% rename from tools/clang/test/CodeGenSPIRV/raytracing.nv.library.hlsl rename to tools/clang/test/CodeGenSPIRV_Lit/raytracing.nv.library.hlsl index 10cd75d6a0..3298e98f5f 100644 --- a/tools/clang/test/CodeGenSPIRV/raytracing.nv.library.hlsl +++ b/tools/clang/test/CodeGenSPIRV_Lit/raytracing.nv.library.hlsl @@ -1,33 +1,35 @@ -// RUN: %dxc -T lib_6_3 -fspv-extension=SPV_NV_ray_tracing -fspv-extension=SPV_KHR_ray_query +// RUN: %dxc -T lib_6_3 -fspv-extension=SPV_NV_ray_tracing -fspv-extension=SPV_KHR_ray_query -fcgl %s -spirv | FileCheck %s // CHECK: OpCapability RayTracingNV // CHECK: OpExtension "SPV_NV_ray_tracing" -// CHECK: OpEntryPoint RayGenerationNV %MyRayGenMain "MyRayGenMain" {{%\d+}} {{%\d+}} {{%\d+}} {{%\d+}} {{%\d+}} {{%\d+}} %gl_InstanceID {{%\d+}} %gl_PrimitiveID {{%\d+}} {{%\d+}} {{%\d+}} {{%\d+}} {{%\d+}} -// CHECK: OpEntryPoint RayGenerationNV %MyRayGenMain2 "MyRayGenMain2" {{%\d+}} {{%\d+}} {{%\d+}} {{%\d+}} {{%\d+}} {{%\d+}} %gl_InstanceID {{%\d+}} %gl_PrimitiveID {{%\d+}} {{%\d+}} {{%\d+}} {{%\d+}} {{%\d+}} -// CHECK: OpEntryPoint MissNV %MyMissMain "MyMissMain" {{%\d+}} {{%\d+}} {{%\d+}} {{%\d+}} {{%\d+}} {{%\d+}} %gl_InstanceID {{%\d+}} %gl_PrimitiveID {{%\d+}} {{%\d+}} {{%\d+}} {{%\d+}} {{%\d+}} -// CHECK: OpEntryPoint MissNV %MyMissMain2 "MyMissMain2" {{%\d+}} {{%\d+}} {{%\d+}} {{%\d+}} {{%\d+}} {{%\d+}} %gl_InstanceID {{%\d+}} %gl_PrimitiveID {{%\d+}} {{%\d+}} {{%\d+}} {{%\d+}} {{%\d+}} -// CHECK: OpEntryPoint IntersectionNV %MyISecMain "MyISecMain" {{%\d+}} {{%\d+}} {{%\d+}} {{%\d+}} {{%\d+}} {{%\d+}} %gl_InstanceID {{%\d+}} %gl_PrimitiveID {{%\d+}} {{%\d+}} {{%\d+}} {{%\d+}} {{%\d+}} -// CHECK: OpEntryPoint IntersectionNV %MyISecMain2 "MyISecMain2" {{%\d+}} {{%\d+}} {{%\d+}} {{%\d+}} {{%\d+}} {{%\d+}} %gl_InstanceID {{%\d+}} %gl_PrimitiveID {{%\d+}} {{%\d+}} {{%\d+}} {{%\d+}} {{%\d+}} -// CHECK: OpEntryPoint AnyHitNV %MyAHitMain "MyAHitMain" {{%\d+}} {{%\d+}} {{%\d+}} {{%\d+}} {{%\d+}} {{%\d+}} %gl_InstanceID {{%\d+}} %gl_PrimitiveID {{%\d+}} {{%\d+}} {{%\d+}} {{%\d+}} {{%\d+}} -// CHECK: OpEntryPoint AnyHitNV %MyAHitMain2 "MyAHitMain2" {{%\d+}} {{%\d+}} {{%\d+}} {{%\d+}} {{%\d+}} {{%\d+}} %gl_InstanceID {{%\d+}} %gl_PrimitiveID {{%\d+}} {{%\d+}} {{%\d+}} {{%\d+}} {{%\d+}} -// CHECK: OpEntryPoint ClosestHitNV %MyCHitMain "MyCHitMain" {{%\d+}} {{%\d+}} {{%\d+}} {{%\d+}} {{%\d+}} {{%\d+}} %gl_InstanceID {{%\d+}} %gl_PrimitiveID {{%\d+}} {{%\d+}} {{%\d+}} {{%\d+}} {{%\d+}} -// CHECK: OpEntryPoint ClosestHitNV %MyCHitMain2 "MyCHitMain2" {{%\d+}} {{%\d+}} {{%\d+}} {{%\d+}} {{%\d+}} {{%\d+}} %gl_InstanceID {{%\d+}} %gl_PrimitiveID {{%\d+}} {{%\d+}} {{%\d+}} {{%\d+}} {{%\d+}} -// CHECK: OpEntryPoint CallableNV %MyCallMain "MyCallMain" {{%\d+}} {{%\d+}} {{%\d+}} {{%\d+}} {{%\d+}} {{%\d+}} %gl_InstanceID {{%\d+}} %gl_PrimitiveID {{%\d+}} {{%\d+}} {{%\d+}} {{%\d+}} {{%\d+}} -// CHECK: OpEntryPoint CallableNV %MyCallMain2 "MyCallMain2" {{%\d+}} {{%\d+}} {{%\d+}} {{%\d+}} {{%\d+}} {{%\d+}} %gl_InstanceID {{%\d+}} %gl_PrimitiveID {{%\d+}} {{%\d+}} {{%\d+}} {{%\d+}} {{%\d+}} -// CHECK: OpDecorate [[a:%\d+]] BuiltIn LaunchIdNV -// CHECK: OpDecorate [[b:%\d+]] BuiltIn LaunchSizeNV -// CHECK: OpDecorate [[c:%\d+]] BuiltIn WorldRayOriginNV -// CHECK: OpDecorate [[d:%\d+]] BuiltIn WorldRayDirectionNV -// CHECK: OpDecorate [[e:%\d+]] BuiltIn RayTminNV -// CHECK: OpDecorate [[f:%\d+]] BuiltIn IncomingRayFlagsNV +// CHECK: OpEntryPoint RayGenerationNV %MyRayGenMain "MyRayGenMain" {{%[0-9]+}} {{%[0-9]+}} {{%[0-9]+}} {{%[0-9]+}} {{%[0-9]+}} {{%[0-9]+}} %gl_InstanceID {{%[0-9]+}} %gl_PrimitiveID {{%[0-9]+}} {{%[0-9]+}} {{%[0-9]+}} {{%[0-9]+}} {{%[0-9]+}} +// CHECK: OpEntryPoint RayGenerationNV %MyRayGenMain2 "MyRayGenMain2" {{%[0-9]+}} {{%[0-9]+}} {{%[0-9]+}} {{%[0-9]+}} {{%[0-9]+}} {{%[0-9]+}} %gl_InstanceID {{%[0-9]+}} %gl_PrimitiveID {{%[0-9]+}} {{%[0-9]+}} {{%[0-9]+}} {{%[0-9]+}} {{%[0-9]+}} +// CHECK: OpEntryPoint MissNV %MyMissMain "MyMissMain" {{%[0-9]+}} {{%[0-9]+}} {{%[0-9]+}} {{%[0-9]+}} {{%[0-9]+}} {{%[0-9]+}} %gl_InstanceID {{%[0-9]+}} %gl_PrimitiveID {{%[0-9]+}} {{%[0-9]+}} {{%[0-9]+}} {{%[0-9]+}} {{%[0-9]+}} +// CHECK: OpEntryPoint MissNV %MyMissMain2 "MyMissMain2" {{%[0-9]+}} {{%[0-9]+}} {{%[0-9]+}} {{%[0-9]+}} {{%[0-9]+}} {{%[0-9]+}} %gl_InstanceID {{%[0-9]+}} %gl_PrimitiveID {{%[0-9]+}} {{%[0-9]+}} {{%[0-9]+}} {{%[0-9]+}} {{%[0-9]+}} +// CHECK: OpEntryPoint IntersectionNV %MyISecMain "MyISecMain" {{%[0-9]+}} {{%[0-9]+}} {{%[0-9]+}} {{%[0-9]+}} {{%[0-9]+}} {{%[0-9]+}} %gl_InstanceID {{%[0-9]+}} %gl_PrimitiveID {{%[0-9]+}} {{%[0-9]+}} {{%[0-9]+}} {{%[0-9]+}} {{%[0-9]+}} +// CHECK: OpEntryPoint IntersectionNV %MyISecMain2 "MyISecMain2" {{%[0-9]+}} {{%[0-9]+}} {{%[0-9]+}} {{%[0-9]+}} {{%[0-9]+}} {{%[0-9]+}} %gl_InstanceID {{%[0-9]+}} %gl_PrimitiveID {{%[0-9]+}} {{%[0-9]+}} {{%[0-9]+}} {{%[0-9]+}} {{%[0-9]+}} +// CHECK: OpEntryPoint AnyHitNV %MyAHitMain "MyAHitMain" {{%[0-9]+}} {{%[0-9]+}} {{%[0-9]+}} {{%[0-9]+}} {{%[0-9]+}} {{%[0-9]+}} %gl_InstanceID {{%[0-9]+}} %gl_PrimitiveID {{%[0-9]+}} {{%[0-9]+}} {{%[0-9]+}} {{%[0-9]+}} {{%[0-9]+}} +// CHECK: OpEntryPoint AnyHitNV %MyAHitMain2 "MyAHitMain2" {{%[0-9]+}} {{%[0-9]+}} {{%[0-9]+}} {{%[0-9]+}} {{%[0-9]+}} {{%[0-9]+}} %gl_InstanceID {{%[0-9]+}} %gl_PrimitiveID {{%[0-9]+}} {{%[0-9]+}} {{%[0-9]+}} {{%[0-9]+}} {{%[0-9]+}} +// CHECK: OpEntryPoint ClosestHitNV %MyCHitMain "MyCHitMain" {{%[0-9]+}} {{%[0-9]+}} {{%[0-9]+}} {{%[0-9]+}} {{%[0-9]+}} {{%[0-9]+}} %gl_InstanceID {{%[0-9]+}} %gl_PrimitiveID {{%[0-9]+}} {{%[0-9]+}} {{%[0-9]+}} {{%[0-9]+}} {{%[0-9]+}} +// CHECK: OpEntryPoint ClosestHitNV %MyCHitMain2 "MyCHitMain2" {{%[0-9]+}} {{%[0-9]+}} {{%[0-9]+}} {{%[0-9]+}} {{%[0-9]+}} {{%[0-9]+}} %gl_InstanceID {{%[0-9]+}} %gl_PrimitiveID {{%[0-9]+}} {{%[0-9]+}} {{%[0-9]+}} {{%[0-9]+}} {{%[0-9]+}} +// CHECK: OpEntryPoint CallableNV %MyCallMain "MyCallMain" {{%[0-9]+}} {{%[0-9]+}} {{%[0-9]+}} {{%[0-9]+}} {{%[0-9]+}} {{%[0-9]+}} %gl_InstanceID {{%[0-9]+}} %gl_PrimitiveID {{%[0-9]+}} {{%[0-9]+}} {{%[0-9]+}} {{%[0-9]+}} {{%[0-9]+}} +// CHECK: OpEntryPoint CallableNV %MyCallMain2 "MyCallMain2" {{%[0-9]+}} {{%[0-9]+}} {{%[0-9]+}} {{%[0-9]+}} {{%[0-9]+}} {{%[0-9]+}} %gl_InstanceID {{%[0-9]+}} %gl_PrimitiveID {{%[0-9]+}} {{%[0-9]+}} {{%[0-9]+}} {{%[0-9]+}} {{%[0-9]+}} +// CHECK: OpDecorate [[a:%[0-9]+]] BuiltIn LaunchIdNV +// CHECK: OpDecorate [[b:%[0-9]+]] BuiltIn LaunchSizeNV +// CHECK: OpDecorate [[c:%[0-9]+]] BuiltIn WorldRayOriginNV +// CHECK: OpDecorate [[d:%[0-9]+]] BuiltIn WorldRayDirectionNV +// CHECK: OpDecorate [[e:%[0-9]+]] BuiltIn RayTminNV +// CHECK: OpDecorate [[f:%[0-9]+]] BuiltIn IncomingRayFlagsNV // CHECK: OpDecorate %gl_InstanceID BuiltIn InstanceId -// CHECK: OpDecorate [[g:%\d+]] BuiltIn InstanceCustomIndexNV +// CHECK: OpDecorate [[g:%[0-9]+]] BuiltIn InstanceCustomIndexNV // CHECK: OpDecorate %gl_PrimitiveID BuiltIn PrimitiveId -// CHECK: OpDecorate [[h:%\d+]] BuiltIn ObjectRayOriginNV -// CHECK: OpDecorate [[i:%\d+]] BuiltIn ObjectRayDirectionNV -// CHECK: OpDecorate [[j:%\d+]] BuiltIn ObjectToWorldNV -// CHECK: OpDecorate [[k:%\d+]] BuiltIn WorldToObjectNV -// CHECK: OpDecorate [[l:%\d+]] BuiltIn HitKindNV +// CHECK: OpDecorate [[h:%[0-9]+]] BuiltIn ObjectRayOriginNV +// CHECK: OpDecorate [[i:%[0-9]+]] BuiltIn ObjectRayDirectionNV +// CHECK: OpDecorate [[j:%[0-9]+]] BuiltIn ObjectToWorldNV +// CHECK: OpDecorate [[k:%[0-9]+]] BuiltIn WorldToObjectNV +// CHECK: OpDecorate [[l:%[0-9]+]] BuiltIn HitKindNV +// CHECK: %accelerationStructureNV = OpTypeAccelerationStructureKHR +// CHECK-NOT: OpTypeAccelerationStructureKHR // CHECK: OpTypePointer CallableDataNV %CallData struct CallData @@ -44,7 +46,6 @@ struct Attribute { float2 bary; }; -// CHECK-COUNT-1: [[rstype:%\d+]] = OpTypeAccelerationStructureNV RaytracingAccelerationStructure rs; @@ -63,7 +64,7 @@ void MyRayGenMain() { rayDesc.Direction = float3(0.0f, 0.0f, -1.0f); rayDesc.TMin = 0.0f; rayDesc.TMax = 1000.0f; -// CHECK: OpTraceNV {{%\d+}} %uint_0 %uint_255 %uint_0 %uint_1 %uint_0 {{%\d+}} {{%\d+}} {{%\d+}} {{%\d+}} %uint_0 +// CHECK: OpTraceNV {{%[0-9]+}} %uint_0 %uint_255 %uint_0 %uint_1 %uint_0 {{%[0-9]+}} {{%[0-9]+}} {{%[0-9]+}} {{%[0-9]+}} %uint_0 TraceRay(rs, 0x0, 0xff, 0, 1, 0, rayDesc, myPayload); // CHECK: OpExecuteCallableNV %uint_0 %uint_0 CallShader(0, myCallData); @@ -236,7 +237,7 @@ void MyCHitMain(inout Payload MyPayload, in Attribute MyAttr) { rayDesc.Direction = float3(0.0f, 0.0f, -1.0f); rayDesc.TMin = 0.0f; rayDesc.TMax = 1000.0f; -// CHECK: OpTraceNV {{%\d+}} %uint_0 %uint_255 %uint_0 %uint_1 %uint_0 {{%\d+}} {{%\d+}} {{%\d+}} {{%\d+}} %uint_0 +// CHECK: OpTraceNV {{%[0-9]+}} %uint_0 %uint_255 %uint_0 %uint_1 %uint_0 {{%[0-9]+}} {{%[0-9]+}} {{%[0-9]+}} {{%[0-9]+}} %uint_0 TraceRay(rs, 0x0, 0xff, 0, 1, 0, rayDesc, myPayload); } diff --git a/tools/clang/test/CodeGenSPIRV/raytracing.nv.miss.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/raytracing.nv.miss.hlsl similarity index 57% rename from tools/clang/test/CodeGenSPIRV/raytracing.nv.miss.hlsl rename to tools/clang/test/CodeGenSPIRV_Lit/raytracing.nv.miss.hlsl index f26c40e91d..dfcee24911 100644 --- a/tools/clang/test/CodeGenSPIRV/raytracing.nv.miss.hlsl +++ b/tools/clang/test/CodeGenSPIRV_Lit/raytracing.nv.miss.hlsl @@ -1,12 +1,12 @@ -// RUN: %dxc -T lib_6_3 -fspv-extension=SPV_NV_ray_tracing +// RUN: %dxc -T lib_6_3 -fspv-extension=SPV_NV_ray_tracing -fcgl %s -spirv | FileCheck %s // CHECK: OpCapability RayTracingNV // CHECK: OpExtension "SPV_NV_ray_tracing" -// CHECK: OpDecorate [[a:%\d+]] BuiltIn LaunchIdNV -// CHECK: OpDecorate [[b:%\d+]] BuiltIn LaunchSizeNV -// CHECK: OpDecorate [[c:%\d+]] BuiltIn WorldRayOriginNV -// CHECK: OpDecorate [[d:%\d+]] BuiltIn WorldRayDirectionNV -// CHECK: OpDecorate [[e:%\d+]] BuiltIn RayTminNV -// CHECK: OpDecorate [[f:%\d+]] BuiltIn IncomingRayFlagsNV +// CHECK: OpDecorate [[a:%[0-9]+]] BuiltIn LaunchIdNV +// CHECK: OpDecorate [[b:%[0-9]+]] BuiltIn LaunchSizeNV +// CHECK: OpDecorate [[c:%[0-9]+]] BuiltIn WorldRayOriginNV +// CHECK: OpDecorate [[d:%[0-9]+]] BuiltIn WorldRayDirectionNV +// CHECK: OpDecorate [[e:%[0-9]+]] BuiltIn RayTminNV +// CHECK: OpDecorate [[f:%[0-9]+]] BuiltIn IncomingRayFlagsNV // CHECK: OpTypePointer IncomingRayPayloadNV %Payload struct Payload diff --git a/tools/clang/test/CodeGenSPIRV/raytracing.nv.raygen.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/raytracing.nv.raygen.hlsl similarity index 66% rename from tools/clang/test/CodeGenSPIRV/raytracing.nv.raygen.hlsl rename to tools/clang/test/CodeGenSPIRV_Lit/raytracing.nv.raygen.hlsl index 3cc2df5c8d..0fc3e37f8e 100644 --- a/tools/clang/test/CodeGenSPIRV/raytracing.nv.raygen.hlsl +++ b/tools/clang/test/CodeGenSPIRV_Lit/raytracing.nv.raygen.hlsl @@ -1,10 +1,11 @@ -// RUN: %dxc -T lib_6_3 -fspv-extension=SPV_NV_ray_tracing -fspv-extension=SPV_KHR_ray_query +// RUN: %dxc -T lib_6_3 -fspv-extension=SPV_NV_ray_tracing -fspv-extension=SPV_KHR_ray_query -fcgl %s -spirv | FileCheck %s // CHECK: OpCapability RayTracingNV // CHECK: OpExtension "SPV_NV_ray_tracing" -// CHECK: OpDecorate [[a:%\d+]] BuiltIn LaunchIdNV -// CHECK: OpDecorate [[b:%\d+]] BuiltIn LaunchSizeNV +// CHECK: OpDecorate [[a:%[0-9]+]] BuiltIn LaunchIdNV +// CHECK: OpDecorate [[b:%[0-9]+]] BuiltIn LaunchSizeNV -// CHECK-COUNT-1: [[rstype:%\d+]] = OpTypeAccelerationStructureNV +// CHECK: %accelerationStructureNV = OpTypeAccelerationStructureKHR +// CHECK-NOT: OpTypeAccelerationStructureKHR RaytracingAccelerationStructure rs; struct Payload @@ -31,7 +32,7 @@ void main() { rayDesc.Direction = float3(0.0f, 0.0f, -1.0f); rayDesc.TMin = 0.0f; rayDesc.TMax = 1000.0f; - // CHECK: OpTraceNV {{%\d+}} %uint_0 %uint_255 %uint_0 %uint_1 %uint_0 {{%\d+}} {{%\d+}} {{%\d+}} {{%\d+}} %uint_0 + // CHECK: OpTraceNV {{%[0-9]+}} %uint_0 %uint_255 %uint_0 %uint_1 %uint_0 {{%[0-9]+}} {{%[0-9]+}} {{%[0-9]+}} {{%[0-9]+}} %uint_0 TraceRay(rs, 0x0, 0xff, 0, 1, 0, rayDesc, myPayload); // CHECK: OpExecuteCallableNV %uint_0 %uint_0 CallShader(0, myCallData); diff --git a/tools/clang/test/CodeGenSPIRV_Lit/reduce.load.size.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/reduce.load.size.hlsl new file mode 100644 index 0000000000..89f228d613 --- /dev/null +++ b/tools/clang/test/CodeGenSPIRV_Lit/reduce.load.size.hlsl @@ -0,0 +1,32 @@ +// RUN: %dxc -T cs_6_0 -E main -fspv-reduce-load-size -O0 %s -spirv | FileCheck %s + +struct S { + uint f; +}; + +cbuffer gBuffer { uint a[6]; }; + +RWStructuredBuffer gRWSBuffer; + +// CHECK-NOT: OpCompositeExtract + +// CHECK: [[p0:%[a-zA-Z0-9_]+]] = OpAccessChain %_ptr_Uniform_uint {{%[a-zA-Z0-9_]+}} %uint_0 +// CHECK: OpLoad %uint [[p0]] +// CHECK: [[p1:%[a-zA-Z0-9_]+]] = OpAccessChain %_ptr_Uniform_uint {{%[a-zA-Z0-9_]+}} %uint_1 +// CHECK: OpLoad %uint [[p1]] +// CHECK: [[p2:%[a-zA-Z0-9_]+]] = OpAccessChain %_ptr_Uniform_uint {{%[a-zA-Z0-9_]+}} %uint_2 +// CHECK: OpLoad %uint [[p2]] +// CHECK: [[p3:%[a-zA-Z0-9_]+]] = OpAccessChain %_ptr_Uniform_uint {{%[a-zA-Z0-9_]+}} %uint_3 +// CHECK: OpLoad %uint [[p3]] +// CHECK: [[p4:%[a-zA-Z0-9_]+]] = OpAccessChain %_ptr_Uniform_uint {{%[a-zA-Z0-9_]+}} %uint_4 +// CHECK: OpLoad %uint [[p4]] +// CHECK: [[p5:%[a-zA-Z0-9_]+]] = OpAccessChain %_ptr_Uniform_uint {{%[a-zA-Z0-9_]+}} %uint_5 +// CHECK: OpLoad %uint [[p5]] +uint foo(uint p[6]) { + return p[0] + p[1] + p[2] + p[3] + p[4] + p[5]; +} + +[numthreads(1,1,1)] +void main() { + gRWSBuffer[0].f = foo(a); +} diff --git a/tools/clang/test/CodeGenSPIRV_Lit/semantic.barycentrics.ps.np-c.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/semantic.barycentrics.ps.np-c.hlsl new file mode 100644 index 0000000000..13a6a28ec3 --- /dev/null +++ b/tools/clang/test/CodeGenSPIRV_Lit/semantic.barycentrics.ps.np-c.hlsl @@ -0,0 +1,23 @@ +// RUN: %dxc -T ps_6_1 -E main -spirv -Od %s 2>&1 | FileCheck %s + +// CHECK: OpExtension "SPV_KHR_fragment_shader_barycentric" + +// CHECK: OpEntryPoint Fragment +// CHECK-SAME: [[bary:%[0-9]+]] + +// CHECK: OpDecorate [[bary]] BuiltIn BaryCoordNoPerspKHR +// CHECK: OpDecorate [[bary]] Centroid + +// CHECK: [[bary]] = OpVariable %_ptr_Input_v3float Input + +float4 main(noperspective centroid float3 bary : SV_Barycentrics) : SV_Target { + return float4(bary, 1.0); +// CHECK: %param_var_bary = OpVariable %_ptr_Function_v3float Function +// CHECK-NEXT: [[c2:%[0-9]+]] = OpLoad %v3float [[bary]] +// CHECK-NEXT: [[x:%[0-9]+]] = OpCompositeExtract %float [[c2]] 0 +// CHECK-NEXT: [[y:%[0-9]+]] = OpCompositeExtract %float [[c2]] 1 +// CHECK-NEXT: [[xy:%[0-9]+]] = OpFAdd %float [[x]] [[y]] +// CHECK-NEXT: [[z:%[0-9]+]] = OpFSub %float %float_1 [[xy]] +// CHECK-NEXT: [[c3:%[0-9]+]] = OpCompositeConstruct %v3float [[x]] [[y]] [[z]] +// CHECK-NEXT: OpStore %param_var_bary [[c3]] +} diff --git a/tools/clang/test/CodeGenSPIRV_Lit/semantic.barycentrics.ps.np-s.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/semantic.barycentrics.ps.np-s.hlsl new file mode 100644 index 0000000000..443526a4de --- /dev/null +++ b/tools/clang/test/CodeGenSPIRV_Lit/semantic.barycentrics.ps.np-s.hlsl @@ -0,0 +1,23 @@ +// RUN: %dxc -T ps_6_1 -E main -spirv -Od %s 2>&1 | FileCheck %s + +// CHECK: OpExtension "SPV_KHR_fragment_shader_barycentric" + +// CHECK: OpEntryPoint Fragment +// CHECK-SAME: [[bary:%[0-9]+]] + +// CHECK: OpDecorate [[bary]] BuiltIn BaryCoordNoPerspKHR +// CHECK: OpDecorate [[bary]] Sample + +// CHECK: [[bary]] = OpVariable %_ptr_Input_v3float Input + +float4 main(noperspective sample float3 bary : SV_Barycentrics) : SV_Target { + return float4(bary, 1.0); +// CHECK: %param_var_bary = OpVariable %_ptr_Function_v3float Function +// CHECK-NEXT: [[c2:%[0-9]+]] = OpLoad %v3float [[bary]] +// CHECK-NEXT: [[x:%[0-9]+]] = OpCompositeExtract %float [[c2]] 0 +// CHECK-NEXT: [[y:%[0-9]+]] = OpCompositeExtract %float [[c2]] 1 +// CHECK-NEXT: [[xy:%[0-9]+]] = OpFAdd %float [[x]] [[y]] +// CHECK-NEXT: [[z:%[0-9]+]] = OpFSub %float %float_1 [[xy]] +// CHECK-NEXT: [[c3:%[0-9]+]] = OpCompositeConstruct %v3float [[x]] [[y]] [[z]] +// CHECK-NEXT: OpStore %param_var_bary [[c3]] +} diff --git a/tools/clang/test/CodeGenSPIRV_Lit/semantic.barycentrics.ps.np.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/semantic.barycentrics.ps.np.hlsl new file mode 100644 index 0000000000..53e2c7976b --- /dev/null +++ b/tools/clang/test/CodeGenSPIRV_Lit/semantic.barycentrics.ps.np.hlsl @@ -0,0 +1,22 @@ +// RUN: %dxc -T ps_6_1 -E main -spirv -Od %s 2>&1 | FileCheck %s + +// CHECK: OpExtension "SPV_KHR_fragment_shader_barycentric" + +// CHECK: OpEntryPoint Fragment +// CHECK-SAME: [[bary:%[0-9]+]] + +// CHECK: OpDecorate [[bary]] BuiltIn BaryCoordNoPerspKHR + +// CHECK: [[bary]] = OpVariable %_ptr_Input_v3float Input + +float4 main(noperspective float3 bary : SV_Barycentrics) : SV_Target { + return float4(bary, 1.0); +// CHECK: %param_var_bary = OpVariable %_ptr_Function_v3float Function +// CHECK-NEXT: [[c2:%[0-9]+]] = OpLoad %v3float [[bary]] +// CHECK-NEXT: [[x:%[0-9]+]] = OpCompositeExtract %float [[c2]] 0 +// CHECK-NEXT: [[y:%[0-9]+]] = OpCompositeExtract %float [[c2]] 1 +// CHECK-NEXT: [[xy:%[0-9]+]] = OpFAdd %float [[x]] [[y]] +// CHECK-NEXT: [[z:%[0-9]+]] = OpFSub %float %float_1 [[xy]] +// CHECK-NEXT: [[c3:%[0-9]+]] = OpCompositeConstruct %v3float [[x]] [[y]] [[z]] +// CHECK-NEXT: OpStore %param_var_bary [[c3]] +} diff --git a/tools/clang/test/CodeGenSPIRV_Lit/semantic.barycentrics.ps.s-c.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/semantic.barycentrics.ps.s-c.hlsl new file mode 100644 index 0000000000..d184d1ef5b --- /dev/null +++ b/tools/clang/test/CodeGenSPIRV_Lit/semantic.barycentrics.ps.s-c.hlsl @@ -0,0 +1,23 @@ +// RUN: %dxc -T ps_6_1 -E main -spirv -Od %s 2>&1 | FileCheck %s + +// CHECK: OpExtension "SPV_KHR_fragment_shader_barycentric" + +// CHECK: OpEntryPoint Fragment +// CHECK-SAME: [[bary:%[0-9]+]] + +// CHECK: OpDecorate [[bary]] BuiltIn BaryCoordKHR +// CHECK: OpDecorate [[bary]] Centroid + +// CHECK: [[bary]] = OpVariable %_ptr_Input_v3float Input + +float4 main(centroid float3 bary : SV_Barycentrics) : SV_Target { + return float4(bary, 1.0); +// CHECK: %param_var_bary = OpVariable %_ptr_Function_v3float Function +// CHECK-NEXT: [[c2:%[0-9]+]] = OpLoad %v3float [[bary]] +// CHECK-NEXT: [[x:%[0-9]+]] = OpCompositeExtract %float [[c2]] 0 +// CHECK-NEXT: [[y:%[0-9]+]] = OpCompositeExtract %float [[c2]] 1 +// CHECK-NEXT: [[xy:%[0-9]+]] = OpFAdd %float [[x]] [[y]] +// CHECK-NEXT: [[z:%[0-9]+]] = OpFSub %float %float_1 [[xy]] +// CHECK-NEXT: [[c3:%[0-9]+]] = OpCompositeConstruct %v3float [[x]] [[y]] [[z]] +// CHECK-NEXT: OpStore %param_var_bary [[c3]] +} diff --git a/tools/clang/test/CodeGenSPIRV_Lit/semantic.barycentrics.ps.s-s.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/semantic.barycentrics.ps.s-s.hlsl new file mode 100644 index 0000000000..14fd29803d --- /dev/null +++ b/tools/clang/test/CodeGenSPIRV_Lit/semantic.barycentrics.ps.s-s.hlsl @@ -0,0 +1,23 @@ +// RUN: %dxc -T ps_6_1 -E main -spirv -Od %s 2>&1 | FileCheck %s + +// CHECK: OpExtension "SPV_KHR_fragment_shader_barycentric" + +// CHECK: OpEntryPoint Fragment +// CHECK-SAME: [[bary:%[0-9]+]] + +// CHECK: OpDecorate [[bary]] BuiltIn BaryCoordKHR +// CHECK: OpDecorate [[bary]] Sample + +// CHECK: [[bary]] = OpVariable %_ptr_Input_v3float Input + +float4 main(sample float3 bary : SV_Barycentrics) : SV_Target { + return float4(bary, 1.0); +// CHECK: %param_var_bary = OpVariable %_ptr_Function_v3float Function +// CHECK-NEXT: [[c2:%[0-9]+]] = OpLoad %v3float [[bary]] +// CHECK-NEXT: [[x:%[0-9]+]] = OpCompositeExtract %float [[c2]] 0 +// CHECK-NEXT: [[y:%[0-9]+]] = OpCompositeExtract %float [[c2]] 1 +// CHECK-NEXT: [[xy:%[0-9]+]] = OpFAdd %float [[x]] [[y]] +// CHECK-NEXT: [[z:%[0-9]+]] = OpFSub %float %float_1 [[xy]] +// CHECK-NEXT: [[c3:%[0-9]+]] = OpCompositeConstruct %v3float [[x]] [[y]] [[z]] +// CHECK-NEXT: OpStore %param_var_bary [[c3]] +} diff --git a/tools/clang/test/CodeGenSPIRV_Lit/semantic.barycentrics.ps.s.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/semantic.barycentrics.ps.s.hlsl new file mode 100644 index 0000000000..77a07268b1 --- /dev/null +++ b/tools/clang/test/CodeGenSPIRV_Lit/semantic.barycentrics.ps.s.hlsl @@ -0,0 +1,22 @@ +// RUN: %dxc -T ps_6_1 -E main -spirv -Od %s 2>&1 | FileCheck %s + +// CHECK: OpExtension "SPV_KHR_fragment_shader_barycentric" + +// CHECK: OpEntryPoint Fragment +// CHECK-SAME: [[bary:%[0-9]+]] + +// CHECK: OpDecorate [[bary]] BuiltIn BaryCoordKHR + +// CHECK: [[bary]] = OpVariable %_ptr_Input_v3float Input + +float4 main(float3 bary : SV_Barycentrics) : SV_Target { + return float4(bary, 1.0); +// CHECK: %param_var_bary = OpVariable %_ptr_Function_v3float Function +// CHECK-NEXT: [[c2:%[0-9]+]] = OpLoad %v3float [[bary]] +// CHECK-NEXT: [[x:%[0-9]+]] = OpCompositeExtract %float [[c2]] 0 +// CHECK-NEXT: [[y:%[0-9]+]] = OpCompositeExtract %float [[c2]] 1 +// CHECK-NEXT: [[xy:%[0-9]+]] = OpFAdd %float [[x]] [[y]] +// CHECK-NEXT: [[z:%[0-9]+]] = OpFSub %float %float_1 [[xy]] +// CHECK-NEXT: [[c3:%[0-9]+]] = OpCompositeConstruct %v3float [[x]] [[y]] [[z]] +// CHECK-NEXT: OpStore %param_var_bary [[c3]] +} diff --git a/tools/clang/test/CodeGenSPIRV/signature.packing.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/signature.packing.hlsl similarity index 93% rename from tools/clang/test/CodeGenSPIRV/signature.packing.hlsl rename to tools/clang/test/CodeGenSPIRV_Lit/signature.packing.hlsl index 83f70706c9..9369e6f76b 100644 --- a/tools/clang/test/CodeGenSPIRV/signature.packing.hlsl +++ b/tools/clang/test/CodeGenSPIRV_Lit/signature.packing.hlsl @@ -1,4 +1,4 @@ -// RUN: %dxc -T vs_6_0 -E main -pack-optimized -O0 +// RUN: %dxc -T vs_6_0 -E main -pack-optimized -O0 %s -spirv | FileCheck %s struct VS_OUTPUT { float4 pos : SV_POSITION; diff --git a/tools/clang/test/CodeGenSPIRV/signature.packing.hs.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/signature.packing.hs.hlsl similarity index 97% rename from tools/clang/test/CodeGenSPIRV/signature.packing.hs.hlsl rename to tools/clang/test/CodeGenSPIRV_Lit/signature.packing.hs.hlsl index 8f85862370..0262246a3a 100644 --- a/tools/clang/test/CodeGenSPIRV/signature.packing.hs.hlsl +++ b/tools/clang/test/CodeGenSPIRV_Lit/signature.packing.hs.hlsl @@ -1,4 +1,4 @@ -// RUN: %dxc -T hs_6_0 -E main -pack-optimized -O0 +// RUN: %dxc -T hs_6_0 -E main -pack-optimized -O0 %s -spirv | FileCheck %s struct HSPatchConstData { float tessFactor[3] : SV_TessFactor; diff --git a/tools/clang/test/CodeGenSPIRV_Lit/single.derivative.execmode.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/single.derivative.execmode.hlsl new file mode 100644 index 0000000000..75b127bb04 --- /dev/null +++ b/tools/clang/test/CodeGenSPIRV_Lit/single.derivative.execmode.hlsl @@ -0,0 +1,26 @@ +// RUN: %dxc -T cs_6_6 -E main -fspv-extension=SPV_NV_compute_shader_derivatives -fcgl %s -spirv 2>&1 | FileCheck %s + +// This test checks that the execution mode is not added multiple times. Other +// tests will verify that the code generation is correct. + +// CHECK: OpCapability ComputeDerivativeGroupQuadsNV +// CHECK: OpExtension "SPV_NV_compute_shader_derivatives" +// CHECK: OpExecutionMode %main DerivativeGroupQuadsNV +// CHECK-NOT: OpExecutionMode %main DerivativeGroupQuadsNV + +SamplerState ss : register(s2); +SamplerComparisonState scs; + +RWStructuredBuffer o; +Texture1D t1; + +[numthreads(2,2,1)] +void main(uint3 id : SV_GroupThreadID) +{ + uint v = id.x; + o[0] = t1.CalculateLevelOfDetail(ss, 0.5); + o[1] = t1.CalculateLevelOfDetailUnclamped(ss, 0.5); + o[2] = t1.Sample(ss, 1); + o[3] = t1.SampleBias(ss, 1, 0.5); + o[4] = t1.SampleCmp(scs, 1, 0.5); +} \ No newline at end of file diff --git a/tools/clang/test/CodeGenSPIRV/spirv.interpolation.ps.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/spirv.interpolation.ps.hlsl similarity index 97% rename from tools/clang/test/CodeGenSPIRV/spirv.interpolation.ps.hlsl rename to tools/clang/test/CodeGenSPIRV_Lit/spirv.interpolation.ps.hlsl index 5c039faac9..7274d0d241 100644 --- a/tools/clang/test/CodeGenSPIRV/spirv.interpolation.ps.hlsl +++ b/tools/clang/test/CodeGenSPIRV_Lit/spirv.interpolation.ps.hlsl @@ -1,4 +1,4 @@ -// RUN: %dxc -T ps_6_0 -E main +// RUN: %dxc -T ps_6_0 -E main -fcgl %s -spirv | FileCheck %s // Required by the sample interpolation mode // CHECK: OpCapability SampleRateShading diff --git a/tools/clang/test/CodeGenSPIRV/spirv.interpolation.vs.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/spirv.interpolation.vs.hlsl similarity index 95% rename from tools/clang/test/CodeGenSPIRV/spirv.interpolation.vs.hlsl rename to tools/clang/test/CodeGenSPIRV_Lit/spirv.interpolation.vs.hlsl index 0e9d5dc978..5d445dfe26 100644 --- a/tools/clang/test/CodeGenSPIRV/spirv.interpolation.vs.hlsl +++ b/tools/clang/test/CodeGenSPIRV_Lit/spirv.interpolation.vs.hlsl @@ -1,4 +1,4 @@ -// RUN: %dxc -T vs_6_0 -E main +// RUN: %dxc -T vs_6_0 -E main -fcgl %s -spirv | FileCheck %s // Required by the sample interpolation mode // CHECK: OpCapability SampleRateShading diff --git a/tools/clang/test/CodeGenSPIRV_Lit/spirv.legal.cbuffer.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/spirv.legal.cbuffer.hlsl new file mode 100644 index 0000000000..d855174c91 --- /dev/null +++ b/tools/clang/test/CodeGenSPIRV_Lit/spirv.legal.cbuffer.hlsl @@ -0,0 +1,76 @@ +// RUN: %dxc -T ps_6_0 -E main -fcgl %s -spirv | FileCheck %s + +// %type_ConstantBuffer_S is the type for myCBuffer. With layout decoration. +// %S is the type for myASBuffer elements. With layout decoration. +// %S_0 is the type for function local variables. Without layout decoration. + +// CHECK: OpMemberDecorate %type_ConstantBuffer_S 0 Offset 0 +// CHECK: OpMemberDecorate %S 0 Offset 0 +// CHECK-NOT: OpMemberDecorate %S_0 0 Offset 0 + +// CHECK: %type_ConstantBuffer_S = OpTypeStruct %v4float +// CHECK: %S = OpTypeStruct %v4float +// CHECK: %S_0 = OpTypeStruct %v4float +struct S { + float4 f; +}; + +// CHECK: %myCBuffer = OpVariable %_ptr_Uniform_type_ConstantBuffer_S Uniform +ConstantBuffer myCBuffer; +AppendStructuredBuffer myASBuffer; + +S retStuff(); + +float4 doStuff(S buffer) { + return buffer.f; +} + +float4 main(in float4 pos : SV_Position) : SV_Target +{ +// Initializing a T with a ConstantBuffer is a copy +// CHECK: [[val:%[0-9]+]] = OpLoad %type_ConstantBuffer_S %myCBuffer +// CHECK-NEXT: [[vec:%[0-9]+]] = OpCompositeExtract %v4float [[val]] 0 +// CHECK-NEXT: [[tmp:%[0-9]+]] = OpCompositeConstruct %S_0 [[vec]] +// CHECK-NEXT: OpStore %buffer1 [[tmp]] + S buffer1 = myCBuffer; + +// Assigning a ConstantBuffer to a T is a copy +// CHECK: [[val_0:%[0-9]+]] = OpLoad %type_ConstantBuffer_S %myCBuffer +// CHECK-NEXT: [[vec_0:%[0-9]+]] = OpCompositeExtract %v4float [[val_0]] 0 +// CHECK-NEXT: [[tmp_0:%[0-9]+]] = OpCompositeConstruct %S_0 [[vec_0]] +// CHECK-NEXT: OpStore %buffer2 [[tmp_0]] + S buffer2; + buffer2 = myCBuffer; + +// We have the same struct type here +// CHECK: [[val_1:%[0-9]+]] = OpFunctionCall %S_0 %retStuff +// CHECK-NEXT: OpStore %buffer3 [[val_1]] + S buffer3; + buffer3 = retStuff(); + +// Write out each component recursively +// CHECK: [[ptr:%[0-9]+]] = OpAccessChain %_ptr_Uniform_S %myASBuffer %uint_0 {{%[0-9]+}} +// CHECK-NEXT: [[val_2:%[0-9]+]] = OpLoad %type_ConstantBuffer_S %myCBuffer +// CHECK-NEXT: [[vec_1:%[0-9]+]] = OpCompositeExtract %v4float [[val_2]] 0 +// CHECK-NEXT: [[tmp_1:%[0-9]+]] = OpCompositeConstruct %S_0 [[vec_1]] +// CHECK-NEXT: [[vec_2:%[0-9]+]] = OpCompositeExtract %v4float [[tmp_1]] 0 +// CHECK-NEXT: [[tmp_2:%[0-9]+]] = OpCompositeConstruct %S [[vec_2]] +// CHECK-NEXT: OpStore [[ptr]] [[tmp_2]] + myASBuffer.Append(myCBuffer); + +// Passing a ConstantBuffer to a T parameter is a copy +// CHECK: [[val_3:%[0-9]+]] = OpLoad %type_ConstantBuffer_S %myCBuffer +// CHECK-NEXT: [[vec_3:%[0-9]+]] = OpCompositeExtract %v4float [[val_3]] 0 +// CHECK-NEXT: [[tmp_3:%[0-9]+]] = OpCompositeConstruct %S_0 [[vec_3]] +// CHECK-NEXT: OpStore %param_var_buffer [[tmp_3]] + return doStuff(myCBuffer); +} + +S retStuff() { +// Returning a ConstantBuffer as a T is a copy +// CHECK: [[val_4:%[0-9]+]] = OpLoad %type_ConstantBuffer_S %myCBuffer +// CHECK-NEXT: [[vec_4:%[0-9]+]] = OpCompositeExtract %v4float [[val_4]] 0 +// CHECK-NEXT: [[ret:%[0-9]+]] = OpCompositeConstruct %S_0 [[vec_4]] +// CHECK-NEXT: OpReturnValue [[ret]] + return myCBuffer; +} diff --git a/tools/clang/test/CodeGenSPIRV_Lit/spirv.legal.tbuffer.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/spirv.legal.tbuffer.hlsl new file mode 100644 index 0000000000..27f0e02bde --- /dev/null +++ b/tools/clang/test/CodeGenSPIRV_Lit/spirv.legal.tbuffer.hlsl @@ -0,0 +1,81 @@ +// RUN: %dxc -T ps_6_0 -E main -fcgl %s -spirv | FileCheck %s + +// Note: The following is invalid SPIR-V code. +// +// * The assignment ignores storage class (and thus layout) difference. + +// %type_TextureBuffer_S is the type for myTBuffer. With layout decoration. +// %S is the type for myASBuffer elements. With layout decoration. +// %S_0 is the type for function local variables. Without layout decoration. + +// CHECK: OpMemberDecorate %type_TextureBuffer_S 0 Offset 0 +// CHECK: OpMemberDecorate %S 0 Offset 0 +// CHECK-NOT: OpMemberDecorate %S_0 0 Offset 0 + +// CHECK: %type_TextureBuffer_S = OpTypeStruct %v4float +// CHECK: %S = OpTypeStruct %v4float +// CHECK: %S_0 = OpTypeStruct %v4float +struct S { + float4 f; +}; + +// CHECK: %myTBuffer = OpVariable %_ptr_Uniform_type_TextureBuffer_S Uniform +TextureBuffer myTBuffer; +AppendStructuredBuffer myASBuffer; + +S retStuff(); + +float4 doStuff(S buffer) { + return buffer.f; +} + +float4 main(in float4 pos : SV_Position) : SV_Target +{ +// Initializing a T with a TextureBuffer is a copy +// CHECK: [[val:%[0-9]+]] = OpLoad %type_TextureBuffer_S %myTBuffer +// CHECK-NEXT: [[vec:%[0-9]+]] = OpCompositeExtract %v4float [[val]] 0 +// CHECK-NEXT: [[tmp:%[0-9]+]] = OpCompositeConstruct %S_0 [[vec]] +// CHECK-NEXT: OpStore %buffer1 [[tmp]] + S buffer1 = myTBuffer; + +// Assigning a TextureBuffer to a T is a copy +// CHECK: [[val_0:%[0-9]+]] = OpLoad %type_TextureBuffer_S %myTBuffer +// CHECK-NEXT: [[vec_0:%[0-9]+]] = OpCompositeExtract %v4float [[val_0]] 0 +// CHECK-NEXT: [[tmp_0:%[0-9]+]] = OpCompositeConstruct %S_0 [[vec_0]] +// CHECK-NEXT: OpStore %buffer2 [[tmp_0]] + S buffer2; + buffer2 = myTBuffer; + +// We have the same struct type here +// CHECK: [[val_1:%[0-9]+]] = OpFunctionCall %S_0 %retStuff +// CHECK-NEXT: OpStore %buffer3 [[val_1]] + S buffer3; + buffer3 = retStuff(); + +// TODO: The underlying struct type has the same layout but %type_TextureBuffer_S +// has an additional BufferBlock decoration. So this causes an validation error. +// CHECK: [[ptr:%[0-9]+]] = OpAccessChain %_ptr_Uniform_S %myASBuffer %uint_0 {{%[0-9]+}} +// CHECK-NEXT: [[tb:%[0-9]+]] = OpLoad %type_TextureBuffer_S %myTBuffer +// CHECK-NEXT: [[vec_1:%[0-9]+]] = OpCompositeExtract %v4float [[tb]] 0 +// CHECK-NEXT: [[loc:%[0-9]+]] = OpCompositeConstruct %S_0 [[vec_1]] +// CHECK-NEXT: [[vec_2:%[0-9]+]] = OpCompositeExtract %v4float [[loc]] 0 +// CHECK-NEXT: [[val_2:%[0-9]+]] = OpCompositeConstruct %S [[vec_2]] +// CHECK-NEXT: OpStore [[ptr]] [[val_2]] + myASBuffer.Append(myTBuffer); + +// Passing a TextureBuffer to a T parameter is a copy +// CHECK: [[val_3:%[0-9]+]] = OpLoad %type_TextureBuffer_S %myTBuffer +// CHECK-NEXT: [[vec_3:%[0-9]+]] = OpCompositeExtract %v4float [[val_3]] 0 +// CHECK-NEXT: [[tmp_1:%[0-9]+]] = OpCompositeConstruct %S_0 [[vec_3]] +// CHECK-NEXT: OpStore %param_var_buffer [[tmp_1]] + return doStuff(myTBuffer); +} + +S retStuff() { +// Returning a TextureBuffer as a T is a copy +// CHECK: [[val_4:%[0-9]+]] = OpLoad %type_TextureBuffer_S %myTBuffer +// CHECK-NEXT: [[vec_4:%[0-9]+]] = OpCompositeExtract %v4float [[val_4]] 0 +// CHECK-NEXT: [[ret:%[0-9]+]] = OpCompositeConstruct %S_0 [[vec_4]] +// CHECK-NEXT: OpReturnValue [[ret]] + return myTBuffer; +} diff --git a/tools/clang/test/CodeGenSPIRV/spirv.stage-io.16bit.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/spirv.stage-io.16bit.hlsl similarity index 95% rename from tools/clang/test/CodeGenSPIRV/spirv.stage-io.16bit.hlsl rename to tools/clang/test/CodeGenSPIRV_Lit/spirv.stage-io.16bit.hlsl index 0082d15623..78eb29663c 100644 --- a/tools/clang/test/CodeGenSPIRV/spirv.stage-io.16bit.hlsl +++ b/tools/clang/test/CodeGenSPIRV_Lit/spirv.stage-io.16bit.hlsl @@ -1,4 +1,4 @@ -// RUN: %dxc -T vs_6_2 -E main -enable-16bit-types +// RUN: %dxc -T vs_6_2 -E main -enable-16bit-types -fcgl %s -spirv | FileCheck %s // CHECK: OpCapability StorageInputOutput16 diff --git a/tools/clang/test/CodeGenSPIRV/spirv.stage-io.relaxed-precision.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/spirv.stage-io.relaxed-precision.hlsl similarity index 97% rename from tools/clang/test/CodeGenSPIRV/spirv.stage-io.relaxed-precision.hlsl rename to tools/clang/test/CodeGenSPIRV_Lit/spirv.stage-io.relaxed-precision.hlsl index db650fe50b..81245937e4 100644 --- a/tools/clang/test/CodeGenSPIRV/spirv.stage-io.relaxed-precision.hlsl +++ b/tools/clang/test/CodeGenSPIRV_Lit/spirv.stage-io.relaxed-precision.hlsl @@ -1,4 +1,4 @@ -// RUN: %dxc -T vs_6_2 -E main +// RUN: %dxc -T vs_6_2 -E main -fcgl %s -spirv | FileCheck %s // CHECK: OpDecorate %in_var_A Location 0 // CHECK: OpDecorate %in_var_B Location 4 diff --git a/tools/clang/test/CodeGenSPIRV/spirv.user-semantic.vs.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/spirv.user-semantic.vs.hlsl similarity index 92% rename from tools/clang/test/CodeGenSPIRV/spirv.user-semantic.vs.hlsl rename to tools/clang/test/CodeGenSPIRV_Lit/spirv.user-semantic.vs.hlsl index 7aa11e854a..3ac2611663 100644 --- a/tools/clang/test/CodeGenSPIRV/spirv.user-semantic.vs.hlsl +++ b/tools/clang/test/CodeGenSPIRV_Lit/spirv.user-semantic.vs.hlsl @@ -1,4 +1,4 @@ -// RUN: %dxc -T vs_6_0 -E main -fspv-reflect +// RUN: %dxc -T vs_6_0 -E main -fspv-reflect -fcgl %s -spirv | FileCheck %s // CHECK: OpExtension "SPV_GOOGLE_hlsl_functionality1" diff --git a/tools/clang/test/CodeGenSPIRV_Lit/spv.inline.executionmode.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/spv.inline.executionmode.hlsl new file mode 100644 index 0000000000..b57585d36e --- /dev/null +++ b/tools/clang/test/CodeGenSPIRV_Lit/spv.inline.executionmode.hlsl @@ -0,0 +1,6 @@ +// RUN: %dxc -T ps_6_0 -E main -fcgl %s -spirv | FileCheck %s + +// CHECK: OpExecutionMode %main DepthLess +// CHECK-NEXT: OpExecutionMode %main PostDepthCoverage +[[vk::spvexecutionmode(4446),vk::spvexecutionmode(15)]] +void main() {} diff --git a/tools/clang/test/CodeGenSPIRV_Lit/spv.inline.executionmode.undefined.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/spv.inline.executionmode.undefined.hlsl new file mode 100644 index 0000000000..b7743faf92 --- /dev/null +++ b/tools/clang/test/CodeGenSPIRV_Lit/spv.inline.executionmode.undefined.hlsl @@ -0,0 +1,5 @@ +// RUN: not %dxc -T ps_6_0 -E main -fcgl %s -spirv 2>&1 | FileCheck %s + +// CHECK: Invalid execution mode operand: 999999 +[[vk::spvexecutionmode(999999)]] +void main() {} diff --git a/tools/clang/test/CodeGenSPIRV_Lit/texture.calculate.lod.compute.linear.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/texture.calculate.lod.compute.linear.hlsl new file mode 100644 index 0000000000..00cdf1aa48 --- /dev/null +++ b/tools/clang/test/CodeGenSPIRV_Lit/texture.calculate.lod.compute.linear.hlsl @@ -0,0 +1,22 @@ +// RUN: %dxc -T cs_6_6 -E main -fspv-extension=SPV_NV_compute_shader_derivatives -fcgl %s -spirv 2>&1 | FileCheck %s + +// CHECK: OpCapability ComputeDerivativeGroupLinearNV +// CHECK: OpExtension "SPV_NV_compute_shader_derivatives" +// CHECK: OpExecutionMode %main DerivativeGroupLinearNV + +SamplerState ss : register(s2); +SamplerComparisonState scs; + +RWStructuredBuffer o; +Texture1D t1; + +[numthreads(16,1,1)] +void main(uint3 id : SV_GroupThreadID) +{ + //CHECK: [[t1:%[0-9]+]] = OpLoad %type_1d_image %t1 + //CHECK-NEXT: [[ss1:%[0-9]+]] = OpLoad %type_sampler %ss + //CHECK-NEXT: [[si1:%[0-9]+]] = OpSampledImage %type_sampled_image [[t1]] [[ss1]] + //CHECK-NEXT: [[query1:%[0-9]+]] = OpImageQueryLod %v2float [[si1]] %float_0_5 + //CHECK-NEXT: {{%[0-9]+}} = OpCompositeExtract %float [[query1]] 0 + o[0] = t1.CalculateLevelOfDetail(ss, 0.5); +} \ No newline at end of file diff --git a/tools/clang/test/CodeGenSPIRV_Lit/texture.calculate.lod.compute.quad.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/texture.calculate.lod.compute.quad.hlsl new file mode 100644 index 0000000000..8ed4ebed3c --- /dev/null +++ b/tools/clang/test/CodeGenSPIRV_Lit/texture.calculate.lod.compute.quad.hlsl @@ -0,0 +1,22 @@ +// RUN: %dxc -T cs_6_6 -E main -fspv-extension=SPV_NV_compute_shader_derivatives -fcgl %s -spirv 2>&1 | FileCheck %s + +// CHECK: OpCapability ComputeDerivativeGroupQuadsNV +// CHECK: OpExtension "SPV_NV_compute_shader_derivatives" +// CHECK: OpExecutionMode %main DerivativeGroupQuadsNV + +SamplerState ss : register(s2); +SamplerComparisonState scs; + +RWStructuredBuffer o; +Texture1D t1; + +[numthreads(8,8,1)] +void main(uint3 id : SV_GroupThreadID) +{ + //CHECK: [[t1:%[0-9]+]] = OpLoad %type_1d_image %t1 + //CHECK-NEXT: [[ss1:%[0-9]+]] = OpLoad %type_sampler %ss + //CHECK-NEXT: [[si1:%[0-9]+]] = OpSampledImage %type_sampled_image [[t1]] [[ss1]] + //CHECK-NEXT: [[query1:%[0-9]+]] = OpImageQueryLod %v2float [[si1]] %float_0_5 + //CHECK-NEXT: {{%[0-9]+}} = OpCompositeExtract %float [[query1]] 0 + o[0] = t1.CalculateLevelOfDetail(ss, 0.5); +} \ No newline at end of file diff --git a/tools/clang/test/CodeGenSPIRV_Lit/texture.calculate.lod.unclamped.compute.linear.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/texture.calculate.lod.unclamped.compute.linear.hlsl new file mode 100644 index 0000000000..617dcdab47 --- /dev/null +++ b/tools/clang/test/CodeGenSPIRV_Lit/texture.calculate.lod.unclamped.compute.linear.hlsl @@ -0,0 +1,22 @@ +// RUN: %dxc -T cs_6_6 -E main -fspv-extension=SPV_NV_compute_shader_derivatives -fcgl %s -spirv 2>&1 | FileCheck %s + +// CHECK: OpCapability ComputeDerivativeGroupLinearNV +// CHECK: OpExtension "SPV_NV_compute_shader_derivatives" +// CHECK: OpExecutionMode %main DerivativeGroupLinearNV + +SamplerState ss : register(s2); +SamplerComparisonState scs; + +RWStructuredBuffer o; +Texture1D t1; + +[numthreads(4,1,1)] +void main(uint3 id : SV_GroupThreadID) +{ + //CHECK: [[t1:%[0-9]+]] = OpLoad %type_1d_image %t1 + //CHECK-NEXT: [[ss1:%[0-9]+]] = OpLoad %type_sampler %ss + //CHECK-NEXT: [[si1:%[0-9]+]] = OpSampledImage %type_sampled_image [[t1]] [[ss1]] + //CHECK-NEXT: [[query1:%[0-9]+]] = OpImageQueryLod %v2float [[si1]] %float_0_5 + //CHECK-NEXT: {{%[0-9]+}} = OpCompositeExtract %float [[query1]] 1 + o[0] = t1.CalculateLevelOfDetailUnclamped(ss, 0.5); +} \ No newline at end of file diff --git a/tools/clang/test/CodeGenSPIRV_Lit/texture.calculate.lod.unclamped.compute.quad.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/texture.calculate.lod.unclamped.compute.quad.hlsl new file mode 100644 index 0000000000..ebaad50b55 --- /dev/null +++ b/tools/clang/test/CodeGenSPIRV_Lit/texture.calculate.lod.unclamped.compute.quad.hlsl @@ -0,0 +1,22 @@ +// RUN: %dxc -T cs_6_6 -E main -fspv-extension=SPV_NV_compute_shader_derivatives -fcgl %s -spirv 2>&1 | FileCheck %s + +// CHECK: OpCapability ComputeDerivativeGroupQuadsNV +// CHECK: OpExtension "SPV_NV_compute_shader_derivatives" +// CHECK: OpExecutionMode %main DerivativeGroupQuadsNV + +SamplerState ss : register(s2); +SamplerComparisonState scs; + +RWStructuredBuffer o; +Texture1D t1; + +[numthreads(4,24,1)] +void main(uint3 id : SV_GroupThreadID) +{ + //CHECK: [[t1:%[0-9]+]] = OpLoad %type_1d_image %t1 + //CHECK-NEXT: [[ss1:%[0-9]+]] = OpLoad %type_sampler %ss + //CHECK-NEXT: [[si1:%[0-9]+]] = OpSampledImage %type_sampled_image [[t1]] [[ss1]] + //CHECK-NEXT: [[query1:%[0-9]+]] = OpImageQueryLod %v2float [[si1]] %float_0_5 + //CHECK-NEXT: {{%[0-9]+}} = OpCompositeExtract %float [[query1]] 1 + o[0] = t1.CalculateLevelOfDetailUnclamped(ss, 0.5); +} \ No newline at end of file diff --git a/tools/clang/test/CodeGenSPIRV_Lit/texture.sample-invalid-implicit-lod.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/texture.sample-invalid-implicit-lod.hlsl index 8f4e0a4782..b58864283b 100644 --- a/tools/clang/test/CodeGenSPIRV_Lit/texture.sample-invalid-implicit-lod.hlsl +++ b/tools/clang/test/CodeGenSPIRV_Lit/texture.sample-invalid-implicit-lod.hlsl @@ -10,20 +10,20 @@ Texture3D t3 : register(t3); TextureCube t4 : register(t4); float4 main(int2 offset: A) : SV_Position { -// CHECK: sampling with implicit lod is only allowed in fragment shaders +// CHECK: sampling with implicit lod is only allowed in fragment and compute shaders float4 val1 = t1.Sample(gSampler, 0.5); -// CHECK: sampling with implicit lod is only allowed in fragment shaders +// CHECK: sampling with implicit lod is only allowed in fragment and compute shaders float4 val3 = t3.Sample(gSampler, float3(0.5, 0.25, 0.3), 3); -// CHECK: sampling with implicit lod is only allowed in fragment shaders +// CHECK: sampling with implicit lod is only allowed in fragment and compute shaders float4 val4 = t4.Sample(gSampler, float3(0.5, 0.25, 0.3)); -// CHECK: sampling with implicit lod is only allowed in fragment shaders +// CHECK: sampling with implicit lod is only allowed in fragment and compute shaders float4 val6 = t4.Sample(gSampler, float3(0.5, 0.25, 0.3), /*clamp*/ 2.0f); uint status; -// CHECK: sampling with implicit lod is only allowed in fragment shaders +// CHECK: sampling with implicit lod is only allowed in fragment and compute shaders float4 val8 = t4.Sample(gSampler, float3(0.5, 0.25, 0.3), /*clamp*/ 2.0f, status); return float4(0.0, 0.0, 0.0, 1.0); diff --git a/tools/clang/test/CodeGenSPIRV_Lit/texture.sample.compute.linear.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/texture.sample.compute.linear.hlsl new file mode 100644 index 0000000000..bdaa1fd99a --- /dev/null +++ b/tools/clang/test/CodeGenSPIRV_Lit/texture.sample.compute.linear.hlsl @@ -0,0 +1,21 @@ +// RUN: %dxc -T cs_6_6 -E main -fspv-extension=SPV_NV_compute_shader_derivatives -fcgl %s -spirv 2>&1 | FileCheck %s + +// CHECK: OpCapability ComputeDerivativeGroupLinearNV +// CHECK: OpExtension "SPV_NV_compute_shader_derivatives" +// CHECK: OpExecutionMode %main DerivativeGroupLinearNV + +SamplerState ss : register(s2); +SamplerComparisonState scs; + +RWStructuredBuffer o; +Texture1D t1; + +[numthreads(24,1,1)] +void main(uint3 id : SV_GroupThreadID) +{ + // CHECK: [[t1:%[0-9]+]] = OpLoad %type_1d_image %t1 + // CHECK-NEXT: [[ss:%[0-9]+]] = OpLoad %type_sampler %ss + // CHECK-NEXT: [[sampledImg:%[0-9]+]] = OpSampledImage %type_sampled_image [[t1]] [[ss]] + // CHECK-NEXT: {{%[0-9]+}} = OpImageSampleImplicitLod %v4float [[sampledImg]] %float_1 None + o[0] = t1.Sample(ss, 1); +} \ No newline at end of file diff --git a/tools/clang/test/CodeGenSPIRV_Lit/texture.sample.compute.quad.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/texture.sample.compute.quad.hlsl new file mode 100644 index 0000000000..9f846f1374 --- /dev/null +++ b/tools/clang/test/CodeGenSPIRV_Lit/texture.sample.compute.quad.hlsl @@ -0,0 +1,21 @@ +// RUN: %dxc -T cs_6_6 -E main -fspv-extension=SPV_NV_compute_shader_derivatives -fcgl %s -spirv 2>&1 | FileCheck %s + +// CHECK: OpCapability ComputeDerivativeGroupQuadsNV +// CHECK: OpExtension "SPV_NV_compute_shader_derivatives" +// CHECK: OpExecutionMode %main DerivativeGroupQuadsNV + +SamplerState ss : register(s2); +SamplerComparisonState scs; + +RWStructuredBuffer o; +Texture1D t1; + +[numthreads(2,2,1)] +void main(uint3 id : SV_GroupThreadID) +{ + // CHECK: [[t1:%[0-9]+]] = OpLoad %type_1d_image %t1 + // CHECK-NEXT: [[ss:%[0-9]+]] = OpLoad %type_sampler %ss + // CHECK-NEXT: [[sampledImg:%[0-9]+]] = OpSampledImage %type_sampled_image [[t1]] [[ss]] + // CHECK-NEXT: {{%[0-9]+}} = OpImageSampleImplicitLod %v4float [[sampledImg]] %float_1 None + o[0] = t1.Sample(ss, 1); +} \ No newline at end of file diff --git a/tools/clang/test/CodeGenSPIRV_Lit/texture.samplebias.compute.linear.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/texture.samplebias.compute.linear.hlsl new file mode 100644 index 0000000000..4db7b5f336 --- /dev/null +++ b/tools/clang/test/CodeGenSPIRV_Lit/texture.samplebias.compute.linear.hlsl @@ -0,0 +1,21 @@ +// RUN: %dxc -T cs_6_6 -E main -fspv-extension=SPV_NV_compute_shader_derivatives -fcgl %s -spirv 2>&1 | FileCheck %s + +// CHECK: OpCapability ComputeDerivativeGroupLinearNV +// CHECK: OpExtension "SPV_NV_compute_shader_derivatives" +// CHECK: OpExecutionMode %main DerivativeGroupLinearNV + +SamplerState ss : register(s2); +SamplerComparisonState scs; + +RWStructuredBuffer o; +Texture1D t1; + +[numthreads(8,1,1)] +void main(uint3 id : SV_GroupThreadID) +{ + // CHECK: [[t1:%[0-9]+]] = OpLoad %type_1d_image %t1 + // CHECK-NEXT: [[ss:%[0-9]+]] = OpLoad %type_sampler %ss + // CHECK-NEXT: [[sampledImg:%[0-9]+]] = OpSampledImage %type_sampled_image [[t1]] [[ss]] + // CHECK-NEXT: {{%[0-9]+}} = OpImageSampleImplicitLod %v4float [[sampledImg]] %float_1 Bias %float_0_5 + o[0] = t1.SampleBias(ss, 1, 0.5); +} \ No newline at end of file diff --git a/tools/clang/test/CodeGenSPIRV_Lit/texture.samplebias.compute.quad.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/texture.samplebias.compute.quad.hlsl new file mode 100644 index 0000000000..e90f5d81bb --- /dev/null +++ b/tools/clang/test/CodeGenSPIRV_Lit/texture.samplebias.compute.quad.hlsl @@ -0,0 +1,21 @@ +// RUN: %dxc -T cs_6_6 -E main -fspv-extension=SPV_NV_compute_shader_derivatives -fcgl %s -spirv 2>&1 | FileCheck %s + +// CHECK: OpCapability ComputeDerivativeGroupQuadsNV +// CHECK: OpExtension "SPV_NV_compute_shader_derivatives" +// CHECK: OpExecutionMode %main DerivativeGroupQuadsNV + +SamplerState ss : register(s2); +SamplerComparisonState scs; + +RWStructuredBuffer o; +Texture1D t1; + +[numthreads(4,4,1)] +void main(uint3 id : SV_GroupThreadID) +{ + // CHECK: [[t1:%[0-9]+]] = OpLoad %type_1d_image %t1 + // CHECK-NEXT: [[ss:%[0-9]+]] = OpLoad %type_sampler %ss + // CHECK-NEXT: [[sampledImg:%[0-9]+]] = OpSampledImage %type_sampled_image [[t1]] [[ss]] + // CHECK-NEXT: {{%[0-9]+}} = OpImageSampleImplicitLod %v4float [[sampledImg]] %float_1 Bias %float_0_5 + o[0] = t1.SampleBias(ss, 1, 0.5); +} \ No newline at end of file diff --git a/tools/clang/test/CodeGenSPIRV_Lit/texture.samplecmp.compute.linear.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/texture.samplecmp.compute.linear.hlsl new file mode 100644 index 0000000000..6c1904aaa5 --- /dev/null +++ b/tools/clang/test/CodeGenSPIRV_Lit/texture.samplecmp.compute.linear.hlsl @@ -0,0 +1,21 @@ +// RUN: %dxc -T cs_6_6 -E main -fspv-extension=SPV_NV_compute_shader_derivatives -fcgl %s -spirv 2>&1 | FileCheck %s + +// CHECK: OpCapability ComputeDerivativeGroupLinearNV +// CHECK: OpExtension "SPV_NV_compute_shader_derivatives" +// CHECK: OpExecutionMode %main DerivativeGroupLinearNV + +SamplerState ss : register(s2); +SamplerComparisonState scs; + +RWStructuredBuffer o; +Texture1D t1; + +[numthreads(12,1,1)] +void main(uint3 id : SV_GroupThreadID) +{ + // CHECK: [[t1:%[0-9]+]] = OpLoad %type_1d_image %t1 + // CHECK-NEXT: [[scs:%[0-9]+]] = OpLoad %type_sampler %scs + // CHECK-NEXT: [[sampledImg:%[0-9]+]] = OpSampledImage %type_sampled_image [[t1]] [[scs]] + // CHECK-NEXT: {{%[0-9]+}} = OpImageSampleDrefImplicitLod %float [[sampledImg]] %float_1 %float_0_5 + o[0] = t1.SampleCmp(scs, 1, 0.5); +} \ No newline at end of file diff --git a/tools/clang/test/CodeGenSPIRV_Lit/texture.samplecmp.compute.quad.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/texture.samplecmp.compute.quad.hlsl new file mode 100644 index 0000000000..a54bda3e9b --- /dev/null +++ b/tools/clang/test/CodeGenSPIRV_Lit/texture.samplecmp.compute.quad.hlsl @@ -0,0 +1,21 @@ +// RUN: %dxc -T cs_6_6 -E main -fspv-extension=SPV_NV_compute_shader_derivatives -fcgl %s -spirv 2>&1 | FileCheck %s + +// CHECK: OpCapability ComputeDerivativeGroupQuadsNV +// CHECK: OpExtension "SPV_NV_compute_shader_derivatives" +// CHECK: OpExecutionMode %main DerivativeGroupQuadsNV + +SamplerState ss : register(s2); +SamplerComparisonState scs; + +RWStructuredBuffer o; +Texture1D t1; + +[numthreads(2,10,1)] +void main(uint3 id : SV_GroupThreadID) +{ + // CHECK: [[t1:%[0-9]+]] = OpLoad %type_1d_image %t1 + // CHECK-NEXT: [[scs:%[0-9]+]] = OpLoad %type_sampler %scs + // CHECK-NEXT: [[sampledImg:%[0-9]+]] = OpSampledImage %type_sampled_image [[t1]] [[scs]] + // CHECK-NEXT: {{%[0-9]+}} = OpImageSampleDrefImplicitLod %float [[sampledImg]] %float_1 %float_0_5 + o[0] = t1.SampleCmp(scs, 1, 0.5); +} \ No newline at end of file diff --git a/tools/clang/test/CodeGenSPIRV_Lit/undefined.static.template.member.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/undefined.static.template.member.hlsl new file mode 100644 index 0000000000..9a94e9cedd --- /dev/null +++ b/tools/clang/test/CodeGenSPIRV_Lit/undefined.static.template.member.hlsl @@ -0,0 +1,21 @@ +// RUN: not %dxc -T ps_6_7 -E main -fcgl %s -spirv 2>&1 | FileCheck %s + +template +struct GaussLegendreValues +{ + const static T wi[N]; +}; + +static int test_value = 1567; + +float main() : SV_Target +{ + return float(GaussLegendreValues<2>::wi[test_value]); +} + +// CHECK: :6:20: warning: variable 'GaussLegendreValues<2, double>::wi' has internal linkage but is not defined [-Wundefined-internal] +// CHECK-NEXT: const static T wi[N]; +// CHECK: :13:42: note: used here +// CHECK-NEXT: return float(GaussLegendreValues<2>::wi[test_value]); +// CHECK: :6:20: fatal error: found unregistered decl +// CHECK-NEXT: const static T wi[N]; diff --git a/tools/clang/test/CodeGenSPIRV_Lit/unsupported/rayquery_init_rgen.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/unsupported/rayquery_init_rgen.hlsl index d719b127ec..7cc122601e 100644 --- a/tools/clang/test/CodeGenSPIRV_Lit/unsupported/rayquery_init_rgen.hlsl +++ b/tools/clang/test/CodeGenSPIRV_Lit/unsupported/rayquery_init_rgen.hlsl @@ -4,7 +4,8 @@ // CHECK: OpExtension "SPV_KHR_ray_tracing" // CHECK: OpExtension "SPV_KHR_ray_query" -// CHECK-COUNT-1: [[rs:%\d+]] = OpTypeAccelerationStructureNV +// CHECK: %accelerationStructureNV = OpTypeAccelerationStructureKHR +// CHECK-NOT: OpTypeAccelerationStructureKHR RaytracingAccelerationStructure AccelerationStructure : register(t0); RayDesc MakeRayDesc() { diff --git a/tools/clang/test/CodeGenSPIRV/use.rvalue.for.member-expr.of.array-subscript.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/use.rvalue.for.member-expr.of.array-subscript.hlsl similarity index 82% rename from tools/clang/test/CodeGenSPIRV/use.rvalue.for.member-expr.of.array-subscript.hlsl rename to tools/clang/test/CodeGenSPIRV_Lit/use.rvalue.for.member-expr.of.array-subscript.hlsl index 865a142040..f99394913d 100644 --- a/tools/clang/test/CodeGenSPIRV/use.rvalue.for.member-expr.of.array-subscript.hlsl +++ b/tools/clang/test/CodeGenSPIRV_Lit/use.rvalue.for.member-expr.of.array-subscript.hlsl @@ -1,4 +1,4 @@ -// RUN: %dxc -T cs_6_0 -E main -HV 2021 +// RUN: %dxc -T cs_6_0 -E main -HV 2021 -fcgl %s -spirv | FileCheck %s // Tests that a rvalue is used for the index of ArraySubscriptExpr. The newly // introduced template support generates a template instance of @@ -13,8 +13,8 @@ struct BufferAccess { template T load(uint index) { - // CHECK: [[handle_ptr:%\d+]] = OpAccessChain %_ptr_Function_uint %param_this %int_0 - // CHECK: [[handle:%\d+]] = OpLoad %uint [[handle_ptr]] + // CHECK: [[handle_ptr:%[0-9]+]] = OpAccessChain %_ptr_Function_uint %param_this %int_0 + // CHECK: [[handle:%[0-9]+]] = OpLoad %uint [[handle_ptr]] // CHECK: OpAccessChain %_ptr_Uniform_type_ByteAddressBuffer %babuf [[handle]] return babuf[this.handle].Load(index * sizeof(T)); } diff --git a/tools/clang/test/CodeGenSPIRV_Lit/var.init.struct.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/var.init.struct.hlsl new file mode 100644 index 0000000000..8166e33c15 --- /dev/null +++ b/tools/clang/test/CodeGenSPIRV_Lit/var.init.struct.hlsl @@ -0,0 +1,106 @@ +// RUN: %dxc -T vs_6_0 -E main -fcgl %s -spirv | FileCheck %s + +struct S { + int3 a; + uint b; + float2x2 c; +}; + +struct T { + // Same fields as S + int3 h; + uint i; + float2x2 j; + + // Additional field + bool2 k; + + // Embedded S + S l; + + // Similar to S but need some casts + float3 m; + int n; + float2x2 o; +}; + +struct O { + int x; +}; + +struct P { + O y; + float z; +}; + +struct Q : O { + float z; +}; + +struct W { + float4 color; +}; + +void main() { +// CHECK-LABEL: %bb_entry = OpLabel + + // Flat initializer list +// CHECK: [[a:%[0-9]+]] = OpCompositeConstruct %v3int %int_1 %int_2 %int_3 +// CHECK-NEXT: [[c0:%[0-9]+]] = OpCompositeConstruct %v2float %float_1 %float_2 +// CHECK-NEXT: [[c1:%[0-9]+]] = OpCompositeConstruct %v2float %float_3 %float_4 +// CHECK-NEXT: [[c:%[0-9]+]] = OpCompositeConstruct %mat2v2float [[c0]] [[c1]] +// CHECK-NEXT: [[s1:%[0-9]+]] = OpCompositeConstruct %S [[a]] %uint_42 [[c]] +// CHECK-NEXT: OpStore %s1 [[s1]] + S s1 = {1, 2, 3, 42, 1., 2., 3., 4.}; + + // Random parentheses +// CHECK: [[a:%[0-9]+]] = OpCompositeConstruct %v3int %int_1 %int_2 %int_3 +// CHECK-NEXT: [[c0:%[0-9]+]] = OpCompositeConstruct %v2float %float_1 %float_2 +// CHECK-NEXT: [[c1:%[0-9]+]] = OpCompositeConstruct %v2float %float_3 %float_4 +// CHECK-NEXT: [[c:%[0-9]+]] = OpCompositeConstruct %mat2v2float [[c0]] [[c1]] +// CHECK-NEXT: [[s2:%[0-9]+]] = OpCompositeConstruct %S [[a]] %uint_42 [[c]] +// CHECK-NEXT: OpStore %s2 [[s2]] + S s2 = {{1, 2}, 3, {{42}, {{1.}}}, {2., {3., 4.}}}; + + // Flat initalizer list for nested structs +// CHECK: [[y:%[0-9]+]] = OpCompositeConstruct %O %int_1 +// CHECK-NEXT: [[p:%[0-9]+]] = OpCompositeConstruct %P [[y]] %float_2 +// CHECK-NEXT: OpStore %p [[p]] + P p = {1, 2.}; + + // Initalizer list for struct with inheritance. +// CHECK: [[y:%[0-9]+]] = OpCompositeConstruct %O %int_1 +// CHECK-NEXT: [[q:%[0-9]+]] = OpCompositeConstruct %Q [[y]] %float_2 +// CHECK-NEXT: OpStore %q [[q]] + Q q = {1, 2.}; + + // Mixed case: use struct as a whole, decomposing struct, type casting + +// CHECK-NEXT: [[s1_val:%[0-9]+]] = OpLoad %S %s1 +// CHECK-NEXT: [[l:%[0-9]+]] = OpLoad %S %s2 +// CHECK-NEXT: [[s2_val:%[0-9]+]] = OpLoad %S %s2 +// CHECK-NEXT: [[h:%[0-9]+]] = OpCompositeExtract %v3int [[s1_val]] 0 +// CHECK-NEXT: [[i:%[0-9]+]] = OpCompositeExtract %uint [[s1_val]] 1 +// CHECK-NEXT: [[j:%[0-9]+]] = OpCompositeExtract %mat2v2float [[s1_val]] 2 + +// CHECK-NEXT: [[k:%[0-9]+]] = OpCompositeConstruct %v2bool %true %false + +// CHECK-NEXT: [[s2av:%[0-9]+]] = OpCompositeExtract %v3int [[s2_val]] 0 +// CHECK-NEXT: [[s2bv:%[0-9]+]] = OpCompositeExtract %uint [[s2_val]] 1 +// CHECK-NEXT: [[o:%[0-9]+]] = OpCompositeExtract %mat2v2float [[s2_val]] 2 +// CHECK-NEXT: [[m:%[0-9]+]] = OpConvertSToF %v3float [[s2av]] +// CHECK-NEXT: [[n:%[0-9]+]] = OpBitcast %int [[s2bv]] +// CHECK-NEXT: [[t:%[0-9]+]] = OpCompositeConstruct %T [[h]] [[i]] [[j]] [[k]] [[l]] [[m]] [[n]] [[o]] +// CHECK-NEXT: OpStore %t [[t]] + T t = {s1, // Decomposing struct + true, false, // constructing field from scalar + s2, // Embedded struct + s2 // Decomposing struct + type casting + }; + + // Using InitListExpr +// CHECK: [[int4_zero:%[0-9]+]] = OpCompositeConstruct %v4int %int_0 %int_0 %int_0 %int_0 +// CHECK-NEXT: [[float4_zero:%[0-9]+]] = OpConvertSToF %v4float [[int4_zero]] +// CHECK-NEXT: {{%[0-9]+}} = OpCompositeConstruct %W [[float4_zero]] + W w = { (0).xxxx }; +} diff --git a/tools/clang/test/CodeGenSPIRV/vk.1p2.block-decoration.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/vk.1p2.block-decoration.hlsl similarity index 72% rename from tools/clang/test/CodeGenSPIRV/vk.1p2.block-decoration.hlsl rename to tools/clang/test/CodeGenSPIRV_Lit/vk.1p2.block-decoration.hlsl index 68d8ef1d99..3fc7d1525b 100644 --- a/tools/clang/test/CodeGenSPIRV/vk.1p2.block-decoration.hlsl +++ b/tools/clang/test/CodeGenSPIRV_Lit/vk.1p2.block-decoration.hlsl @@ -1,4 +1,4 @@ -// RUN: %dxc -T cs_6_0 -E main -fspv-target-env=vulkan1.2 +// RUN: %dxc -T cs_6_0 -E main -fspv-target-env=vulkan1.2 -fcgl %s -spirv | FileCheck %s // We cannot use BufferBlock decoration for SPIR-V 1.4 or above. // Instead, we must use Block decorated StorageBuffer Storage Class. @@ -28,11 +28,11 @@ RWStructuredBuffer rwsb; [numthreads(1, 1, 1)] void main() { -// CHECK: [[vec:%\d+]] = OpAccessChain %_ptr_StorageBuffer_v4float %rwsb %int_0 %uint_2 %int_0 %int_1 -// CHECK: {{%\d+}} = OpAccessChain %_ptr_StorageBuffer_float [[vec]] %int_0 +// CHECK: [[vec:%[0-9]+]] = OpAccessChain %_ptr_StorageBuffer_v4float %rwsb %int_0 %uint_2 %int_0 %int_1 +// CHECK: {{%[0-9]+}} = OpAccessChain %_ptr_StorageBuffer_float [[vec]] %int_0 float a = rwsb[2].f[1].x; -// CHECK: [[counterPtr:%\d+]] = OpAccessChain %_ptr_StorageBuffer_int %counter_var_rwsb %uint_0 -// CHECK: {{%\d+}} = OpAtomicIAdd %int [[counterPtr]] %uint_1 %uint_0 %int_1 +// CHECK: [[counterPtr:%[0-9]+]] = OpAccessChain %_ptr_StorageBuffer_int %counter_var_rwsb %uint_0 +// CHECK: {{%[0-9]+}} = OpAtomicIAdd %int [[counterPtr]] %uint_1 %uint_0 %int_1 rwsb.IncrementCounter(); } diff --git a/tools/clang/test/CodeGenSPIRV/vk.1p2.entry-point.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/vk.1p2.entry-point.hlsl similarity index 89% rename from tools/clang/test/CodeGenSPIRV/vk.1p2.entry-point.hlsl rename to tools/clang/test/CodeGenSPIRV_Lit/vk.1p2.entry-point.hlsl index 7b407e518e..319f6c6633 100644 --- a/tools/clang/test/CodeGenSPIRV/vk.1p2.entry-point.hlsl +++ b/tools/clang/test/CodeGenSPIRV_Lit/vk.1p2.entry-point.hlsl @@ -1,4 +1,4 @@ -// RUN: %dxc -T ps_6_0 -E main -fspv-target-env=vulkan1.2 +// RUN: %dxc -T ps_6_0 -E main -fspv-target-env=vulkan1.2 -fcgl %s -spirv | FileCheck %s // CHECK: OpEntryPoint Fragment %main "main" // CHECK-DAG: %_Globals diff --git a/tools/clang/test/CodeGenSPIRV/vk.1p2.remove.bufferblock.runtimearray.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/vk.1p2.remove.bufferblock.runtimearray.hlsl similarity index 91% rename from tools/clang/test/CodeGenSPIRV/vk.1p2.remove.bufferblock.runtimearray.hlsl rename to tools/clang/test/CodeGenSPIRV_Lit/vk.1p2.remove.bufferblock.runtimearray.hlsl index 1f45a8ba2b..3c1973e555 100644 --- a/tools/clang/test/CodeGenSPIRV/vk.1p2.remove.bufferblock.runtimearray.hlsl +++ b/tools/clang/test/CodeGenSPIRV_Lit/vk.1p2.remove.bufferblock.runtimearray.hlsl @@ -1,4 +1,4 @@ -// RUN: %dxc -T cs_6_5 -E main -fspv-target-env=vulkan1.2 +// RUN: %dxc -T cs_6_5 -E main -fspv-target-env=vulkan1.2 -fcgl %s -spirv | FileCheck %s struct MeshPart { uint indexOffset; diff --git a/tools/clang/test/CodeGenSPIRV/vk.1p3.discard.to-demote.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/vk.1p3.discard.to-demote.hlsl similarity index 83% rename from tools/clang/test/CodeGenSPIRV/vk.1p3.discard.to-demote.hlsl rename to tools/clang/test/CodeGenSPIRV_Lit/vk.1p3.discard.to-demote.hlsl index b6bc73fcae..315dfe7f30 100644 --- a/tools/clang/test/CodeGenSPIRV/vk.1p3.discard.to-demote.hlsl +++ b/tools/clang/test/CodeGenSPIRV_Lit/vk.1p3.discard.to-demote.hlsl @@ -1,4 +1,4 @@ -// RUN: %dxc -T ps_6_0 -E main -fspv-target-env=vulkan1.3 +// RUN: %dxc -T ps_6_0 -E main -fspv-target-env=vulkan1.3 -fcgl %s -spirv | FileCheck %s // CHECK: OpCapability DemoteToHelperInvocation diff --git a/tools/clang/test/CodeGenSPIRV/vk.attribute.image-format.arrays.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/vk.attribute.image-format.arrays.hlsl similarity index 85% rename from tools/clang/test/CodeGenSPIRV/vk.attribute.image-format.arrays.hlsl rename to tools/clang/test/CodeGenSPIRV_Lit/vk.attribute.image-format.arrays.hlsl index 625ecc2daf..3d45441060 100644 --- a/tools/clang/test/CodeGenSPIRV/vk.attribute.image-format.arrays.hlsl +++ b/tools/clang/test/CodeGenSPIRV_Lit/vk.attribute.image-format.arrays.hlsl @@ -1,4 +1,4 @@ -// RUN: %dxc -T cs_6_0 -E main +// RUN: %dxc -T cs_6_0 -E main -fcgl %s -spirv | FileCheck %s // CHECK: OpTypeImage %float Buffer 2 0 0 2 Rgba16f [[vk::image_format("rgba16f")]] diff --git a/tools/clang/test/CodeGenSPIRV/vk.attribute.image-format.o3.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/vk.attribute.image-format.o3.hlsl similarity index 95% rename from tools/clang/test/CodeGenSPIRV/vk.attribute.image-format.o3.hlsl rename to tools/clang/test/CodeGenSPIRV_Lit/vk.attribute.image-format.o3.hlsl index 93cdf76a3d..5b6a84d10d 100644 --- a/tools/clang/test/CodeGenSPIRV/vk.attribute.image-format.o3.hlsl +++ b/tools/clang/test/CodeGenSPIRV_Lit/vk.attribute.image-format.o3.hlsl @@ -1,4 +1,4 @@ -// RUN: %dxc -T cs_6_0 -E main -O3 +// RUN: %dxc -T cs_6_0 -E main -O3 %s -spirv | FileCheck %s //CHECK: OpTypeImage %float Buffer 2 0 0 2 Rgba16f [[vk::image_format("rgba16f")]] diff --git a/tools/clang/test/CodeGenSPIRV/vk.attribute.image-format.simple.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/vk.attribute.image-format.simple.hlsl similarity index 83% rename from tools/clang/test/CodeGenSPIRV/vk.attribute.image-format.simple.hlsl rename to tools/clang/test/CodeGenSPIRV_Lit/vk.attribute.image-format.simple.hlsl index f4b1629682..07eb7a8828 100644 --- a/tools/clang/test/CodeGenSPIRV/vk.attribute.image-format.simple.hlsl +++ b/tools/clang/test/CodeGenSPIRV_Lit/vk.attribute.image-format.simple.hlsl @@ -1,4 +1,4 @@ -// RUN: %dxc -T cs_6_0 -E main -O3 +// RUN: %dxc -T cs_6_0 -E main -O3 %s -spirv | FileCheck %s //CHECK: OpTypeImage %float Buffer 2 0 0 2 Rgba16f [[vk::image_format("rgba16f")]] diff --git a/tools/clang/test/CodeGenSPIRV/vk.binding.cl.auto-shift-bindings.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/vk.binding.cl.auto-shift-bindings.hlsl similarity index 98% rename from tools/clang/test/CodeGenSPIRV/vk.binding.cl.auto-shift-bindings.hlsl rename to tools/clang/test/CodeGenSPIRV_Lit/vk.binding.cl.auto-shift-bindings.hlsl index 81daa54dbe..2789f7d341 100644 --- a/tools/clang/test/CodeGenSPIRV/vk.binding.cl.auto-shift-bindings.hlsl +++ b/tools/clang/test/CodeGenSPIRV_Lit/vk.binding.cl.auto-shift-bindings.hlsl @@ -1,4 +1,4 @@ -// RUN: %dxc -T ps_6_0 -E main -fvk-b-shift 100 0 -fvk-t-shift 200 0 -fvk-t-shift 300 1 -fvk-s-shift 500 0 -fvk-u-shift 700 0 -fvk-auto-shift-bindings -fspv-flatten-resource-arrays +// RUN: %dxc -T ps_6_0 -E main -fvk-b-shift 100 0 -fvk-t-shift 200 0 -fvk-t-shift 300 1 -fvk-s-shift 500 0 -fvk-u-shift 700 0 -fvk-auto-shift-bindings -fspv-flatten-resource-arrays -fcgl %s -spirv | FileCheck %s // Tests that we can set shift for more than one sets of the same register type // Tests that we can override shift for the same set diff --git a/tools/clang/test/CodeGenSPIRV/vk.binding.cl.flatten-arrays.example1-optimized.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/vk.binding.cl.flatten-arrays.example1-optimized.hlsl similarity index 98% rename from tools/clang/test/CodeGenSPIRV/vk.binding.cl.flatten-arrays.example1-optimized.hlsl rename to tools/clang/test/CodeGenSPIRV_Lit/vk.binding.cl.flatten-arrays.example1-optimized.hlsl index 869e959fb2..efe6e50bda 100644 --- a/tools/clang/test/CodeGenSPIRV/vk.binding.cl.flatten-arrays.example1-optimized.hlsl +++ b/tools/clang/test/CodeGenSPIRV_Lit/vk.binding.cl.flatten-arrays.example1-optimized.hlsl @@ -1,4 +1,4 @@ -// RUN: %dxc -T ps_6_0 -E main -fspv-flatten-resource-arrays -O3 +// RUN: %dxc -T ps_6_0 -E main -fspv-flatten-resource-arrays -O3 %s -spirv | FileCheck %s // CHECK: OpDecorate %AnotherTexture Binding 5 // CHECK: OpDecorate %NextTexture Binding 6 diff --git a/tools/clang/test/CodeGenSPIRV/vk.binding.cl.flatten-arrays.example1.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/vk.binding.cl.flatten-arrays.example1.hlsl similarity index 89% rename from tools/clang/test/CodeGenSPIRV/vk.binding.cl.flatten-arrays.example1.hlsl rename to tools/clang/test/CodeGenSPIRV_Lit/vk.binding.cl.flatten-arrays.example1.hlsl index 75a39268ba..a005907c09 100644 --- a/tools/clang/test/CodeGenSPIRV/vk.binding.cl.flatten-arrays.example1.hlsl +++ b/tools/clang/test/CodeGenSPIRV_Lit/vk.binding.cl.flatten-arrays.example1.hlsl @@ -1,4 +1,4 @@ -// RUN: %dxc -T ps_6_0 -E main -fspv-flatten-resource-arrays +// RUN: %dxc -T ps_6_0 -E main -fspv-flatten-resource-arrays -fcgl %s -spirv | FileCheck %s // CHECK: OpDecorate %MyTextures Binding 0 // CHECK: OpDecorate %AnotherTexture Binding 5 diff --git a/tools/clang/test/CodeGenSPIRV/vk.binding.cl.flatten-arrays.example2-optimized.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/vk.binding.cl.flatten-arrays.example2-optimized.hlsl similarity index 98% rename from tools/clang/test/CodeGenSPIRV/vk.binding.cl.flatten-arrays.example2-optimized.hlsl rename to tools/clang/test/CodeGenSPIRV_Lit/vk.binding.cl.flatten-arrays.example2-optimized.hlsl index 89c2da3938..2f14468544 100644 --- a/tools/clang/test/CodeGenSPIRV/vk.binding.cl.flatten-arrays.example2-optimized.hlsl +++ b/tools/clang/test/CodeGenSPIRV_Lit/vk.binding.cl.flatten-arrays.example2-optimized.hlsl @@ -1,4 +1,4 @@ -// RUN: %dxc -T ps_6_0 -E main -fspv-flatten-resource-arrays -O3 +// RUN: %dxc -T ps_6_0 -E main -fspv-flatten-resource-arrays -O3 %s -spirv | FileCheck %s // CHECK: OpDecorate %AnotherTexture Binding 3 // CHECK: OpDecorate %MySampler Binding 2 diff --git a/tools/clang/test/CodeGenSPIRV/vk.binding.cl.flatten-arrays.example2.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/vk.binding.cl.flatten-arrays.example2.hlsl similarity index 92% rename from tools/clang/test/CodeGenSPIRV/vk.binding.cl.flatten-arrays.example2.hlsl rename to tools/clang/test/CodeGenSPIRV_Lit/vk.binding.cl.flatten-arrays.example2.hlsl index 36bda8c53c..a0cc5d1906 100644 --- a/tools/clang/test/CodeGenSPIRV/vk.binding.cl.flatten-arrays.example2.hlsl +++ b/tools/clang/test/CodeGenSPIRV_Lit/vk.binding.cl.flatten-arrays.example2.hlsl @@ -1,4 +1,4 @@ -// RUN: %dxc -T ps_6_0 -E main -fspv-flatten-resource-arrays +// RUN: %dxc -T ps_6_0 -E main -fspv-flatten-resource-arrays -fcgl %s -spirv | FileCheck %s // CHECK: OpDecorate %AnotherTexture Binding 3 diff --git a/tools/clang/test/CodeGenSPIRV/vk.binding.cl.flatten-arrays.example3.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/vk.binding.cl.flatten-arrays.example3.hlsl similarity index 97% rename from tools/clang/test/CodeGenSPIRV/vk.binding.cl.flatten-arrays.example3.hlsl rename to tools/clang/test/CodeGenSPIRV_Lit/vk.binding.cl.flatten-arrays.example3.hlsl index 86cce66a83..da1e41de0c 100644 --- a/tools/clang/test/CodeGenSPIRV/vk.binding.cl.flatten-arrays.example3.hlsl +++ b/tools/clang/test/CodeGenSPIRV_Lit/vk.binding.cl.flatten-arrays.example3.hlsl @@ -1,4 +1,4 @@ -// RUN: %dxc -T ps_6_0 -E main -fspv-flatten-resource-arrays -O3 +// RUN: %dxc -T ps_6_0 -E main -fspv-flatten-resource-arrays -O3 %s -spirv | FileCheck %s // This shader tests that loop unrolling is performed before resource array // flattening is done. diff --git a/tools/clang/test/CodeGenSPIRV/vk.binding.cl.globals.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/vk.binding.cl.globals.hlsl similarity index 71% rename from tools/clang/test/CodeGenSPIRV/vk.binding.cl.globals.hlsl rename to tools/clang/test/CodeGenSPIRV_Lit/vk.binding.cl.globals.hlsl index 2bcf9db52e..39309a5a47 100644 --- a/tools/clang/test/CodeGenSPIRV/vk.binding.cl.globals.hlsl +++ b/tools/clang/test/CodeGenSPIRV_Lit/vk.binding.cl.globals.hlsl @@ -1,4 +1,4 @@ -// RUN: %dxc -T ps_6_0 -E main -fvk-bind-globals 1 2 +// RUN: %dxc -T ps_6_0 -E main -fvk-bind-globals 1 2 -fcgl %s -spirv | FileCheck %s // CHECK: OpDecorate %_Globals DescriptorSet 2 // CHECK: OpDecorate %_Globals Binding 1 diff --git a/tools/clang/test/CodeGenSPIRV/vk.binding.cl.register-and-globals.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/vk.binding.cl.register-and-globals.hlsl similarity index 89% rename from tools/clang/test/CodeGenSPIRV/vk.binding.cl.register-and-globals.hlsl rename to tools/clang/test/CodeGenSPIRV_Lit/vk.binding.cl.register-and-globals.hlsl index bed03cc128..b51745a20f 100644 --- a/tools/clang/test/CodeGenSPIRV/vk.binding.cl.register-and-globals.hlsl +++ b/tools/clang/test/CodeGenSPIRV_Lit/vk.binding.cl.register-and-globals.hlsl @@ -1,4 +1,4 @@ -// RUN: %dxc -T ps_6_0 -E main -fvk-bind-register t5 0 1 2 -vkbr s3 1 3 4 -fvk-bind-globals 7 8 +// RUN: %dxc -T ps_6_0 -E main -fvk-bind-register t5 0 1 2 -vkbr s3 1 3 4 -fvk-bind-globals 7 8 -fcgl %s -spirv | FileCheck %s // CHECK: OpDecorate %MyTexture DescriptorSet 2 // CHECK: OpDecorate %MyTexture Binding 1 diff --git a/tools/clang/test/CodeGenSPIRV/vk.binding.cl.register.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/vk.binding.cl.register.hlsl similarity index 90% rename from tools/clang/test/CodeGenSPIRV/vk.binding.cl.register.hlsl rename to tools/clang/test/CodeGenSPIRV_Lit/vk.binding.cl.register.hlsl index 23d7129bd5..cb301e9256 100644 --- a/tools/clang/test/CodeGenSPIRV/vk.binding.cl.register.hlsl +++ b/tools/clang/test/CodeGenSPIRV_Lit/vk.binding.cl.register.hlsl @@ -1,4 +1,4 @@ -// RUN: %dxc -T ps_6_0 -E main -fvk-bind-register t5 0 1 2 -vkbr s3 1 3 4 +// RUN: %dxc -T ps_6_0 -E main -fvk-bind-register t5 0 1 2 -vkbr s3 1 3 4 -fcgl %s -spirv | FileCheck %s // CHECK: OpDecorate %MyTexture DescriptorSet 2 // CHECK: OpDecorate %MyTexture Binding 1 diff --git a/tools/clang/test/CodeGenSPIRV/vk.binding.cl.shift.all-sets.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/vk.binding.cl.shift.all-sets.hlsl similarity index 95% rename from tools/clang/test/CodeGenSPIRV/vk.binding.cl.shift.all-sets.hlsl rename to tools/clang/test/CodeGenSPIRV_Lit/vk.binding.cl.shift.all-sets.hlsl index 80adc58af5..4a8a7415fb 100644 --- a/tools/clang/test/CodeGenSPIRV/vk.binding.cl.shift.all-sets.hlsl +++ b/tools/clang/test/CodeGenSPIRV_Lit/vk.binding.cl.shift.all-sets.hlsl @@ -1,4 +1,4 @@ -// RUN: %dxc -T ps_6_0 -E main -fvk-b-shift 1000 all -fvk-t-shift 2000 all -fvk-s-shift 3000 all -fvk-u-shift 4000 all +// RUN: %dxc -T ps_6_0 -E main -fvk-b-shift 1000 all -fvk-t-shift 2000 all -fvk-s-shift 3000 all -fvk-u-shift 4000 all -fcgl %s -spirv | FileCheck %s struct S { float4 f; diff --git a/tools/clang/test/CodeGenSPIRV/vk.binding.cl.shift.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/vk.binding.cl.shift.hlsl similarity index 97% rename from tools/clang/test/CodeGenSPIRV/vk.binding.cl.shift.hlsl rename to tools/clang/test/CodeGenSPIRV_Lit/vk.binding.cl.shift.hlsl index 361fad187f..652f42dcc7 100644 --- a/tools/clang/test/CodeGenSPIRV/vk.binding.cl.shift.hlsl +++ b/tools/clang/test/CodeGenSPIRV_Lit/vk.binding.cl.shift.hlsl @@ -1,4 +1,4 @@ -// RUN: %dxc -T ps_6_0 -E main -fvk-b-shift 100 0 -fvk-b-shift 200 2 -fvk-t-shift 200 0 -fvk-t-shift 300 1 -fvk-t-shift 400 0 -fvk-s-shift 500 0 -fvk-s-shift 600 2 -fvk-u-shift 700 0 -fvk-u-shift 800 3 +// RUN: %dxc -T ps_6_0 -E main -fvk-b-shift 100 0 -fvk-b-shift 200 2 -fvk-t-shift 200 0 -fvk-t-shift 300 1 -fvk-t-shift 400 0 -fvk-s-shift 500 0 -fvk-s-shift 600 2 -fvk-u-shift 700 0 -fvk-u-shift 800 3 -fcgl %s -spirv | FileCheck %s // Tests that we can set shift for more than one sets of the same register type // Tests that we can override shift for the same set diff --git a/tools/clang/test/CodeGenSPIRV/vk.binding.counter.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/vk.binding.counter.hlsl similarity index 96% rename from tools/clang/test/CodeGenSPIRV/vk.binding.counter.hlsl rename to tools/clang/test/CodeGenSPIRV_Lit/vk.binding.counter.hlsl index 6467af58b8..33d96835dc 100644 --- a/tools/clang/test/CodeGenSPIRV/vk.binding.counter.hlsl +++ b/tools/clang/test/CodeGenSPIRV_Lit/vk.binding.counter.hlsl @@ -1,4 +1,4 @@ -// RUN: %dxc -T ps_6_0 -E main +// RUN: %dxc -T ps_6_0 -E main -fcgl %s -spirv | FileCheck %s struct S { float4 f; diff --git a/tools/clang/test/CodeGenSPIRV/vk.binding.default-space.explicit.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/vk.binding.default-space.explicit.hlsl similarity index 93% rename from tools/clang/test/CodeGenSPIRV/vk.binding.default-space.explicit.hlsl rename to tools/clang/test/CodeGenSPIRV_Lit/vk.binding.default-space.explicit.hlsl index 2c9701b38e..ab21e6ff43 100644 --- a/tools/clang/test/CodeGenSPIRV/vk.binding.default-space.explicit.hlsl +++ b/tools/clang/test/CodeGenSPIRV_Lit/vk.binding.default-space.explicit.hlsl @@ -1,4 +1,4 @@ -// RUN: %dxc -T ps_6_0 -E main -auto-binding-space 77 +// RUN: %dxc -T ps_6_0 -E main -auto-binding-space 77 -fcgl %s -spirv | FileCheck %s // Since both the descriptor set and binding are mentioned via "[[vk::binding]]", // the "-auto-binding-space" has no effect: diff --git a/tools/clang/test/CodeGenSPIRV/vk.binding.default-space.implicit.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/vk.binding.default-space.implicit.hlsl similarity index 95% rename from tools/clang/test/CodeGenSPIRV/vk.binding.default-space.implicit.hlsl rename to tools/clang/test/CodeGenSPIRV_Lit/vk.binding.default-space.implicit.hlsl index f400f54515..d2e2031685 100644 --- a/tools/clang/test/CodeGenSPIRV/vk.binding.default-space.implicit.hlsl +++ b/tools/clang/test/CodeGenSPIRV_Lit/vk.binding.default-space.implicit.hlsl @@ -1,4 +1,4 @@ -// RUN: %dxc -T ps_6_0 -E main -auto-binding-space 77 +// RUN: %dxc -T ps_6_0 -E main -auto-binding-space 77 -fcgl %s -spirv | FileCheck %s // CHECK: OpDecorate %sampler1 DescriptorSet 77 // CHECK-NEXT: OpDecorate %sampler1 Binding 0 diff --git a/tools/clang/test/CodeGenSPIRV/vk.binding.default-space.with-shift-all.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/vk.binding.default-space.with-shift-all.hlsl similarity index 97% rename from tools/clang/test/CodeGenSPIRV/vk.binding.default-space.with-shift-all.hlsl rename to tools/clang/test/CodeGenSPIRV_Lit/vk.binding.default-space.with-shift-all.hlsl index 36ce113098..a04a543f85 100644 --- a/tools/clang/test/CodeGenSPIRV/vk.binding.default-space.with-shift-all.hlsl +++ b/tools/clang/test/CodeGenSPIRV_Lit/vk.binding.default-space.with-shift-all.hlsl @@ -1,4 +1,4 @@ -// RUN: %dxc -T ps_6_0 -E main -auto-binding-space 77 -fvk-b-shift 1000 all -fvk-t-shift 2000 all -fvk-s-shift 3000 all -fvk-u-shift 4000 all +// RUN: %dxc -T ps_6_0 -E main -auto-binding-space 77 -fvk-b-shift 1000 all -fvk-t-shift 2000 all -fvk-s-shift 3000 all -fvk-u-shift 4000 all -fcgl %s -spirv | FileCheck %s struct S { float4 f; diff --git a/tools/clang/test/CodeGenSPIRV/vk.binding.default-space.with-shift.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/vk.binding.default-space.with-shift.hlsl similarity index 97% rename from tools/clang/test/CodeGenSPIRV/vk.binding.default-space.with-shift.hlsl rename to tools/clang/test/CodeGenSPIRV_Lit/vk.binding.default-space.with-shift.hlsl index 03ecf09d36..b9859c9ae2 100644 --- a/tools/clang/test/CodeGenSPIRV/vk.binding.default-space.with-shift.hlsl +++ b/tools/clang/test/CodeGenSPIRV_Lit/vk.binding.default-space.with-shift.hlsl @@ -1,4 +1,4 @@ -// RUN: %dxc -T ps_6_0 -E main -auto-binding-space 77 -fvk-b-shift 100 77 -fvk-b-shift 200 2 -fvk-t-shift 400 77 -fvk-t-shift 300 1 -fvk-s-shift 500 77 -fvk-s-shift 600 2 -fvk-u-shift 700 77 -fvk-u-shift 800 3 +// RUN: %dxc -T ps_6_0 -E main -auto-binding-space 77 -fvk-b-shift 100 77 -fvk-b-shift 200 2 -fvk-t-shift 400 77 -fvk-t-shift 300 1 -fvk-s-shift 500 77 -fvk-s-shift 600 2 -fvk-u-shift 700 77 -fvk-u-shift 800 3 -fcgl %s -spirv | FileCheck %s // Tests that we can set shift for more than one sets of the same register type // Tests that we can override shift for the same set diff --git a/tools/clang/test/CodeGenSPIRV/vk.binding.explicit.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/vk.binding.explicit.hlsl similarity index 97% rename from tools/clang/test/CodeGenSPIRV/vk.binding.explicit.hlsl rename to tools/clang/test/CodeGenSPIRV_Lit/vk.binding.explicit.hlsl index fd06a600c4..7793ee70e7 100644 --- a/tools/clang/test/CodeGenSPIRV/vk.binding.explicit.hlsl +++ b/tools/clang/test/CodeGenSPIRV_Lit/vk.binding.explicit.hlsl @@ -1,4 +1,4 @@ -// RUN: %dxc -T ps_6_0 -E main +// RUN: %dxc -T ps_6_0 -E main -fcgl %s -spirv | FileCheck %s // CHECK: OpDecorate %sampler1 DescriptorSet 0 // CHECK-NEXT: OpDecorate %sampler1 Binding 0 diff --git a/tools/clang/test/CodeGenSPIRV/vk.binding.flatten-arrays.var-index.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/vk.binding.flatten-arrays.var-index.hlsl similarity index 66% rename from tools/clang/test/CodeGenSPIRV/vk.binding.flatten-arrays.var-index.hlsl rename to tools/clang/test/CodeGenSPIRV_Lit/vk.binding.flatten-arrays.var-index.hlsl index 36c57a44c1..771533a6a3 100644 --- a/tools/clang/test/CodeGenSPIRV/vk.binding.flatten-arrays.var-index.hlsl +++ b/tools/clang/test/CodeGenSPIRV_Lit/vk.binding.flatten-arrays.var-index.hlsl @@ -1,4 +1,4 @@ -// RUN: %dxc -T ps_6_0 -E main -fspv-flatten-resource-arrays -O3 +// RUN: %dxc -T ps_6_0 -E main -fspv-flatten-resource-arrays -O3 %s -spirv | FileCheck %s // CHECK: OpName %x_0_ "x[0]" // CHECK: OpName %x_1_ "x[1]" @@ -21,19 +21,19 @@ Texture2D y[3] : register(t2); float4 main(uint instanceID : INSTANCEID, float2 texCoord : TEXCOORD) : SV_TARGET { -// CHECK: [[instanceID:%\d+]] = OpLoad %uint %in_var_INSTANCEID -// CHECK: [[texCoord:%\d+]] = OpLoad %v2float %in_var_TEXCOORD -// CHECK: [[instanceID_idx:%\d+]] = OpUMod %uint [[instanceID]] %uint_2 -// CHECK: OpSelectionMerge [[merge0:%\d+]] None -// CHECK: OpSwitch [[instanceID_idx]] [[default0:%\d+]] 0 [[sw0_bb0:%\d+]] 1 [[sw0_bb1:%\d+]] +// CHECK: [[instanceID:%[0-9]+]] = OpLoad %uint %in_var_INSTANCEID +// CHECK: [[texCoord:%[0-9]+]] = OpLoad %v2float %in_var_TEXCOORD +// CHECK: [[instanceID_idx:%[0-9]+]] = OpUMod %uint [[instanceID]] %uint_2 +// CHECK: OpSelectionMerge [[merge0:%[0-9]+]] None +// CHECK: OpSwitch [[instanceID_idx]] [[default0:%[0-9]+]] 0 [[sw0_bb0:%[0-9]+]] 1 [[sw0_bb1:%[0-9]+]] // CHECK: [[sw0_bb0]] = OpLabel -// CHECK: OpSelectionMerge [[merge1:%\d+]] None -// CHECK: OpSwitch [[instanceID]] {{%\d+}} 0 {{%\d+}} 1 {{%\d+}} 2 +// CHECK: OpSelectionMerge [[merge1:%[0-9]+]] None +// CHECK: OpSwitch [[instanceID]] {{%[0-9]+}} 0 {{%[0-9]+}} 1 {{%[0-9]+}} 2 // CHECK: OpLabel -// CHECK: [[x_0:%\d+]] = OpLoad %type_sampler %x_0_ -// CHECK: [[y_0:%\d+]] = OpLoad %type_2d_image %y_0_ -// CHECK: [[xy_00:%\d+]] = OpSampledImage %type_sampled_image [[y_0]] [[x_0]] -// CHECK: [[sample0:%\d+]] = OpImageSampleImplicitLod %v4float [[xy_00]] [[texCoord]] None +// CHECK: [[x_0:%[0-9]+]] = OpLoad %type_sampler %x_0_ +// CHECK: [[y_0:%[0-9]+]] = OpLoad %type_2d_image %y_0_ +// CHECK: [[xy_00:%[0-9]+]] = OpSampledImage %type_sampled_image [[y_0]] [[x_0]] +// CHECK: [[sample0:%[0-9]+]] = OpImageSampleImplicitLod %v4float [[xy_00]] [[texCoord]] None // CHECK: OpBranch [[merge1]] // CHECK: OpLabel // CHECK: OpLoad %type_sampler %x_0_ @@ -47,10 +47,10 @@ float4 main(uint instanceID : INSTANCEID, float2 texCoord : TEXCOORD) : SV_TARGE // CHECK: OpSampledImage %type_sampled_image // CHECK: OpImageSampleImplicitLod %v4float // CHECK: OpBranch [[merge1]] -// CHECK: [[default1:%\d+]] = OpLabel +// CHECK: [[default1:%[0-9]+]] = OpLabel // CHECK: OpBranch [[merge1]] // CHECK: [[merge1]] = OpLabel -// CHECK: OpPhi %v4float [[sample0]] {{%\d+}} {{%\d+}} {{%\d+}} {{%\d+}} {{%\d+}} {{%\d+}} [[default1]] +// CHECK: OpPhi %v4float [[sample0]] {{%[0-9]+}} {{%[0-9]+}} {{%[0-9]+}} {{%[0-9]+}} {{%[0-9]+}} {{%[0-9]+}} [[default1]] // CHECK: OpBranch [[merge0]] // CHECK: [[sw0_bb1]] = OpLabel @@ -74,7 +74,7 @@ float4 main(uint instanceID : INSTANCEID, float2 texCoord : TEXCOORD) : SV_TARGE // CHECK: [[default0]] = OpLabel // CHECK: OpBranch [[merge0]] // CHECK: [[merge0]] = OpLabel -// CHECK: [[value:%\d+]] = OpPhi %v4float {{%\d+}} {{%\d+}} {{%\d+}} {{%\d+}} {{%\d+}} [[default0]] +// CHECK: [[value:%[0-9]+]] = OpPhi %v4float {{%[0-9]+}} {{%[0-9]+}} {{%[0-9]+}} {{%[0-9]+}} {{%[0-9]+}} [[default0]] // CHECK: OpStore %out_var_SV_TARGET [[value]] return y[instanceID].Sample(x[instanceID % 2], texCoord); diff --git a/tools/clang/test/CodeGenSPIRV/vk.binding.global-struct-of-resources.optimized.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/vk.binding.global-struct-of-resources.optimized.hlsl similarity index 66% rename from tools/clang/test/CodeGenSPIRV/vk.binding.global-struct-of-resources.optimized.hlsl rename to tools/clang/test/CodeGenSPIRV_Lit/vk.binding.global-struct-of-resources.optimized.hlsl index 7943fbc0a2..c02c21b2b8 100644 --- a/tools/clang/test/CodeGenSPIRV/vk.binding.global-struct-of-resources.optimized.hlsl +++ b/tools/clang/test/CodeGenSPIRV_Lit/vk.binding.global-struct-of-resources.optimized.hlsl @@ -1,4 +1,4 @@ -// RUN: %dxc -T ps_6_0 -E main -O3 +// RUN: %dxc -T ps_6_0 -E main -O3 %s -spirv | FileCheck %s // Check the names // @@ -133,56 +133,56 @@ S secondGlobal; float4 main() : SV_Target { return -// CHECK: [[fg_0_0_t_0:%\d+]] = OpLoad %type_2d_image %firstGlobal_0__0__t_0_ -// CHECK: [[fg_0_0_t_1:%\d+]] = OpLoad %type_2d_image %firstGlobal_0__0__t_1_ -// CHECK: [[fg_0_0_tt_0_s_1:%\d+]] = OpLoad %type_sampler %firstGlobal_0__0__tt_0__s_1_ -// CHECK: [[fg_0_0_tt_1_s_2:%\d+]] = OpLoad %type_sampler %firstGlobal_0__0__tt_1__s_2_ -// CHECK: [[sampled_img_1:%\d+]] = OpSampledImage %type_sampled_image [[fg_0_0_t_0]] [[fg_0_0_tt_0_s_1]] -// CHECK: {{%\d+}} = OpImageSampleImplicitLod %v4float [[sampled_img_1]] -// CHECK: [[sampled_img_2:%\d+]] = OpSampledImage %type_sampled_image [[fg_0_0_t_1]] [[fg_0_0_tt_1_s_2]] -// CHECK: {{%\d+}} = OpImageSampleImplicitLod %v4float [[sampled_img_2]] +// CHECK: [[fg_1_t_0:%[0-9]+]] = OpLoad %type_2d_image %firstGlobal_0__0__t_0_ +// CHECK: [[fg_1_t_1:%[0-9]+]] = OpLoad %type_2d_image %firstGlobal_0__0__t_1_ +// CHECK: [[fg_1_tt_0_s_1:%[0-9]+]] = OpLoad %type_sampler %firstGlobal_0__0__tt_0__s_1_ +// CHECK: [[fg_1_tt_1_s_2:%[0-9]+]] = OpLoad %type_sampler %firstGlobal_0__0__tt_1__s_2_ +// CHECK: [[sampled_img_1:%[0-9]+]] = OpSampledImage %type_sampled_image [[fg_1_t_0]] [[fg_1_tt_0_s_1]] +// CHECK: {{%[0-9]+}} = OpImageSampleImplicitLod %v4float [[sampled_img_1]] +// CHECK: [[sampled_img_2:%[0-9]+]] = OpSampledImage %type_sampled_image [[fg_1_t_1]] [[fg_1_tt_1_s_2]] +// CHECK: {{%[0-9]+}} = OpImageSampleImplicitLod %v4float [[sampled_img_2]] // CHECK: OpFAdd tex2D(firstGlobal[0][0], float2(0,0)) + -// CHECK: [[fg_0_1_t_0:%\d+]] = OpLoad %type_2d_image %firstGlobal_0__1__t_0_ -// CHECK: [[fg_0_1_t_1:%\d+]] = OpLoad %type_2d_image %firstGlobal_0__1__t_1_ -// CHECK: [[fg_0_1_tt_0_s_1:%\d+]] = OpLoad %type_sampler %firstGlobal_0__1__tt_0__s_1_ -// CHECK: [[fg_0_1_tt_1_s_2:%\d+]] = OpLoad %type_sampler %firstGlobal_0__1__tt_1__s_2_ -// CHECK: [[sampled_img_3:%\d+]] = OpSampledImage %type_sampled_image [[fg_0_1_t_0]] [[fg_0_1_tt_0_s_1]] -// CHECK: {{%\d+}} = OpImageSampleImplicitLod %v4float [[sampled_img_3]] -// CHECK: [[sampled_img_4:%\d+]] = OpSampledImage %type_sampled_image [[fg_0_1_t_1]] [[fg_0_1_tt_1_s_2]] -// CHECK: {{%\d+}} = OpImageSampleImplicitLod %v4float [[sampled_img_4]] +// CHECK: [[fg_0_1_t_0:%[0-9]+]] = OpLoad %type_2d_image %firstGlobal_0__1__t_0_ +// CHECK: [[fg_0_1_t_1:%[0-9]+]] = OpLoad %type_2d_image %firstGlobal_0__1__t_1_ +// CHECK: [[fg_0_1_tt_0_s_1:%[0-9]+]] = OpLoad %type_sampler %firstGlobal_0__1__tt_0__s_1_ +// CHECK: [[fg_0_1_tt_1_s_2:%[0-9]+]] = OpLoad %type_sampler %firstGlobal_0__1__tt_1__s_2_ +// CHECK: [[sampled_img_3:%[0-9]+]] = OpSampledImage %type_sampled_image [[fg_0_1_t_0]] [[fg_0_1_tt_0_s_1]] +// CHECK: {{%[0-9]+}} = OpImageSampleImplicitLod %v4float [[sampled_img_3]] +// CHECK: [[sampled_img_4:%[0-9]+]] = OpSampledImage %type_sampled_image [[fg_0_1_t_1]] [[fg_0_1_tt_1_s_2]] +// CHECK: {{%[0-9]+}} = OpImageSampleImplicitLod %v4float [[sampled_img_4]] // CHECK: OpFAdd tex2D(firstGlobal[0][1], float2(0,0)) + -// CHECK: [[fg_1_0_t_0:%\d+]] = OpLoad %type_2d_image %firstGlobal_1__0__t_0_ -// CHECK: [[fg_1_0_t_1:%\d+]] = OpLoad %type_2d_image %firstGlobal_1__0__t_1_ -// CHECK: [[fg_1_0_tt_0_s_1:%\d+]] = OpLoad %type_sampler %firstGlobal_1__0__tt_0__s_1_ -// CHECK: [[fg_1_0_tt_1_s_2:%\d+]] = OpLoad %type_sampler %firstGlobal_1__0__tt_1__s_2_ -// CHECK: [[sampled_img_5:%\d+]] = OpSampledImage %type_sampled_image [[fg_1_0_t_0]] [[fg_1_0_tt_0_s_1]] -// CHECK: {{%\d+}} = OpImageSampleImplicitLod %v4float [[sampled_img_5]] -// CHECK: [[sampled_img_6:%\d+]] = OpSampledImage %type_sampled_image [[fg_1_0_t_1]] [[fg_1_0_tt_1_s_2]] -// CHECK: {{%\d+}} = OpImageSampleImplicitLod %v4float [[sampled_img_6]] +// CHECK: [[fg_1_0_t_0:%[0-9]+]] = OpLoad %type_2d_image %firstGlobal_1__0__t_0_ +// CHECK: [[fg_1_0_t_1:%[0-9]+]] = OpLoad %type_2d_image %firstGlobal_1__0__t_1_ +// CHECK: [[fg_1_0_tt_0_s_1:%[0-9]+]] = OpLoad %type_sampler %firstGlobal_1__0__tt_0__s_1_ +// CHECK: [[fg_1_0_tt_1_s_2:%[0-9]+]] = OpLoad %type_sampler %firstGlobal_1__0__tt_1__s_2_ +// CHECK: [[sampled_img_5:%[0-9]+]] = OpSampledImage %type_sampled_image [[fg_1_0_t_0]] [[fg_1_0_tt_0_s_1]] +// CHECK: {{%[0-9]+}} = OpImageSampleImplicitLod %v4float [[sampled_img_5]] +// CHECK: [[sampled_img_6:%[0-9]+]] = OpSampledImage %type_sampled_image [[fg_1_0_t_1]] [[fg_1_0_tt_1_s_2]] +// CHECK: {{%[0-9]+}} = OpImageSampleImplicitLod %v4float [[sampled_img_6]] // CHECK: OpFAdd tex2D(firstGlobal[1][0], float2(0,0)) + -// CHECK: [[fg_1_1_t_0:%\d+]] = OpLoad %type_2d_image %firstGlobal_1__1__t_0_ -// CHECK: [[fg_1_1_t_1:%\d+]] = OpLoad %type_2d_image %firstGlobal_1__1__t_1_ -// CHECK: [[fg_1_1_tt_0_s_1:%\d+]] = OpLoad %type_sampler %firstGlobal_1__1__tt_0__s_1_ -// CHECK: [[fg_1_1_tt_1_s_2:%\d+]] = OpLoad %type_sampler %firstGlobal_1__1__tt_1__s_2_ -// CHECK: [[sampled_img_7:%\d+]] = OpSampledImage %type_sampled_image [[fg_1_1_t_0]] [[fg_1_1_tt_0_s_1]] -// CHECK: {{%\d+}} = OpImageSampleImplicitLod %v4float [[sampled_img_7]] -// CHECK: [[sampled_img_8:%\d+]] = OpSampledImage %type_sampled_image [[fg_1_1_t_1]] [[fg_1_1_tt_1_s_2]] -// CHECK: {{%\d+}} = OpImageSampleImplicitLod %v4float [[sampled_img_8]] +// CHECK: [[fg_1_1_t_0:%[0-9]+]] = OpLoad %type_2d_image %firstGlobal_1__1__t_0_ +// CHECK: [[fg_1_1_t_1:%[0-9]+]] = OpLoad %type_2d_image %firstGlobal_1__1__t_1_ +// CHECK: [[fg_1_1_tt_0_s_1:%[0-9]+]] = OpLoad %type_sampler %firstGlobal_1__1__tt_0__s_1_ +// CHECK: [[fg_1_1_tt_1_s_2:%[0-9]+]] = OpLoad %type_sampler %firstGlobal_1__1__tt_1__s_2_ +// CHECK: [[sampled_img_7:%[0-9]+]] = OpSampledImage %type_sampled_image [[fg_1_1_t_0]] [[fg_1_1_tt_0_s_1]] +// CHECK: {{%[0-9]+}} = OpImageSampleImplicitLod %v4float [[sampled_img_7]] +// CHECK: [[sampled_img_8:%[0-9]+]] = OpSampledImage %type_sampled_image [[fg_1_1_t_1]] [[fg_1_1_tt_1_s_2]] +// CHECK: {{%[0-9]+}} = OpImageSampleImplicitLod %v4float [[sampled_img_8]] // CHECK: OpFAdd tex2D(firstGlobal[1][1], float2(0,0)) + -// CHECK: [[sg_t_0:%\d+]] = OpLoad %type_2d_image %secondGlobal_t_0_ -// CHECK: [[sg_tt_0_s_1:%\d+]] = OpLoad %type_sampler %secondGlobal_tt_0__s_1_ -// CHECK: [[sampled_img_9:%\d+]] = OpSampledImage %type_sampled_image [[sg_t_0]] [[sg_tt_0_s_1]] -// CHECK: {{%\d+}} = OpImageSampleImplicitLod %v4float [[sampled_img_9]] +// CHECK: [[sg_t_0:%[0-9]+]] = OpLoad %type_2d_image %secondGlobal_t_0_ +// CHECK: [[sg_tt_0_s_1:%[0-9]+]] = OpLoad %type_sampler %secondGlobal_tt_0__s_1_ +// CHECK: [[sampled_img_9:%[0-9]+]] = OpSampledImage %type_sampled_image [[sg_t_0]] [[sg_tt_0_s_1]] +// CHECK: {{%[0-9]+}} = OpImageSampleImplicitLod %v4float [[sampled_img_9]] // CHECK: OpFAdd secondGlobal.t[0].Sample(secondGlobal.tt[0].s[1], float2(0,0)) + -// CHECK: [[sg_t_1:%\d+]] = OpLoad %type_2d_image %secondGlobal_t_1_ -// CHECK: [[sg_tt_1_s_2:%\d+]] = OpLoad %type_sampler %secondGlobal_tt_1__s_2_ -// CHECK: [[sampled_img_10:%\d+]] = OpSampledImage %type_sampled_image [[sg_t_1]] [[sg_tt_1_s_2]] -// CHECK: {{%\d+}} = OpImageSampleImplicitLod %v4float [[sampled_img_10]] +// CHECK: [[sg_t_1:%[0-9]+]] = OpLoad %type_2d_image %secondGlobal_t_1_ +// CHECK: [[sg_tt_1_s_2:%[0-9]+]] = OpLoad %type_sampler %secondGlobal_tt_1__s_2_ +// CHECK: [[sampled_img_10:%[0-9]+]] = OpSampledImage %type_sampled_image [[sg_t_1]] [[sg_tt_1_s_2]] +// CHECK: {{%[0-9]+}} = OpImageSampleImplicitLod %v4float [[sampled_img_10]] secondGlobal.t[1].Sample(secondGlobal.tt[1].s[2], float2(0,0)); } diff --git a/tools/clang/test/CodeGenSPIRV/vk.binding.global-struct-of-resources.pass-legalization.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/vk.binding.global-struct-of-resources.pass-legalization.hlsl similarity index 90% rename from tools/clang/test/CodeGenSPIRV/vk.binding.global-struct-of-resources.pass-legalization.hlsl rename to tools/clang/test/CodeGenSPIRV_Lit/vk.binding.global-struct-of-resources.pass-legalization.hlsl index d7424a7689..b997c0dba0 100644 --- a/tools/clang/test/CodeGenSPIRV/vk.binding.global-struct-of-resources.pass-legalization.hlsl +++ b/tools/clang/test/CodeGenSPIRV_Lit/vk.binding.global-struct-of-resources.pass-legalization.hlsl @@ -1,4 +1,4 @@ -// RUN: %dxc -T ps_6_0 -E main -O0 +// RUN: %dxc -T ps_6_0 -E main -O0 %s -spirv | FileCheck %s // CHECK: OpDecorate %g_CombinedTextureSampler_t DescriptorSet 0 // CHECK: OpDecorate %g_CombinedTextureSampler_t Binding 0 diff --git a/tools/clang/test/CodeGenSPIRV/vk.binding.implicit.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/vk.binding.implicit.hlsl similarity index 96% rename from tools/clang/test/CodeGenSPIRV/vk.binding.implicit.hlsl rename to tools/clang/test/CodeGenSPIRV_Lit/vk.binding.implicit.hlsl index e4519246f3..d920f7aa67 100644 --- a/tools/clang/test/CodeGenSPIRV/vk.binding.implicit.hlsl +++ b/tools/clang/test/CodeGenSPIRV_Lit/vk.binding.implicit.hlsl @@ -1,4 +1,4 @@ -// RUN: %dxc -T ps_6_0 -E main +// RUN: %dxc -T ps_6_0 -E main -fcgl %s -spirv | FileCheck %s // CHECK: OpDecorate %sampler1 DescriptorSet 0 // CHECK-NEXT: OpDecorate %sampler1 Binding 0 diff --git a/tools/clang/test/CodeGenSPIRV/vk.binding.precedence.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/vk.binding.precedence.hlsl similarity index 98% rename from tools/clang/test/CodeGenSPIRV/vk.binding.precedence.hlsl rename to tools/clang/test/CodeGenSPIRV_Lit/vk.binding.precedence.hlsl index dc4db0dbaa..c98b7ba45a 100644 --- a/tools/clang/test/CodeGenSPIRV/vk.binding.precedence.hlsl +++ b/tools/clang/test/CodeGenSPIRV_Lit/vk.binding.precedence.hlsl @@ -1,4 +1,4 @@ -// RUN: %dxc -T ps_6_0 -E main +// RUN: %dxc -T ps_6_0 -E main -fcgl %s -spirv | FileCheck %s struct S { float4 f; diff --git a/tools/clang/test/CodeGenSPIRV/vk.binding.register.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/vk.binding.register.hlsl similarity index 97% rename from tools/clang/test/CodeGenSPIRV/vk.binding.register.hlsl rename to tools/clang/test/CodeGenSPIRV_Lit/vk.binding.register.hlsl index 48ce028ea8..02d9f373ab 100644 --- a/tools/clang/test/CodeGenSPIRV/vk.binding.register.hlsl +++ b/tools/clang/test/CodeGenSPIRV_Lit/vk.binding.register.hlsl @@ -1,4 +1,4 @@ -// RUN: %dxc -T ps_6_0 -E main +// RUN: %dxc -T ps_6_0 -E main -fcgl %s -spirv | FileCheck %s // CHECK: OpDecorate %sampler1 DescriptorSet 0 // CHECK-NEXT: OpDecorate %sampler1 Binding 1 diff --git a/tools/clang/test/CodeGenSPIRV/vk.binding.register.space-only.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/vk.binding.register.space-only.hlsl similarity index 97% rename from tools/clang/test/CodeGenSPIRV/vk.binding.register.space-only.hlsl rename to tools/clang/test/CodeGenSPIRV_Lit/vk.binding.register.space-only.hlsl index 1de9f3f4c2..bb72b3bb91 100644 --- a/tools/clang/test/CodeGenSPIRV/vk.binding.register.space-only.hlsl +++ b/tools/clang/test/CodeGenSPIRV_Lit/vk.binding.register.space-only.hlsl @@ -1,4 +1,4 @@ -// RUN: %dxc -T ps_6_0 -E main +// RUN: %dxc -T ps_6_0 -E main -fcgl %s -spirv | FileCheck %s // CHECK: OpDecorate %sampler1 DescriptorSet 1 // CHECK-NEXT: OpDecorate %sampler1 Binding 0 diff --git a/tools/clang/test/CodeGenSPIRV/vk.cloption.invert-w.ds.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/vk.cloption.invert-w.ds.hlsl similarity index 78% rename from tools/clang/test/CodeGenSPIRV/vk.cloption.invert-w.ds.hlsl rename to tools/clang/test/CodeGenSPIRV_Lit/vk.cloption.invert-w.ds.hlsl index 27c0f0f9ef..c7341fc139 100644 --- a/tools/clang/test/CodeGenSPIRV/vk.cloption.invert-w.ds.hlsl +++ b/tools/clang/test/CodeGenSPIRV_Lit/vk.cloption.invert-w.ds.hlsl @@ -1,4 +1,4 @@ -// RUN: %dxc -T ds_6_0 -E main -fvk-use-dx-position-w +// RUN: %dxc -T ds_6_0 -E main -fvk-use-dx-position-w -fcgl %s -spirv | FileCheck %s // HS PCF output struct HsPcfOut { @@ -26,4 +26,4 @@ DsCpOut main(OutputPatch patch, // Make sure -fvk-use-dx-position-w is ignored for non-PS stages // CHECK: OpLoad %_arr_v4float_uint_3 %gl_Position -// CHECK-NOT: OpCompositeInsert %v4float {{%\d+}} {{%\d+}} 3 +// CHECK-NOT: OpCompositeInsert %v4float {{%[0-9]+}} {{%[0-9]+}} 3 diff --git a/tools/clang/test/CodeGenSPIRV_Lit/vk.cloption.invert-w.ps.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/vk.cloption.invert-w.ps.hlsl new file mode 100644 index 0000000000..49fb2e82d9 --- /dev/null +++ b/tools/clang/test/CodeGenSPIRV_Lit/vk.cloption.invert-w.ps.hlsl @@ -0,0 +1,12 @@ +// RUN: %dxc -T ps_6_0 -E main -fvk-use-dx-position-w -fcgl %s -spirv | FileCheck %s + +float4 main(float4 pos: SV_Position) : SV_Target { + return pos; +} + +// CHECK: [[old:%[0-9]+]] = OpLoad %v4float %gl_FragCoord +// CHECK-NEXT: [[oldW:%[0-9]+]] = OpCompositeExtract %float [[old]] 3 +// CHECK-NEXT: [[newW:%[0-9]+]] = OpFDiv %float %float_1 [[oldW]] +// CHECK-NEXT: [[new:%[0-9]+]] = OpCompositeInsert %v4float [[newW]] [[old]] 3 +// CHECK-NEXT: OpStore %param_var_pos [[new]] +// CHECK-NEXT: OpFunctionCall %v4float %src_main %param_var_pos diff --git a/tools/clang/test/CodeGenSPIRV/vk.cloption.invert-y.ds.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/vk.cloption.invert-y.ds.hlsl similarity index 52% rename from tools/clang/test/CodeGenSPIRV/vk.cloption.invert-y.ds.hlsl rename to tools/clang/test/CodeGenSPIRV_Lit/vk.cloption.invert-y.ds.hlsl index 87e41aa152..3bf63e536c 100644 --- a/tools/clang/test/CodeGenSPIRV/vk.cloption.invert-y.ds.hlsl +++ b/tools/clang/test/CodeGenSPIRV_Lit/vk.cloption.invert-y.ds.hlsl @@ -1,4 +1,4 @@ -// RUN: %dxc -T ds_6_0 -E main -fvk-invert-y +// RUN: %dxc -T ds_6_0 -E main -fvk-invert-y -fcgl %s -spirv | FileCheck %s // HS PCF output struct HsPcfOut { @@ -24,9 +24,9 @@ DsCpOut main(OutputPatch patch, return dsOut; } -// CHECK: [[call:%\d+]] = OpFunctionCall %DsCpOut %src_main %param_var_patch %param_var_pcfData -// CHECK-NEXT: [[val:%\d+]] = OpCompositeExtract %v4float [[call]] 0 -// CHECK-NEXT: [[oldY:%\d+]] = OpCompositeExtract %float [[val]] 1 -// CHECK-NEXT: [[newY:%\d+]] = OpFNegate %float [[oldY]] -// CHECK-NEXT: [[pos:%\d+]] = OpCompositeInsert %v4float [[newY]] [[val]] 1 +// CHECK: [[call:%[0-9]+]] = OpFunctionCall %DsCpOut %src_main %param_var_patch %param_var_pcfData +// CHECK-NEXT: [[val:%[0-9]+]] = OpCompositeExtract %v4float [[call]] 0 +// CHECK-NEXT: [[oldY:%[0-9]+]] = OpCompositeExtract %float [[val]] 1 +// CHECK-NEXT: [[newY:%[0-9]+]] = OpFNegate %float [[oldY]] +// CHECK-NEXT: [[pos:%[0-9]+]] = OpCompositeInsert %v4float [[newY]] [[val]] 1 // CHECK-NEXT: OpStore %gl_Position_0 [[pos]] diff --git a/tools/clang/test/CodeGenSPIRV/vk.cloption.invert-y.gs.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/vk.cloption.invert-y.gs.hlsl similarity index 51% rename from tools/clang/test/CodeGenSPIRV/vk.cloption.invert-y.gs.hlsl rename to tools/clang/test/CodeGenSPIRV_Lit/vk.cloption.invert-y.gs.hlsl index c49d3dd663..703477cca2 100644 --- a/tools/clang/test/CodeGenSPIRV/vk.cloption.invert-y.gs.hlsl +++ b/tools/clang/test/CodeGenSPIRV_Lit/vk.cloption.invert-y.gs.hlsl @@ -1,4 +1,4 @@ -// RUN: %dxc -T gs_6_0 -E main -fvk-invert-y +// RUN: %dxc -T gs_6_0 -E main -fvk-invert-y -fcgl %s -spirv | FileCheck %s // GS per-vertex input struct GsVIn { @@ -16,11 +16,11 @@ void main(in line GsVIn inData[2], GsVOut vertex; vertex = (GsVOut)0; -// CHECK: [[vert:%\d+]] = OpLoad %GsVOut %vertex -// CHECK-NEXT: [[val:%\d+]] = OpCompositeExtract %v4float [[vert]] 0 -// CHECK-NEXT: [[oldY:%\d+]] = OpCompositeExtract %float [[val]] 1 -// CHECK-NEXT: [[newY:%\d+]] = OpFNegate %float [[oldY]] -// CHECK-NEXT: [[pos:%\d+]] = OpCompositeInsert %v4float [[newY]] [[val]] 1 +// CHECK: [[vert:%[0-9]+]] = OpLoad %GsVOut %vertex +// CHECK-NEXT: [[val:%[0-9]+]] = OpCompositeExtract %v4float [[vert]] 0 +// CHECK-NEXT: [[oldY:%[0-9]+]] = OpCompositeExtract %float [[val]] 1 +// CHECK-NEXT: [[newY:%[0-9]+]] = OpFNegate %float [[oldY]] +// CHECK-NEXT: [[pos:%[0-9]+]] = OpCompositeInsert %v4float [[newY]] [[val]] 1 // CHECK-NEXT: OpStore %gl_Position_0 [[pos]] outData.Append(vertex); diff --git a/tools/clang/test/CodeGenSPIRV_Lit/vk.cloption.invert-y.vs.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/vk.cloption.invert-y.vs.hlsl new file mode 100644 index 0000000000..0920aa4512 --- /dev/null +++ b/tools/clang/test/CodeGenSPIRV_Lit/vk.cloption.invert-y.vs.hlsl @@ -0,0 +1,11 @@ +// RUN: %dxc -T vs_6_0 -E main -fvk-invert-y -fcgl %s -spirv | FileCheck %s + +float4 main(float4 a : A) : SV_Position { + return a; +} + +// CHECK: [[a:%[0-9]+]] = OpFunctionCall %v4float %src_main %param_var_a +// CHECK-NEXT: [[oldY:%[0-9]+]] = OpCompositeExtract %float [[a]] 1 +// CHECK-NEXT: [[newY:%[0-9]+]] = OpFNegate %float [[oldY]] +// CHECK-NEXT: [[pos:%[0-9]+]] = OpCompositeInsert %v4float [[newY]] [[a]] 1 +// CHECK-NEXT: OpStore %gl_Position [[pos]] diff --git a/tools/clang/test/CodeGenSPIRV/vk.combined-image-sampler.binding-shift.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/vk.combined-image-sampler.binding-shift.hlsl similarity index 95% rename from tools/clang/test/CodeGenSPIRV/vk.combined-image-sampler.binding-shift.hlsl rename to tools/clang/test/CodeGenSPIRV_Lit/vk.combined-image-sampler.binding-shift.hlsl index 712e32a213..d087086a1a 100644 --- a/tools/clang/test/CodeGenSPIRV/vk.combined-image-sampler.binding-shift.hlsl +++ b/tools/clang/test/CodeGenSPIRV_Lit/vk.combined-image-sampler.binding-shift.hlsl @@ -1,4 +1,4 @@ -// RUN: %dxc -T ps_6_0 -E main -fvk-t-shift 10 0 -fvk-s-shift 20 0 +// RUN: %dxc -T ps_6_0 -E main -fvk-t-shift 10 0 -fvk-s-shift 20 0 -fcgl %s -spirv | FileCheck %s // CHECK: OpDecorate %sam DescriptorSet 0 // CHECK: OpDecorate %sam Binding 10 diff --git a/tools/clang/test/CodeGenSPIRV/vk.combined-image-sampler.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/vk.combined-image-sampler.hlsl similarity index 72% rename from tools/clang/test/CodeGenSPIRV/vk.combined-image-sampler.hlsl rename to tools/clang/test/CodeGenSPIRV_Lit/vk.combined-image-sampler.hlsl index 08271024c3..5a0b529447 100644 --- a/tools/clang/test/CodeGenSPIRV/vk.combined-image-sampler.hlsl +++ b/tools/clang/test/CodeGenSPIRV_Lit/vk.combined-image-sampler.hlsl @@ -1,4 +1,4 @@ -// RUN: %dxc -T ps_6_0 -E main -O0 +// RUN: %dxc -T ps_6_0 -E main -O0 %s -spirv | FileCheck %s // CHECK: OpDecorate %tex0 DescriptorSet 1 // CHECK: OpDecorate %tex0 Binding 0 @@ -47,22 +47,22 @@ float4 sampleLevel(int i) { float4 main(int3 offset: A) : SV_Target { float4 ret = 0; -// CHECK: [[tex0:%\w+]] = OpLoad %type_sampled_image %tex0 +// CHECK: [[tex0:%[a-zA-Z0-9_]+]] = OpLoad %type_sampled_image %tex0 // CHECK: OpImageSampleExplicitLod %v4float [[tex0]] ret += sampleLevel(0); -// CHECK: [[tex1:%\w+]] = OpLoad %type_sampled_image %tex1 +// CHECK: [[tex1:%[a-zA-Z0-9_]+]] = OpLoad %type_sampled_image %tex1 // CHECK: OpImageSampleExplicitLod %v4float [[tex1]] ret += sampleLevel(1); -// CHECK: [[tex2:%\w+]] = OpLoad %type_sampled_image %tex2 +// CHECK: [[tex2:%[a-zA-Z0-9_]+]] = OpLoad %type_sampled_image %tex2 // CHECK: OpImageSampleExplicitLod %v4float [[tex2]] ret += sampleLevel(2); -// CHECK: [[tex0:%\w+]] = OpLoad %type_sampled_image %tex0 -// CHECK: [[img_extracted_from_tex0:%\w+]] = OpImage %type_2d_image [[tex0]] -// CHECK: [[sam3:%\w+]] = OpLoad %type_sampler %sam3 -// CHECK: [[sampled_image:%\w+]] = OpSampledImage %type_sampled_image [[img_extracted_from_tex0]] [[sam3]] +// CHECK: [[tex0_0:%[a-zA-Z0-9_]+]] = OpLoad %type_sampled_image %tex0 +// CHECK: [[img_extracted_from_tex0:%[a-zA-Z0-9_]+]] = OpImage %type_2d_image [[tex0_0]] +// CHECK: [[sam3:%[a-zA-Z0-9_]+]] = OpLoad %type_sampler %sam3 +// CHECK: [[sampled_image:%[a-zA-Z0-9_]+]] = OpSampledImage %type_sampled_image [[img_extracted_from_tex0]] [[sam3]] // CHECK: OpImageSampleExplicitLod %v4float [[sampled_image]] ret += getTexture(0).SampleLevel(getSampler(3), float2(1, 2), 10, 2); diff --git a/tools/clang/test/CodeGenSPIRV/vk.combined-image-sampler.texture-array.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/vk.combined-image-sampler.texture-array.hlsl similarity index 76% rename from tools/clang/test/CodeGenSPIRV/vk.combined-image-sampler.texture-array.hlsl rename to tools/clang/test/CodeGenSPIRV_Lit/vk.combined-image-sampler.texture-array.hlsl index b1ee8cba64..6422653c00 100644 --- a/tools/clang/test/CodeGenSPIRV/vk.combined-image-sampler.texture-array.hlsl +++ b/tools/clang/test/CodeGenSPIRV_Lit/vk.combined-image-sampler.texture-array.hlsl @@ -1,8 +1,8 @@ -// RUN: %dxc -T ps_6_0 -E main -O0 +// RUN: %dxc -T ps_6_0 -E main -O0 %s -spirv | FileCheck %s -// CHECK: [[img:%\w+]] = OpTypeImage %float 2D 2 1 0 1 Unknown -// CHECK: [[sampled_img:%\w+]] = OpTypeSampledImage [[img]] -// CHECK: [[ptr_type:%\w+]] = OpTypePointer UniformConstant [[sampled_img]] +// CHECK: [[img:%[a-zA-Z0-9_]+]] = OpTypeImage %float 2D 2 1 0 1 Unknown +// CHECK: [[sampled_img:%[a-zA-Z0-9_]+]] = OpTypeSampledImage [[img]] +// CHECK: [[ptr_type:%[a-zA-Z0-9_]+]] = OpTypePointer UniformConstant [[sampled_img]] // CHECK: %textureArray = OpVariable [[ptr_type]] UniformConstant [[vk::combinedImageSampler]] diff --git a/tools/clang/test/CodeGenSPIRV/vk.early-and-lates-tests.depth-unchanged.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/vk.early-and-lates-tests.depth-unchanged.hlsl similarity index 79% rename from tools/clang/test/CodeGenSPIRV/vk.early-and-lates-tests.depth-unchanged.hlsl rename to tools/clang/test/CodeGenSPIRV_Lit/vk.early-and-lates-tests.depth-unchanged.hlsl index 023fabe0a9..920ad93727 100644 --- a/tools/clang/test/CodeGenSPIRV/vk.early-and-lates-tests.depth-unchanged.hlsl +++ b/tools/clang/test/CodeGenSPIRV_Lit/vk.early-and-lates-tests.depth-unchanged.hlsl @@ -1,4 +1,4 @@ -// RUN: %dxc -T ps_6_0 -E main +// RUN: %dxc -T ps_6_0 -E main -fcgl %s -spirv | FileCheck %s // CHECK: OpExtension "SPV_AMD_shader_early_and_late_fragment_tests" // CHECK: OpExecutionMode %main EarlyAndLateFragmentTestsAMD diff --git a/tools/clang/test/CodeGenSPIRV/vk.early-and-lates-tests.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/vk.early-and-lates-tests.hlsl similarity index 73% rename from tools/clang/test/CodeGenSPIRV/vk.early-and-lates-tests.hlsl rename to tools/clang/test/CodeGenSPIRV_Lit/vk.early-and-lates-tests.hlsl index 3839f3d097..341bb95b2f 100644 --- a/tools/clang/test/CodeGenSPIRV/vk.early-and-lates-tests.hlsl +++ b/tools/clang/test/CodeGenSPIRV_Lit/vk.early-and-lates-tests.hlsl @@ -1,4 +1,4 @@ -// RUN: %dxc -T ps_6_0 -E main +// RUN: %dxc -T ps_6_0 -E main -fcgl %s -spirv | FileCheck %s // CHECK: OpExtension "SPV_AMD_shader_early_and_late_fragment_tests" // CHECK: OpExecutionMode %main EarlyAndLateFragmentTestsAMD diff --git a/tools/clang/test/CodeGenSPIRV/vk.early-and-lates-tests.stencil-ref-greater-equal-back.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/vk.early-and-lates-tests.stencil-ref-greater-equal-back.hlsl similarity index 81% rename from tools/clang/test/CodeGenSPIRV/vk.early-and-lates-tests.stencil-ref-greater-equal-back.hlsl rename to tools/clang/test/CodeGenSPIRV_Lit/vk.early-and-lates-tests.stencil-ref-greater-equal-back.hlsl index 00b0a30b2f..d048e2fe01 100644 --- a/tools/clang/test/CodeGenSPIRV/vk.early-and-lates-tests.stencil-ref-greater-equal-back.hlsl +++ b/tools/clang/test/CodeGenSPIRV_Lit/vk.early-and-lates-tests.stencil-ref-greater-equal-back.hlsl @@ -1,4 +1,4 @@ -// RUN: %dxc -T ps_6_0 -E main +// RUN: %dxc -T ps_6_0 -E main -fcgl %s -spirv | FileCheck %s // CHECK: OpExtension "SPV_AMD_shader_early_and_late_fragment_tests" // CHECK: OpExecutionMode %main EarlyAndLateFragmentTestsAMD diff --git a/tools/clang/test/CodeGenSPIRV/vk.early-and-lates-tests.stencil-ref-greater-equal-front.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/vk.early-and-lates-tests.stencil-ref-greater-equal-front.hlsl similarity index 81% rename from tools/clang/test/CodeGenSPIRV/vk.early-and-lates-tests.stencil-ref-greater-equal-front.hlsl rename to tools/clang/test/CodeGenSPIRV_Lit/vk.early-and-lates-tests.stencil-ref-greater-equal-front.hlsl index 52e31bc7e0..b68430cb25 100644 --- a/tools/clang/test/CodeGenSPIRV/vk.early-and-lates-tests.stencil-ref-greater-equal-front.hlsl +++ b/tools/clang/test/CodeGenSPIRV_Lit/vk.early-and-lates-tests.stencil-ref-greater-equal-front.hlsl @@ -1,4 +1,4 @@ -// RUN: %dxc -T ps_6_0 -E main +// RUN: %dxc -T ps_6_0 -E main -fcgl %s -spirv | FileCheck %s // CHECK: OpExtension "SPV_AMD_shader_early_and_late_fragment_tests" // CHECK: OpExecutionMode %main EarlyAndLateFragmentTestsAMD diff --git a/tools/clang/test/CodeGenSPIRV/vk.early-and-lates-tests.stencil-ref-less-equal-back.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/vk.early-and-lates-tests.stencil-ref-less-equal-back.hlsl similarity index 80% rename from tools/clang/test/CodeGenSPIRV/vk.early-and-lates-tests.stencil-ref-less-equal-back.hlsl rename to tools/clang/test/CodeGenSPIRV_Lit/vk.early-and-lates-tests.stencil-ref-less-equal-back.hlsl index a1612ee027..6a587b3b63 100644 --- a/tools/clang/test/CodeGenSPIRV/vk.early-and-lates-tests.stencil-ref-less-equal-back.hlsl +++ b/tools/clang/test/CodeGenSPIRV_Lit/vk.early-and-lates-tests.stencil-ref-less-equal-back.hlsl @@ -1,4 +1,4 @@ -// RUN: %dxc -T ps_6_0 -E main +// RUN: %dxc -T ps_6_0 -E main -fcgl %s -spirv | FileCheck %s // CHECK: OpExtension "SPV_AMD_shader_early_and_late_fragment_tests" // CHECK: OpExecutionMode %main EarlyAndLateFragmentTestsAMD diff --git a/tools/clang/test/CodeGenSPIRV/vk.early-and-lates-tests.stencil-ref-less-equal-front.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/vk.early-and-lates-tests.stencil-ref-less-equal-front.hlsl similarity index 80% rename from tools/clang/test/CodeGenSPIRV/vk.early-and-lates-tests.stencil-ref-less-equal-front.hlsl rename to tools/clang/test/CodeGenSPIRV_Lit/vk.early-and-lates-tests.stencil-ref-less-equal-front.hlsl index c93705cffc..f08995fcf4 100644 --- a/tools/clang/test/CodeGenSPIRV/vk.early-and-lates-tests.stencil-ref-less-equal-front.hlsl +++ b/tools/clang/test/CodeGenSPIRV_Lit/vk.early-and-lates-tests.stencil-ref-less-equal-front.hlsl @@ -1,4 +1,4 @@ -// RUN: %dxc -T ps_6_0 -E main +// RUN: %dxc -T ps_6_0 -E main -fcgl %s -spirv | FileCheck %s // CHECK: OpExtension "SPV_AMD_shader_early_and_late_fragment_tests" // CHECK: OpExecutionMode %main EarlyAndLateFragmentTestsAMD diff --git a/tools/clang/test/CodeGenSPIRV/vk.early-and-lates-tests.stencil-ref-unchanged-back.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/vk.early-and-lates-tests.stencil-ref-unchanged-back.hlsl similarity index 81% rename from tools/clang/test/CodeGenSPIRV/vk.early-and-lates-tests.stencil-ref-unchanged-back.hlsl rename to tools/clang/test/CodeGenSPIRV_Lit/vk.early-and-lates-tests.stencil-ref-unchanged-back.hlsl index 713430f1ca..4eadd9ac22 100644 --- a/tools/clang/test/CodeGenSPIRV/vk.early-and-lates-tests.stencil-ref-unchanged-back.hlsl +++ b/tools/clang/test/CodeGenSPIRV_Lit/vk.early-and-lates-tests.stencil-ref-unchanged-back.hlsl @@ -1,4 +1,4 @@ -// RUN: %dxc -T ps_6_0 -E main +// RUN: %dxc -T ps_6_0 -E main -fcgl %s -spirv | FileCheck %s // CHECK: OpExtension "SPV_AMD_shader_early_and_late_fragment_tests" // CHECK: OpExecutionMode %main EarlyAndLateFragmentTestsAMD diff --git a/tools/clang/test/CodeGenSPIRV/vk.early-and-lates-tests.stencil-ref-unchanged-front.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/vk.early-and-lates-tests.stencil-ref-unchanged-front.hlsl similarity index 81% rename from tools/clang/test/CodeGenSPIRV/vk.early-and-lates-tests.stencil-ref-unchanged-front.hlsl rename to tools/clang/test/CodeGenSPIRV_Lit/vk.early-and-lates-tests.stencil-ref-unchanged-front.hlsl index f541d28f09..b699164119 100644 --- a/tools/clang/test/CodeGenSPIRV/vk.early-and-lates-tests.stencil-ref-unchanged-front.hlsl +++ b/tools/clang/test/CodeGenSPIRV_Lit/vk.early-and-lates-tests.stencil-ref-unchanged-front.hlsl @@ -1,4 +1,4 @@ -// RUN: %dxc -T ps_6_0 -E main +// RUN: %dxc -T ps_6_0 -E main -fcgl %s -spirv | FileCheck %s // CHECK: OpExtension "SPV_AMD_shader_early_and_late_fragment_tests" // CHECK: OpExecutionMode %main EarlyAndLateFragmentTestsAMD diff --git a/tools/clang/test/CodeGenSPIRV/vk.layout.16bit-types.pc.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/vk.layout.16bit-types.pc.hlsl similarity index 90% rename from tools/clang/test/CodeGenSPIRV/vk.layout.16bit-types.pc.hlsl rename to tools/clang/test/CodeGenSPIRV_Lit/vk.layout.16bit-types.pc.hlsl index 60d5d6dbda..c485bbbd9f 100644 --- a/tools/clang/test/CodeGenSPIRV/vk.layout.16bit-types.pc.hlsl +++ b/tools/clang/test/CodeGenSPIRV_Lit/vk.layout.16bit-types.pc.hlsl @@ -1,4 +1,4 @@ -// RUN: %dxc -T ps_6_2 -E main -enable-16bit-types +// RUN: %dxc -T ps_6_2 -E main -enable-16bit-types -fcgl %s -spirv | FileCheck %s // CHECK: OpCapability StoragePushConstant16 diff --git a/tools/clang/test/CodeGenSPIRV/vk.layout.16bit-types.sbuffer.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/vk.layout.16bit-types.sbuffer.hlsl similarity index 91% rename from tools/clang/test/CodeGenSPIRV/vk.layout.16bit-types.sbuffer.hlsl rename to tools/clang/test/CodeGenSPIRV_Lit/vk.layout.16bit-types.sbuffer.hlsl index 1dc680cc06..18bd415c37 100644 --- a/tools/clang/test/CodeGenSPIRV/vk.layout.16bit-types.sbuffer.hlsl +++ b/tools/clang/test/CodeGenSPIRV_Lit/vk.layout.16bit-types.sbuffer.hlsl @@ -1,4 +1,4 @@ -// RUN: %dxc -T ps_6_2 -E main -enable-16bit-types +// RUN: %dxc -T ps_6_2 -E main -enable-16bit-types -fcgl %s -spirv | FileCheck %s // XXXXX: OpCapability StorageBuffer16BitAccess diff --git a/tools/clang/test/CodeGenSPIRV_Lit/vk.layout.cbuffer.boolean.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/vk.layout.cbuffer.boolean.hlsl new file mode 100644 index 0000000000..6b7164f08e --- /dev/null +++ b/tools/clang/test/CodeGenSPIRV_Lit/vk.layout.cbuffer.boolean.hlsl @@ -0,0 +1,162 @@ +// RUN: %dxc -T ps_6_0 -HV 2018 -E main -fcgl %s -spirv | FileCheck %s + +// CHECK: OpDecorate %_arr_v3uint_uint_2 ArrayStride 16 +// CHECK: OpMemberDecorate %FrameConstants 0 Offset 0 +// CHECK: OpMemberDecorate %FrameConstants 1 Offset 4 +// CHECK: OpMemberDecorate %FrameConstants 2 Offset 16 +// CHECK: OpMemberDecorate %type_CONSTANTS 0 Offset 0 +// CHECK: OpDecorate %type_CONSTANTS Block + +// CHECK: [[v3uint0:%[0-9]+]] = OpConstantComposite %v3uint %uint_0 %uint_0 %uint_0 +// CHECK: [[v2uint0:%[0-9]+]] = OpConstantComposite %v2uint %uint_0 %uint_0 + +// CHECK: %T = OpTypeStruct %_arr_uint_uint_1 +struct T { + bool boolArray[1]; +}; + +// CHECK: %FrameConstants = OpTypeStruct %uint %v3uint %_arr_v3uint_uint_2 %T +struct FrameConstants +{ + bool boolScalar; + bool3 boolVec; + row_major bool2x3 boolMat; + T t; +}; + +[[vk::binding(0, 0)]] +cbuffer CONSTANTS +{ + FrameConstants frameConstants; +}; + +// These are the types that hold SPIR-V booleans, rather than Uints. +// CHECK: %T_0 = OpTypeStruct %_arr_bool_uint_1 +// CHECK: %FrameConstants_0 = OpTypeStruct %bool %v3bool %_arr_v3bool_uint_2 %T_0 + +float4 main(in float4 texcoords : TEXCOORD0) : SV_TARGET +{ +// CHECK: [[FrameConstants:%[0-9]+]] = OpAccessChain %_ptr_Uniform_FrameConstants %CONSTANTS %int_0 +// CHECK-NEXT: [[uintVecPtr:%[0-9]+]] = OpAccessChain %_ptr_Uniform_v3uint [[FrameConstants]] %int_1 +// CHECK-NEXT: [[uintVec:%[0-9]+]] = OpLoad %v3uint [[uintVecPtr]] +// CHECK-NEXT: [[boolVec:%[0-9]+]] = OpINotEqual %v3bool [[uintVec]] [[v3uint0]] +// CHECK-NEXT: OpStore %a [[boolVec]] + bool3 a = frameConstants.boolVec; + +// CHECK: [[FrameConstants_0:%[0-9]+]] = OpAccessChain %_ptr_Uniform_FrameConstants %CONSTANTS %int_0 +// CHECK-NEXT: [[uintPtr:%[0-9]+]] = OpAccessChain %_ptr_Uniform_uint [[FrameConstants_0]] %int_1 %uint_0 +// CHECK-NEXT: [[uint:%[0-9]+]] = OpLoad %uint [[uintPtr]] +// CHECK-NEXT: [[bool:%[0-9]+]] = OpINotEqual %bool [[uint]] %uint_0 +// CHECK-NEXT: OpStore %b [[bool]] + bool b = frameConstants.boolVec[0]; + +// CHECK: [[FrameConstants_1:%[0-9]+]] = OpAccessChain %_ptr_Uniform_FrameConstants %CONSTANTS %int_0 +// CHECK-NEXT: [[uintPtr_0:%[0-9]+]] = OpAccessChain %_ptr_Uniform_uint [[FrameConstants_1]] %int_0 +// CHECK-NEXT: [[uint_0:%[0-9]+]] = OpLoad %uint [[uintPtr_0]] +// CHECK-NEXT: [[bool_0:%[0-9]+]] = OpINotEqual %bool [[uint_0]] %uint_0 +// CHECK-NEXT: OpStore %c [[bool_0]] + bool c = frameConstants.boolScalar; + +// CHECK: [[FrameConstants_2:%[0-9]+]] = OpAccessChain %_ptr_Uniform_FrameConstants %CONSTANTS %int_0 +// CHECK-NEXT: [[uintMatPtr:%[0-9]+]] = OpAccessChain %_ptr_Uniform__arr_v3uint_uint_2 [[FrameConstants_2]] %int_2 +// CHECK-NEXT: [[uintMat:%[0-9]+]] = OpLoad %_arr_v3uint_uint_2 [[uintMatPtr]] +// CHECK-NEXT: [[uintVec1:%[0-9]+]] = OpCompositeExtract %v3uint [[uintMat]] 0 +// CHECK-NEXT: [[boolVec1:%[0-9]+]] = OpINotEqual %v3bool [[uintVec1]] [[v3uint0]] +// CHECK-NEXT: [[uintVec2:%[0-9]+]] = OpCompositeExtract %v3uint [[uintMat]] 1 +// CHECK-NEXT: [[boolVec2:%[0-9]+]] = OpINotEqual %v3bool [[uintVec2]] [[v3uint0]] +// CHECK-NEXT: [[boolMat:%[0-9]+]] = OpCompositeConstruct %_arr_v3bool_uint_2 [[boolVec1]] [[boolVec2]] +// CHECK-NEXT: OpStore %d [[boolMat]] + bool2x3 d = frameConstants.boolMat; + +// CHECK: [[FrameConstants_3:%[0-9]+]] = OpAccessChain %_ptr_Uniform_FrameConstants %CONSTANTS %int_0 +// CHECK-NEXT: [[uintVecPtr_0:%[0-9]+]] = OpAccessChain %_ptr_Uniform_v3uint [[FrameConstants_3]] %int_2 %uint_0 +// CHECK-NEXT: [[uintVec_0:%[0-9]+]] = OpLoad %v3uint [[uintVecPtr_0]] +// CHECK-NEXT: [[boolVec_0:%[0-9]+]] = OpINotEqual %v3bool [[uintVec_0]] [[v3uint0]] +// CHECK-NEXT: OpStore %e [[boolVec_0]] + bool3 e = frameConstants.boolMat[0]; + +// CHECK: [[FrameConstants_4:%[0-9]+]] = OpAccessChain %_ptr_Uniform_FrameConstants %CONSTANTS %int_0 +// CHECK-NEXT: [[uintPtr_1:%[0-9]+]] = OpAccessChain %_ptr_Uniform_uint [[FrameConstants_4]] %int_2 %uint_1 %uint_2 +// CHECK-NEXT: [[uint_1:%[0-9]+]] = OpLoad %uint [[uintPtr_1]] +// CHECK-NEXT: [[bool_1:%[0-9]+]] = OpINotEqual %bool [[uint_1]] %uint_0 +// CHECK-NEXT: OpStore %f [[bool_1]] + bool f = frameConstants.boolMat[1][2]; + +// Swizzle Vector: out of order +// CHECK: [[FrameConstants_5:%[0-9]+]] = OpAccessChain %_ptr_Uniform_FrameConstants %CONSTANTS %int_0 +// CHECK-NEXT: [[uintVecPtr_1:%[0-9]+]] = OpAccessChain %_ptr_Uniform_v3uint [[FrameConstants_5]] %int_1 +// CHECK-NEXT: [[uintVec_1:%[0-9]+]] = OpLoad %v3uint [[uintVecPtr_1]] +// CHECK-NEXT: [[boolVec_1:%[0-9]+]] = OpINotEqual %v3bool [[uintVec_1]] [[v3uint0]] +// CHECK-NEXT: [[swizzle:%[0-9]+]] = OpVectorShuffle %v2bool [[boolVec_1]] [[boolVec_1]] 1 0 +// CHECK-NEXT: OpStore %g [[swizzle]] + bool2 g = frameConstants.boolVec.yx; + +// Swizzle Vector: one element only. +// CHECK: [[FrameConstants_6:%[0-9]+]] = OpAccessChain %_ptr_Uniform_FrameConstants %CONSTANTS %int_0 +// CHECK-NEXT: [[uintVecPtr_2:%[0-9]+]] = OpAccessChain %_ptr_Uniform_v3uint [[FrameConstants_6]] %int_1 +// CHECK-NEXT: [[uintPtr_2:%[0-9]+]] = OpAccessChain %_ptr_Uniform_uint [[uintVecPtr_2]] %int_0 +// CHECK-NEXT: [[uint_2:%[0-9]+]] = OpLoad %uint [[uintPtr_2]] +// CHECK-NEXT: [[bool_2:%[0-9]+]] = OpINotEqual %bool [[uint_2]] %uint_0 +// CHECK-NEXT: OpStore %h [[bool_2]] + bool h = frameConstants.boolVec.x; + +// Swizzle Vector: original indeces. +// CHECK: [[FrameConstants_7:%[0-9]+]] = OpAccessChain %_ptr_Uniform_FrameConstants %CONSTANTS %int_0 +// CHECK-NEXT: [[uintVecPtr_3:%[0-9]+]] = OpAccessChain %_ptr_Uniform_v3uint [[FrameConstants_7]] %int_1 +// CHECK-NEXT: [[uintVec_2:%[0-9]+]] = OpLoad %v3uint [[uintVecPtr_3]] +// CHECK-NEXT: [[boolVec_2:%[0-9]+]] = OpINotEqual %v3bool [[uintVec_2]] [[v3uint0]] +// CHECK-NEXT: OpStore %i [[boolVec_2]] + bool3 i = frameConstants.boolVec.xyz; + +// Swizzle Vector: on temporary value (rvalue) +// CHECK: [[uintVec1_0:%[0-9]+]] = OpLoad %v3uint {{%[0-9]+}} +// CHECK-NEXT: [[boolVec1_0:%[0-9]+]] = OpINotEqual %v3bool [[uintVec1_0]] [[v3uint0]] +// CHECK: [[uintVec2_0:%[0-9]+]] = OpLoad %v3uint {{%[0-9]+}} +// CHECK-NEXT: [[boolVec2_0:%[0-9]+]] = OpINotEqual %v3bool [[uintVec2_0]] [[v3uint0]] +// CHECK-NEXT: [[temporary:%[0-9]+]] = OpLogicalAnd %v3bool [[boolVec1_0]] [[boolVec2_0]] +// CHECK-NEXT: [[bool_3:%[0-9]+]] = OpCompositeExtract %bool [[temporary]] 0 +// CHECK-NEXT: OpStore %j [[bool_3]] + bool j = (frameConstants.boolVec && frameConstants.boolVec).x; + +// CHECK: [[FrameConstants_8:%[0-9]+]] = OpAccessChain %_ptr_Uniform_FrameConstants %CONSTANTS %int_0 +// CHECK-NEXT: [[uintMatPtr_0:%[0-9]+]] = OpAccessChain %_ptr_Uniform__arr_v3uint_uint_2 [[FrameConstants_8]] %int_2 +// CHECK-NEXT: [[uintPtr_3:%[0-9]+]] = OpAccessChain %_ptr_Uniform_uint [[uintMatPtr_0]] %int_1 %int_2 +// CHECK-NEXT: [[uint0:%[0-9]+]] = OpLoad %uint [[uintPtr_3]] +// CHECK-NEXT: [[uintPtr_4:%[0-9]+]] = OpAccessChain %_ptr_Uniform_uint [[uintMatPtr_0]] %int_0 %int_1 +// CHECK-NEXT: [[uint1:%[0-9]+]] = OpLoad %uint [[uintPtr_4]] +// CHECK-NEXT: [[uintVec_3:%[0-9]+]] = OpCompositeConstruct %v2uint [[uint0]] [[uint1]] +// CHECK-NEXT: [[boolVec_3:%[0-9]+]] = OpINotEqual %v2bool [[uintVec_3]] [[v2uint0]] +// CHECK-NEXT: OpStore %k [[boolVec_3]] + bool2 k = frameConstants.boolMat._m12_m01; + +// CHECK: [[FrameConstants_9:%[0-9]+]] = OpAccessChain %_ptr_Uniform_FrameConstants %CONSTANTS %int_0 +// CHECK-NEXT: [[ptr:%[0-9]+]] = OpAccessChain %_ptr_Uniform_uint [[FrameConstants_9]] %int_3 %int_0 %int_2 +// CHECK-NEXT: [[uint_3:%[0-9]+]] = OpLoad %uint [[ptr]] +// CHECK-NEXT: [[bool_4:%[0-9]+]] = OpINotEqual %bool [[uint_3]] %uint_0 +// CHECK-NEXT: OpStore %l [[bool_4]] + bool l = frameConstants.t.boolArray[2]; + +// CHECK: [[FrameConstantsPtr:%[0-9]+]] = OpAccessChain %_ptr_Uniform_FrameConstants %CONSTANTS %int_0 +// CHECK-NEXT: [[FrameConstants_10:%[0-9]+]] = OpLoad %FrameConstants [[FrameConstantsPtr]] +// CHECK-NEXT: [[fc_0_uint:%[0-9]+]] = OpCompositeExtract %uint [[FrameConstants_10]] 0 +// CHECK-NEXT: [[fc_0_bool:%[0-9]+]] = OpINotEqual %bool [[fc_0_uint]] %uint_0 +// CHECK-NEXT: [[fc_1_uint3:%[0-9]+]] = OpCompositeExtract %v3uint [[FrameConstants_10]] 1 +// CHECK-NEXT: [[fc_1_bool3:%[0-9]+]] = OpINotEqual %v3bool [[fc_1_uint3]] [[v3uint0]] +// CHECK-NEXT: [[fc_2_uintMat:%[0-9]+]] = OpCompositeExtract %_arr_v3uint_uint_2 [[FrameConstants_10]] 2 +// CHECK-NEXT: [[fc_2_uintMat_row0_uint:%[0-9]+]] = OpCompositeExtract %v3uint [[fc_2_uintMat]] 0 +// CHECK-NEXT: [[fc_2_uintMat_row0_bool:%[0-9]+]] = OpINotEqual %v3bool [[fc_2_uintMat_row0_uint]] [[v3uint0]] +// CHECK-NEXT: [[fc_2_uintMat_row1_uint:%[0-9]+]] = OpCompositeExtract %v3uint [[fc_2_uintMat]] 1 +// CHECK-NEXT: [[fc_2_uintMat_row1_bool:%[0-9]+]] = OpINotEqual %v3bool [[fc_2_uintMat_row1_uint]] [[v3uint0]] +// CHECK-NEXT: [[fc_2_boolMat:%[0-9]+]] = OpCompositeConstruct %_arr_v3bool_uint_2 [[fc_2_uintMat_row0_bool]] [[fc_2_uintMat_row1_bool]] +// CHECK-NEXT: [[fc_3_T:%[0-9]+]] = OpCompositeExtract %T [[FrameConstants_10]] 3 +// CHECK-NEXT: [[fc_3_T_0_uint_arr:%[0-9]+]] = OpCompositeExtract %_arr_uint_uint_1 [[fc_3_T]] 0 +// CHECK-NEXT: [[fc_3_T_1_uint:%[0-9]+]] = OpCompositeExtract %uint [[fc_3_T_0_uint_arr]] 0 +// CHECK-NEXT: [[fc_3_T_1_bool:%[0-9]+]] = OpINotEqual %bool [[fc_3_T_1_uint]] %uint_0 +// CHECK-NEXT: [[fc_3_T_0_bool_arr:%[0-9]+]] = OpCompositeConstruct %_arr_bool_uint_1 [[fc_3_T_1_bool]] +// CHECK-NEXT: [[fc_3_T_bool:%[0-9]+]] = OpCompositeConstruct %T_0 [[fc_3_T_0_bool_arr]] +// CHECK-NEXT: [[fc:%[0-9]+]] = OpCompositeConstruct %FrameConstants_0 [[fc_0_bool]] [[fc_1_bool3]] [[fc_2_boolMat]] [[fc_3_T_bool]] +// CHECK-NEXT: OpStore %fc [[fc]] + FrameConstants fc = frameConstants; + + return (1.0).xxxx; +} diff --git a/tools/clang/test/CodeGenSPIRV/vk.layout.cbuffer.derived-struct.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/vk.layout.cbuffer.derived-struct.hlsl similarity index 93% rename from tools/clang/test/CodeGenSPIRV/vk.layout.cbuffer.derived-struct.hlsl rename to tools/clang/test/CodeGenSPIRV_Lit/vk.layout.cbuffer.derived-struct.hlsl index 0a48dd1951..53b28b7505 100644 --- a/tools/clang/test/CodeGenSPIRV/vk.layout.cbuffer.derived-struct.hlsl +++ b/tools/clang/test/CodeGenSPIRV_Lit/vk.layout.cbuffer.derived-struct.hlsl @@ -1,4 +1,4 @@ -// RUN: %dxc -T vs_6_2 -E main -enable-16bit-types +// RUN: %dxc -T vs_6_2 -E main -enable-16bit-types -fcgl %s -spirv | FileCheck %s struct VertexInput { float4 position : POSITION; diff --git a/tools/clang/test/CodeGenSPIRV/vk.layout.cbuffer.packoffset.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/vk.layout.cbuffer.packoffset.hlsl similarity index 94% rename from tools/clang/test/CodeGenSPIRV/vk.layout.cbuffer.packoffset.hlsl rename to tools/clang/test/CodeGenSPIRV_Lit/vk.layout.cbuffer.packoffset.hlsl index 3ceccc7487..23f96388d8 100644 --- a/tools/clang/test/CodeGenSPIRV/vk.layout.cbuffer.packoffset.hlsl +++ b/tools/clang/test/CodeGenSPIRV_Lit/vk.layout.cbuffer.packoffset.hlsl @@ -1,4 +1,4 @@ -// RUN: %dxc -T vs_6_0 -E main +// RUN: %dxc -T vs_6_0 -E main -fcgl %s -spirv | FileCheck %s // CHECK: OpMemberDecorate %type_MyCBuffer 0 Offset 0 // CHECK: OpMemberDecorate %type_MyCBuffer 1 Offset 32 diff --git a/tools/clang/test/CodeGenSPIRV/vk.layout.cbuffer.zpc.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/vk.layout.cbuffer.zpc.hlsl similarity index 54% rename from tools/clang/test/CodeGenSPIRV/vk.layout.cbuffer.zpc.hlsl rename to tools/clang/test/CodeGenSPIRV_Lit/vk.layout.cbuffer.zpc.hlsl index e3f12e46f0..34201d65e6 100644 --- a/tools/clang/test/CodeGenSPIRV/vk.layout.cbuffer.zpc.hlsl +++ b/tools/clang/test/CodeGenSPIRV_Lit/vk.layout.cbuffer.zpc.hlsl @@ -1,4 +1,4 @@ -// RUN: %dxc -T vs_6_0 -E main -Zpc +// RUN: %dxc -T vs_6_0 -E main -Zpc -fcgl %s -spirv | FileCheck %s // CHECK: OpDecorate %_arr_mat2v3float_uint_5 ArrayStride 32 // CHECK: OpDecorate %_arr_mat2v3float_uint_5_0 ArrayStride 48 @@ -21,9 +21,9 @@ cbuffer MyCBuffer { void main() { // Check that the result types for access chains are correct -// CHECK: {{%\d+}} = OpAccessChain %_ptr_Uniform__arr_mat2v3float_uint_5 %MyCBuffer %int_0 -// CHECK: {{%\d+}} = OpAccessChain %_ptr_Uniform__arr_mat2v3float_uint_5_0 %MyCBuffer %int_1 -// CHECK: {{%\d+}} = OpAccessChain %_ptr_Uniform__arr_mat2v3float_uint_5_0 %MyCBuffer %int_2 +// CHECK: {{%[0-9]+}} = OpAccessChain %_ptr_Uniform__arr_mat2v3float_uint_5 %MyCBuffer %int_0 +// CHECK: {{%[0-9]+}} = OpAccessChain %_ptr_Uniform__arr_mat2v3float_uint_5_0 %MyCBuffer %int_1 +// CHECK: {{%[0-9]+}} = OpAccessChain %_ptr_Uniform__arr_mat2v3float_uint_5_0 %MyCBuffer %int_2 float2x3 m1 = matrices1[1]; float2x3 m2 = matrices2[2]; float2x3 m3 = matrices3[3]; @@ -32,12 +32,12 @@ void main() { // due to layout decoration on the rhs of the assignments below, // a load and store is performed for each vector. -// CHECK: [[ptr_matrices4:%\d+]] = OpAccessChain %_ptr_Uniform__arr__arr_v3int_uint_2_uint_5 %MyCBuffer %int_3 -// CHECK-NEXT: [[ptr_matrices4_1:%\d+]] = OpAccessChain %_ptr_Uniform__arr_v3int_uint_2 [[ptr_matrices4]] %int_1 -// CHECK-NEXT: [[matrices4_1:%\d+]] = OpLoad %_arr_v3int_uint_2 [[ptr_matrices4_1]] -// CHECK-NEXT: [[matrices4_1_row0:%\d+]] = OpCompositeExtract %v3int [[matrices4_1]] 0 -// CHECK-NEXT: [[matrices4_1_row1:%\d+]] = OpCompositeExtract %v3int [[matrices4_1]] 1 -// CHECK-NEXT: [[tmp:%\d+]] = OpCompositeConstruct %_arr_v3int_uint_2_0 [[matrices4_1_row0]] [[matrices4_1_row1]] +// CHECK: [[ptr_matrices4:%[0-9]+]] = OpAccessChain %_ptr_Uniform__arr__arr_v3int_uint_2_uint_5 %MyCBuffer %int_3 +// CHECK-NEXT: [[ptr_matrices4_1:%[0-9]+]] = OpAccessChain %_ptr_Uniform__arr_v3int_uint_2 [[ptr_matrices4]] %int_1 +// CHECK-NEXT: [[matrices4_1:%[0-9]+]] = OpLoad %_arr_v3int_uint_2 [[ptr_matrices4_1]] +// CHECK-NEXT: [[matrices4_1_row0:%[0-9]+]] = OpCompositeExtract %v3int [[matrices4_1]] 0 +// CHECK-NEXT: [[matrices4_1_row1:%[0-9]+]] = OpCompositeExtract %v3int [[matrices4_1]] 1 +// CHECK-NEXT: [[tmp:%[0-9]+]] = OpCompositeConstruct %_arr_v3int_uint_2_0 [[matrices4_1_row0]] [[matrices4_1_row1]] // CHECK-NEXT: OpStore %m4 [[tmp]] int2x3 m4 = matrices4[1]; } diff --git a/tools/clang/test/CodeGenSPIRV_Lit/vk.layout.cbuffer.zpr.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/vk.layout.cbuffer.zpr.hlsl new file mode 100644 index 0000000000..3b64eedb62 --- /dev/null +++ b/tools/clang/test/CodeGenSPIRV_Lit/vk.layout.cbuffer.zpr.hlsl @@ -0,0 +1,52 @@ +// RUN: %dxc -T vs_6_0 -E main -Zpr -fcgl %s -spirv | FileCheck %s + +// CHECK: OpDecorate %_arr_mat2v3float_uint_5 ArrayStride 32 +// CHECK: OpDecorate %_arr_mat2v3float_uint_5_0 ArrayStride 48 + +// CHECK: OpDecorate %_arr_v3int_uint_2 ArrayStride 16 +// CHECK: OpDecorate %_arr__arr_v3int_uint_2_uint_5 ArrayStride 32 + +// CHECK: OpMemberDecorate %type_MyCBuffer 0 ColMajor +// CHECK: OpMemberDecorate %type_MyCBuffer 1 RowMajor +// CHECK: OpMemberDecorate %type_MyCBuffer 2 ColMajor + +// CHECK: %type_MyCBuffer = OpTypeStruct %_arr_mat2v3float_uint_5 %_arr_mat2v3float_uint_5_0 %_arr_mat2v3float_uint_5 +cbuffer MyCBuffer { + row_major float2x3 matrices1[5]; + column_major float2x3 matrices2[5]; + float2x3 matrices3[5]; + + row_major int2x3 matrices4[5]; + int2x3 matrices5[5]; +} + +void main() { + // Check that the result types for access chains are correct +// CHECK: {{%[0-9]+}} = OpAccessChain %_ptr_Uniform__arr_mat2v3float_uint_5 %MyCBuffer %int_0 +// CHECK: {{%[0-9]+}} = OpAccessChain %_ptr_Uniform__arr_mat2v3float_uint_5_0 %MyCBuffer %int_1 +// CHECK: {{%[0-9]+}} = OpAccessChain %_ptr_Uniform__arr_mat2v3float_uint_5 %MyCBuffer %int_2 + float2x3 m1 = matrices1[1]; + float2x3 m2 = matrices2[2]; + float2x3 m3 = matrices3[3]; + + // Note: Since non-fp matrices are represented as arrays of vectors, and + // due to layout decoration on the rhs of the assignments below, + // a load and store is performed for each vector. + +// CHECK: [[ptr_matrices4:%[0-9]+]] = OpAccessChain %_ptr_Uniform__arr__arr_v3int_uint_2_uint_5 %MyCBuffer %int_3 +// CHECK-NEXT: [[ptr_matrices4_1:%[0-9]+]] = OpAccessChain %_ptr_Uniform__arr_v3int_uint_2 [[ptr_matrices4]] %int_1 +// CHECK-NEXT: [[matrices4_1:%[0-9]+]] = OpLoad %_arr_v3int_uint_2 [[ptr_matrices4_1]] +// CHECK-NEXT: [[matrices4_1_row0:%[0-9]+]] = OpCompositeExtract %v3int [[matrices4_1]] 0 +// CHECK-NEXT: [[matrices4_1_row1:%[0-9]+]] = OpCompositeExtract %v3int [[matrices4_1]] 1 +// CHECK-NEXT: [[tmp:%[0-9]+]] = OpCompositeConstruct %_arr_v3int_uint_2_0 [[matrices4_1_row0]] [[matrices4_1_row1]] +// CHECK-NEXT: OpStore %m4 [[tmp]] + int2x3 m4 = matrices4[1]; +// CHECK: [[ptr_matrices5:%[0-9]+]] = OpAccessChain %_ptr_Uniform__arr__arr_v3int_uint_2_uint_5 %MyCBuffer %int_4 +// CHECK-NEXT: [[ptr_matrices5_2:%[0-9]+]] = OpAccessChain %_ptr_Uniform__arr_v3int_uint_2 [[ptr_matrices5]] %int_2 +// CHECK-NEXT: [[matrices5_2:%[0-9]+]] = OpLoad %_arr_v3int_uint_2 [[ptr_matrices5_2]] +// CHECK-NEXT: [[matrices_5_2_row0:%[0-9]+]] = OpCompositeExtract %v3int [[matrices5_2]] 0 +// CHECK-NEXT: [[matrices_5_2_row1:%[0-9]+]] = OpCompositeExtract %v3int [[matrices5_2]] 1 +// CHECK-NEXT: [[tmp_0:%[0-9]+]] = OpCompositeConstruct %_arr_v3int_uint_2_0 [[matrices_5_2_row0]] [[matrices_5_2_row1]] +// CHECK-NEXT: OpStore %m5 [[tmp_0]] + int2x3 m5 = matrices5[2]; +} diff --git a/tools/clang/test/CodeGenSPIRV_Lit/vk.layout.rwstructuredbuffer.boolean.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/vk.layout.rwstructuredbuffer.boolean.hlsl new file mode 100644 index 0000000000..c3ffc75ea3 --- /dev/null +++ b/tools/clang/test/CodeGenSPIRV_Lit/vk.layout.rwstructuredbuffer.boolean.hlsl @@ -0,0 +1,91 @@ +// RUN: %dxc -T vs_6_0 -E main -fcgl %s -spirv | FileCheck %s + +// CHECK: [[v3uint1:%[0-9]+]] = OpConstantComposite %v3uint %uint_1 %uint_1 %uint_1 +// CHECK: [[v3uint0:%[0-9]+]] = OpConstantComposite %v3uint %uint_0 %uint_0 %uint_0 + +// CHECK: %T = OpTypeStruct %_arr_uint_uint_1 +struct T { + bool boolArray[1]; +}; + +// CHECK: %S = OpTypeStruct %uint %v3uint %_arr_v3uint_uint_2 %T +struct S +{ + bool boolScalar; + bool3 boolVec; + row_major bool2x3 boolMat; + T t; +}; + +RWStructuredBuffer values; + +// These are the types that hold SPIR-V booleans, rather than Uints. +// CHECK: %T_0 = OpTypeStruct %_arr_bool_uint_1 +// CHECK: %S_0 = OpTypeStruct %bool %v3bool %_arr_v3bool_uint_2 %T_0 + +void main() +{ + bool3 boolVecVar; + bool2 boolVecVar2; + row_major bool2x3 boolMatVar; + +// CHECK: [[uintPtr:%[0-9]+]] = OpAccessChain %_ptr_Uniform_uint %values %int_0 %uint_0 %int_0 +// CHECK-NEXT: [[convertTrueToUint:%[0-9]+]] = OpSelect %uint %true %uint_1 %uint_0 +// CHECK-NEXT: OpStore [[uintPtr]] [[convertTrueToUint]] + values[0].boolScalar = true; + +// CHECK: [[boolVecVar:%[0-9]+]] = OpLoad %v3bool %boolVecVar +// CHECK-NEXT: [[uintVecPtr:%[0-9]+]] = OpAccessChain %_ptr_Uniform_v3uint %values %int_0 %uint_1 %int_1 +// CHECK-NEXT: [[uintVecVar:%[0-9]+]] = OpSelect %v3uint [[boolVecVar]] [[v3uint1]] [[v3uint0]] +// CHECK-NEXT: OpStore [[uintVecPtr]] [[uintVecVar]] + values[1].boolVec = boolVecVar; + + // TODO: In the following cases, OpAccessChain runs into type mismatch issues due to decoration differences. + // values[2].boolMat = boolMatVar; + // values[0].boolVec.yzx = boolVecVar; + // values[0].boolMat._m12_m11 = boolVecVar2; + +// CHECK: [[sPtr:%[0-9]+]] = OpAccessChain %_ptr_Uniform_S %values %int_0 %uint_0 +// CHECK-NEXT: [[s:%[0-9]+]] = OpLoad %S [[sPtr]] +// CHECK-NEXT: [[s0:%[0-9]+]] = OpCompositeExtract %uint [[s]] 0 +// CHECK-NEXT: [[s0_bool:%[0-9]+]] = OpINotEqual %bool [[s0]] %uint_0 +// CHECK-NEXT: [[s1:%[0-9]+]] = OpCompositeExtract %v3uint [[s]] 1 +// CHECK-NEXT: [[s1_bool:%[0-9]+]] = OpINotEqual %v3bool [[s1]] [[v3uint0]] +// CHECK-NEXT: [[s2:%[0-9]+]] = OpCompositeExtract %_arr_v3uint_uint_2 [[s]] 2 +// CHECK-NEXT: [[s2_row0:%[0-9]+]] = OpCompositeExtract %v3uint [[s2]] 0 +// CHECK-NEXT: [[s2_row0_bool:%[0-9]+]] = OpINotEqual %v3bool [[s2_row0]] [[v3uint0]] +// CHECK-NEXT: [[s2_row1:%[0-9]+]] = OpCompositeExtract %v3uint [[s2]] 1 +// CHECK-NEXT: [[s2_row1_bool:%[0-9]+]] = OpINotEqual %v3bool [[s2_row1]] [[v3uint0]] +// CHECK-NEXT: [[s2_bool:%[0-9]+]] = OpCompositeConstruct %_arr_v3bool_uint_2 [[s2_row0_bool]] [[s2_row1_bool]] +// CHECK-NEXT: [[t:%[0-9]+]] = OpCompositeExtract %T [[s]] 3 +// CHECK-NEXT: [[t0_uint_arr:%[0-9]+]] = OpCompositeExtract %_arr_uint_uint_1 [[t]] 0 +// CHECK-NEXT: [[t0_0_uint:%[0-9]+]] = OpCompositeExtract %uint [[t0_uint_arr]] 0 +// CHECK-NEXT: [[t0_0_bool:%[0-9]+]] = OpINotEqual %bool [[t0_0_uint]] %uint_0 +// CHECK-NEXT: [[t0_bool:%[0-9]+]] = OpCompositeConstruct %_arr_bool_uint_1 [[t0_0_bool]] +// CHECK-NEXT: [[t_bool:%[0-9]+]] = OpCompositeConstruct %T_0 [[t0_bool]] +// CHECK-NEXT: [[s_bool:%[0-9]+]] = OpCompositeConstruct %S_0 [[s0_bool]] [[s1_bool]] [[s2_bool]] [[t_bool]] +// CHECK-NEXT: OpStore %s [[s_bool]] + S s = values[0]; + +// CHECK: [[s_0:%[0-9]+]] = OpLoad %S_0 %s +// CHECK-NEXT: [[resultPtr:%[0-9]+]] = OpAccessChain %_ptr_Uniform_S %values %int_0 %uint_1 +// CHECK-NEXT: [[s0_bool_0:%[0-9]+]] = OpCompositeExtract %bool [[s_0]] 0 +// CHECK-NEXT: [[s0_uint:%[0-9]+]] = OpSelect %uint [[s0_bool_0]] %uint_1 %uint_0 +// CHECK-NEXT: [[s1_boolVec:%[0-9]+]] = OpCompositeExtract %v3bool [[s_0]] 1 +// CHECK-NEXT: [[s1_uintVec:%[0-9]+]] = OpSelect %v3uint [[s1_boolVec]] +// CHECK-NEXT: [[s2_boolMat:%[0-9]+]] = OpCompositeExtract %_arr_v3bool_uint_2 [[s_0]] 2 +// CHECK-NEXT: [[s2_boolMat_row0:%[0-9]+]] = OpCompositeExtract %v3bool [[s2_boolMat]] 0 +// CHECK-NEXT: [[s2_boolMat_row0_uint:%[0-9]+]] = OpSelect %v3uint [[s2_boolMat_row0]] +// CHECK-NEXT: [[s2_boolMat_row1:%[0-9]+]] = OpCompositeExtract %v3bool [[s2_boolMat]] 1 +// CHECK-NEXT: [[s2_boolMat_row1_uint:%[0-9]+]] = OpSelect %v3uint [[s2_boolMat_row1]] +// CHECK-NEXT: [[s2_uintMat:%[0-9]+]] = OpCompositeConstruct %_arr_v3uint_uint_2 [[s2_boolMat_row0_uint]] [[s2_boolMat_row1_uint]] +// CHECK-NEXT: [[t_0:%[0-9]+]] = OpCompositeExtract %T_0 [[s_0]] 3 +// CHECK-NEXT: [[t0_bool_arr:%[0-9]+]] = OpCompositeExtract %_arr_bool_uint_1 [[t_0]] 0 +// CHECK-NEXT: [[t0_bool_arr_0:%[0-9]+]] = OpCompositeExtract %bool [[t0_bool_arr]] 0 +// CHECK-NEXT: [[t0_bool_arr_0_uint:%[0-9]+]] = OpSelect %uint [[t0_bool_arr_0]] %uint_1 %uint_0 +// CHECK-NEXT: [[t0_uint_arr_0:%[0-9]+]] = OpCompositeConstruct %_arr_uint_uint_1 [[t0_bool_arr_0_uint]] +// CHECK-NEXT: [[t_uint:%[0-9]+]] = OpCompositeConstruct %T [[t0_uint_arr_0]] +// CHECK-NEXT: [[s_uint:%[0-9]+]] = OpCompositeConstruct %S [[s0_uint]] [[s1_uintVec]] [[s2_uintMat]] [[t_uint]] +// CHECK-NEXT: OpStore [[resultPtr_0:%[0-9]+]] [[s_uint]] + values[1] = s; +} diff --git a/tools/clang/test/CodeGenSPIRV_Lit/vk.layout.struct.bitfield.assignment.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/vk.layout.struct.bitfield.assignment.hlsl new file mode 100644 index 0000000000..4ff934e684 --- /dev/null +++ b/tools/clang/test/CodeGenSPIRV_Lit/vk.layout.struct.bitfield.assignment.hlsl @@ -0,0 +1,78 @@ +// RUN: %dxc -T vs_6_0 -E main -HV 2021 -fcgl %s -spirv | FileCheck %s + +// Sanity check. +struct S1 { + uint f1 : 1; +}; + +struct S2 { + uint f1 : 1; + uint f2 : 3; + uint f3 : 8; + uint f4 : 1; +}; + +struct S3 { + uint f1 : 1; + int f2 : 1; + uint f3 : 1; +}; + +void main() : A { + S1 s1; +// CHECK: [[ptr:%[0-9]+]] = OpAccessChain %_ptr_Function_uint %s1 %int_0 +// CHECK: [[load:%[0-9]+]] = OpLoad %uint [[ptr]] +// CHECK: [[insert:%[0-9]+]] = OpBitFieldInsert %uint [[load]] %uint_1 %uint_0 %uint_1 +// CHECK: OpStore [[ptr]] [[insert]] + s1.f1 = 1; + + S2 s2; +// CHECK: [[ptr_0:%[0-9]+]] = OpAccessChain %_ptr_Function_uint %s2 %int_0 +// CHECK: [[load_0:%[0-9]+]] = OpLoad %uint [[ptr_0]] +// CHECK: [[insert_0:%[0-9]+]] = OpBitFieldInsert %uint [[load_0]] %uint_1 %uint_0 %uint_1 +// CHECK: OpStore [[ptr_0]] [[insert_0]] + s2.f1 = 1; +// CHECK: [[ptr_1:%[0-9]+]] = OpAccessChain %_ptr_Function_uint %s2 %int_0 +// CHECK: [[load_1:%[0-9]+]] = OpLoad %uint [[ptr_1]] +// CHECK: [[insert_1:%[0-9]+]] = OpBitFieldInsert %uint [[load_1]] %uint_5 %uint_1 %uint_3 +// CHECK: OpStore [[ptr_1]] [[insert_1]] + s2.f2 = 5; +// CHECK: [[ptr_2:%[0-9]+]] = OpAccessChain %_ptr_Function_uint %s2 %int_0 +// CHECK: [[load_2:%[0-9]+]] = OpLoad %uint [[ptr_2]] +// CHECK: [[insert_2:%[0-9]+]] = OpBitFieldInsert %uint [[load_2]] %uint_2 %uint_4 %uint_8 +// CHECK: OpStore [[ptr_2]] [[insert_2]] + s2.f3 = 2; + +// CHECK: [[ptr_3:%[0-9]+]] = OpAccessChain %_ptr_Function_uint %s2 %int_0 +// CHECK: [[load_3:%[0-9]+]] = OpLoad %uint [[ptr_3]] +// CHECK: [[insert_3:%[0-9]+]] = OpBitFieldInsert %uint [[load_3]] %uint_1 %uint_12 %uint_1 +// CHECK: OpStore [[ptr_3]] [[insert_3]] + s2.f4 = 1; + + S3 s3; +// CHECK: [[ptr_4:%[0-9]+]] = OpAccessChain %_ptr_Function_uint %s3 %int_0 +// CHECK: [[load_4:%[0-9]+]] = OpLoad %uint [[ptr_4]] +// CHECK: [[insert_4:%[0-9]+]] = OpBitFieldInsert %uint [[load_4]] %uint_1 %uint_0 %uint_1 +// CHECK: OpStore [[ptr_4]] [[insert_4]] + s3.f1 = 1; +// CHECK: [[ptr_5:%[0-9]+]] = OpAccessChain %_ptr_Function_int %s3 %int_1 +// CHECK: [[load_5:%[0-9]+]] = OpLoad %int [[ptr_5]] +// CHECK: [[insert_5:%[0-9]+]] = OpBitFieldInsert %int [[load_5]] %int_0 %uint_0 %uint_1 +// CHECK: OpStore [[ptr_5]] [[insert_5]] + s3.f2 = 0; +// CHECK: [[ptr_6:%[0-9]+]] = OpAccessChain %_ptr_Function_uint %s3 %int_2 +// CHECK: [[load_6:%[0-9]+]] = OpLoad %uint [[ptr_6]] +// CHECK: [[insert_6:%[0-9]+]] = OpBitFieldInsert %uint [[load_6]] %uint_1 %uint_0 %uint_1 +// CHECK: OpStore [[ptr_6]] [[insert_6]] + s3.f3 = 1; + +// CHECK: [[ptr_7:%[0-9]+]] = OpAccessChain %_ptr_Function_uint %s2 %int_0 +// CHECK: [[load_7:%[0-9]+]] = OpLoad %uint [[ptr_7]] +// CHECK: [[s2f4_extract:%[0-9]+]] = OpBitFieldUExtract %uint [[load_7]] %uint_12 %uint_1 +// CHECK: [[s2f4_sext:%[0-9]+]] = OpBitcast %int [[s2f4_extract]] +// CHECK: [[ptr_8:%[0-9]+]] = OpAccessChain %_ptr_Function_int %s3 %int_1 +// CHECK: [[load_8:%[0-9]+]] = OpLoad %int [[ptr_8]] +// CHECK: [[insert_7:%[0-9]+]] = OpBitFieldInsert %int [[load_8]] [[s2f4_sext]] %uint_0 %uint_1 +// CHECK: OpStore [[ptr_8]] [[insert_7]] + s3.f2 = s2.f4; +} diff --git a/tools/clang/test/CodeGenSPIRV/vk.layout.struct.bitfield.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/vk.layout.struct.bitfield.hlsl similarity index 98% rename from tools/clang/test/CodeGenSPIRV/vk.layout.struct.bitfield.hlsl rename to tools/clang/test/CodeGenSPIRV_Lit/vk.layout.struct.bitfield.hlsl index 84235901fd..ac77cc70ce 100644 --- a/tools/clang/test/CodeGenSPIRV/vk.layout.struct.bitfield.hlsl +++ b/tools/clang/test/CodeGenSPIRV_Lit/vk.layout.struct.bitfield.hlsl @@ -1,4 +1,4 @@ -// RUN: %dxc -T vs_6_0 -E main -HV 2021 +// RUN: %dxc -T vs_6_0 -E main -HV 2021 -fcgl %s -spirv | FileCheck %s // CHECK: OpMemberDecorate %S1 0 Offset 0 // CHECK-NOT: OpMemberDecorate %S1 1 Offset {{.+}} diff --git a/tools/clang/test/CodeGenSPIRV/vk.layout.struct.relaxed.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/vk.layout.struct.relaxed.hlsl similarity index 94% rename from tools/clang/test/CodeGenSPIRV/vk.layout.struct.relaxed.hlsl rename to tools/clang/test/CodeGenSPIRV_Lit/vk.layout.struct.relaxed.hlsl index 9ed0896175..b1faceef44 100644 --- a/tools/clang/test/CodeGenSPIRV/vk.layout.struct.relaxed.hlsl +++ b/tools/clang/test/CodeGenSPIRV_Lit/vk.layout.struct.relaxed.hlsl @@ -1,4 +1,4 @@ -// RUN: %dxc -T vs_6_0 -E main +// RUN: %dxc -T vs_6_0 -E main -fcgl %s -spirv | FileCheck %s struct S { float4 f1; diff --git a/tools/clang/test/CodeGenSPIRV/vk.layout.vector.relaxed.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/vk.layout.vector.relaxed.hlsl similarity index 98% rename from tools/clang/test/CodeGenSPIRV/vk.layout.vector.relaxed.hlsl rename to tools/clang/test/CodeGenSPIRV_Lit/vk.layout.vector.relaxed.hlsl index ddfb5749f9..4cb8e523a8 100644 --- a/tools/clang/test/CodeGenSPIRV/vk.layout.vector.relaxed.hlsl +++ b/tools/clang/test/CodeGenSPIRV_Lit/vk.layout.vector.relaxed.hlsl @@ -1,4 +1,4 @@ -// RUN: %dxc -T ps_6_0 -E main +// RUN: %dxc -T ps_6_0 -E main -fcgl %s -spirv | FileCheck %s // For ConstantBuffer & cbuffer // CHECK: OpMemberDecorate %S 0 Offset 0 diff --git a/tools/clang/test/CodeGenSPIRV/vk.location.exp-in.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/vk.location.exp-in.hlsl similarity index 93% rename from tools/clang/test/CodeGenSPIRV/vk.location.exp-in.hlsl rename to tools/clang/test/CodeGenSPIRV_Lit/vk.location.exp-in.hlsl index c44d628283..cf8f038f0d 100644 --- a/tools/clang/test/CodeGenSPIRV/vk.location.exp-in.hlsl +++ b/tools/clang/test/CodeGenSPIRV_Lit/vk.location.exp-in.hlsl @@ -1,4 +1,4 @@ -// RUN: %dxc -T vs_6_0 -E main +// RUN: %dxc -T vs_6_0 -E main -fcgl %s -spirv | FileCheck %s struct S { [[vk::location(2)]] int a: A; // In nested struct --- A -> 2 diff --git a/tools/clang/test/CodeGenSPIRV/vk.location.exp-out.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/vk.location.exp-out.hlsl similarity index 93% rename from tools/clang/test/CodeGenSPIRV/vk.location.exp-out.hlsl rename to tools/clang/test/CodeGenSPIRV_Lit/vk.location.exp-out.hlsl index b4bdacd1de..385323c62b 100644 --- a/tools/clang/test/CodeGenSPIRV/vk.location.exp-out.hlsl +++ b/tools/clang/test/CodeGenSPIRV_Lit/vk.location.exp-out.hlsl @@ -1,4 +1,4 @@ -// RUN: %dxc -T vs_6_0 -E main +// RUN: %dxc -T vs_6_0 -E main -fcgl %s -spirv | FileCheck %s struct S { int a: A; diff --git a/tools/clang/test/CodeGenSPIRV/vk.location.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/vk.location.hlsl similarity index 94% rename from tools/clang/test/CodeGenSPIRV/vk.location.hlsl rename to tools/clang/test/CodeGenSPIRV_Lit/vk.location.hlsl index 7b99f067d5..50170c6d1a 100644 --- a/tools/clang/test/CodeGenSPIRV/vk.location.hlsl +++ b/tools/clang/test/CodeGenSPIRV_Lit/vk.location.hlsl @@ -1,4 +1,4 @@ -// RUN: %dxc -T vs_6_0 -E main +// RUN: %dxc -T vs_6_0 -E main -fcgl %s -spirv | FileCheck %s struct S { [[vk::location(2)]] int a: A; // In nested struct --- A -> 2 diff --git a/tools/clang/test/CodeGenSPIRV/vk.push-constant.anon-struct.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/vk.push-constant.anon-struct.hlsl similarity index 91% rename from tools/clang/test/CodeGenSPIRV/vk.push-constant.anon-struct.hlsl rename to tools/clang/test/CodeGenSPIRV_Lit/vk.push-constant.anon-struct.hlsl index 4c67b97858..356e3f1e46 100644 --- a/tools/clang/test/CodeGenSPIRV/vk.push-constant.anon-struct.hlsl +++ b/tools/clang/test/CodeGenSPIRV_Lit/vk.push-constant.anon-struct.hlsl @@ -1,4 +1,4 @@ -// RUN: %dxc -T vs_6_0 -E main +// RUN: %dxc -T vs_6_0 -E main -fcgl %s -spirv | FileCheck %s // CHECK: OpName %type_PushConstant_ "type.PushConstant." // CHECK: OpMemberName %type_PushConstant_ 0 "a" diff --git a/tools/clang/test/CodeGenSPIRV/vk.push-constant.constantbuffer.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/vk.push-constant.constantbuffer.hlsl similarity index 82% rename from tools/clang/test/CodeGenSPIRV/vk.push-constant.constantbuffer.hlsl rename to tools/clang/test/CodeGenSPIRV_Lit/vk.push-constant.constantbuffer.hlsl index da3c9184b1..902ef75159 100644 --- a/tools/clang/test/CodeGenSPIRV/vk.push-constant.constantbuffer.hlsl +++ b/tools/clang/test/CodeGenSPIRV_Lit/vk.push-constant.constantbuffer.hlsl @@ -1,4 +1,4 @@ -// RUN: %dxc -T ps_6_0 -E main +// RUN: %dxc -T ps_6_0 -E main -fcgl %s -spirv | FileCheck %s struct StructA { diff --git a/tools/clang/test/CodeGenSPIRV/vk.push-constant.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/vk.push-constant.hlsl similarity index 57% rename from tools/clang/test/CodeGenSPIRV/vk.push-constant.hlsl rename to tools/clang/test/CodeGenSPIRV_Lit/vk.push-constant.hlsl index c170dc7fe3..9aecb8589a 100644 --- a/tools/clang/test/CodeGenSPIRV/vk.push-constant.hlsl +++ b/tools/clang/test/CodeGenSPIRV_Lit/vk.push-constant.hlsl @@ -1,4 +1,4 @@ -// RUN: %dxc -T vs_6_0 -E main +// RUN: %dxc -T vs_6_0 -E main -fcgl %s -spirv | FileCheck %s struct T { float2 val[3]; @@ -25,14 +25,14 @@ S pcs; float main() : A { return -// CHECK: {{%\d+}} = OpAccessChain %_ptr_PushConstant_float %pcs %int_0 +// CHECK: {{%[0-9]+}} = OpAccessChain %_ptr_PushConstant_float %pcs %int_0 pcs.f1 + -// CHECK: [[ptr:%\d+]] = OpAccessChain %_ptr_PushConstant_v3float %pcs %int_1 -// CHECK: {{%\d+}} = OpAccessChain %_ptr_PushConstant_float [[ptr]] %int_2 +// CHECK: [[ptr:%[0-9]+]] = OpAccessChain %_ptr_PushConstant_v3float %pcs %int_1 +// CHECK: {{%[0-9]+}} = OpAccessChain %_ptr_PushConstant_float [[ptr]] %int_2 pcs.f2.z + -// CHECK: {{%\d+}} = OpAccessChain %_ptr_PushConstant_float %pcs %int_2 %uint_1 %uint_2 +// CHECK: {{%[0-9]+}} = OpAccessChain %_ptr_PushConstant_float %pcs %int_2 %uint_1 %uint_2 pcs.f3[1][2] + -// CHECK: [[ptr:%\d+]] = OpAccessChain %_ptr_PushConstant_v2float %pcs %int_3 %int_0 %int_2 -// CHECK: {{%\d+}} = OpAccessChain %_ptr_PushConstant_float [[ptr]] %int_1 +// CHECK: [[ptr_0:%[0-9]+]] = OpAccessChain %_ptr_PushConstant_v2float %pcs %int_3 %int_0 %int_2 +// CHECK: {{%[0-9]+}} = OpAccessChain %_ptr_PushConstant_float [[ptr_0]] %int_1 pcs.f4.val[2].y; } diff --git a/tools/clang/test/CodeGenSPIRV/vk.push-constant.offset.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/vk.push-constant.offset.hlsl similarity index 84% rename from tools/clang/test/CodeGenSPIRV/vk.push-constant.offset.hlsl rename to tools/clang/test/CodeGenSPIRV_Lit/vk.push-constant.offset.hlsl index acbb6ddab3..ecd32f842f 100644 --- a/tools/clang/test/CodeGenSPIRV/vk.push-constant.offset.hlsl +++ b/tools/clang/test/CodeGenSPIRV_Lit/vk.push-constant.offset.hlsl @@ -1,4 +1,4 @@ -// RUN: %dxc -T vs_6_0 -E main +// RUN: %dxc -T vs_6_0 -E main -fcgl %s -spirv | FileCheck %s // CHECK: OpMemberDecorate %type_PushConstant_S 0 Offset 0 // CHECK: OpMemberDecorate %type_PushConstant_S 1 Offset 8 diff --git a/tools/clang/test/CodeGenSPIRV/vk.shader-record-ext.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/vk.shader-record-ext.hlsl similarity index 62% rename from tools/clang/test/CodeGenSPIRV/vk.shader-record-ext.hlsl rename to tools/clang/test/CodeGenSPIRV_Lit/vk.shader-record-ext.hlsl index 06dc503716..670119d345 100644 --- a/tools/clang/test/CodeGenSPIRV/vk.shader-record-ext.hlsl +++ b/tools/clang/test/CodeGenSPIRV_Lit/vk.shader-record-ext.hlsl @@ -1,4 +1,4 @@ -// RUN: %dxc -T lib_6_3 -fspv-target-env=vulkan1.2 +// RUN: %dxc -T lib_6_3 -fspv-target-env=vulkan1.2 -fcgl %s -spirv | FileCheck %s struct T { float2 val[3]; @@ -32,14 +32,14 @@ struct Attribute { float a; }; void main(inout Payload P) { P.p = -// CHECK: {{%\d+}} = OpAccessChain %_ptr_ShaderRecordBufferNV_float %srb %int_0 +// CHECK: {{%[0-9]+}} = OpAccessChain %_ptr_ShaderRecordBufferNV_float %srb %int_0 srb.f1 + -// CHECK: [[ptr:%\d+]] = OpAccessChain %_ptr_ShaderRecordBufferNV_v3float %srb %int_1 -// CHECK: {{%\d+}} = OpAccessChain %_ptr_ShaderRecordBufferNV_float [[ptr]] %int_2 +// CHECK: [[ptr:%[0-9]+]] = OpAccessChain %_ptr_ShaderRecordBufferNV_v3float %srb %int_1 +// CHECK: {{%[0-9]+}} = OpAccessChain %_ptr_ShaderRecordBufferNV_float [[ptr]] %int_2 srb.f2.z + -// CHECK: {{%\d+}} = OpAccessChain %_ptr_ShaderRecordBufferNV_float %srb %int_2 %uint_1 %uint_2 +// CHECK: {{%[0-9]+}} = OpAccessChain %_ptr_ShaderRecordBufferNV_float %srb %int_2 %uint_1 %uint_2 srb.f3[1][2] + -// CHECK: [[ptr:%\d+]] = OpAccessChain %_ptr_ShaderRecordBufferNV_v2float %srb %int_3 %int_0 %int_2 -// CHECK: {{%\d+}} = OpAccessChain %_ptr_ShaderRecordBufferNV_float [[ptr]] %int_1 +// CHECK: [[ptr_0:%[0-9]+]] = OpAccessChain %_ptr_ShaderRecordBufferNV_v2float %srb %int_3 %int_0 %int_2 +// CHECK: {{%[0-9]+}} = OpAccessChain %_ptr_ShaderRecordBufferNV_float [[ptr_0]] %int_1 srb.f4.val[2].y; } diff --git a/tools/clang/test/CodeGenSPIRV/vk.shader-record-ext.offset.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/vk.shader-record-ext.offset.hlsl similarity index 85% rename from tools/clang/test/CodeGenSPIRV/vk.shader-record-ext.offset.hlsl rename to tools/clang/test/CodeGenSPIRV_Lit/vk.shader-record-ext.offset.hlsl index e2709ab03d..0131404ed8 100644 --- a/tools/clang/test/CodeGenSPIRV/vk.shader-record-ext.offset.hlsl +++ b/tools/clang/test/CodeGenSPIRV_Lit/vk.shader-record-ext.offset.hlsl @@ -1,4 +1,4 @@ -// RUN: %dxc -T lib_6_3 -fspv-target-env=vulkan1.2 +// RUN: %dxc -T lib_6_3 -fspv-target-env=vulkan1.2 -fcgl %s -spirv | FileCheck %s // CHECK: OpMemberDecorate %type_ShaderRecordBufferEXT_S 0 Offset 0 // CHECK: OpMemberDecorate %type_ShaderRecordBufferEXT_S 1 Offset 8 diff --git a/tools/clang/test/CodeGenSPIRV/vk.shader-record-nv.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/vk.shader-record-nv.hlsl similarity index 62% rename from tools/clang/test/CodeGenSPIRV/vk.shader-record-nv.hlsl rename to tools/clang/test/CodeGenSPIRV_Lit/vk.shader-record-nv.hlsl index 2a8a0849d8..3c9364b09b 100644 --- a/tools/clang/test/CodeGenSPIRV/vk.shader-record-nv.hlsl +++ b/tools/clang/test/CodeGenSPIRV_Lit/vk.shader-record-nv.hlsl @@ -1,4 +1,4 @@ -// RUN: %dxc -T lib_6_3 -fspv-extension=SPV_NV_ray_tracing +// RUN: %dxc -T lib_6_3 -fspv-extension=SPV_NV_ray_tracing -fcgl %s -spirv | FileCheck %s struct T { float2 val[3]; @@ -32,14 +32,14 @@ struct Attribute { float a; }; void main(inout Payload P) { P.p = -// CHECK: {{%\d+}} = OpAccessChain %_ptr_ShaderRecordBufferNV_float %srb %int_0 +// CHECK: {{%[0-9]+}} = OpAccessChain %_ptr_ShaderRecordBufferNV_float %srb %int_0 srb.f1 + -// CHECK: [[ptr:%\d+]] = OpAccessChain %_ptr_ShaderRecordBufferNV_v3float %srb %int_1 -// CHECK: {{%\d+}} = OpAccessChain %_ptr_ShaderRecordBufferNV_float [[ptr]] %int_2 +// CHECK: [[ptr:%[0-9]+]] = OpAccessChain %_ptr_ShaderRecordBufferNV_v3float %srb %int_1 +// CHECK: {{%[0-9]+}} = OpAccessChain %_ptr_ShaderRecordBufferNV_float [[ptr]] %int_2 srb.f2.z + -// CHECK: {{%\d+}} = OpAccessChain %_ptr_ShaderRecordBufferNV_float %srb %int_2 %uint_1 %uint_2 +// CHECK: {{%[0-9]+}} = OpAccessChain %_ptr_ShaderRecordBufferNV_float %srb %int_2 %uint_1 %uint_2 srb.f3[1][2] + -// CHECK: [[ptr:%\d+]] = OpAccessChain %_ptr_ShaderRecordBufferNV_v2float %srb %int_3 %int_0 %int_2 -// CHECK: {{%\d+}} = OpAccessChain %_ptr_ShaderRecordBufferNV_float [[ptr]] %int_1 +// CHECK: [[ptr_0:%[0-9]+]] = OpAccessChain %_ptr_ShaderRecordBufferNV_v2float %srb %int_3 %int_0 %int_2 +// CHECK: {{%[0-9]+}} = OpAccessChain %_ptr_ShaderRecordBufferNV_float [[ptr_0]] %int_1 srb.f4.val[2].y; } diff --git a/tools/clang/test/CodeGenSPIRV/vk.shader-record-nv.offset.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/vk.shader-record-nv.offset.hlsl similarity index 84% rename from tools/clang/test/CodeGenSPIRV/vk.shader-record-nv.offset.hlsl rename to tools/clang/test/CodeGenSPIRV_Lit/vk.shader-record-nv.offset.hlsl index 6e16920c5e..5277845718 100644 --- a/tools/clang/test/CodeGenSPIRV/vk.shader-record-nv.offset.hlsl +++ b/tools/clang/test/CodeGenSPIRV_Lit/vk.shader-record-nv.offset.hlsl @@ -1,4 +1,4 @@ -// RUN: %dxc -T lib_6_3 -fspv-extension=SPV_NV_ray_tracing +// RUN: %dxc -T lib_6_3 -fspv-extension=SPV_NV_ray_tracing -fcgl %s -spirv | FileCheck %s // CHECK: OpMemberDecorate %type_ShaderRecordBufferNV_S 0 Offset 0 // CHECK: OpMemberDecorate %type_ShaderRecordBufferNV_S 1 Offset 8 diff --git a/tools/clang/test/CodeGenSPIRV/vk.shading-rate.ps.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/vk.shading-rate.ps.hlsl similarity index 50% rename from tools/clang/test/CodeGenSPIRV/vk.shading-rate.ps.hlsl rename to tools/clang/test/CodeGenSPIRV_Lit/vk.shading-rate.ps.hlsl index 32dcbc65b7..9dd8859c1d 100644 --- a/tools/clang/test/CodeGenSPIRV/vk.shading-rate.ps.hlsl +++ b/tools/clang/test/CodeGenSPIRV_Lit/vk.shading-rate.ps.hlsl @@ -1,9 +1,9 @@ -// RUN: %dxc -T ps_6_4 -E main +// RUN: %dxc -T ps_6_4 -E main -fcgl %s -spirv | FileCheck %s float4 main(uint rate : SV_ShadingRate) : SV_TARGET { // CHECK: OpCapability FragmentShadingRateKHR // CHECK: OpExtension "SPV_KHR_fragment_shading_rate" -// CHECK: OpDecorate [[r:%\d+]] BuiltIn ShadingRateKHR -// CHECK: [[r:%\d+]] = OpVariable %_ptr_Input_uint Input +// CHECK: OpDecorate [[r:%[0-9]+]] BuiltIn ShadingRateKHR +// CHECK: [[r_0:%[0-9]+]] = OpVariable %_ptr_Input_uint Input return float4(rate, 0, 0, 0); } diff --git a/tools/clang/test/CodeGenSPIRV_Lit/vk.shading-rate.vs.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/vk.shading-rate.vs.hlsl new file mode 100644 index 0000000000..c31c98680e --- /dev/null +++ b/tools/clang/test/CodeGenSPIRV_Lit/vk.shading-rate.vs.hlsl @@ -0,0 +1,9 @@ +// RUN: %dxc -T vs_6_4 -E main -fcgl %s -spirv | FileCheck %s + +void main(out uint rate : SV_ShadingRate) { +// CHECK: OpCapability FragmentShadingRateKHR +// CHECK: OpExtension "SPV_KHR_fragment_shading_rate" +// CHECK: OpDecorate [[r:%[0-9]+]] BuiltIn PrimitiveShadingRateKHR +// CHECK: [[r_0:%[0-9]+]] = OpVariable %_ptr_Output_uint Output + rate = 0; +} diff --git a/tools/clang/test/CodeGenSPIRV/vk.spec-constant.composite.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/vk.spec-constant.composite.hlsl similarity index 80% rename from tools/clang/test/CodeGenSPIRV/vk.spec-constant.composite.hlsl rename to tools/clang/test/CodeGenSPIRV_Lit/vk.spec-constant.composite.hlsl index 650d950eab..b826b0f8a9 100644 --- a/tools/clang/test/CodeGenSPIRV/vk.spec-constant.composite.hlsl +++ b/tools/clang/test/CodeGenSPIRV_Lit/vk.spec-constant.composite.hlsl @@ -1,4 +1,4 @@ -// RUN: %dxc -T cs_6_0 -E main +// RUN: %dxc -T cs_6_0 -E main -fcgl %s -spirv | FileCheck %s [[vk::constant_id(0)]] const uint kConst = 1; diff --git a/tools/clang/test/CodeGenSPIRV/vk.spec-constant.init.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/vk.spec-constant.init.hlsl similarity index 95% rename from tools/clang/test/CodeGenSPIRV/vk.spec-constant.init.hlsl rename to tools/clang/test/CodeGenSPIRV_Lit/vk.spec-constant.init.hlsl index c32e753e00..dd86f86516 100644 --- a/tools/clang/test/CodeGenSPIRV/vk.spec-constant.init.hlsl +++ b/tools/clang/test/CodeGenSPIRV_Lit/vk.spec-constant.init.hlsl @@ -1,4 +1,4 @@ -// RUN: %dxc -T vs_6_0 -E main +// RUN: %dxc -T vs_6_0 -E main -fcgl %s -spirv | FileCheck %s // CHECK: OpDecorate %b0 SpecId 0 // CHECK: OpDecorate %b1 SpecId 1 diff --git a/tools/clang/test/CodeGenSPIRV/vk.spec-constant.reuse.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/vk.spec-constant.reuse.hlsl similarity index 76% rename from tools/clang/test/CodeGenSPIRV/vk.spec-constant.reuse.hlsl rename to tools/clang/test/CodeGenSPIRV_Lit/vk.spec-constant.reuse.hlsl index 82ad56d61e..95fb0502d7 100644 --- a/tools/clang/test/CodeGenSPIRV/vk.spec-constant.reuse.hlsl +++ b/tools/clang/test/CodeGenSPIRV_Lit/vk.spec-constant.reuse.hlsl @@ -1,4 +1,4 @@ -// RUN: %dxc -T ps_6_0 -HV 2018 -E main +// RUN: %dxc -T ps_6_0 -HV 2018 -E main -fcgl %s -spirv | FileCheck %s // CHECK: OpDecorate %y SpecId 0 [[vk::constant_id(0)]] const bool y = false; diff --git a/tools/clang/test/CodeGenSPIRV/vk.spec-constant.usage.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/vk.spec-constant.usage.hlsl similarity index 78% rename from tools/clang/test/CodeGenSPIRV/vk.spec-constant.usage.hlsl rename to tools/clang/test/CodeGenSPIRV_Lit/vk.spec-constant.usage.hlsl index 51490e59b2..acfc4637e7 100644 --- a/tools/clang/test/CodeGenSPIRV/vk.spec-constant.usage.hlsl +++ b/tools/clang/test/CodeGenSPIRV_Lit/vk.spec-constant.usage.hlsl @@ -1,4 +1,4 @@ -// RUN: %dxc -T vs_6_0 -E main +// RUN: %dxc -T vs_6_0 -E main -fcgl %s -spirv | FileCheck %s // CHECK: OpDecorate %specConst SpecId 10 [[vk::constant_id(10)]] @@ -14,7 +14,7 @@ cbuffer Data { }; */ -// CHECK: [[add:%\d+]] = OpSpecConstantOp %int IAdd %specConst %int_3 +// CHECK: [[add:%[0-9]+]] = OpSpecConstantOp %int IAdd %specConst %int_3 static const int val = specConst + 3; // CHECK-LABEL: %main = OpFunction diff --git a/tools/clang/test/CodeGenSPIRV/vk.subpass-input.binding.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/vk.subpass-input.binding.hlsl similarity index 90% rename from tools/clang/test/CodeGenSPIRV/vk.subpass-input.binding.hlsl rename to tools/clang/test/CodeGenSPIRV_Lit/vk.subpass-input.binding.hlsl index c101f8653e..3c9d6044c7 100644 --- a/tools/clang/test/CodeGenSPIRV/vk.subpass-input.binding.hlsl +++ b/tools/clang/test/CodeGenSPIRV_Lit/vk.subpass-input.binding.hlsl @@ -1,4 +1,4 @@ -// RUN: %dxc -T ps_6_0 -E main +// RUN: %dxc -T ps_6_0 -E main -fcgl %s -spirv | FileCheck %s // CHECK: OpDecorate %SI0 InputAttachmentIndex 0 // CHECK: OpDecorate %SI1 InputAttachmentIndex 1 diff --git a/tools/clang/test/CodeGenSPIRV/vk.subpass-input.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/vk.subpass-input.hlsl similarity index 56% rename from tools/clang/test/CodeGenSPIRV/vk.subpass-input.hlsl rename to tools/clang/test/CodeGenSPIRV_Lit/vk.subpass-input.hlsl index 461e169c8f..42b48c671b 100644 --- a/tools/clang/test/CodeGenSPIRV/vk.subpass-input.hlsl +++ b/tools/clang/test/CodeGenSPIRV_Lit/vk.subpass-input.hlsl @@ -1,8 +1,8 @@ -// RUN: %dxc -T ps_6_0 -E main +// RUN: %dxc -T ps_6_0 -E main -fcgl %s -spirv | FileCheck %s // CHECK: OpCapability InputAttachment -// CHECK: [[v2i00:%\d+]] = OpConstantComposite %v2int %int_0 %int_0 +// CHECK: [[v2i00:%[0-9]+]] = OpConstantComposite %v2int %int_0 %int_0 // CHECK: %type_subpass_image = OpTypeImage %float SubpassData 2 0 0 2 Unknown // CHECK: %_ptr_UniformConstant_type_subpass_image = OpTypePointer UniformConstant %type_subpass_image @@ -41,44 +41,44 @@ [[vk::input_attachment_index(13)]] SubpassInputMS SIMS_u1; float4 main() : SV_Target { -// CHECK: [[img:%\d+]] = OpLoad %type_subpass_image %SI_f4 -// CHECK-NEXT: [[texel:%\d+]] = OpImageRead %v4float [[img]] [[v2i00]] None +// CHECK: [[img:%[0-9]+]] = OpLoad %type_subpass_image %SI_f4 +// CHECK-NEXT: [[texel:%[0-9]+]] = OpImageRead %v4float [[img]] [[v2i00]] None // CHECK-NEXT: OpStore %v0 [[texel]] float4 v0 = SI_f4.SubpassLoad(); -// CHECK: [[img:%\d+]] = OpLoad %type_subpass_image_0 %SI_i3 -// CHECK-NEXT: [[texel:%\d+]] = OpImageRead %v4int [[img]] [[v2i00]] None -// CHECK-NEXT: [[val:%\d+]] = OpVectorShuffle %v3int [[texel]] [[texel]] 0 1 2 +// CHECK: [[img_0:%[0-9]+]] = OpLoad %type_subpass_image_0 %SI_i3 +// CHECK-NEXT: [[texel_0:%[0-9]+]] = OpImageRead %v4int [[img_0]] [[v2i00]] None +// CHECK-NEXT: [[val:%[0-9]+]] = OpVectorShuffle %v3int [[texel_0]] [[texel_0]] 0 1 2 // CHECK-NEXT: OpStore %v1 [[val]] int3 v1 = SI_i3.SubpassLoad(); -// CHECK: [[img:%\d+]] = OpLoad %type_subpass_image_1 %SI_u2 -// CHECK-NEXT: [[texel:%\d+]] = OpImageRead %v4uint [[img]] [[v2i00]] None -// CHECK-NEXT: [[val:%\d+]] = OpVectorShuffle %v2uint [[texel]] [[texel]] 0 1 -// CHECK-NEXT: OpStore %v2 [[val]] +// CHECK: [[img_1:%[0-9]+]] = OpLoad %type_subpass_image_1 %SI_u2 +// CHECK-NEXT: [[texel_1:%[0-9]+]] = OpImageRead %v4uint [[img_1]] [[v2i00]] None +// CHECK-NEXT: [[val_0:%[0-9]+]] = OpVectorShuffle %v2uint [[texel_1]] [[texel_1]] 0 1 +// CHECK-NEXT: OpStore %v2 [[val_0]] uint2 v2 = SI_u2.SubpassLoad(); -// CHECK: [[img:%\d+]] = OpLoad %type_subpass_image %SI_f1 -// CHECK-NEXT: [[texel:%\d+]] = OpImageRead %v4float [[img]] [[v2i00]] None -// CHECK-NEXT: [[val:%\d+]] = OpCompositeExtract %float [[texel]] 0 -// CHECK-NEXT: OpStore %v3 [[val]] +// CHECK: [[img_2:%[0-9]+]] = OpLoad %type_subpass_image %SI_f1 +// CHECK-NEXT: [[texel_2:%[0-9]+]] = OpImageRead %v4float [[img_2]] [[v2i00]] None +// CHECK-NEXT: [[val_1:%[0-9]+]] = OpCompositeExtract %float [[texel_2]] 0 +// CHECK-NEXT: OpStore %v3 [[val_1]] float v3 = SI_f1.SubpassLoad(); -// CHECK: [[img:%\d+]] = OpLoad %type_subpass_image_2 %SIMS_u4 -// CHECK-NEXT: [[texel:%\d+]] = OpImageRead %v4uint [[img]] [[v2i00]] Sample %int_1 -// CHECK-NEXT: OpStore %v10 [[texel]] +// CHECK: [[img_3:%[0-9]+]] = OpLoad %type_subpass_image_2 %SIMS_u4 +// CHECK-NEXT: [[texel_3:%[0-9]+]] = OpImageRead %v4uint [[img_3]] [[v2i00]] Sample %int_1 +// CHECK-NEXT: OpStore %v10 [[texel_3]] uint4 v10 = SIMS_u4.SubpassLoad(1); -// CHECK: [[img:%\d+]] = OpLoad %type_subpass_image_3 %SIMS_f3 -// CHECK-NEXT: [[texel:%\d+]] = OpImageRead %v4float [[img]] [[v2i00]] Sample %int_2 -// CHECK-NEXT: [[val:%\d+]] = OpVectorShuffle %v3float [[texel]] [[texel]] 0 1 2 -// CHECK-NEXT: OpStore %v11 [[val]] +// CHECK: [[img_4:%[0-9]+]] = OpLoad %type_subpass_image_3 %SIMS_f3 +// CHECK-NEXT: [[texel_4:%[0-9]+]] = OpImageRead %v4float [[img_4]] [[v2i00]] Sample %int_2 +// CHECK-NEXT: [[val_2:%[0-9]+]] = OpVectorShuffle %v3float [[texel_4]] [[texel_4]] 0 1 2 +// CHECK-NEXT: OpStore %v11 [[val_2]] float3 v11 = SIMS_f3.SubpassLoad(2); -// CHECK: [[img:%\d+]] = OpLoad %type_subpass_image_4 %SIMS_i2 -// CHECK-NEXT: [[texel:%\d+]] = OpImageRead %v4int [[img]] [[v2i00]] Sample %int_3 -// CHECK-NEXT: [[val:%\d+]] = OpVectorShuffle %v2int [[texel]] [[texel]] 0 1 -// CHECK-NEXT: OpStore %v12 [[val]] +// CHECK: [[img_5:%[0-9]+]] = OpLoad %type_subpass_image_4 %SIMS_i2 +// CHECK-NEXT: [[texel_5:%[0-9]+]] = OpImageRead %v4int [[img_5]] [[v2i00]] Sample %int_3 +// CHECK-NEXT: [[val_3:%[0-9]+]] = OpVectorShuffle %v2int [[texel_5]] [[texel_5]] 0 1 +// CHECK-NEXT: OpStore %v12 [[val_3]] int2 v12 = SIMS_i2.SubpassLoad(3); -// CHECK: [[img:%\d+]] = OpLoad %type_subpass_image_2 %SIMS_u1 -// CHECK-NEXT: [[texel:%\d+]] = OpImageRead %v4uint [[img]] [[v2i00]] Sample %int_4 -// CHECK-NEXT: [[val:%\d+]] = OpCompositeExtract %uint [[texel]] 0 -// CHECK-NEXT: OpStore %v13 [[val]] +// CHECK: [[img_6:%[0-9]+]] = OpLoad %type_subpass_image_2 %SIMS_u1 +// CHECK-NEXT: [[texel_6:%[0-9]+]] = OpImageRead %v4uint [[img_6]] [[v2i00]] Sample %int_4 +// CHECK-NEXT: [[val_4:%[0-9]+]] = OpCompositeExtract %uint [[texel_6]] 0 +// CHECK-NEXT: OpStore %v13 [[val_4]] uint v13 = SIMS_u1.SubpassLoad(4); return v0.x + v1.y + v2.x + v3 + v10.x + v11.y + v12.x + v13; diff --git a/tools/clang/test/CodeGenSPIRV/vk.subpass-input.unused.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/vk.subpass-input.unused.hlsl similarity index 87% rename from tools/clang/test/CodeGenSPIRV/vk.subpass-input.unused.hlsl rename to tools/clang/test/CodeGenSPIRV_Lit/vk.subpass-input.unused.hlsl index 98cb538c9b..51f1b10878 100644 --- a/tools/clang/test/CodeGenSPIRV/vk.subpass-input.unused.hlsl +++ b/tools/clang/test/CodeGenSPIRV_Lit/vk.subpass-input.unused.hlsl @@ -1,7 +1,7 @@ // Test that the we can correctly compile the compute shader when the // subpass input is used in PsSubpassTest, but not in the compute shader. -// RUN: %dxc -T cs_6_0 -E CsTest +// RUN: %dxc -T cs_6_0 -E CsTest -fcgl %s -spirv | FileCheck %s // The subpass input variable should not be in the module. // CHECK-NOT: %subInput diff --git a/tools/clang/test/CodeGenSPIRV/volatile.interface.raygen.vk1p1.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/volatile.interface.raygen.vk1p1.hlsl similarity index 87% rename from tools/clang/test/CodeGenSPIRV/volatile.interface.raygen.vk1p1.hlsl rename to tools/clang/test/CodeGenSPIRV_Lit/volatile.interface.raygen.vk1p1.hlsl index a58fe84da2..913e28914a 100644 --- a/tools/clang/test/CodeGenSPIRV/volatile.interface.raygen.vk1p1.hlsl +++ b/tools/clang/test/CodeGenSPIRV_Lit/volatile.interface.raygen.vk1p1.hlsl @@ -1,4 +1,4 @@ -// RUN: %dxc -T lib_6_3 -fspv-extension=SPV_NV_ray_tracing -fspv-extension=SPV_KHR_ray_query -fspv-extension=SPV_KHR_vulkan_memory_model -fspv-target-env=vulkan1.1 -O0 +// RUN: %dxc -T lib_6_3 -fspv-extension=SPV_NV_ray_tracing -fspv-extension=SPV_KHR_ray_query -fspv-extension=SPV_KHR_vulkan_memory_model -fspv-target-env=vulkan1.1 -O0 %s -spirv | FileCheck %s // CHECK: OpCapability VulkanMemoryModel // CHECK: OpExtension "SPV_KHR_vulkan_memory_model" @@ -30,7 +30,7 @@ void main() { rayDesc.TMin = 0.0f; rayDesc.TMax = 1000.0f; -// CHECK: OpDecorate [[SubgroupSize:%\w+]] BuiltIn SubgroupSize +// CHECK: OpDecorate [[SubgroupSize:%[a-zA-Z0-9_]+]] BuiltIn SubgroupSize // CHECK: [[SubgroupSize]] = OpVariable %_ptr_Input_uint Input // CHECK: OpLoad %uint [[SubgroupSize]] Volatile TraceRay(rs, 0x0, WaveGetLaneCount(), 0, 1, 0, rayDesc, myPayload); diff --git a/tools/clang/test/CodeGenSPIRV/volatile.interface.raygen.vk1p2.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/volatile.interface.raygen.vk1p2.hlsl similarity index 84% rename from tools/clang/test/CodeGenSPIRV/volatile.interface.raygen.vk1p2.hlsl rename to tools/clang/test/CodeGenSPIRV_Lit/volatile.interface.raygen.vk1p2.hlsl index ec0e646c2e..de0a5034bf 100644 --- a/tools/clang/test/CodeGenSPIRV/volatile.interface.raygen.vk1p2.hlsl +++ b/tools/clang/test/CodeGenSPIRV_Lit/volatile.interface.raygen.vk1p2.hlsl @@ -1,4 +1,4 @@ -// RUN: %dxc -T lib_6_3 -fspv-extension=SPV_NV_ray_tracing -fspv-extension=SPV_KHR_ray_query -fspv-target-env=vulkan1.2 -O0 +// RUN: %dxc -T lib_6_3 -fspv-extension=SPV_NV_ray_tracing -fspv-extension=SPV_KHR_ray_query -fspv-target-env=vulkan1.2 -O0 %s -spirv | FileCheck %s // CHECK: OpCapability VulkanMemoryModel @@ -29,7 +29,7 @@ void main() { rayDesc.TMin = 0.0f; rayDesc.TMax = 1000.0f; -// CHECK: OpDecorate [[SubgroupSize:%\w+]] BuiltIn SubgroupSize +// CHECK: OpDecorate [[SubgroupSize:%[a-zA-Z0-9_]+]] BuiltIn SubgroupSize // CHECK: [[SubgroupSize]] = OpVariable %_ptr_Input_uint Input // CHECK: OpLoad %uint [[SubgroupSize]] Volatile TraceRay(rs, 0x0, WaveGetLaneCount(), 0, 1, 0, rayDesc, myPayload); diff --git a/tools/clang/test/CodeGenSPIRV/volatile.interface.raygen.vk1p3.hlsl b/tools/clang/test/CodeGenSPIRV_Lit/volatile.interface.raygen.vk1p3.hlsl similarity index 84% rename from tools/clang/test/CodeGenSPIRV/volatile.interface.raygen.vk1p3.hlsl rename to tools/clang/test/CodeGenSPIRV_Lit/volatile.interface.raygen.vk1p3.hlsl index 8bee8000bb..c4fe52f7bf 100644 --- a/tools/clang/test/CodeGenSPIRV/volatile.interface.raygen.vk1p3.hlsl +++ b/tools/clang/test/CodeGenSPIRV_Lit/volatile.interface.raygen.vk1p3.hlsl @@ -1,10 +1,10 @@ -// RUN: %dxc -T lib_6_3 -fspv-extension=SPV_NV_ray_tracing -fspv-extension=SPV_KHR_ray_query -fspv-target-env=vulkan1.3 -O0 +// RUN: %dxc -T lib_6_3 -fspv-extension=SPV_NV_ray_tracing -fspv-extension=SPV_KHR_ray_query -fspv-target-env=vulkan1.3 -O0 %s -spirv | FileCheck %s // CHECK-NOT: OpCapability VulkanMemoryModel // CHECK: OpMemoryModel Logical GLSL450 -// CHECK: OpDecorate [[SubgroupSize:%\w+]] BuiltIn SubgroupSize +// CHECK: OpDecorate [[SubgroupSize:%[a-zA-Z0-9_]+]] BuiltIn SubgroupSize // CHECK: OpDecorate [[SubgroupSize]] Volatile RaytracingAccelerationStructure rs; diff --git a/tools/clang/test/Coverage/lit.local.cfg b/tools/clang/test/Coverage/lit.local.cfg index 039670617e..76730bee2a 100644 --- a/tools/clang/test/Coverage/lit.local.cfg +++ b/tools/clang/test/Coverage/lit.local.cfg @@ -1 +1 @@ -config.unsupported = True # HLSL Change - Disable lit suites. +config.suffixes = [] # HLSL Change - Disable lit suites. diff --git a/tools/clang/test/CoverageMapping/lit.local.cfg b/tools/clang/test/CoverageMapping/lit.local.cfg index 039670617e..76730bee2a 100644 --- a/tools/clang/test/CoverageMapping/lit.local.cfg +++ b/tools/clang/test/CoverageMapping/lit.local.cfg @@ -1 +1 @@ -config.unsupported = True # HLSL Change - Disable lit suites. +config.suffixes = [] # HLSL Change - Disable lit suites. diff --git a/tools/clang/test/FixIt/lit.local.cfg b/tools/clang/test/FixIt/lit.local.cfg index 039670617e..76730bee2a 100644 --- a/tools/clang/test/FixIt/lit.local.cfg +++ b/tools/clang/test/FixIt/lit.local.cfg @@ -1 +1 @@ -config.unsupported = True # HLSL Change - Disable lit suites. +config.suffixes = [] # HLSL Change - Disable lit suites. diff --git a/tools/clang/test/Format/lit.local.cfg b/tools/clang/test/Format/lit.local.cfg index 039670617e..76730bee2a 100644 --- a/tools/clang/test/Format/lit.local.cfg +++ b/tools/clang/test/Format/lit.local.cfg @@ -1 +1 @@ -config.unsupported = True # HLSL Change - Disable lit suites. +config.suffixes = [] # HLSL Change - Disable lit suites. diff --git a/tools/clang/test/HLSL/rewriter/includes.hlsl b/tools/clang/test/HLSL/rewriter/includes.hlsl index 3a01881a97..08798a33b9 100644 --- a/tools/clang/test/HLSL/rewriter/includes.hlsl +++ b/tools/clang/test/HLSL/rewriter/includes.hlsl @@ -1,6 +1,6 @@ #include "toinclude.hlsl" #include "..\toinclude2.hlsl" -#include "\for_includes_test\toinclude3.hlsl" +#include "for_includes_test\toinclude3.hlsl" int func1(int b){ return includedFunc(b); @@ -12,4 +12,4 @@ int func2(int d){ int func3(int f){ return includedFunc3(f); -} \ No newline at end of file +} diff --git a/tools/clang/test/HLSLFileCheck/hlsl/objects/Texture/sampleInteger.hlsl b/tools/clang/test/HLSLFileCheck/hlsl/objects/Texture/sampleInteger.hlsl index 1639571f1b..51dba96f74 100644 --- a/tools/clang/test/HLSLFileCheck/hlsl/objects/Texture/sampleInteger.hlsl +++ b/tools/clang/test/HLSLFileCheck/hlsl/objects/Texture/sampleInteger.hlsl @@ -1,33 +1,23 @@ -// RUN: %dxc -T ps_6_7 %s -DTYPE=uint | FileCheck %s -// RUN: %dxc -T ps_6_7 %s -DTYPE=int | FileCheck %s +// RUN: %dxc -T ps_6_7 %s -DSKIP_SAMPLE_CMP -DTYPE=uint | FileCheck %s +// RUN: %dxc -T ps_6_7 %s -DSKIP_SAMPLE_CMP -DTYPE=int | FileCheck %s // RUN: %dxc -T ps_6_6 %s -DTYPE=uint | FileCheck %s -check-prefix=CHKFAIL -// RUN: %dxc -T ps_6_7 %s -DTYPE=uint16_t -enable-16bit-types | FileCheck %s -check-prefix=CHECK16 -// RUN: %dxc -T ps_6_7 %s -DTYPE=int16_t -enable-16bit-types | FileCheck %s -check-prefix=CHECK16 +// RUN: %dxc -T ps_6_7 %s -DSKIP_SAMPLE_CMP -DTYPE=uint16_t -enable-16bit-types | FileCheck %s -check-prefix=CHECK16 +// RUN: %dxc -T ps_6_7 %s -DSKIP_SAMPLE_CMP -DTYPE=int16_t -enable-16bit-types | FileCheck %s -check-prefix=CHECK16 // RUN: %dxc -T ps_6_6 %s -DTYPE=uint16_t -enable-16bit-types | FileCheck %s -check-prefix=CHKFAIL SamplerState g_samp : register(s0); SamplerComparisonState g_sampCmp : register(s01); Texture2D g_tex0 : register(t0); -// CHECK: Note: shader requires additional functionality: -// CHECK-NEXT: Advanced Texture Ops // CHECK: call %dx.types.ResRet.i32 @dx.op.sample.i32(i32 60 // CHECK: call %dx.types.ResRet.i32 @dx.op.sampleBias.i32(i32 61 // CHECK: call %dx.types.ResRet.i32 @dx.op.sampleLevel.i32(i32 62 // CHECK: call %dx.types.ResRet.i32 @dx.op.sampleGrad.i32(i32 63 -// CHECK: call %dx.types.ResRet.f32 @dx.op.sampleCmp.f32(i32 64 -// CHECK: call %dx.types.ResRet.f32 @dx.op.sampleCmpLevelZero.f32(i32 65 -// CHECK: call %dx.types.ResRet.f32 @dx.op.sampleCmpLevel.f32(i32 224 -// CHECK16: Note: shader requires additional functionality: -// CHECK16: Advanced Texture Ops // CHECK16: call %dx.types.ResRet.i16 @dx.op.sample.i16(i32 60 // CHECK16: call %dx.types.ResRet.i16 @dx.op.sampleBias.i16(i32 61 // CHECK16: call %dx.types.ResRet.i16 @dx.op.sampleLevel.i16(i32 62 // CHECK16: call %dx.types.ResRet.i16 @dx.op.sampleGrad.i16(i32 63 -// CHECK16: call %dx.types.ResRet.f32 @dx.op.sampleCmp.f32(i32 64 -// CHECK16: call %dx.types.ResRet.f32 @dx.op.sampleCmpLevelZero.f32(i32 65 -// CHECK16: call %dx.types.ResRet.f32 @dx.op.sampleCmpLevel.f32(i32 224 // CHKFAIL: error: cannot Sample from resource containing // CHKFAIL: error: cannot SampleBias from resource containing @@ -35,6 +25,7 @@ Texture2D g_tex0 : register(t0); // CHKFAIL: error: cannot SampleGrad from resource containing // CHKFAIL: error: cannot SampleCmp from resource containing // CHKFAIL: error: cannot SampleCmpLevelZero from resource containing +// CHKFAIL: error: cannot SampleCmpLevel from resource containing float4 main(float2 coord : TEXCOORD0) : SV_Target { float res = 0; @@ -42,9 +33,9 @@ float4 main(float2 coord : TEXCOORD0) : SV_Target { res += g_tex0.SampleBias(g_samp, coord, 0.0); res += g_tex0.SampleLevel(g_samp, coord, 0.0); res += g_tex0.SampleGrad(g_samp, coord, 0.0, 0.0); +#ifndef SKIP_SAMPLE_CMP res += g_tex0.SampleCmp(g_sampCmp, coord, 0.0); res += g_tex0.SampleCmpLevelZero(g_sampCmp, coord, 0.0); -#if __SHADER_TARGET_MAJOR > 6 || (__SHADER_TARGET_MAJOR == 6 && __SHADER_TARGET_MINOR >= 7) res += g_tex0.SampleCmpLevel(g_sampCmp, coord, 0.0, 0.0); #endif return res; diff --git a/tools/clang/test/HLSLFileCheck/passes/dxil/dxil_remove_dead_pass/delete_constant_dce.ll b/tools/clang/test/HLSLFileCheck/passes/dxil/dxil_remove_dead_pass/delete_constant_dce.ll index 4b1c2f986e..cee2576a49 100644 --- a/tools/clang/test/HLSLFileCheck/passes/dxil/dxil_remove_dead_pass/delete_constant_dce.ll +++ b/tools/clang/test/HLSLFileCheck/passes/dxil/dxil_remove_dead_pass/delete_constant_dce.ll @@ -1,4 +1,4 @@ -; RUN: %opt %s -dxil-remove-dead-blocks -S | FileCheck %s +; RUN: %opt %s -hlsl-passes-resume -dxil-remove-dead-blocks -S | FileCheck %s ; Run the pass, to make sure that %val.0 is deleted since its only use is multiplied by 0. ; %val.0 = phi float [ 1.000000e+00, %if.then ], [ 0.000000e+00, %entry ] @@ -7,7 +7,6 @@ ; CHECK: @main ; CHECK-NOT: phi float -; ModuleID = 'F:\dxc\tools\clang\test\HLSLFileCheck\passes\dxil\dxil_remove_dead_pass\delete_constant_dce.hlsl' target datalayout = "e-m:e-p:32:32-i1:32-i8:32-i16:32-i32:32-i64:64-f16:32-f32:32-f64:64-n8:16:32:64" target triple = "dxil-ms-dx" @@ -32,31 +31,31 @@ declare void @dx.noop() #1 define void @main(float* noalias) #2 { entry: %1 = load %cb, %cb* @cb - %cb = call %dx.types.Handle @dx.op.createHandleForLib.cb(i32 160, %cb %1) - %2 = call %dx.types.Handle @dx.op.annotateHandle(i32 216, %dx.types.Handle %cb, %dx.types.ResourceProperties { i32 13, i32 4 }) - call void @dx.noop(), !dbg !18 - call void @llvm.dbg.value(metadata float 0.000000e+00, i64 0, metadata !19, metadata !20), !dbg !18 - %3 = call %dx.types.CBufRet.f32 @dx.op.cbufferLoadLegacy.f32(i32 59, %dx.types.Handle %2, i32 0), !dbg !21 - %4 = extractvalue %dx.types.CBufRet.f32 %3, 0, !dbg !21 - %tobool = fcmp fast une float %4, 0.000000e+00, !dbg !21 - br i1 %tobool, label %if.then, label %if.end, !dbg !23 + %cb = call %dx.types.Handle @dx.op.createHandleForLib.cb(i32 160, %cb %1) ; CreateHandleForLib(Resource) + %2 = call %dx.types.Handle @dx.op.annotateHandle(i32 216, %dx.types.Handle %cb, %dx.types.ResourceProperties { i32 13, i32 4 }) ; AnnotateHandle(res,props) resource: CBuffer + call void @dx.noop(), !dbg !38 ; line:19 col:9 + call void @llvm.dbg.value(metadata float 0.000000e+00, i64 0, metadata !39, metadata !40), !dbg !38 ; var:"val" !DIExpression() func:"main" + %3 = call %dx.types.CBufRet.f32 @dx.op.cbufferLoadLegacy.f32(i32 59, %dx.types.Handle %2, i32 0), !dbg !41 ; line:20 col:7 ; CBufferLoadLegacy(handle,regIndex) + %4 = extractvalue %dx.types.CBufRet.f32 %3, 0, !dbg !41 ; line:20 col:7 + %tobool = fcmp fast une float %4, 0.000000e+00, !dbg !41 ; line:20 col:7 + br i1 %tobool, label %if.then, label %if.end, !dbg !43 ; line:20 col:7 if.then: ; preds = %entry - call void @dx.noop(), !dbg !24 - call void @llvm.dbg.value(metadata float 1.000000e+00, i64 0, metadata !19, metadata !20), !dbg !18 - br label %if.end, !dbg !25 + call void @dx.noop(), !dbg !44 ; line:21 col:9 + call void @llvm.dbg.value(metadata float 1.000000e+00, i64 0, metadata !39, metadata !40), !dbg !38 ; var:"val" !DIExpression() func:"main" + br label %if.end, !dbg !45 ; line:21 col:5 if.end: ; preds = %if.then, %entry %val.0 = phi float [ 1.000000e+00, %if.then ], [ 0.000000e+00, %entry ] - call void @llvm.dbg.value(metadata float %val.0, i64 0, metadata !19, metadata !20), !dbg !18 - call void @dx.noop(), !dbg !26 - call void @llvm.dbg.value(metadata float 0.000000e+00, i64 0, metadata !27, metadata !20), !dbg !26 - %mul = fmul fast float %val.0, 0.000000e+00, !dbg !28 - call void @dx.noop(), !dbg !29 - call void @llvm.dbg.value(metadata float %mul, i64 0, metadata !30, metadata !20), !dbg !29 - call void @dx.noop(), !dbg !31 - call void @dx.op.storeOutput.f32(i32 5, i32 0, i32 0, i8 0, float %mul), !dbg !31 - ret void, !dbg !31 + call void @llvm.dbg.value(metadata float %val.0, i64 0, metadata !39, metadata !40), !dbg !38 ; var:"val" !DIExpression() func:"main" + call void @dx.noop(), !dbg !46 ; line:23 col:9 + call void @llvm.dbg.value(metadata float 0.000000e+00, i64 0, metadata !47, metadata !40), !dbg !46 ; var:"zero" !DIExpression() func:"main" + %mul = fmul fast float %val.0, 0.000000e+00, !dbg !48 ; line:24 col:19 + call void @dx.noop(), !dbg !49 ; line:24 col:9 + call void @llvm.dbg.value(metadata float %mul, i64 0, metadata !50, metadata !40), !dbg !49 ; var:"ret" !DIExpression() func:"main" + call void @dx.noop(), !dbg !51 ; line:26 col:3 + call void @dx.op.storeOutput.f32(i32 5, i32 0, i32 0, i8 0, float %mul), !dbg !51 ; line:26 col:3 ; StoreOutput(outputSigId,rowIndex,colIndex,value) + ret void, !dbg !51 ; line:26 col:3 } ; Function Attrs: nounwind readnone @@ -87,9 +86,16 @@ attributes #3 = { nounwind readonly } !dx.source.defines = !{!2} !dx.source.mainFileName = !{!16} !dx.source.args = !{!17} - -!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !1, producer: "clang version 3.7 (tags/RELEASE_370/final)", isOptimized: false, runtimeVersion: 0, emissionKind: 1, enums: !2, subprograms: !3, globals: !8) -!1 = !DIFile(filename: "F:\5Cdxc\5Ctools\5Cclang\5Ctest\5CHLSLFileCheck\5Cpasses\5Cdxil\5Cdxil_remove_dead_pass\5Cdelete_constant_dce.hlsl", directory: "") +!dx.version = !{!18} +!dx.valver = !{!19} +!dx.shaderModel = !{!20} +!dx.resources = !{!21} +!dx.typeAnnotations = !{!24, !27} +!dx.entryPoints = !{!33} +!dx.rootSignature = !{!37} + +!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !1, producer: "dxc(private) 1.7.0.3848 (dxil-op-cache-init, 44ba911a0)", isOptimized: false, runtimeVersion: 0, emissionKind: 1, enums: !2, subprograms: !3, globals: !8) +!1 = !DIFile(filename: "delete_constant_dce.hlsl", directory: "") !2 = !{} !3 = !{!4} !4 = !DISubprogram(name: "main", scope: !1, file: !1, line: 18, type: !5, isLocal: false, isDefinition: true, scopeLine: 18, flags: DIFlagPrototyped, isOptimized: false, function: void (float*)* @main) @@ -102,21 +108,41 @@ attributes #3 = { nounwind readonly } !11 = !{i32 2, !"Dwarf Version", i32 4} !12 = !{i32 2, !"Debug Info Version", i32 3} !13 = !{!"hlsl-dxilemit", !"hlsl-dxilload"} -!14 = !{!"clang version 3.7 (tags/RELEASE_370/final)"} -!15 = !{!"F:\5Cdxc\5Ctools\5Cclang\5Ctest\5CHLSLFileCheck\5Cpasses\5Cdxil\5Cdxil_remove_dead_pass\5Cdelete_constant_dce.hlsl", !"// RUN: %dxc %s -T ps_6_0 -Od | FileCheck %s\0D\0A\0D\0A// This test verifies the fix for a deficiency in RemoveDeadBlocks where:\0D\0A//\0D\0A// - Value 'ret' that can be reduced to constant by DxilValueCache is removed\0D\0A// - It held on uses for a PHI 'val', but 'val' was not removed\0D\0A// - 'val' is not used, but also not DCE'ed until after DeleteDeadRegion is run\0D\0A// - DeleteDeadRegion cannot delete 'if (foo)' because 'val' still exists.\0D\0A\0D\0A// CHECK: @main\0D\0A// CHECK-NOT: phi\0D\0A\0D\0Acbuffer cb : register(b0) {\0D\0A float foo;\0D\0A}\0D\0A\0D\0A[RootSignature(\22\22)]\0D\0Afloat main() : SV_Target {\0D\0A float val = 0;\0D\0A if (foo)\0D\0A val = 1;\0D\0A\0D\0A float zero = 0;\0D\0A float ret = val * zero;\0D\0A\0D\0A return ret;\0D\0A}\0D\0A"} -!16 = !{!"F:\5Cdxc\5Ctools\5Cclang\5Ctest\5CHLSLFileCheck\5Cpasses\5Cdxil\5Cdxil_remove_dead_pass\5Cdelete_constant_dce.hlsl"} -!17 = !{!"-E", !"main", !"-T", !"ps_6_0", !"/Od", !"/Zi", !"-Qembed_debug"} -!18 = !DILocation(line: 19, column: 9, scope: !4) -!19 = !DILocalVariable(tag: DW_TAG_auto_variable, name: "val", scope: !4, file: !1, line: 19, type: !7) -!20 = !DIExpression() -!21 = !DILocation(line: 20, column: 7, scope: !22) -!22 = distinct !DILexicalBlock(scope: !4, file: !1, line: 20, column: 7) -!23 = !DILocation(line: 20, column: 7, scope: !4) -!24 = !DILocation(line: 21, column: 9, scope: !22) -!25 = !DILocation(line: 21, column: 5, scope: !22) -!26 = !DILocation(line: 23, column: 9, scope: !4) -!27 = !DILocalVariable(tag: DW_TAG_auto_variable, name: "zero", scope: !4, file: !1, line: 23, type: !7) -!28 = !DILocation(line: 24, column: 19, scope: !4) -!29 = !DILocation(line: 24, column: 9, scope: !4) -!30 = !DILocalVariable(tag: DW_TAG_auto_variable, name: "ret", scope: !4, file: !1, line: 24, type: !7) -!31 = !DILocation(line: 26, column: 3, scope: !4) +!14 = !{!"dxc(private) 1.7.0.3848 (dxil-op-cache-init, 44ba911a0)"} +!15 = !{!"delete_constant_dce.hlsl", !"// RUN: %dxc %s -T ps_6_0 -Od | FileCheck %s\0D\0A\0D\0A// This test verifies the fix for a deficiency in RemoveDeadBlocks where:\0D\0A//\0D\0A// - Value 'ret' that can be reduced to constant by DxilValueCache is removed\0D\0A// - It held on uses for a PHI 'val', but 'val' was not removed\0D\0A// - 'val' is not used, but also not DCE'ed until after DeleteDeadRegion is run\0D\0A// - DeleteDeadRegion cannot delete 'if (foo)' because 'val' still exists.\0D\0A\0D\0A// CHECK: @main\0D\0A// CHECK-NOT: phi\0D\0A\0D\0Acbuffer cb : register(b0) {\0D\0A float foo;\0D\0A}\0D\0A\0D\0A[RootSignature(\22\22)]\0D\0Afloat main() : SV_Target {\0D\0A float val = 0;\0D\0A if (foo)\0D\0A val = 1;\0D\0A\0D\0A float zero = 0;\0D\0A float ret = val * zero;\0D\0A\0D\0A return ret;\0D\0A}\0D\0A"} +!16 = !{!"delete_constant_dce.hlsl"} +!17 = !{!"-E", !"main", !"-T", !"ps_6_0", !"-fcgl", !"-Od", !"-Zi", !"-Qembed_debug"} +!18 = !{i32 1, i32 0} +!19 = !{i32 1, i32 7} +!20 = !{!"ps", i32 6, i32 0} +!21 = !{null, null, !22, null} +!22 = !{!23} +!23 = !{i32 0, %cb* @cb, !"cb", i32 0, i32 0, i32 1, i32 4, null} +!24 = !{i32 0, %cb undef, !25} +!25 = !{i32 4, !26} +!26 = !{i32 6, !"foo", i32 3, i32 0, i32 7, i32 9} +!27 = !{i32 1, void (float*)* @main, !28} +!28 = !{!29, !30} +!29 = !{i32 0, !2, !2} +!30 = !{i32 1, !31, !32} +!31 = !{i32 4, !"SV_Target", i32 7, i32 9} +!32 = !{i32 0} +!33 = !{void (float*)* @main, !"main", !34, !21, null} +!34 = !{null, !35, null} +!35 = !{!36} +!36 = !{i32 0, !"SV_Target", i8 9, i8 16, !32, i8 0, i32 1, i8 1, i32 0, i8 0, null} +!37 = !{[24 x i8] c"\02\00\00\00\00\00\00\00\18\00\00\00\00\00\00\00\18\00\00\00\00\00\00\00"} +!38 = !DILocation(line: 19, column: 9, scope: !4) +!39 = !DILocalVariable(tag: DW_TAG_auto_variable, name: "val", scope: !4, file: !1, line: 19, type: !7) +!40 = !DIExpression() +!41 = !DILocation(line: 20, column: 7, scope: !42) +!42 = distinct !DILexicalBlock(scope: !4, file: !1, line: 20, column: 7) +!43 = !DILocation(line: 20, column: 7, scope: !4) +!44 = !DILocation(line: 21, column: 9, scope: !42) +!45 = !DILocation(line: 21, column: 5, scope: !42) +!46 = !DILocation(line: 23, column: 9, scope: !4) +!47 = !DILocalVariable(tag: DW_TAG_auto_variable, name: "zero", scope: !4, file: !1, line: 23, type: !7) +!48 = !DILocation(line: 24, column: 19, scope: !4) +!49 = !DILocation(line: 24, column: 9, scope: !4) +!50 = !DILocalVariable(tag: DW_TAG_auto_variable, name: "ret", scope: !4, file: !1, line: 24, type: !7) +!51 = !DILocation(line: 26, column: 3, scope: !4) diff --git a/tools/clang/test/Headers/lit.local.cfg b/tools/clang/test/Headers/lit.local.cfg index 039670617e..76730bee2a 100644 --- a/tools/clang/test/Headers/lit.local.cfg +++ b/tools/clang/test/Headers/lit.local.cfg @@ -1 +1 @@ -config.unsupported = True # HLSL Change - Disable lit suites. +config.suffixes = [] # HLSL Change - Disable lit suites. diff --git a/tools/clang/test/Integration/lit.local.cfg b/tools/clang/test/Integration/lit.local.cfg index 039670617e..76730bee2a 100644 --- a/tools/clang/test/Integration/lit.local.cfg +++ b/tools/clang/test/Integration/lit.local.cfg @@ -1 +1 @@ -config.unsupported = True # HLSL Change - Disable lit suites. +config.suffixes = [] # HLSL Change - Disable lit suites. diff --git a/tools/clang/test/Layout/lit.local.cfg b/tools/clang/test/Layout/lit.local.cfg index 039670617e..76730bee2a 100644 --- a/tools/clang/test/Layout/lit.local.cfg +++ b/tools/clang/test/Layout/lit.local.cfg @@ -1 +1 @@ -config.unsupported = True # HLSL Change - Disable lit suites. +config.suffixes = [] # HLSL Change - Disable lit suites. diff --git a/tools/clang/test/Lexer/lit.local.cfg b/tools/clang/test/Lexer/lit.local.cfg index 039670617e..76730bee2a 100644 --- a/tools/clang/test/Lexer/lit.local.cfg +++ b/tools/clang/test/Lexer/lit.local.cfg @@ -1 +1 @@ -config.unsupported = True # HLSL Change - Disable lit suites. +config.suffixes = [] # HLSL Change - Disable lit suites. diff --git a/tools/clang/test/Misc/lit.local.cfg b/tools/clang/test/Misc/lit.local.cfg index 039670617e..76730bee2a 100644 --- a/tools/clang/test/Misc/lit.local.cfg +++ b/tools/clang/test/Misc/lit.local.cfg @@ -1 +1 @@ -config.unsupported = True # HLSL Change - Disable lit suites. +config.suffixes = [] # HLSL Change - Disable lit suites. diff --git a/tools/clang/test/PCH/lit.local.cfg b/tools/clang/test/PCH/lit.local.cfg index 039670617e..76730bee2a 100644 --- a/tools/clang/test/PCH/lit.local.cfg +++ b/tools/clang/test/PCH/lit.local.cfg @@ -1 +1 @@ -config.unsupported = True # HLSL Change - Disable lit suites. +config.suffixes = [] # HLSL Change - Disable lit suites. diff --git a/tools/clang/test/Parser/lit.local.cfg b/tools/clang/test/Parser/lit.local.cfg index 039670617e..76730bee2a 100644 --- a/tools/clang/test/Parser/lit.local.cfg +++ b/tools/clang/test/Parser/lit.local.cfg @@ -1 +1 @@ -config.unsupported = True # HLSL Change - Disable lit suites. +config.suffixes = [] # HLSL Change - Disable lit suites. diff --git a/tools/clang/test/Preprocessor/lit.local.cfg b/tools/clang/test/Preprocessor/lit.local.cfg index 039670617e..76730bee2a 100644 --- a/tools/clang/test/Preprocessor/lit.local.cfg +++ b/tools/clang/test/Preprocessor/lit.local.cfg @@ -1 +1 @@ -config.unsupported = True # HLSL Change - Disable lit suites. +config.suffixes = [] # HLSL Change - Disable lit suites. diff --git a/tools/clang/test/Profile/lit.local.cfg b/tools/clang/test/Profile/lit.local.cfg index 039670617e..76730bee2a 100644 --- a/tools/clang/test/Profile/lit.local.cfg +++ b/tools/clang/test/Profile/lit.local.cfg @@ -1 +1 @@ -config.unsupported = True # HLSL Change - Disable lit suites. +config.suffixes = [] # HLSL Change - Disable lit suites. diff --git a/tools/clang/test/Sema/lit.local.cfg b/tools/clang/test/Sema/lit.local.cfg index 44a574be6e..4ee7ebf946 100644 --- a/tools/clang/test/Sema/lit.local.cfg +++ b/tools/clang/test/Sema/lit.local.cfg @@ -1,4 +1,4 @@ -config.unsupported = True # HLSL Change - Disable lit suites. +config.suffixes = [] # HLSL Change - Disable lit suites. config.substitutions = list(config.substitutions) config.substitutions.insert(0, (r'%clang\b', diff --git a/tools/clang/test/SemaCUDA/lit.local.cfg b/tools/clang/test/SemaCUDA/lit.local.cfg index 44a574be6e..4ee7ebf946 100644 --- a/tools/clang/test/SemaCUDA/lit.local.cfg +++ b/tools/clang/test/SemaCUDA/lit.local.cfg @@ -1,4 +1,4 @@ -config.unsupported = True # HLSL Change - Disable lit suites. +config.suffixes = [] # HLSL Change - Disable lit suites. config.substitutions = list(config.substitutions) config.substitutions.insert(0, (r'%clang\b', diff --git a/tools/clang/test/SemaCXX/lit.local.cfg b/tools/clang/test/SemaCXX/lit.local.cfg index 039670617e..76730bee2a 100644 --- a/tools/clang/test/SemaCXX/lit.local.cfg +++ b/tools/clang/test/SemaCXX/lit.local.cfg @@ -1 +1 @@ -config.unsupported = True # HLSL Change - Disable lit suites. +config.suffixes = [] # HLSL Change - Disable lit suites. diff --git a/tools/clang/test/HLSL/array-index-out-of-bounds-HV-2016.hlsl b/tools/clang/test/SemaHLSL/array-index-out-of-bounds-HV-2016.hlsl similarity index 67% rename from tools/clang/test/HLSL/array-index-out-of-bounds-HV-2016.hlsl rename to tools/clang/test/SemaHLSL/array-index-out-of-bounds-HV-2016.hlsl index 2619ec20b1..ebae2f22f4 100644 --- a/tools/clang/test/HLSL/array-index-out-of-bounds-HV-2016.hlsl +++ b/tools/clang/test/SemaHLSL/array-index-out-of-bounds-HV-2016.hlsl @@ -1,7 +1,9 @@ -// RUN: %clang_cc1 -Wno-unused-value -fsyntax-only -ffreestanding -HV 2016 -verify -verify-ignore-unexpected=note %s +// RUN: %dxc -Tlib_6_3 -Wno-unused-value -HV 2016 -verify %s void dead() { + // expected-note@+2 {{array 'array' declared here}} + // expected-note@+1 {{array 'array' declared here}} int array[2]; array[-1] = 0; /* expected-warning {{array index -1 is before the beginning of the array}} fxc-pass {{}} */ array[0] = 0; @@ -9,4 +11,4 @@ void dead() array[2] = 0; /* expected-warning {{array index 2 is past the end of the array (which contains 2 elements)}} fxc-pass {{}} */ } -void main() {} \ No newline at end of file +void main() {} diff --git a/tools/clang/test/HLSL/array-index-out-of-bounds.hlsl b/tools/clang/test/SemaHLSL/array-index-out-of-bounds.hlsl similarity index 70% rename from tools/clang/test/HLSL/array-index-out-of-bounds.hlsl rename to tools/clang/test/SemaHLSL/array-index-out-of-bounds.hlsl index 2e89c481b2..89ca8a1eca 100644 --- a/tools/clang/test/HLSL/array-index-out-of-bounds.hlsl +++ b/tools/clang/test/SemaHLSL/array-index-out-of-bounds.hlsl @@ -1,10 +1,12 @@ -// RUN: %clang_cc1 -Wno-unused-value -fsyntax-only -ffreestanding -verify -verify-ignore-unexpected=note %s +// RUN: %dxc -Tlib_6_3 -Wno-unused-value -verify %s void main() { + // expected-note@+2 {{array 'array' declared here}} + // expected-note@+1 {{array 'array' declared here}} int array[2]; array[-1] = 0; /* expected-error {{array index -1 is out of bounds}} fxc-error {{X3504: array index out of bounds}} */ array[0] = 0; array[1] = 0; array[2] = 0; /* expected-error {{array index 2 is out of bounds}} fxc-error {{X3504: array index out of bounds}} */ -} \ No newline at end of file +} diff --git a/tools/clang/test/HLSL/array-length.hlsl b/tools/clang/test/SemaHLSL/array-length.hlsl similarity index 90% rename from tools/clang/test/HLSL/array-length.hlsl rename to tools/clang/test/SemaHLSL/array-length.hlsl index 99f3a4bedb..cb87572ae5 100644 --- a/tools/clang/test/HLSL/array-length.hlsl +++ b/tools/clang/test/SemaHLSL/array-length.hlsl @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fsyntax-only -ffreestanding -verify -HV 2016 %s +// RUN: %dxc -Tlib_6_3 -verify -HV 2016 %s // :FXC_VERIFY_ARGUMENTS: /T ps_5_0 /E main float4 planes1[8]; diff --git a/tools/clang/test/HLSL/atomic-float-errors.hlsl b/tools/clang/test/SemaHLSL/atomic-float-errors.hlsl similarity index 98% rename from tools/clang/test/HLSL/atomic-float-errors.hlsl rename to tools/clang/test/SemaHLSL/atomic-float-errors.hlsl index de4362dcc7..fb6d77b432 100644 --- a/tools/clang/test/HLSL/atomic-float-errors.hlsl +++ b/tools/clang/test/SemaHLSL/atomic-float-errors.hlsl @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fsyntax-only -ffreestanding -verify %s +// RUN: %dxc -Tlib_6_3 -verify %s // Verify that the first arg determines the overload and the others can be what they will diff --git a/tools/clang/test/HLSL/attributes.hlsl b/tools/clang/test/SemaHLSL/attributes.hlsl similarity index 99% rename from tools/clang/test/HLSL/attributes.hlsl rename to tools/clang/test/SemaHLSL/attributes.hlsl index 05eb7df4a0..aa256b47da 100644 --- a/tools/clang/test/HLSL/attributes.hlsl +++ b/tools/clang/test/SemaHLSL/attributes.hlsl @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fsyntax-only -ffreestanding -HV 2018 -verify %s +// RUN: %dxc -Tlib_6_3 -HV 2018 -verify %s // To test with the classic compiler, run // %sdxroot%\tools\x86\fxc.exe /T ps_5_1 attributes.hlsl diff --git a/tools/clang/test/HLSL/builtin-types-no-inheritance.hlsl b/tools/clang/test/SemaHLSL/builtin-types-no-inheritance.hlsl similarity index 74% rename from tools/clang/test/HLSL/builtin-types-no-inheritance.hlsl rename to tools/clang/test/SemaHLSL/builtin-types-no-inheritance.hlsl index 5cdd5baaa6..9a8ee02f14 100644 --- a/tools/clang/test/HLSL/builtin-types-no-inheritance.hlsl +++ b/tools/clang/test/SemaHLSL/builtin-types-no-inheritance.hlsl @@ -1,4 +1,18 @@ -// RUN: %clang_cc1 -Wno-unused-value -fsyntax-only -ffreestanding -verify -verify-ignore-unexpected=note %s +// RUN: %dxc -Tlib_6_3 -Wno-unused-value -verify %s + +// expected-note@? {{'vector' declared here}} +// expected-note@? {{'matrix' declared here}} +// expected-note@? {{'Texture3D' declared here}} +// expected-note@? {{'ByteAddressBuffer' declared here}} +// expected-note@? {{'StructuredBuffer' declared here}} +// expected-note@? {{'SamplerState' declared here}} +// expected-note@? {{'TriangleStream' declared here}} +// expected-note@? {{'InputPatch' declared here}} +// expected-note@? {{'OutputPatch' declared here}} +// expected-note@? {{'RayDesc' declared here}} +// expected-note@? {{'BuiltInTriangleIntersectionAttributes' declared here}} +// expected-note@? {{'RaytracingAccelerationStructure' declared here}} +// expected-note@? {{'GlobalRootSignature' declared here}} struct F2 : float2 {}; // expected-error {{base 'vector' is marked 'final'}} fxc-error {{X3094: base type is not a struct, class or interface}} struct F4x4 : float4x4 {}; // expected-error {{base 'matrix' is marked 'final'}} fxc-error {{X3094: base type is not a struct, class or interface}} @@ -17,4 +31,4 @@ struct BITIA : BuiltInTriangleIntersectionAttributes {}; // expected-error {{bas struct RTAS : RaytracingAccelerationStructure {}; // expected-error {{base 'RaytracingAccelerationStructure' is marked 'final'}} fxc-error {{X3000: syntax error: unexpected token 'RaytracingAccelerationStructure'}} struct GRS : GlobalRootSignature {}; // expected-error {{base 'GlobalRootSignature' is marked 'final'}} fxc-error {{X3000: syntax error: unexpected token 'GlobalRootSignature'}} -void main() {} \ No newline at end of file +void main() {} diff --git a/tools/clang/test/HLSL/const-assign.hlsl b/tools/clang/test/SemaHLSL/const-assign.hlsl similarity index 85% rename from tools/clang/test/HLSL/const-assign.hlsl rename to tools/clang/test/SemaHLSL/const-assign.hlsl index 6de9d16b3c..e7977b2355 100644 --- a/tools/clang/test/HLSL/const-assign.hlsl +++ b/tools/clang/test/SemaHLSL/const-assign.hlsl @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fsyntax-only -Wno-unused-value -ffreestanding -verify %s +// RUN: %dxc -Tlib_6_3 -Wno-unused-value -verify %s float4 main() : SV_TARGET { diff --git a/tools/clang/test/HLSL/const-default.hlsl b/tools/clang/test/SemaHLSL/const-default.hlsl similarity index 98% rename from tools/clang/test/HLSL/const-default.hlsl rename to tools/clang/test/SemaHLSL/const-default.hlsl index efd07d4202..77365ad014 100644 --- a/tools/clang/test/HLSL/const-default.hlsl +++ b/tools/clang/test/SemaHLSL/const-default.hlsl @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fsyntax-only -Wno-unused-value -ffreestanding -verify %s +// RUN: %dxc -Tlib_6_3 -Wno-unused-value -verify %s float g_float1; /* expected-note {{variable 'g_float1' declared const here}} expected-note {{variable 'g_float1' declared const here}} fxc-pass {{}} */ int4 g_vec1; /* expected-note {{variable 'g_vec1' declared const here}} expected-note {{variable 'g_vec1' declared const here}} fxc-pass {{}} */ diff --git a/tools/clang/test/HLSL/const-expr.hlsl b/tools/clang/test/SemaHLSL/const-expr.hlsl similarity index 99% rename from tools/clang/test/HLSL/const-expr.hlsl rename to tools/clang/test/SemaHLSL/const-expr.hlsl index 2122450af2..82b0fb9e43 100644 --- a/tools/clang/test/HLSL/const-expr.hlsl +++ b/tools/clang/test/SemaHLSL/const-expr.hlsl @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fsyntax-only -Wno-unused-value -ffreestanding -verify %s +// RUN: %dxc -Tlib_6_3 -Wno-unused-value -verify %s float overload1(float f) { return 1; } /* expected-note {{candidate function}} expected-note {{candidate function}} expected-note {{candidate function}} expected-note {{candidate function}} expected-note {{candidate function}} fxc-pass {{}} */ double overload1(double f) { return 2; } /* expected-note {{candidate function}} expected-note {{candidate function}} expected-note {{candidate function}} expected-note {{candidate function}} expected-note {{candidate function}} fxc-pass {{}} */ diff --git a/tools/clang/test/HLSL/conversions-between-type-shapes-strictudt.hlsl b/tools/clang/test/SemaHLSL/conversions-between-type-shapes-strictudt.hlsl similarity index 76% rename from tools/clang/test/HLSL/conversions-between-type-shapes-strictudt.hlsl rename to tools/clang/test/SemaHLSL/conversions-between-type-shapes-strictudt.hlsl index da710afae1..1b9cd9825a 100644 --- a/tools/clang/test/HLSL/conversions-between-type-shapes-strictudt.hlsl +++ b/tools/clang/test/SemaHLSL/conversions-between-type-shapes-strictudt.hlsl @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -HV 2021 -Wno-unused-value -fsyntax-only -ffreestanding -verify -verify-ignore-unexpected=note %s +// RUN: %dxc -Tlib_6_3 -HV 2021 -Wno-unused-value -verify %s // Tests all implicit conversions and explicit casts between type shapes // (scalars, vectors, matrices, arrays and structs). @@ -26,22 +26,99 @@ struct DerivedFrom_S2 : S2 { int c; }; -// Clang generates a bunch of "notes" about overload candidates here, but we're not testing for these +// Clang generates a bunch of "notes" about overload candidates here, we're not testing for these +// Just avoid use -verify-ignore-unexpected. + +// expected-note@+4 {{candidate function not viable: no known conversion from 'A1' (aka 'int [1]') to 'int' for 1st argument}} +// expected-note@+3 {{candidate function not viable: no known conversion from 'S1' to 'int' for 1st argument}} +// expected-note@+2 {{candidate function not viable: no known conversion from 'A2' (aka 'int [2]') to 'int' for 1st argument}} +// expected-note@+1 {{candidate function not viable: no known conversion from 'S2' to 'int' for 1st argument}} void to_i(int i) {} +// expected-note@+4 {{candidate function not viable: no known conversion from 'A2' (aka 'int [2]') to 'int1' for 1st argument}} +// expected-note@+3 {{candidate function not viable: no known conversion from 'S2' to 'int1' for 1st argument}} +// expected-note@+2 {{candidate function not viable: no known conversion from 'A1' (aka 'int [1]') to 'int1' for 1st argument}} +// expected-note@+1 {{candidate function not viable: no known conversion from 'S1' to 'int1' for 1st argument}} void to_v1(int1 v) {} +// expected-note@+4 {{candidate function not viable: no known conversion from 'A2' (aka 'int [2]') to 'int2' for 1st argument}} +// expected-note@+3 {{candidate function not viable: no known conversion from 'S2' to 'int2' for 1st argument}} +// expected-note@+2 {{candidate function not viable: no known conversion from 'A4' (aka 'int [4]') to 'int2' for 1st argument}} +// expected-note@+1 {{candidate function not viable: no known conversion from 'S4' to 'int2' for 1st argument}} void to_v2(int2 v) {} void to_v4(int4 v) {} +// expected-note@+4 {{candidate function not viable: no known conversion from 'A1' (aka 'int [1]') to 'int1x1' for 1st argument}} +// expected-note@+3 {{candidate function not viable: no known conversion from 'S1' to 'int1x1' for 1st argument}} +// expected-note@+2 {{candidate function not viable: no known conversion from 'A2' (aka 'int [2]') to 'int1x1' for 1st argument}} +// expected-note@+1 {{candidate function not viable: no known conversion from 'S2' to 'int1x1' for 1st argument}} void to_m1x1(int1x1 m) {} +// expected-note@+4 {{candidate function not viable: no known conversion from 'A2' (aka 'int [2]') to 'int1x2' for 1st argument}} +// expected-note@+3 {{candidate function not viable: no known conversion from 'S2' to 'int1x2' for 1st argument}} +// expected-note@+2 {{candidate function not viable: no known conversion from 'A4' (aka 'int [4]') to 'int1x2' for 1st argument}} +// expected-note@+1 {{candidate function not viable: no known conversion from 'S4' to 'int1x2' for 1st argument}} void to_m1x2(int1x2 m) {} +// expected-note@+4 {{candidate function not viable: no known conversion from 'S4' to 'int2x1' for 1st argument}} +// expected-note@+3 {{candidate function not viable: no known conversion from 'A4' (aka 'int [4]') to 'int2x1' for 1st argument}} +// expected-note@+2 {{candidate function not viable: no known conversion from 'S2' to 'int2x1' for 1st argument}} +// expected-note@+1 {{candidate function not viable: no known conversion from 'A2' (aka 'int [2]') to 'int2x1' for 1st argument}} void to_m2x1(int2x1 m) {} +// expected-note@+4 {{candidate function not viable: no known conversion from 'S5' to 'int2x2' for 1st argument}} +// expected-note@+3 {{candidate function not viable: no known conversion from 'A5' (aka 'int [5]') to 'int2x2' for 1st argument}} +// expected-note@+2 {{candidate function not viable: no known conversion from 'S4' to 'int2x2' for 1st argument}} +// expected-note@+1 {{candidate function not viable: no known conversion from 'A4' (aka 'int [4]') to 'int2x2' for 1st argument}} void to_m2x2(int2x2 m) {} void to_m3x3(int3x3 m) {} +// expected-note@+8 {{candidate function not viable: no known conversion from 'int' to 'A1' (aka 'int [1]') for 1st argument}} +// expected-note@+7 {{candidate function not viable: no known conversion from 'int1' to 'A1' (aka 'int [1]') for 1st argument}} +// expected-note@+6 {{candidate function not viable: no known conversion from 'int1x1' to 'A1' (aka 'int [1]') for 1st argument}} +// expected-note@+5 {{candidate function not viable: no known conversion from 'S1' to 'A1' (aka 'int [1]') for 1st argument}} +// expected-note@+4 {{candidate function not viable: no known conversion from 'int2' to 'A1' (aka 'int [1]') for 1st argument}} +// expected-note@+3 {{candidate function not viable: no known conversion from 'int2x2' to 'A1' (aka 'int [1]') for 1st argument}} +// expected-note@+2 {{candidate function not viable: no known conversion from 'A2' (aka 'int [2]') to 'A1' (aka 'int [1]') for 1st argument}} +// expected-note@+1 {{candidate function not viable: no known conversion from 'S2' to 'A1' (aka 'int [1]') for 1st argument}} void to_a1(A1 a) {} +// expected-note@+14 {{candidate function not viable: no known conversion from 'int' to 'A2' (aka 'int [2]') for 1st argument}} +// expected-note@+13 {{candidate function not viable: no known conversion from 'int1' to 'A2' (aka 'int [2]') for 1st argument}} +// expected-note@+12 {{candidate function not viable: no known conversion from 'int1x1' to 'A2' (aka 'int [2]') for 1st argument}} +// expected-note@+11 {{candidate function not viable: no known conversion from 'int2' to 'A2' (aka 'int [2]') for 1st argument}} +// expected-note@+10 {{candidate function not viable: no known conversion from 'int1x2' to 'A2' (aka 'int [2]') for 1st argument}} +// expected-note@+9 {{candidate function not viable: no known conversion from 'int2x1' to 'A2' (aka 'int [2]') for 1st argument}} +// expected-note@+8 {{candidate function not viable: no known conversion from 'S2' to 'A2' (aka 'int [2]') for 1st argument}} +// expected-note@+7 {{candidate function not viable: no known conversion from 'int4' to 'A2' (aka 'int [2]') for 1st argument}} +// expected-note@+6 {{candidate function not viable: no known conversion from 'int1x3' to 'A2' (aka 'int [2]') for 1st argument}} +// expected-note@+5 {{candidate function not viable: no known conversion from 'int3x1' to 'A2' (aka 'int [2]') for 1st argument}} +// expected-note@+4 {{candidate function not viable: no known conversion from 'int2x2' to 'A2' (aka 'int [2]') for 1st argument}} +// expected-note@+3 {{candidate function not viable: no known conversion from 'int3x3' to 'A2' (aka 'int [2]') for 1st argument}} +// expected-note@+2 {{candidate function not viable: no known conversion from 'A4' (aka 'int [4]') to 'A2' (aka 'int [2]') for 1st argument}} +// expected-note@+1 {{candidate function not viable: no known conversion from 'S4' to 'A2' (aka 'int [2]') for 1st argument}} void to_a2(A2 a) {} +// expected-note@+1 {{candidate function not viable: no known conversion from 'int2x2' to 'A4' (aka 'int [4]') for 1st argument}} void to_a4(A4 a) {} void to_a5(A5 a) {} +// expected-note@+8 {{candidate function not viable: no known conversion from 'int' to 'S1' for 1st argument}} +// expected-note@+7 {{candidate function not viable: no known conversion from 'int1' to 'S1' for 1st argument}} +// expected-note@+6 {{candidate function not viable: no known conversion from 'int1x1' to 'S1' for 1st argument}} +// expected-note@+5 {{candidate function not viable: no known conversion from 'A1' (aka 'int [1]') to 'S1' for 1st argument}} +// expected-note@+4 {{candidate function not viable: no known conversion from 'int2' to 'S1' for 1st argument}} +// expected-note@+3 {{candidate function not viable: no known conversion from 'int2x2' to 'S1' for 1st argument}} +// expected-note@+2 {{candidate function not viable: no known conversion from 'A2' (aka 'int [2]') to 'S1' for 1st argument}} +// expected-note@+1 {{candidate function not viable: no known conversion from 'S2' to 'S1' for 1st argument}} void to_s1(S1 s) {} +// expected-note@+15 {{candidate function not viable: no known conversion from 'int' to 'S2' for 1st argument}} +// expected-note@+14 {{candidate function not viable: no known conversion from 'int1' to 'S2' for 1st argument}} +// expected-note@+13 {{candidate function not viable: no known conversion from 'int1x1' to 'S2' for 1st argument}} +// expected-note@+12 {{candidate function not viable: no known conversion from 'int2' to 'S2' for 1st argument}} +// expected-note@+11 {{candidate function not viable: no known conversion from 'int1x2' to 'S2' for 1st argument}} +// expected-note@+10 {{candidate function not viable: no known conversion from 'int2x1' to 'S2' for 1st argument}} +// expected-note@+9 {{candidate function not viable: no known conversion from 'A2' (aka 'int [2]') to 'S2' for 1st argument}} +// expected-note@+8 {{candidate function not viable: no known conversion from 'Like_S2' to 'S2' for 1st argument}} +// expected-note@+7 {{candidate function not viable: no known conversion from 'int4' to 'S2' for 1st argument}} +// expected-note@+6 {{candidate function not viable: no known conversion from 'int1x3' to 'S2' for 1st argument}} +// expected-note@+5 {{candidate function not viable: no known conversion from 'int3x1' to 'S2' for 1st argument}} +// expected-note@+4 {{candidate function not viable: no known conversion from 'int2x2' to 'S2' for 1st argument}} +// expected-note@+3 {{candidate function not viable: no known conversion from 'int3x3' to 'S2' for 1st argument}} +// expected-note@+2 {{candidate function not viable: no known conversion from 'A4' (aka 'int [4]') to 'S2' for 1st argument}} +// expected-note@+1 {{candidate function not viable: no known conversion from 'S4' to 'S2' for 1st argument}} void to_s2(S2 s) {} +// expected-note@+1 {{candidate function not viable: no known conversion from 'int2x2' to 'S4' for 1st argument}} void to_s4(S4 s) {} void to_s5(S5 s) {} diff --git a/tools/clang/test/HLSL/conversions-between-type-shapes.hlsl b/tools/clang/test/SemaHLSL/conversions-between-type-shapes.hlsl similarity index 76% rename from tools/clang/test/HLSL/conversions-between-type-shapes.hlsl rename to tools/clang/test/SemaHLSL/conversions-between-type-shapes.hlsl index 26fcc0d668..985edd2a3f 100644 --- a/tools/clang/test/HLSL/conversions-between-type-shapes.hlsl +++ b/tools/clang/test/SemaHLSL/conversions-between-type-shapes.hlsl @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -Wno-unused-value -fsyntax-only -ffreestanding -verify -verify-ignore-unexpected=note -HV 2018 %s +// RUN: %dxc -Tlib_6_3 -Wno-unused-value -verify -HV 2018 %s // Tests all implicit conversions and explicit casts between type shapes // (scalars, vectors, matrices, arrays and structs). @@ -16,22 +16,95 @@ struct S2 { int a, b; }; struct S4 { int a, b, c, d; }; struct S5 { int a, b, c, d, e; }; -// Clang generates a bunch of "notes" about overload candidates here, but we're not testing for these +// Clang generates a bunch of "notes" about overload candidates here, we're not testing for these +// Just avoid use -verify-ignore-unexpected. + +// expected-note@+4 {{candidate function not viable: no known conversion from 'S1' to 'int' for 1st argument}} +// expected-note@+3 {{candidate function not viable: no known conversion from 'A1' (aka 'int [1]') to 'int' for 1st argument}} +// expected-note@+2 {{candidate function not viable: no known conversion from 'A2' (aka 'int [2]') to 'int' for 1st argument}} +// expected-note@+1 {{candidate function not viable: no known conversion from 'S2' to 'int' for 1st argument}} void to_i(int i) {} +// expected-note@+4 {{candidate function not viable: no known conversion from 'A1' (aka 'int [1]') to 'int1' for 1st argument}} +// expected-note@+3 {{candidate function not viable: no known conversion from 'S1' to 'int1' for 1st argument}} +// expected-note@+2 {{candidate function not viable: no known conversion from 'A2' (aka 'int [2]') to 'int1' for 1st argument}} +// expected-note@+1 {{candidate function not viable: no known conversion from 'S2' to 'int1' for 1st argument}} void to_v1(int1 v) {} +// expected-note@+4 {{candidate function not viable: no known conversion from 'A2' (aka 'int [2]') to 'int2' for 1st argument}} +// expected-note@+3 {{candidate function not viable: no known conversion from 'S2' to 'int2' for 1st argument}} +// expected-note@+2 {{candidate function not viable: no known conversion from 'A4' (aka 'int [4]') to 'int2' for 1st argument}} +// expected-note@+1 {{candidate function not viable: no known conversion from 'S4' to 'int2' for 1st argument}} void to_v2(int2 v) {} void to_v4(int4 v) {} +// expected-note@+4 {{candidate function not viable: no known conversion from 'A1' (aka 'int [1]') to 'int1x1' for 1st argument}} +// expected-note@+3 {{candidate function not viable: no known conversion from 'S1' to 'int1x1' for 1st argument}} +// expected-note@+2 {{candidate function not viable: no known conversion from 'A2' (aka 'int [2]') to 'int1x1' for 1st argument}} +// expected-note@+1 {{candidate function not viable: no known conversion from 'S2' to 'int1x1' for 1st argument}} void to_m1x1(int1x1 m) {} +// expected-note@+4 {{candidate function not viable: no known conversion from 'A4' (aka 'int [4]') to 'int1x2' for 1st argument}} +// expected-note@+3 {{candidate function not viable: no known conversion from 'S2' to 'int1x2' for 1st argument}} +// expected-note@+2 {{candidate function not viable: no known conversion from 'A2' (aka 'int [2]') to 'int1x2' for 1st argument}} +// expected-note@+1 {{candidate function not viable: no known conversion from 'S4' to 'int1x2' for 1st argument}} void to_m1x2(int1x2 m) {} +// expected-note@+4 {{candidate function not viable: no known conversion from 'A2' (aka 'int [2]') to 'int2x1' for 1st argument}} +// expected-note@+3 {{candidate function not viable: no known conversion from 'A4' (aka 'int [4]') to 'int2x1' for 1st argument}} +// expected-note@+2 {{candidate function not viable: no known conversion from 'S4' to 'int2x1' for 1st argument}} +// expected-note@+1 {{candidate function not viable: no known conversion from 'S2' to 'int2x1' for 1st argument}} void to_m2x1(int2x1 m) {} +// expected-note@+4 {{candidate function not viable: no known conversion from 'S4' to 'int2x2' for 1st argument}} +// expected-note@+3 {{candidate function not viable: no known conversion from 'A4' (aka 'int [4]') to 'int2x2' for 1st argument}} +// expected-note@+2 {{candidate function not viable: no known conversion from 'A5' (aka 'int [5]') to 'int2x2' for 1st argument}} +// expected-note@+1 {{candidate function not viable: no known conversion from 'S5' to 'int2x2' for 1st argument}} void to_m2x2(int2x2 m) {} void to_m3x3(int3x3 m) {} +// expected-note@+7 {{candidate function not viable: no known conversion from 'int' to 'A1' (aka 'int [1]') for 1st argument}} +// expected-note@+6 {{candidate function not viable: no known conversion from 'int1' to 'A1' (aka 'int [1]') for 1st argument}} +// expected-note@+5 {{candidate function not viable: no known conversion from 'int1x1' to 'A1' (aka 'int [1]') for 1st argument}} +// expected-note@+4 {{candidate function not viable: no known conversion from 'int2' to 'A1' (aka 'int [1]') for 1st argument}} +// expected-note@+3 {{candidate function not viable: no known conversion from 'int2x2' to 'A1' (aka 'int [1]') for 1st argument}} +// expected-note@+2 {{candidate function not viable: no known conversion from 'A2' (aka 'int [2]') to 'A1' (aka 'int [1]') for 1st argument}} +// expected-note@+1 {{candidate function not viable: no known conversion from 'S2' to 'A1' (aka 'int [1]') for 1st argument}} void to_a1(A1 a) {} +// expected-note@+13 {{candidate function not viable: no known conversion from 'int' to 'A2' (aka 'int [2]') for 1st argument}} +// expected-note@+12 {{candidate function not viable: no known conversion from 'int1' to 'A2' (aka 'int [2]') for 1st argument}} +// expected-note@+11 {{candidate function not viable: no known conversion from 'int1x1' to 'A2' (aka 'int [2]') for 1st argument}} +// expected-note@+10 {{candidate function not viable: no known conversion from 'int2' to 'A2' (aka 'int [2]') for 1st argument}} +// expected-note@+9 {{candidate function not viable: no known conversion from 'int1x2' to 'A2' (aka 'int [2]') for 1st argument}} +// expected-note@+8 {{candidate function not viable: no known conversion from 'int2x1' to 'A2' (aka 'int [2]') for 1st argument}} +// expected-note@+7 {{candidate function not viable: no known conversion from 'int4' to 'A2' (aka 'int [2]') for 1st argument}} +// expected-note@+6 {{candidate function not viable: no known conversion from 'int1x3' to 'A2' (aka 'int [2]') for 1st argument}} +// expected-note@+5 {{candidate function not viable: no known conversion from 'int3x1' to 'A2' (aka 'int [2]') for 1st argument}} +// expected-note@+4 {{candidate function not viable: no known conversion from 'int2x2' to 'A2' (aka 'int [2]') for 1st argument}} +// expected-note@+3 {{candidate function not viable: no known conversion from 'int3x3' to 'A2' (aka 'int [2]') for 1st argument}} +// expected-note@+2 {{candidate function not viable: no known conversion from 'A4' (aka 'int [4]') to 'A2' (aka 'int [2]') for 1st argument}} +// expected-note@+1 {{candidate function not viable: no known conversion from 'S4' to 'A2' (aka 'int [2]') for 1st argument}} void to_a2(A2 a) {} +// expected-note@+1 {{candidate function not viable: no known conversion from 'int2x2' to 'A4' (aka 'int [4]') for 1st argument}} void to_a4(A4 a) {} + void to_a5(A5 a) {} +// expected-note@+7 {{candidate function not viable: no known conversion from 'int2' to 'S1' for 1st argument}} +// expected-note@+6 {{candidate function not viable: no known conversion from 'int2x2' to 'S1' for 1st argument}} +// expected-note@+5 {{candidate function not viable: no known conversion from 'A2' (aka 'int [2]') to 'S1' for 1st argument}} +// expected-note@+4 {{candidate function not viable: no known conversion from 'S2' to 'S1' for 1st argument}} +// expected-note@+3 {{candidate function not viable: no known conversion from 'int' to 'S1' for 1st argument}} +// expected-note@+2 {{candidate function not viable: no known conversion from 'int1' to 'S1' for 1st argument}} +// expected-note@+1 {{candidate function not viable: no known conversion from 'int1x1' to 'S1' for 1st argument}} void to_s1(S1 s) {} +// expected-note@+13 {{candidate function not viable: no known conversion from 'int' to 'S2' for 1st argument}} +// expected-note@+12 {{candidate function not viable: no known conversion from 'int1' to 'S2' for 1st argument}} +// expected-note@+11 {{candidate function not viable: no known conversion from 'int1x1' to 'S2' for 1st argument}} +// expected-note@+10 {{candidate function not viable: no known conversion from 'int2' to 'S2' for 1st argument}} +// expected-note@+9 {{candidate function not viable: no known conversion from 'int1x2' to 'S2' for 1st argument}} +// expected-note@+8 {{candidate function not viable: no known conversion from 'int2x1' to 'S2' for 1st argument}} +// expected-note@+7 {{candidate function not viable: no known conversion from 'int4' to 'S2' for 1st argument}} +// expected-note@+6 {{candidate function not viable: no known conversion from 'int1x3' to 'S2' for 1st argument}} +// expected-note@+5 {{candidate function not viable: no known conversion from 'int3x1' to 'S2' for 1st argument}} +// expected-note@+4 {{candidate function not viable: no known conversion from 'int2x2' to 'S2' for 1st argument}} +// expected-note@+3 {{candidate function not viable: no known conversion from 'int3x3' to 'S2' for 1st argument}} +// expected-note@+2 {{candidate function not viable: no known conversion from 'A4' (aka 'int [4]') to 'S2' for 1st argument}} +// expected-note@+1 {{candidate function not viable: no known conversion from 'S4' to 'S2' for 1st argument}} void to_s2(S2 s) {} +// expected-note@+1 {{candidate function not viable: no known conversion from 'int2x2' to 'S4' for 1st argument}} void to_s4(S4 s) {} void to_s5(S5 s) {} diff --git a/tools/clang/test/HLSL/conversions-non-numeric-aggregates.hlsl b/tools/clang/test/SemaHLSL/conversions-non-numeric-aggregates.hlsl similarity index 91% rename from tools/clang/test/HLSL/conversions-non-numeric-aggregates.hlsl rename to tools/clang/test/SemaHLSL/conversions-non-numeric-aggregates.hlsl index 6fe8946993..d72fdc8590 100644 --- a/tools/clang/test/HLSL/conversions-non-numeric-aggregates.hlsl +++ b/tools/clang/test/SemaHLSL/conversions-non-numeric-aggregates.hlsl @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -Wno-unused-value -fsyntax-only -ffreestanding -verify -verify-ignore-unexpected=note %s +// RUN: %dxc -Tlib_6_3 -Wno-unused-value -verify %s // Tests that conversions between numeric and non-numeric types/aggregates are disallowed. diff --git a/tools/clang/test/HLSL/cxx11-attributes.hlsl b/tools/clang/test/SemaHLSL/cxx11-attributes.hlsl similarity index 90% rename from tools/clang/test/HLSL/cxx11-attributes.hlsl rename to tools/clang/test/SemaHLSL/cxx11-attributes.hlsl index b553d8158d..4f835a82d4 100644 --- a/tools/clang/test/HLSL/cxx11-attributes.hlsl +++ b/tools/clang/test/SemaHLSL/cxx11-attributes.hlsl @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fsyntax-only -ffreestanding -verify %s +// RUN: %dxc -Tlib_6_3 -verify %s [[vk::binding(4, 3)]] // expected-warning {{'binding' attribute ignored}} cbuffer myCBuffer { diff --git a/tools/clang/test/HLSL/enums.hlsl b/tools/clang/test/SemaHLSL/enums.hlsl similarity index 99% rename from tools/clang/test/HLSL/enums.hlsl rename to tools/clang/test/SemaHLSL/enums.hlsl index b06386d689..c607703310 100644 --- a/tools/clang/test/HLSL/enums.hlsl +++ b/tools/clang/test/SemaHLSL/enums.hlsl @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -HV 2017 -fsyntax-only -ffreestanding -verify %s +// RUN: %dxc -Tlib_6_3 -HV 2017 -verify %s enum MyEnum { ZERO, diff --git a/tools/clang/test/HLSL/function-template-default.hlsl b/tools/clang/test/SemaHLSL/function-template-default.hlsl similarity index 62% rename from tools/clang/test/HLSL/function-template-default.hlsl rename to tools/clang/test/SemaHLSL/function-template-default.hlsl index 55e85fa743..f006ca9f58 100644 --- a/tools/clang/test/HLSL/function-template-default.hlsl +++ b/tools/clang/test/SemaHLSL/function-template-default.hlsl @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fsyntax-only -HV 2021 -verify %s +// RUN: %dxc -Tlib_6_3 -HV 2021 -verify %s // expected-no-diagnostics template diff --git a/tools/clang/test/HLSL/functions.hlsl b/tools/clang/test/SemaHLSL/functions.hlsl similarity index 99% rename from tools/clang/test/HLSL/functions.hlsl rename to tools/clang/test/SemaHLSL/functions.hlsl index a1e4b7dcf4..c7f7a4546b 100644 --- a/tools/clang/test/HLSL/functions.hlsl +++ b/tools/clang/test/SemaHLSL/functions.hlsl @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fsyntax-only -Wno-unused-value -ffreestanding -HV 2018 -verify %s +// RUN: %dxc -Tlib_6_3 -Wno-unused-value -HV 2018 -verify %s // __decltype is the GCC way of saying 'decltype', but doesn't require C++11 // _Static_assert is the C11 way of saying 'static_assert', but doesn't require C++11 diff --git a/tools/clang/test/HLSL/incomp_array_err.hlsl b/tools/clang/test/SemaHLSL/incomp_array_err.hlsl similarity index 94% rename from tools/clang/test/HLSL/incomp_array_err.hlsl rename to tools/clang/test/SemaHLSL/incomp_array_err.hlsl index a4da32fa47..cd152f1649 100644 --- a/tools/clang/test/HLSL/incomp_array_err.hlsl +++ b/tools/clang/test/SemaHLSL/incomp_array_err.hlsl @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fsyntax-only -ffreestanding -verify %s +// RUN: %dxc -Tlib_6_3 -verify %s // Verify error on on incomplete array in a struct or class @@ -26,4 +26,4 @@ class foo3 { class foo4 { float4 member; int a[]; // expected-error {{array dimensions of struct/class members must be explicit}} fxc-error {{X3072: 'foo4::a': array dimensions of struct/class members must be explicit}} -}; \ No newline at end of file +}; diff --git a/tools/clang/test/HLSL/incomplete-type.hlsl b/tools/clang/test/SemaHLSL/incomplete-type.hlsl similarity index 66% rename from tools/clang/test/HLSL/incomplete-type.hlsl rename to tools/clang/test/SemaHLSL/incomplete-type.hlsl index a724205428..8869b80400 100644 --- a/tools/clang/test/HLSL/incomplete-type.hlsl +++ b/tools/clang/test/SemaHLSL/incomplete-type.hlsl @@ -1,8 +1,12 @@ -// RUN: %clang_cc1 -Wno-unused-value -fsyntax-only -ffreestanding -verify -verify-ignore-unexpected=note %s +// RUN: %dxc -Tlib_6_3 -Wno-unused-value -verify %s // Tests that the compiler is well-behaved with regard to uses of incomplete types. // Regression test for GitHub #2058, which crashed in this case. +// expected-note@+4 {{forward declaration of 'S'}} +// expected-note@+3 {{forward declaration of 'S'}} +// expected-note@+2 {{forward declaration of 'S'}} +// expected-note@+1 {{forward declaration of 'S'}} struct S; ConstantBuffer CB; // expected-error {{variable has incomplete type 'S'}} S func( // expected-error {{incomplete result type 'S' in function definition}} @@ -10,4 +14,4 @@ S func( // expected-error {{incomplete result type 'S' in function definition}} { S local; // expected-error {{variable has incomplete type 'S'}} return (S)0; // expected-error {{'S' is an incomplete type}} -} \ No newline at end of file +} diff --git a/tools/clang/test/HLSL/indexing-operator.hlsl b/tools/clang/test/SemaHLSL/indexing-operator.hlsl similarity index 98% rename from tools/clang/test/HLSL/indexing-operator.hlsl rename to tools/clang/test/SemaHLSL/indexing-operator.hlsl index d48c8ca747..e4658f1e00 100644 --- a/tools/clang/test/HLSL/indexing-operator.hlsl +++ b/tools/clang/test/SemaHLSL/indexing-operator.hlsl @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fsyntax-only -Wno-unused-value -ffreestanding -verify %s +// RUN: %dxc -Tlib_6_3 -Wno-unused-value -verify %s // To test with the classic compiler, run // %sdxroot%\tools\x86\fxc.exe /T vs_5_1 indexing-operator.hlsl @@ -492,8 +492,8 @@ float4 test_mips_double_indexing() `-ImplicitCastExpr 'uint2':'vector' `-DeclRefExpr 'uint2':'vector' lvalue Var 'pos2' 'uint2':'vector' */ - f4 += g_t1da.mips[mipSlice][pos3]; /* expected-error {{no viable overloaded operator[] for type 'Texture1DArray >::mips_slice_type'}} expected-note {{candidate function [with element = const vector &] not viable: no known conversion from 'vector<[...], 3>' to 'vector<[...], 2>' for 1st argument}} fxc-error {{X3120: invalid type for index - index must be a scalar, or a vector with the correct number of dimensions}} */ - f4 += g_t1da.mips[mipSlice][pos4]; /* expected-error {{no viable overloaded operator[] for type 'Texture1DArray >::mips_slice_type'}} expected-note {{candidate function [with element = const vector &] not viable: no known conversion from 'vector<[...], 4>' to 'vector<[...], 2>' for 1st argument}} fxc-error {{X3120: invalid type for index - index must be a scalar, or a vector with the correct number of dimensions}} */ + f4 += g_t1da.mips[mipSlice][pos3]; /* expected-error {{no viable overloaded operator[] for type 'Texture1DArray >::mips_slice_type'}} expected-note {{candidate function [with element = const vector &] not viable: no known conversion from 'vector' to 'vector' for 1st argument}} fxc-error {{X3120: invalid type for index - index must be a scalar, or a vector with the correct number of dimensions}} */ + f4 += g_t1da.mips[mipSlice][pos4]; /* expected-error {{no viable overloaded operator[] for type 'Texture1DArray >::mips_slice_type'}} expected-note {{candidate function [with element = const vector &] not viable: no known conversion from 'vector' to 'vector' for 1st argument}} fxc-error {{X3120: invalid type for index - index must be a scalar, or a vector with the correct number of dimensions}} */ // fxc error X3120: invalid type for index - index must be a scalar, or a vector with the correct number of dimensions f4 += g_t2d.mips[mipSlice][pos]; // expected-error {{no viable overloaded operator[] for type 'Texture2D >::mips_slice_type'}} expected-note {{candidate function [with element = const vector &] not viable: no known conversion from 'uint' to 'vector' for 1st argument}} fxc-error {{X3120: invalid type for index - index must be a scalar, or a vector with the correct number of dimensions}} f4 += g_t2d.mips[mipSlice][pos2]; @@ -518,7 +518,7 @@ float4 test_mips_double_indexing() */ // fxc error X3120: invalid type for index - index must be a scalar, or a vector with the correct number of dimensions f4 += g_t2da.mips[mipSlice][pos]; // expected-error {{no viable overloaded operator[] for type 'Texture2DArray >::mips_slice_type'}} expected-note {{candidate function [with element = const vector &] not viable: no known conversion from 'uint' to 'vector' for 1st argument}} fxc-error {{X3120: invalid type for index - index must be a scalar, or a vector with the correct number of dimensions}} - f4 += g_t2da.mips[mipSlice][pos2]; /* expected-error {{no viable overloaded operator[] for type 'Texture2DArray >::mips_slice_type'}} expected-note {{candidate function [with element = const vector &] not viable: no known conversion from 'vector<[...], 2>' to 'vector<[...], 3>' for 1st argument}} fxc-error {{X3120: invalid type for index - index must be a scalar, or a vector with the correct number of dimensions}} */ + f4 += g_t2da.mips[mipSlice][pos2]; /* expected-error {{no viable overloaded operator[] for type 'Texture2DArray >::mips_slice_type'}} expected-note {{candidate function [with element = const vector &] not viable: no known conversion from 'vector' to 'vector' for 1st argument}} fxc-error {{X3120: invalid type for index - index must be a scalar, or a vector with the correct number of dimensions}} */ f4 += g_t2da.mips[mipSlice][pos3]; /*verify-ast CompoundAssignOperator 'float4':'vector' lvalue '+=' ComputeLHSTy='float4':'vector' ComputeResultTy='float4':'vector' @@ -539,14 +539,14 @@ float4 test_mips_double_indexing() `-ImplicitCastExpr 'uint3':'vector' `-DeclRefExpr 'uint3':'vector' lvalue Var 'pos3' 'uint3':'vector' */ - f4 += g_t2da.mips[mipSlice][pos4]; /* expected-error {{no viable overloaded operator[] for type 'Texture2DArray >::mips_slice_type'}} expected-note {{candidate function [with element = const vector &] not viable: no known conversion from 'vector<[...], 4>' to 'vector<[...], 3>' for 1st argument}} fxc-error {{X3120: invalid type for index - index must be a scalar, or a vector with the correct number of dimensions}} */ + f4 += g_t2da.mips[mipSlice][pos4]; /* expected-error {{no viable overloaded operator[] for type 'Texture2DArray >::mips_slice_type'}} expected-note {{candidate function [with element = const vector &] not viable: no known conversion from 'vector' to 'vector' for 1st argument}} fxc-error {{X3120: invalid type for index - index must be a scalar, or a vector with the correct number of dimensions}} */ // fxc error X3018: invalid subscript 'mips' f4 += g_t2dms.mips[mipSlice][pos]; // expected-error {{no member named 'mips' in 'Texture2DMS, 8>'}} fxc-error {{X3018: invalid subscript 'mips'}} // fxc error X3018: invalid subscript 'mips' f4 += g_t2dmsa.mips[mipSlice][pos]; // expected-error {{no member named 'mips' in 'Texture2DMSArray, 8>'}} fxc-error {{X3018: invalid subscript 'mips'}} // fxc error X3120: invalid type for index - index must be a scalar, or a vector with the correct number of dimensions f4 += g_t3d.mips[mipSlice][pos]; // expected-error {{no viable overloaded operator[] for type 'Texture3D >::mips_slice_type'}} expected-note {{candidate function [with element = const vector &] not viable: no known conversion from 'uint' to 'vector' for 1st argument}} fxc-error {{X3120: invalid type for index - index must be a scalar, or a vector with the correct number of dimensions}} - f4 += g_t3d.mips[mipSlice][pos2]; // expected-error {{no viable overloaded operator[] for type 'Texture3D >::mips_slice_type'}} expected-note {{candidate function [with element = const vector &] not viable: no known conversion from 'vector<[...], 2>' to 'vector<[...], 3>' for 1st argument}} fxc-error {{X3120: invalid type for index - index must be a scalar, or a vector with the correct number of dimensions}} + f4 += g_t3d.mips[mipSlice][pos2]; // expected-error {{no viable overloaded operator[] for type 'Texture3D >::mips_slice_type'}} expected-note {{candidate function [with element = const vector &] not viable: no known conversion from 'vector' to 'vector' for 1st argument}} fxc-error {{X3120: invalid type for index - index must be a scalar, or a vector with the correct number of dimensions}} f4 += g_t3d.mips[mipSlice][pos3]; /*verify-ast CompoundAssignOperator 'float4':'vector' lvalue '+=' ComputeLHSTy='float4':'vector' ComputeResultTy='float4':'vector' @@ -567,7 +567,7 @@ float4 test_mips_double_indexing() `-ImplicitCastExpr 'uint3':'vector' `-DeclRefExpr 'uint3':'vector' lvalue Var 'pos3' 'uint3':'vector' */ - f4 += g_t3d.mips[mipSlice][pos4]; // expected-error {{no viable overloaded operator[] for type 'Texture3D >::mips_slice_type'}} expected-note {{candidate function [with element = const vector &] not viable: no known conversion from 'vector<[...], 4>' to 'vector<[...], 3>' for 1st argument}} fxc-error {{X3120: invalid type for index - index must be a scalar, or a vector with the correct number of dimensions}} + f4 += g_t3d.mips[mipSlice][pos4]; // expected-error {{no viable overloaded operator[] for type 'Texture3D >::mips_slice_type'}} expected-note {{candidate function [with element = const vector &] not viable: no known conversion from 'vector' to 'vector' for 1st argument}} fxc-error {{X3120: invalid type for index - index must be a scalar, or a vector with the correct number of dimensions}} // fxc error X3018: invalid subscript 'mips' f4 += g_tc.mips[mipSlice][pos]; // expected-error {{no member named 'mips' in 'TextureCube >'}} fxc-error {{X3018: invalid subscript 'mips'}} // fxc error X3018: invalid subscript 'mips' diff --git a/tools/clang/test/HLSL/intrinsic-examples.hlsl b/tools/clang/test/SemaHLSL/intrinsic-examples.hlsl similarity index 99% rename from tools/clang/test/HLSL/intrinsic-examples.hlsl rename to tools/clang/test/SemaHLSL/intrinsic-examples.hlsl index dafa9a95b5..db55b7c652 100644 --- a/tools/clang/test/HLSL/intrinsic-examples.hlsl +++ b/tools/clang/test/SemaHLSL/intrinsic-examples.hlsl @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fsyntax-only -ffreestanding -verify -HV 2018 -enable-16bit-types %s +// RUN: %dxc -Tlib_6_3 -verify -HV 2018 -enable-16bit-types %s // :FXC_VERIFY_ARGUMENTS: /E FontPixelShader /T ps_5_1 /Gec diff --git a/tools/clang/test/HLSL/invalid-decl-template-arg.hlsl b/tools/clang/test/SemaHLSL/invalid-decl-template-arg.hlsl similarity index 88% rename from tools/clang/test/HLSL/invalid-decl-template-arg.hlsl rename to tools/clang/test/SemaHLSL/invalid-decl-template-arg.hlsl index 0feb5301d3..88fc9113bb 100644 --- a/tools/clang/test/HLSL/invalid-decl-template-arg.hlsl +++ b/tools/clang/test/SemaHLSL/invalid-decl-template-arg.hlsl @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fsyntax-only -verify %s +// RUN: %dxc -Tlib_6_3 -verify %s struct FOOO_A_B { // expected-note{{'FOOO_A_B' declared here}} expected-note{{definition of 'FOOO_A_B' is not complete until the closing '}'}} FOOO_A v0; // expected-error{{unknown type name 'FOOO_A'; did you mean 'FOOO_A_B'}} expected-error{{field has incomplete type 'FOOO_A_B}} diff --git a/tools/clang/test/HLSL/loop-induction-scoping-2021.hlsl b/tools/clang/test/SemaHLSL/loop-induction-scoping-2021.hlsl similarity index 72% rename from tools/clang/test/HLSL/loop-induction-scoping-2021.hlsl rename to tools/clang/test/SemaHLSL/loop-induction-scoping-2021.hlsl index 22b4d82d54..c60403a72c 100644 --- a/tools/clang/test/HLSL/loop-induction-scoping-2021.hlsl +++ b/tools/clang/test/SemaHLSL/loop-induction-scoping-2021.hlsl @@ -1,4 +1,7 @@ -// RUN: %clang_cc1 -fsyntax-only -ffreestanding -verify -HV 2021 %s +// RUN: %dxc -Tlib_6_3 -verify -HV 2021 %s +// RUN: %dxc -Tps_6_0 -verify -HV 2021 %s + +// expected-no-diagnostics uint g_count1; uint g_count2; diff --git a/tools/clang/test/HLSL/matrix-assignments.hlsl b/tools/clang/test/SemaHLSL/matrix-assignments.hlsl similarity index 99% rename from tools/clang/test/HLSL/matrix-assignments.hlsl rename to tools/clang/test/SemaHLSL/matrix-assignments.hlsl index 47d3e78fc3..4d12dbf663 100644 --- a/tools/clang/test/HLSL/matrix-assignments.hlsl +++ b/tools/clang/test/SemaHLSL/matrix-assignments.hlsl @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fsyntax-only -ffreestanding -verify %s +// RUN: %dxc -Tlib_6_3 -verify %s // To test with the classic compiler, run // %sdxroot%\tools\x86\fxc.exe /T vs_2_0 matrix-assignments.hlsl diff --git a/tools/clang/test/HLSL/matrix-syntax-exact-precision.hlsl b/tools/clang/test/SemaHLSL/matrix-syntax-exact-precision.hlsl similarity index 99% rename from tools/clang/test/HLSL/matrix-syntax-exact-precision.hlsl rename to tools/clang/test/SemaHLSL/matrix-syntax-exact-precision.hlsl index bdf8b94aee..d55cbf1d7b 100644 --- a/tools/clang/test/HLSL/matrix-syntax-exact-precision.hlsl +++ b/tools/clang/test/SemaHLSL/matrix-syntax-exact-precision.hlsl @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -enable-16bit-types -fsyntax-only -ffreestanding -verify -HV 2018 %s +// RUN: %dxc -Tlib_6_3 -enable-16bit-types -verify -HV 2018 %s // To test with the classic compiler, run diff --git a/tools/clang/test/HLSL/matrix-syntax.hlsl b/tools/clang/test/SemaHLSL/matrix-syntax.hlsl similarity index 99% rename from tools/clang/test/HLSL/matrix-syntax.hlsl rename to tools/clang/test/SemaHLSL/matrix-syntax.hlsl index c8d57d7b05..95329f13d2 100644 --- a/tools/clang/test/HLSL/matrix-syntax.hlsl +++ b/tools/clang/test/SemaHLSL/matrix-syntax.hlsl @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fsyntax-only -ffreestanding -verify %s +// RUN: %dxc -Tlib_6_3 -verify %s // To test with the classic compiler, run diff --git a/tools/clang/test/HLSL/mintypes-promotion-warnings.hlsl b/tools/clang/test/SemaHLSL/mintypes-promotion-warnings.hlsl similarity index 77% rename from tools/clang/test/HLSL/mintypes-promotion-warnings.hlsl rename to tools/clang/test/SemaHLSL/mintypes-promotion-warnings.hlsl index 5ab1635b34..11783b233c 100644 --- a/tools/clang/test/HLSL/mintypes-promotion-warnings.hlsl +++ b/tools/clang/test/SemaHLSL/mintypes-promotion-warnings.hlsl @@ -1,9 +1,11 @@ -// RUN: %clang_cc1 -Wno-unused-value -fsyntax-only -ffreestanding -verify -verify-ignore-unexpected=note %s +// RUN: %dxc -Tlib_6_3 -Wno-unused-value -verify %s // Verify minfloat/minint promotion warnings for shader input/outputs void main( min10float in_f10, // expected-warning {{'min10float' is promoted to 'min16float'}} fxc-pass {{}} min12int in_i12, // expected-warning {{'min12int' is promoted to 'min16int'}} fxc-pass {{}} + // expected-note@+1 {{variable 'out_f10' is declared here}} out min10float out_f10, // expected-warning {{'min10float' is promoted to 'min16float'}} fxc-pass {{}} + // expected-note@+1 {{variable 'out_i12' is declared here}} out min12int out_i12) {} // expected-warning {{'min12int' is promoted to 'min16int'}} fxc-pass {{}} expected-warning{{parameter 'out_f10' is uninitialized when used here}} expected-warning{{parameter 'out_i12' is uninitialized when used here}} diff --git a/tools/clang/test/HLSL/more-operators.hlsl b/tools/clang/test/SemaHLSL/more-operators.hlsl similarity index 99% rename from tools/clang/test/HLSL/more-operators.hlsl rename to tools/clang/test/SemaHLSL/more-operators.hlsl index 9d4ba51bde..55924f6b68 100644 --- a/tools/clang/test/HLSL/more-operators.hlsl +++ b/tools/clang/test/SemaHLSL/more-operators.hlsl @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fsyntax-only -Wno-unused-value -ffreestanding -verify %s +// RUN: %dxc -Tlib_6_3 -Wno-unused-value -verify %s // This file includes operator tests that target specific cases that are not // otherwise covered by the other generated files. diff --git a/tools/clang/test/HLSL/object-operators.hlsl b/tools/clang/test/SemaHLSL/object-operators.hlsl similarity index 99% rename from tools/clang/test/HLSL/object-operators.hlsl rename to tools/clang/test/SemaHLSL/object-operators.hlsl index 2790b7012c..5af6fdb70d 100644 --- a/tools/clang/test/HLSL/object-operators.hlsl +++ b/tools/clang/test/SemaHLSL/object-operators.hlsl @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fsyntax-only -Wno-unused-value -ffreestanding -verify %s +// RUN: %dxc -Tlib_6_3 -Wno-unused-value -verify %s // we use -Wno-unused-value because we generate some no-op expressions to yield errors // without also putting them in a static assertion diff --git a/tools/clang/test/HLSL/out-param-diagnostics.hlsl b/tools/clang/test/SemaHLSL/out-param-diagnostics.hlsl similarity index 99% rename from tools/clang/test/HLSL/out-param-diagnostics.hlsl rename to tools/clang/test/SemaHLSL/out-param-diagnostics.hlsl index 35b56afd8a..44349af7c7 100644 --- a/tools/clang/test/HLSL/out-param-diagnostics.hlsl +++ b/tools/clang/test/SemaHLSL/out-param-diagnostics.hlsl @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fsyntax-only -verify %s +// RUN: %dxc -Tlib_6_3 -verify %s void UnusedEmpty(out int Val) {} // expected-warning{{parameter 'Val' is uninitialized when used here}} expected-note{{variable 'Val' is declared here}} diff --git a/tools/clang/test/HLSL/overloading-new-delete-errors.hlsl b/tools/clang/test/SemaHLSL/overloading-new-delete-errors.hlsl similarity index 91% rename from tools/clang/test/HLSL/overloading-new-delete-errors.hlsl rename to tools/clang/test/SemaHLSL/overloading-new-delete-errors.hlsl index f1a182ceea..820388fbf0 100644 --- a/tools/clang/test/HLSL/overloading-new-delete-errors.hlsl +++ b/tools/clang/test/SemaHLSL/overloading-new-delete-errors.hlsl @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fsyntax-only -Wno-unused-value -ffreestanding -verify -HV 2021 %s +// RUN: %dxc -Tlib_6_3 -Wno-unused-value -verify -HV 2021 %s // This test checks that when we overload new or delete operator // dxcompiler generates error and no crashes are observed. diff --git a/tools/clang/test/HLSL/overloading-unsupported-operators.hlsl b/tools/clang/test/SemaHLSL/overloading-unsupported-operators.hlsl similarity index 94% rename from tools/clang/test/HLSL/overloading-unsupported-operators.hlsl rename to tools/clang/test/SemaHLSL/overloading-unsupported-operators.hlsl index 83fc66ffec..60324a0649 100644 --- a/tools/clang/test/HLSL/overloading-unsupported-operators.hlsl +++ b/tools/clang/test/SemaHLSL/overloading-unsupported-operators.hlsl @@ -1,4 +1,5 @@ -// RUN: %clang_cc1 -fsyntax-only -Wno-unused-value -ffreestanding -verify -HV 2021 %s +// RUN: %dxc -Tlib_6_3 -Wno-unused-value -verify -HV 2021 %s +// RUN: %dxc -Tcs_6_0 -verify -HV 2021 %s // This test checks that dxcompiler generates errors when overloading operators // that are not supported for overloading in HLSL 2021 diff --git a/tools/clang/test/HLSL/packreg.hlsl b/tools/clang/test/SemaHLSL/packreg.hlsl similarity index 99% rename from tools/clang/test/HLSL/packreg.hlsl rename to tools/clang/test/SemaHLSL/packreg.hlsl index a766467429..309f0e0dbb 100644 --- a/tools/clang/test/HLSL/packreg.hlsl +++ b/tools/clang/test/SemaHLSL/packreg.hlsl @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fsyntax-only -ffreestanding -verify %s +// RUN: %dxc -Tlib_6_3 -verify %s // :FXC_VERIFY_ARGUMENTS: /E main /T ps_5_1 // fxc error X3115: Conflicting register semantics: 's0' and 's1' diff --git a/tools/clang/test/HLSL/pragma-region.hlsl b/tools/clang/test/SemaHLSL/pragma-region.hlsl similarity index 85% rename from tools/clang/test/HLSL/pragma-region.hlsl rename to tools/clang/test/SemaHLSL/pragma-region.hlsl index 38d5347664..dd1be74961 100644 --- a/tools/clang/test/HLSL/pragma-region.hlsl +++ b/tools/clang/test/SemaHLSL/pragma-region.hlsl @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fsyntax-only -ffreestanding -verify %s +// RUN: %dxc -Tlib_6_3 -verify %s // expected-no-diagnostics diff --git a/tools/clang/test/HLSL/raytracing-entry-diags.hlsl b/tools/clang/test/SemaHLSL/raytracing-entry-diags.hlsl similarity index 99% rename from tools/clang/test/HLSL/raytracing-entry-diags.hlsl rename to tools/clang/test/SemaHLSL/raytracing-entry-diags.hlsl index 966aabce22..4376fbe068 100644 --- a/tools/clang/test/HLSL/raytracing-entry-diags.hlsl +++ b/tools/clang/test/SemaHLSL/raytracing-entry-diags.hlsl @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fsyntax-only -ffreestanding -verify %s +// RUN: %dxc -Tlib_6_3 -verify %s [shader("anyhit")] diff --git a/tools/clang/test/HLSL/raytracings.hlsl b/tools/clang/test/SemaHLSL/raytracings.hlsl similarity index 93% rename from tools/clang/test/HLSL/raytracings.hlsl rename to tools/clang/test/SemaHLSL/raytracings.hlsl index 6e2ee5fc11..d3bc01fcd6 100644 --- a/tools/clang/test/HLSL/raytracings.hlsl +++ b/tools/clang/test/SemaHLSL/raytracings.hlsl @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -HV 2018 -Wno-unused-value -fsyntax-only -ffreestanding -verify %s +// RUN: %dxc -Tlib_6_3 -HV 2018 -Wno-unused-value -verify %s void run() { RAY_FLAG rayFlags = diff --git a/tools/clang/test/HLSL/scalar-assignments-exact-precision.hlsl b/tools/clang/test/SemaHLSL/scalar-assignments-exact-precision.hlsl similarity index 99% rename from tools/clang/test/HLSL/scalar-assignments-exact-precision.hlsl rename to tools/clang/test/SemaHLSL/scalar-assignments-exact-precision.hlsl index df085b22cd..98991aa97c 100644 --- a/tools/clang/test/HLSL/scalar-assignments-exact-precision.hlsl +++ b/tools/clang/test/SemaHLSL/scalar-assignments-exact-precision.hlsl @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -enable-16bit-types -fsyntax-only -ffreestanding -verify -HV 2018 %s +// RUN: %dxc -Tlib_6_3 -enable-16bit-types -verify -HV 2018 %s // To test with the classic compiler, run // %sdxroot%\tools\x86\fxc.exe /T vs_5_1 scalar-assignments.hlsl diff --git a/tools/clang/test/HLSL/scalar-assignments.hlsl b/tools/clang/test/SemaHLSL/scalar-assignments.hlsl similarity index 99% rename from tools/clang/test/HLSL/scalar-assignments.hlsl rename to tools/clang/test/SemaHLSL/scalar-assignments.hlsl index e8499059db..c6fd2e9d13 100644 --- a/tools/clang/test/HLSL/scalar-assignments.hlsl +++ b/tools/clang/test/SemaHLSL/scalar-assignments.hlsl @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fsyntax-only -ffreestanding -verify %s +// RUN: %dxc -Tlib_6_3 -verify %s // To test with the classic compiler, run // %sdxroot%\tools\x86\fxc.exe /T vs_5_1 scalar-assignments.hlsl diff --git a/tools/clang/test/HLSL/scalar-operators-assign-exact-precision.hlsl b/tools/clang/test/SemaHLSL/scalar-operators-assign-exact-precision.hlsl similarity index 99% rename from tools/clang/test/HLSL/scalar-operators-assign-exact-precision.hlsl rename to tools/clang/test/SemaHLSL/scalar-operators-assign-exact-precision.hlsl index 6823330443..7c0d7cf74e 100644 --- a/tools/clang/test/HLSL/scalar-operators-assign-exact-precision.hlsl +++ b/tools/clang/test/SemaHLSL/scalar-operators-assign-exact-precision.hlsl @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fsyntax-only -Wno-unused-value -Wno-conversion -ffreestanding -verify -enable-16bit-types -HV 2018 %s +// RUN: %dxc -Tlib_6_3 -Wno-unused-value -Wno-conversion -verify -enable-16bit-types -HV 2018 %s // // we use -Wno-unused-value because we generate some no-op expressions to yield errors diff --git a/tools/clang/test/HLSL/scalar-operators-assign.hlsl b/tools/clang/test/SemaHLSL/scalar-operators-assign.hlsl similarity index 99% rename from tools/clang/test/HLSL/scalar-operators-assign.hlsl rename to tools/clang/test/SemaHLSL/scalar-operators-assign.hlsl index 1b5fe27a9a..23f80b03a9 100644 --- a/tools/clang/test/HLSL/scalar-operators-assign.hlsl +++ b/tools/clang/test/SemaHLSL/scalar-operators-assign.hlsl @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fsyntax-only -Wno-unused-value -Wno-conversion -ffreestanding -verify %s +// RUN: %dxc -Tlib_6_3 -Wno-unused-value -Wno-conversion -verify %s // // we use -Wno-unused-value because we generate some no-op expressions to yield errors diff --git a/tools/clang/test/HLSL/scalar-operators-exact-precision.hlsl b/tools/clang/test/SemaHLSL/scalar-operators-exact-precision.hlsl similarity index 99% rename from tools/clang/test/HLSL/scalar-operators-exact-precision.hlsl rename to tools/clang/test/SemaHLSL/scalar-operators-exact-precision.hlsl index 45dcadc4ce..6dcd018829 100644 --- a/tools/clang/test/HLSL/scalar-operators-exact-precision.hlsl +++ b/tools/clang/test/SemaHLSL/scalar-operators-exact-precision.hlsl @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -enable-16bit-types -fsyntax-only -Wno-unused-value -ffreestanding -verify -HV 2018 %s +// RUN: %dxc -Tlib_6_3 -enable-16bit-types -Wno-unused-value -verify -HV 2018 %s // we use -Wno-unused-value because we generate some no-op expressions to yield errors // without also putting them in a static assertion diff --git a/tools/clang/test/HLSL/scalar-operators.hlsl b/tools/clang/test/SemaHLSL/scalar-operators.hlsl similarity index 99% rename from tools/clang/test/HLSL/scalar-operators.hlsl rename to tools/clang/test/SemaHLSL/scalar-operators.hlsl index 2c31891f72..a58a6be1e5 100644 --- a/tools/clang/test/HLSL/scalar-operators.hlsl +++ b/tools/clang/test/SemaHLSL/scalar-operators.hlsl @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fsyntax-only -Wno-unused-value -ffreestanding -verify %s +// RUN: %dxc -Tlib_6_3 -Wno-unused-value -verify %s // we use -Wno-unused-value because we generate some no-op expressions to yield errors // without also putting them in a static assertion diff --git a/tools/clang/test/HLSL/sizeof.hlsl b/tools/clang/test/SemaHLSL/sizeof.hlsl similarity index 91% rename from tools/clang/test/HLSL/sizeof.hlsl rename to tools/clang/test/SemaHLSL/sizeof.hlsl index 25e5a2699a..bb132d2dc8 100644 --- a/tools/clang/test/HLSL/sizeof.hlsl +++ b/tools/clang/test/SemaHLSL/sizeof.hlsl @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -Wno-unused-value -fsyntax-only -ffreestanding -verify -verify-ignore-unexpected=note %s +// RUN: %dxc -Tlib_6_3 -Wno-unused-value -verify %s // Tests usage of the sizeof operator diff --git a/tools/clang/test/HLSL/spec.hlsl b/tools/clang/test/SemaHLSL/spec.hlsl similarity index 92% rename from tools/clang/test/HLSL/spec.hlsl rename to tools/clang/test/SemaHLSL/spec.hlsl index 3c13a1496d..4830d695ff 100644 --- a/tools/clang/test/HLSL/spec.hlsl +++ b/tools/clang/test/SemaHLSL/spec.hlsl @@ -1,4 +1,5 @@ -// RUN: %clang_cc1 -fsyntax-only -ffreestanding -verify %s +// RUN: %dxc -Tlib_6_3 -HV 2018 -verify %s +// RUN: %dxc -Tps_6_0 -HV 2018 -verify %s // This file provides test cases that are cross-references to the HLSL // specification. @@ -78,7 +79,7 @@ namespace ns_basic { //typedef int UNKA[]; // UNKA is an incomplete type ; fxc-error {{error X3072: array dimensions of type must be explicit}} // cbuffer C; // fxc-error {{error X3000: syntax error: unexpected token ';'}} - string s = "my string"; + string s = "my string"; // expected-error {{string declaration may only appear in global scope}} int int_var; uint uint_var; dword dword_var; @@ -151,7 +152,7 @@ namespace ns_std_conversions { fn_f4(i); // vector splat fn_u4(f4); // vector element fn_f4(u4); // vector element - f3 = f4; // vector truncate + f3 = f4; // expected-warning {{implicit truncation of vector type}} // f4 = f3; // fxc-error {{error X3017: cannot implicitly convert from 'float3' to 'float4'}} fn_iof(f1); // inout case (float1->float - vector single element conversion; float->float1 vector splat) fn_iof1(u); // inout case (uint->float1 - vector splat; float1->uint vector single element conversion) @@ -194,6 +195,7 @@ namespace ns_std_conversions { fn_f14(1); u = f11; // matrix single element conversion + // expected-warning@+1 {{implicit truncation of vector type}} u = f14; // matrix scalar truncation conversion u2 = f11; // matrix single element vector conversion @@ -202,8 +204,11 @@ namespace ns_std_conversions { //u3 = f12; // cannot convert if target has more u44 = f44; // matrix element-type conversion + // expected-warning@+1 {{implicit truncation of vector type}} u22 = f44; // can convert to smaller + // expected-warning@+1 {{implicit truncation of vector type}} u22 = f33; // can convert to smaller + // expected-warning@+1 {{implicit truncation of vector type}} f32 = f33; // can convert as long as each dimension is smaller //u44 = f22; // cannot convert to bigger } @@ -307,14 +312,14 @@ namespace ns_std_conversions { namespace ns_overloading { // * Overloading // ** Overloadable declarations - int f(int a) { return a; } - int f(const int a) { return a; } + int f(int a) { return a; } // expected-note {{previous definition is here}} + int f(const int a) { return a; } // expected-error {{redefinition of 'f'}} int f_default_0(int a = 3); //int f_default_0(int a = 4); // error X3114: 'a': default parameters can only be provided in the first prototype - int f_default(int a = 1) { return a; } - int f_default(int a = 3); // TODO: after definition, declaration may provide default, and this is ignored + int f_default(int a = 1) { return a; } // expected-note {{previous definition is here}} + int f_default(int a = 3); // expected-error {{redefinition of default argument}} // int f_default_args(int a, int b = 0); - int f_default_args(int a = 0, int b); + int f_default_args(int a = 0, int b); // expected-error {{missing default argument on parameter 'b'}} int f_default_args() { return 1; } int f_default_args_equiv(int a); int f_default_args_equiv(int a = 1); diff --git a/tools/clang/test/HLSL/string.hlsl b/tools/clang/test/SemaHLSL/string.hlsl similarity index 98% rename from tools/clang/test/HLSL/string.hlsl rename to tools/clang/test/SemaHLSL/string.hlsl index 0ed4ac65f2..70424b73ff 100644 --- a/tools/clang/test/HLSL/string.hlsl +++ b/tools/clang/test/SemaHLSL/string.hlsl @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fsyntax-only -Wno-unused-value -ffreestanding -verify %s +// RUN: %dxc -Tlib_6_3 -Wno-unused-value -verify %s static const string s_global1 = "my global string 1"; /*verify-ast @@ -74,4 +74,4 @@ float4 main() : SV_Target0 { /* */ printf("hi mom", 1, 2, 3); hello_here("a", "b", 1); return cp4_local; -} \ No newline at end of file +} diff --git a/tools/clang/test/HLSL/struct-assignments.hlsl b/tools/clang/test/SemaHLSL/struct-assignments.hlsl similarity index 98% rename from tools/clang/test/HLSL/struct-assignments.hlsl rename to tools/clang/test/SemaHLSL/struct-assignments.hlsl index 15c323f24f..26bb07d92a 100644 --- a/tools/clang/test/HLSL/struct-assignments.hlsl +++ b/tools/clang/test/SemaHLSL/struct-assignments.hlsl @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fsyntax-only -ffreestanding -verify %s +// RUN: %dxc -Tlib_6_3 -verify %s // To test with the classic compiler, run // %sdxroot%\tools\x86\fxc.exe /T vs_5_1 struct-assignments.hlsl @@ -144,4 +144,4 @@ void main() { pick_one(sf2_all); sf2_all = pick_two(sf2_all); -} \ No newline at end of file +} diff --git a/tools/clang/test/HLSL/subobjects-syntax.hlsl b/tools/clang/test/SemaHLSL/subobjects-syntax.hlsl similarity index 99% rename from tools/clang/test/HLSL/subobjects-syntax.hlsl rename to tools/clang/test/SemaHLSL/subobjects-syntax.hlsl index 13b1aaf4e0..c72acfab2a 100644 --- a/tools/clang/test/HLSL/subobjects-syntax.hlsl +++ b/tools/clang/test/SemaHLSL/subobjects-syntax.hlsl @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -Wno-unused-value -ffreestanding -verify %s +// RUN: %dxc -Tlib_6_3 -Wno-unused-value -verify %s string globalRs = "CBV(b0)"; string localRs = "UAV(u0, visibility = SHADER_VISIBILITY_GEOMETRY)"; @@ -101,4 +101,4 @@ ProceduralPrimitiveHitGroup ppHitGt2_9 = { "a", "b", ""}; int main(int i : INDEX) : SV_Target { return 1; -} \ No newline at end of file +} diff --git a/tools/clang/test/HLSL/template-checks.hlsl b/tools/clang/test/SemaHLSL/template-checks.hlsl similarity index 97% rename from tools/clang/test/HLSL/template-checks.hlsl rename to tools/clang/test/SemaHLSL/template-checks.hlsl index a5200fa1c3..62528521de 100644 --- a/tools/clang/test/HLSL/template-checks.hlsl +++ b/tools/clang/test/SemaHLSL/template-checks.hlsl @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fsyntax-only -ffreestanding -verify %s +// RUN: %dxc -Tlib_6_3 -verify %s Texture2D t_float4; Texture2D t_obj_sampler; /* expected-error {{'SamplerState' is an object and cannot be used as a type parameter}} fxc-error {{X3124: object element type cannot be an object type}} */ @@ -34,4 +34,4 @@ void vain() { asb.Append(); /* expected-error {{no matching member function for call to 'Append'}} expected-note {{candidate function template not viable: requires single argument 'value', but no arguments were provided}} fxc-error {{X3013: AppendStructuredBuffer.Append()}} fxc-error {{X3013: 'Append': no matching 0 parameter intrinsic method}} fxc-error {{X3013: Possible intrinsic methods are:}} */ asb.Append(f4, f4); /* expected-error {{no matching member function for call to 'Append'}} expected-note {{candidate function template not viable: requires single argument 'value', but 2 arguments were provided}} fxc-error {{X3013: AppendStructuredBuffer.Append()}} fxc-error {{X3013: 'Append': no matching 2 parameter intrinsic method}} fxc-error {{X3013: Possible intrinsic methods are:}} */ asb.Append(f4); -} \ No newline at end of file +} diff --git a/tools/clang/test/HLSL/template-diag-deferred.hlsl b/tools/clang/test/SemaHLSL/template-diag-deferred.hlsl similarity index 78% rename from tools/clang/test/HLSL/template-diag-deferred.hlsl rename to tools/clang/test/SemaHLSL/template-diag-deferred.hlsl index 0c5a50172c..16e4da1275 100644 --- a/tools/clang/test/HLSL/template-diag-deferred.hlsl +++ b/tools/clang/test/SemaHLSL/template-diag-deferred.hlsl @@ -1,3 +1,5 @@ +// RUN: %dxc -Tlib_6_6 -HV 2021 -verify %s + template void neverInstantiated(uint2 pos) { globallycoherent T Val = 0.0f; } @@ -14,6 +16,7 @@ template void doSomething2(uint2 pos) { } void Fn() { + // expected-note@+1{{in instantiation of function template specialization 'doSomething' requested here}} doSomething(uint2(0,0)); doSomething2 >(uint2(0,0)); } diff --git a/tools/clang/test/HLSL/template-literal-substitution-failure.hlsl b/tools/clang/test/SemaHLSL/template-literal-substitution-failure.hlsl similarity index 83% rename from tools/clang/test/HLSL/template-literal-substitution-failure.hlsl rename to tools/clang/test/SemaHLSL/template-literal-substitution-failure.hlsl index 7a5b43fc26..1cb3f56697 100644 --- a/tools/clang/test/HLSL/template-literal-substitution-failure.hlsl +++ b/tools/clang/test/SemaHLSL/template-literal-substitution-failure.hlsl @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fsyntax-only -ffreestanding -HV 2021 -verify %s +// RUN: %dxc -Tlib_6_3 -HV 2021 -verify %s RWStructuredBuffer Output; // expected-note@+1 {{candidate template ignored: deduced conflicting types for parameter 'T' ('float' vs. 'literal float')}} diff --git a/tools/clang/test/HLSL/use-undefined-overloaded-operator.hlsl b/tools/clang/test/SemaHLSL/use-undefined-overloaded-operator.hlsl similarity index 83% rename from tools/clang/test/HLSL/use-undefined-overloaded-operator.hlsl rename to tools/clang/test/SemaHLSL/use-undefined-overloaded-operator.hlsl index 04526ca0a8..b4d33683cb 100644 --- a/tools/clang/test/HLSL/use-undefined-overloaded-operator.hlsl +++ b/tools/clang/test/SemaHLSL/use-undefined-overloaded-operator.hlsl @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fsyntax-only -Wno-unused-value -ffreestanding -verify -HV 2021 %s +// RUN: %dxc -Tlib_6_3 -Wno-unused-value -verify -HV 2021 %s // This test checks that when we use undefined overloaded operator // dxcompiler generates error and no crashes are observed. diff --git a/tools/clang/test/HLSL/varmods-syntax.hlsl b/tools/clang/test/SemaHLSL/varmods-syntax.hlsl similarity index 99% rename from tools/clang/test/HLSL/varmods-syntax.hlsl rename to tools/clang/test/SemaHLSL/varmods-syntax.hlsl index e8a508acc7..8bb5bb2fc5 100644 --- a/tools/clang/test/HLSL/varmods-syntax.hlsl +++ b/tools/clang/test/SemaHLSL/varmods-syntax.hlsl @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fsyntax-only -ffreestanding -verify %s +// RUN: %dxc -Tlib_6_3 -verify %s // The following is meant to be processed by the CodeTags extension in the "VS For Everything" Visual Studio extension: /* @@ -1148,4 +1148,4 @@ class C out float fn_out() { return 1.0f; } /* expected-error {{HLSL usage 'out' is only valid on a parameter}} fxc-error {{X3000: syntax error: unexpected token 'out'}} */ inout float fn_inout() { return 1.0f; } /* expected-error {{HLSL usage 'inout' is only valid on a parameter}} fxc-error {{X3000: syntax error: unexpected token 'inout'}} */ -}; \ No newline at end of file +}; diff --git a/tools/clang/test/HLSL/vector-assignments.hlsl b/tools/clang/test/SemaHLSL/vector-assignments.hlsl similarity index 95% rename from tools/clang/test/HLSL/vector-assignments.hlsl rename to tools/clang/test/SemaHLSL/vector-assignments.hlsl index d4f331cf4a..f564308c61 100644 --- a/tools/clang/test/HLSL/vector-assignments.hlsl +++ b/tools/clang/test/SemaHLSL/vector-assignments.hlsl @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fsyntax-only -ffreestanding -verify %s +// RUN: %dxc -Tlib_6_3 -verify %s // To test with the classic compiler, run // %sdxroot%\tools\x86\fxc.exe /T vs_2_0 vector-assignments.hlsl @@ -73,7 +73,7 @@ float2 f2c_f2_f = float3(f2c_f_f, 1); // expected-warning {{implicit truncation // *assignments* do mind if they are widening. // fxc error: error X3017: cannot implicitly convert from 'float3' to 'float4' -float4 f4c_f2_f = f3c_f2_f; // expected-error {{cannot initialize a variable of type 'vector<[...], 4>' with an lvalue of type 'vector<[...], 3>'}} fxc-error {{X3017: cannot implicitly convert from 'float3' to 'float4'}} +float4 f4c_f2_f = f3c_f2_f; // expected-error {{cannot initialize a variable of type 'vector' with an lvalue of type 'vector'}} fxc-error {{X3017: cannot implicitly convert from 'float3' to 'float4'}} // initializers only work on assignment. // fxc error: // error X3000: syntax error: unexpected token '{' diff --git a/tools/clang/test/HLSL/vector-syntax-mix.hlsl b/tools/clang/test/SemaHLSL/vector-syntax-mix.hlsl similarity index 89% rename from tools/clang/test/HLSL/vector-syntax-mix.hlsl rename to tools/clang/test/SemaHLSL/vector-syntax-mix.hlsl index 986e3aaeae..2911149ea4 100644 --- a/tools/clang/test/HLSL/vector-syntax-mix.hlsl +++ b/tools/clang/test/SemaHLSL/vector-syntax-mix.hlsl @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fsyntax-only -ffreestanding -verify %s +// RUN: %dxc -Tlib_6_3 -verify %s void fn() { // Can't use this initialization syntax yet. @@ -12,4 +12,4 @@ void fn() { float4 myothervar; myothervar.xgba = myvar.xyzw; // expected-error {{vector component names cannot mix 'xyzw' and 'rgba'}} fxc-error {{X3018: invalid subscript 'xgba'}} myothervar.rgbx = myvar.xyzw; // expected-error {{vector component names cannot mix 'xyzw' and 'rgba'}} fxc-error {{X3018: invalid subscript 'rgbx'}} -} \ No newline at end of file +} diff --git a/tools/clang/test/SemaTemplate/lit.local.cfg b/tools/clang/test/SemaTemplate/lit.local.cfg index 039670617e..76730bee2a 100644 --- a/tools/clang/test/SemaTemplate/lit.local.cfg +++ b/tools/clang/test/SemaTemplate/lit.local.cfg @@ -1 +1 @@ -config.unsupported = True # HLSL Change - Disable lit suites. +config.suffixes = [] # HLSL Change - Disable lit suites. diff --git a/tools/clang/test/Tooling/lit.local.cfg b/tools/clang/test/Tooling/lit.local.cfg index a6f1e93e98..a8540b58af 100644 --- a/tools/clang/test/Tooling/lit.local.cfg +++ b/tools/clang/test/Tooling/lit.local.cfg @@ -1,3 +1,3 @@ -config.unsupported = True # HLSL Change - Disable lit suites. +config.suffixes = [] # HLSL Change - Disable lit suites. if config.root.clang_staticanalyzer == 0: config.unsupported = True diff --git a/tools/clang/test/VFS/lit.local.cfg b/tools/clang/test/VFS/lit.local.cfg index 039670617e..76730bee2a 100644 --- a/tools/clang/test/VFS/lit.local.cfg +++ b/tools/clang/test/VFS/lit.local.cfg @@ -1 +1 @@ -config.unsupported = True # HLSL Change - Disable lit suites. +config.suffixes = [] # HLSL Change - Disable lit suites. diff --git a/tools/clang/tools/dxclib/dxc.cpp b/tools/clang/tools/dxclib/dxc.cpp index 2e20bd742b..16cf86ccf7 100644 --- a/tools/clang/tools/dxclib/dxc.cpp +++ b/tools/clang/tools/dxclib/dxc.cpp @@ -778,7 +778,8 @@ void DxcContext::Recompile(IDxcBlob *pSource, IDxcLibrary *pLibrary, IFT(pPdbUtils->GetSourceName(i, &pFileName)); IFT(pIncludeHandler->insertIncludeFile(pFileName, pSourceFile, 0)); if (pMainFileName == pFileName) { - pCompileSource.Attach(pSourceFile); + // Transfer pSourceFile to avoid extra AddRef+Release. + pCompileSource.Attach(pSourceFile.Detach()); } } @@ -803,11 +804,6 @@ void DxcContext::Recompile(IDxcBlob *pSource, IDxcLibrary *pLibrary, pIncludeHandler, &pResult)); } -#ifndef _WIN32 - // FIXME: fix crash on linux when not detach pCompileSource. - pCompileSource.Detach(); -#endif - *ppCompileResult = pResult.Detach(); } diff --git a/tools/clang/unittests/HLSL/AllocatorTest.cpp b/tools/clang/unittests/HLSL/AllocatorTest.cpp index ce31706b1d..5f78f58ed4 100644 --- a/tools/clang/unittests/HLSL/AllocatorTest.cpp +++ b/tools/clang/unittests/HLSL/AllocatorTest.cpp @@ -9,9 +9,6 @@ /////////////////////////////////////////////////////////////////////////////// #include "dxc/Support/WinIncludes.h" -#ifdef _WIN32 -#include "WexTestClass.h" -#endif #include "dxc/Test/HlslTestUtils.h" #include "dxc/HLSL/DxilSpanAllocator.h" @@ -104,6 +101,7 @@ bool Align(unsigned &pos, unsigned end, unsigned align) { struct Element { Element() = default; Element(const Element &) = default; + Element &operator=(const Element &) = default; Element(unsigned id, unsigned start, unsigned end) : id(id), start(start), end(end) {} bool operator<(const Element &other) { return id < other.id; } diff --git a/tools/clang/unittests/HLSL/CMakeLists.txt b/tools/clang/unittests/HLSL/CMakeLists.txt index d122b23876..0fd570a28b 100644 --- a/tools/clang/unittests/HLSL/CMakeLists.txt +++ b/tools/clang/unittests/HLSL/CMakeLists.txt @@ -42,7 +42,9 @@ add_clang_library(ClangHLSLTests SHARED Objects.cpp OptimizerTest.cpp OptionsTest.cpp + PixDiaTest.cpp PixTest.cpp + PixTestUtils.cpp RewriterTest.cpp SystemValueTest.cpp ValidationTest.cpp @@ -53,8 +55,7 @@ add_clang_library(ClangHLSLTests SHARED else (WIN32) set(HLSL_IGNORE_SOURCES MSFileSysTest.cpp - PixTest.cpp - RewriterTest.cpp + PixDiaTest.cpp ) add_clang_unittest(ClangHLSLTests @@ -71,6 +72,9 @@ add_clang_unittest(ClangHLSLTests Objects.cpp OptimizerTest.cpp OptionsTest.cpp + RewriterTest.cpp + PixTest.cpp + PixTestUtils.cpp SystemValueTest.cpp TestMain.cpp ValidationTest.cpp @@ -95,6 +99,7 @@ target_link_libraries(ClangHLSLTests PRIVATE else(WIN32) target_link_libraries(ClangHLSLTests dxcompiler + LLVMDxilDia HLSLTestLib ) endif(WIN32) diff --git a/tools/clang/unittests/HLSL/DXIsenseTest.cpp b/tools/clang/unittests/HLSL/DXIsenseTest.cpp index 0e363ff4ec..0739406ee6 100644 --- a/tools/clang/unittests/HLSL/DXIsenseTest.cpp +++ b/tools/clang/unittests/HLSL/DXIsenseTest.cpp @@ -13,9 +13,6 @@ #include "dxc/Test/HLSLTestData.h" #include -#ifdef _WIN32 -#include "WexTestClass.h" -#endif #include "dxc/Support/microcom.h" #include "dxc/Test/HlslTestUtils.h" diff --git a/tools/clang/unittests/HLSL/DxilModuleTest.cpp b/tools/clang/unittests/HLSL/DxilModuleTest.cpp index 6dc31d30d0..72bf1fd303 100644 --- a/tools/clang/unittests/HLSL/DxilModuleTest.cpp +++ b/tools/clang/unittests/HLSL/DxilModuleTest.cpp @@ -71,6 +71,8 @@ class DxilModuleTest : public ::testing::Test { TEST_METHOD(PayloadQualifier) + TEST_METHOD(CanonicalSystemValueSemantic) + void VerifyValidatorVersionFails(LPCWSTR shaderModel, const std::vector &arguments, const std::vector &expectedErrors); @@ -598,4 +600,24 @@ TEST_F(DxilModuleTest, PayloadQualifier) { DXIL::PayloadAccessShaderStage::Anyhit)); } } -} \ No newline at end of file +} + +TEST_F(DxilModuleTest, CanonicalSystemValueSemantic) { + // Verify that the semantic name is canonicalized. + + // This is difficult to do from a FileCheck test because system value + // semantics get canonicallized during the metadata emit. However, having a + // non-canonical semantic name at earlier stages can lead to inconsistency + // between the strings used earlier and the final canonicalized version. This + // makes sure the string gets canonicalized when the signature elsement is + // created. + + std::unique_ptr newElt = + std::make_unique( + hlsl::DXIL::SigPointKind::VSOut); + newElt->Initialize("sV_pOsItIoN", hlsl::CompType::getF32(), + hlsl::InterpolationMode( + hlsl::DXIL::InterpolationMode::LinearNoperspective), + 1, 4, 0, 0, 0, {0}); + VERIFY_ARE_EQUAL_STR("SV_Position", newElt->GetSemanticName().data()); +} diff --git a/tools/clang/unittests/HLSL/LinkerTest.cpp b/tools/clang/unittests/HLSL/LinkerTest.cpp index 628431aeac..7cafa0db06 100644 --- a/tools/clang/unittests/HLSL/LinkerTest.cpp +++ b/tools/clang/unittests/HLSL/LinkerTest.cpp @@ -18,9 +18,6 @@ #include -#ifdef _WIN32 -#include "WexTestClass.h" -#endif #include "dxc/DxilContainer/DxilContainer.h" #include "dxc/Support/Global.h" // for IFT macro #include "dxc/Test/DxcTestUtils.h" diff --git a/tools/clang/unittests/HLSL/MSFileSysTest.cpp b/tools/clang/unittests/HLSL/MSFileSysTest.cpp index 73bb13571b..5707865281 100644 --- a/tools/clang/unittests/HLSL/MSFileSysTest.cpp +++ b/tools/clang/unittests/HLSL/MSFileSysTest.cpp @@ -13,7 +13,6 @@ // Includes on Windows are highly order dependent. #include #include "dxc/Support/WinIncludes.h" -#include "WexTestClass.h" #include "dxc/Test/HlslTestUtils.h" #include "llvm/Support/MSFileSystem.h" @@ -38,14 +37,15 @@ private: \ volatile std::atomic m_dwRef; \ \ public: \ - ULONG STDMETHODCALLTYPE AddRef() { return (ULONG)++m_dwRef; } \ - ULONG STDMETHODCALLTYPE Release() { \ + ULONG STDMETHODCALLTYPE AddRef() override { return (ULONG)++m_dwRef; } \ + ULONG STDMETHODCALLTYPE Release() override { \ ULONG result = (ULONG)--m_dwRef; \ if (result == 0) \ delete this; \ return result; \ } \ - HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, void **ppvObject) { \ + HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, void **ppvObject) \ + override { \ if (ppvObject == nullptr) \ return E_POINTER; \ if (IsEqualIID(iid, __uuidof(IUnknown)) || \ @@ -100,12 +100,12 @@ class FixedEnumSTATSTG : public IEnumSTATSTG { m_items[i].pwcsName = CoTaskMemDup(m_items[i].pwcsName); } } - ~FixedEnumSTATSTG() { + virtual ~FixedEnumSTATSTG() { for (auto &item : m_items) CoTaskMemFree(item.pwcsName); } - virtual HRESULT STDMETHODCALLTYPE Next(ULONG celt, STATSTG *rgelt, - ULONG *pceltFetched) { + HRESULT STDMETHODCALLTYPE Next(ULONG celt, STATSTG *rgelt, + ULONG *pceltFetched) override { if (celt != 1 || pceltFetched == nullptr) return E_NOTIMPL; if (m_index >= m_items.size()) { @@ -119,22 +119,20 @@ class FixedEnumSTATSTG : public IEnumSTATSTG { ++m_index; return S_OK; } - virtual HRESULT STDMETHODCALLTYPE Skip(ULONG celt) { return E_NOTIMPL; } - virtual HRESULT STDMETHODCALLTYPE Reset(void) { return E_NOTIMPL; } - virtual HRESULT STDMETHODCALLTYPE Clone(IEnumSTATSTG **) { return E_NOTIMPL; } + HRESULT STDMETHODCALLTYPE Skip(ULONG celt) override { return E_NOTIMPL; } + HRESULT STDMETHODCALLTYPE Reset(void) override { return E_NOTIMPL; } + HRESULT STDMETHODCALLTYPE Clone(IEnumSTATSTG **) override { + return E_NOTIMPL; + } }; class MockDxcSystemAccess : public IDxcSystemAccess { SIMPLE_IUNKNOWN_IMPL1(IDxcSystemAccess) -private: - LPCSTR m_fileName; - LPCSTR m_contents; - unsigned m_length; public: unsigned findCount; MockDxcSystemAccess() : m_dwRef(0), findCount(1) {} - + virtual ~MockDxcSystemAccess() {} static HRESULT Create(MockDxcSystemAccess **pResult) { *pResult = new (std::nothrow) MockDxcSystemAccess(); if (*pResult == nullptr) @@ -143,8 +141,8 @@ class MockDxcSystemAccess : public IDxcSystemAccess { return S_OK; } - virtual HRESULT STDMETHODCALLTYPE EnumFiles(LPCWSTR fileName, - IEnumSTATSTG **pResult) override { + HRESULT STDMETHODCALLTYPE EnumFiles(LPCWSTR fileName, + IEnumSTATSTG **pResult) override { wchar_t hlslName[] = L"filename.hlsl"; wchar_t fxName[] = L"filename2.fx"; STATSTG items[] = {{hlslName, @@ -180,94 +178,96 @@ class MockDxcSystemAccess : public IDxcSystemAccess { *pResult = resultEnum; return S_OK; } - virtual HRESULT STDMETHODCALLTYPE OpenStorage(LPCWSTR lpFileName, - DWORD dwDesiredAccess, - DWORD dwShareMode, - DWORD dwCreationDisposition, - DWORD dwFlagsAndAttributes, - IUnknown **pResult) override { + HRESULT STDMETHODCALLTYPE OpenStorage(LPCWSTR lpFileName, + DWORD dwDesiredAccess, + DWORD dwShareMode, + DWORD dwCreationDisposition, + DWORD dwFlagsAndAttributes, + IUnknown **pResult) override { *pResult = SHCreateMemStream(nullptr, 0); return (*pResult == nullptr) ? E_OUTOFMEMORY : S_OK; } - virtual HRESULT STDMETHODCALLTYPE + HRESULT STDMETHODCALLTYPE SetStorageTime(IUnknown *storage, const FILETIME *lpCreationTime, const FILETIME *lpLastAccessTime, const FILETIME *lpLastWriteTime) override { return E_NOTIMPL; } - virtual HRESULT STDMETHODCALLTYPE GetFileInformationForStorage( + HRESULT STDMETHODCALLTYPE GetFileInformationForStorage( IUnknown *storage, LPBY_HANDLE_FILE_INFORMATION lpFileInformation) override { return E_NOTIMPL; } - virtual HRESULT STDMETHODCALLTYPE - GetFileTypeForStorage(IUnknown *storage, DWORD *fileType) override { + HRESULT STDMETHODCALLTYPE GetFileTypeForStorage(IUnknown *storage, + DWORD *fileType) override { return E_NOTIMPL; } - virtual HRESULT STDMETHODCALLTYPE CreateHardLinkInStorage( + HRESULT STDMETHODCALLTYPE CreateHardLinkInStorage( LPCWSTR lpFileName, LPCWSTR lpExistingFileName) override { return E_NOTIMPL; } - virtual HRESULT STDMETHODCALLTYPE MoveStorage(LPCWSTR lpExistingFileName, - LPCWSTR lpNewFileName, - DWORD dwFlags) override { + HRESULT STDMETHODCALLTYPE MoveStorage(LPCWSTR lpExistingFileName, + LPCWSTR lpNewFileName, + DWORD dwFlags) override { return E_NOTIMPL; } - virtual HRESULT STDMETHODCALLTYPE + HRESULT STDMETHODCALLTYPE GetFileAttributesForStorage(LPCWSTR lpFileName, DWORD *pResult) override { return E_NOTIMPL; } - virtual HRESULT STDMETHODCALLTYPE DeleteStorage(LPCWSTR lpFileName) override { + HRESULT STDMETHODCALLTYPE DeleteStorage(LPCWSTR lpFileName) override { return E_NOTIMPL; } - virtual HRESULT STDMETHODCALLTYPE + HRESULT STDMETHODCALLTYPE RemoveDirectoryStorage(LPCWSTR lpFileName) override { return E_NOTIMPL; } - virtual HRESULT STDMETHODCALLTYPE + HRESULT STDMETHODCALLTYPE CreateDirectoryStorage(LPCWSTR lpPathName) override { return E_NOTIMPL; } - virtual HRESULT STDMETHODCALLTYPE GetCurrentDirectoryForStorage( - DWORD nBufferLength, LPWSTR lpBuffer, DWORD *len) override { + HRESULT STDMETHODCALLTYPE GetCurrentDirectoryForStorage(DWORD nBufferLength, + LPWSTR lpBuffer, + DWORD *len) override { return E_NOTIMPL; } - virtual HRESULT STDMETHODCALLTYPE GetMainModuleFileNameW( - DWORD nBufferLength, LPWSTR lpBuffer, DWORD *len) override { + HRESULT STDMETHODCALLTYPE GetMainModuleFileNameW(DWORD nBufferLength, + LPWSTR lpBuffer, + DWORD *len) override { return E_NOTIMPL; } - virtual HRESULT STDMETHODCALLTYPE GetTempStoragePath(DWORD nBufferLength, - LPWSTR lpBuffer, - DWORD *len) override { + HRESULT STDMETHODCALLTYPE GetTempStoragePath(DWORD nBufferLength, + LPWSTR lpBuffer, + DWORD *len) override { return E_NOTIMPL; } - virtual HRESULT STDMETHODCALLTYPE - SupportsCreateSymbolicLink(BOOL *pResult) override { + HRESULT STDMETHODCALLTYPE SupportsCreateSymbolicLink(BOOL *pResult) override { return E_NOTIMPL; } - virtual HRESULT STDMETHODCALLTYPE CreateSymbolicLinkInStorage( + HRESULT STDMETHODCALLTYPE CreateSymbolicLinkInStorage( LPCWSTR lpSymlinkFileName, LPCWSTR lpTargetFileName, DWORD dwFlags) override { return E_NOTIMPL; } - virtual HRESULT STDMETHODCALLTYPE CreateStorageMapping( - IUnknown *hFile, DWORD flProtect, DWORD dwMaximumSizeHigh, - DWORD dwMaximumSizeLow, IUnknown **pResult) override { + HRESULT STDMETHODCALLTYPE CreateStorageMapping(IUnknown *hFile, + DWORD flProtect, + DWORD dwMaximumSizeHigh, + DWORD dwMaximumSizeLow, + IUnknown **pResult) override { return E_NOTIMPL; } - virtual HRESULT MapViewOfFile(IUnknown *hFileMappingObject, - DWORD dwDesiredAccess, DWORD dwFileOffsetHigh, - DWORD dwFileOffsetLow, - SIZE_T dwNumberOfBytesToMap, - ID3D10Blob **pResult) override { + HRESULT MapViewOfFile(IUnknown *hFileMappingObject, DWORD dwDesiredAccess, + DWORD dwFileOffsetHigh, DWORD dwFileOffsetLow, + SIZE_T dwNumberOfBytesToMap, + ID3D10Blob **pResult) override { return E_NOTIMPL; } - virtual HRESULT STDMETHODCALLTYPE - OpenStdStorage(int standardFD, IUnknown **pResult) override { + HRESULT STDMETHODCALLTYPE OpenStdStorage(int standardFD, + IUnknown **pResult) override { return E_NOTIMPL; } - virtual HRESULT STDMETHODCALLTYPE - GetStreamDisplay(ITextFont **textFont, unsigned *columnCount) override { + HRESULT STDMETHODCALLTYPE GetStreamDisplay(ITextFont **textFont, + unsigned *columnCount) override { return E_NOTIMPL; } }; @@ -306,7 +306,7 @@ void MSFileSysTest::FindFirstWhenInvokedThenFailsIfNoMatch() { CreateMSFileSystemForIface(access, &fileSystem); WIN32_FIND_DATAW findData; HANDLE h = fileSystem->FindFirstFileW(L"foobar", &findData); - VERIFY_ARE_EQUAL(ERROR_FILE_NOT_FOUND, GetLastError()); + VERIFY_ARE_EQUAL(ERROR_FILE_NOT_FOUND, (long)GetLastError()); VERIFY_ARE_EQUAL(INVALID_HANDLE_VALUE, h); VERIFY_ARE_EQUAL_WSTR(L"", findData.cFileName); delete fileSystem; @@ -323,7 +323,7 @@ void MSFileSysTest::FindNextWhenLastThenNoMatch() { VERIFY_ARE_NOT_EQUAL(INVALID_HANDLE_VALUE, h); BOOL findNext = fileSystem->FindNextFileW(h, &findData); VERIFY_IS_FALSE(findNext); - VERIFY_ARE_EQUAL(ERROR_FILE_NOT_FOUND, GetLastError()); + VERIFY_ARE_EQUAL(ERROR_FILE_NOT_FOUND, (long)GetLastError()); fileSystem->FindClose(h); delete fileSystem; } @@ -357,7 +357,7 @@ void MSFileSysTest::OpenWhenNewThenZeroSize() { char buf[4]; DWORD bytesRead; VERIFY_IS_TRUE(fileSystem->ReadFile(h, buf, _countof(buf), &bytesRead)); - VERIFY_ARE_EQUAL(0, bytesRead); + VERIFY_ARE_EQUAL(0u, bytesRead); fileSystem->CloseHandle(h); delete fileSystem; } diff --git a/tools/clang/unittests/HLSL/Objects.cpp b/tools/clang/unittests/HLSL/Objects.cpp index 87dd72efad..5e972f467b 100644 --- a/tools/clang/unittests/HLSL/Objects.cpp +++ b/tools/clang/unittests/HLSL/Objects.cpp @@ -12,9 +12,6 @@ #include "dxc/Test/HLSLTestData.h" #include -#ifdef _WIN32 -#include "WexTestClass.h" -#endif #include "dxc/Test/HlslTestUtils.h" #include diff --git a/tools/clang/unittests/HLSL/OptionsTest.cpp b/tools/clang/unittests/HLSL/OptionsTest.cpp index 5e3bb6e639..22ac556351 100644 --- a/tools/clang/unittests/HLSL/OptionsTest.cpp +++ b/tools/clang/unittests/HLSL/OptionsTest.cpp @@ -23,9 +23,6 @@ #include #include "dxc/Test/HLSLTestData.h" -#ifdef _WIN32 -#include "WexTestClass.h" -#endif #include "dxc/Test/HlslTestUtils.h" #include "dxc/DxilContainer/DxilContainer.h" diff --git a/tools/clang/unittests/HLSL/PixDiaTest.cpp b/tools/clang/unittests/HLSL/PixDiaTest.cpp new file mode 100644 index 0000000000..1bda72106e --- /dev/null +++ b/tools/clang/unittests/HLSL/PixDiaTest.cpp @@ -0,0 +1,2758 @@ +/////////////////////////////////////////////////////////////////////////////// +// // +// PixDiaTest.cpp // +// Copyright (C) Microsoft Corporation. All rights reserved. // +// This file is distributed under the University of Illinois Open Source // +// License. See LICENSE.TXT for details. // +// // +// Provides tests for the PIX-specific components related to dia // +// // +/////////////////////////////////////////////////////////////////////////////// + +// This whole file is win32-only +#ifdef _WIN32 + +#include "dxc/DxilContainer/DxilContainer.h" +#include "dxc/Support/WinIncludes.h" +#include "dxc/dxcapi.h" + +#include "dxc/Test/DxcTestUtils.h" +#include "dxc/Test/HLSLTestData.h" +#include "dxc/Test/HlslTestUtils.h" + +#include "llvm/Support/raw_os_ostream.h" + +#include <../lib/DxilDia/DxilDiaSession.h> + +#include "PixTestUtils.h" + +using namespace std; +using namespace hlsl; +using namespace hlsl_test; +using namespace pix_test; + +// Aligned to SymTagEnum. +const char *SymTagEnumText[] = { + "Null", // SymTagNull + "Exe", // SymTagExe + "Compiland", // SymTagCompiland + "CompilandDetails", // SymTagCompilandDetails + "CompilandEnv", // SymTagCompilandEnv + "Function", // SymTagFunction + "Block", // SymTagBlock + "Data", // SymTagData + "Annotation", // SymTagAnnotation + "Label", // SymTagLabel + "PublicSymbol", // SymTagPublicSymbol + "UDT", // SymTagUDT + "Enum", // SymTagEnum + "FunctionType", // SymTagFunctionType + "PointerType", // SymTagPointerType + "ArrayType", // SymTagArrayType + "BaseType", // SymTagBaseType + "Typedef", // SymTagTypedef + "BaseClass", // SymTagBaseClass + "Friend", // SymTagFriend + "FunctionArgType", // SymTagFunctionArgType + "FuncDebugStart", // SymTagFuncDebugStart + "FuncDebugEnd", // SymTagFuncDebugEnd + "UsingNamespace", // SymTagUsingNamespace + "VTableShape", // SymTagVTableShape + "VTable", // SymTagVTable + "Custom", // SymTagCustom + "Thunk", // SymTagThunk + "CustomType", // SymTagCustomType + "ManagedType", // SymTagManagedType + "Dimension", // SymTagDimension + "CallSite", // SymTagCallSite + "InlineSite", // SymTagInlineSite + "BaseInterface", // SymTagBaseInterface + "VectorType", // SymTagVectorType + "MatrixType", // SymTagMatrixType + "HLSLType", // SymTagHLSLType + "Caller", // SymTagCaller + "Callee", // SymTagCallee + "Export", // SymTagExport + "HeapAllocationSite", // SymTagHeapAllocationSite + "CoffGroup", // SymTagCoffGroup +}; + +// Aligned to DataKind. +const char *DataKindText[] = { + "Unknown", "Local", "StaticLocal", "Param", "ObjectPtr", + "FileStatic", "Global", "Member", "StaticMember", "Constant", +}; + +static void CompileAndGetDebugPart(dxc::DxcDllSupport &dllSupport, + const char *source, const wchar_t *profile, + IDxcBlob **ppDebugPart) { + CComPtr pContainer; + CComPtr pLib; + CComPtr pReflection; + UINT32 index; + std::vector args; + args.push_back(L"/Zi"); + args.push_back(L"/Qembed_debug"); + + VerifyCompileOK(dllSupport, source, profile, args, &pContainer); + VERIFY_SUCCEEDED(dllSupport.CreateInstance(CLSID_DxcLibrary, &pLib)); + VERIFY_SUCCEEDED( + dllSupport.CreateInstance(CLSID_DxcContainerReflection, &pReflection)); + VERIFY_SUCCEEDED(pReflection->Load(pContainer)); + VERIFY_SUCCEEDED( + pReflection->FindFirstPartKind(hlsl::DFCC_ShaderDebugInfoDXIL, &index)); + VERIFY_SUCCEEDED(pReflection->GetPartContent(index, ppDebugPart)); +} + +static LPCWSTR defaultFilename = L"source.hlsl"; + +static HRESULT UnAliasType(IDxcPixType *MaybeAlias, + IDxcPixType **OriginalType) { + *OriginalType = nullptr; + CComPtr Tmp(MaybeAlias); + + do { + HRESULT hr; + + CComPtr Alias; + hr = Tmp->UnAlias(&Alias); + if (FAILED(hr)) { + return hr; + } + if (hr == S_FALSE) { + break; + } + Tmp = Alias; + } while (true); + + *OriginalType = Tmp.Detach(); + return S_OK; +} + +class PixDiaTest { +public: + BEGIN_TEST_CLASS(PixDiaTest) + TEST_CLASS_PROPERTY(L"Parallel", L"true") + TEST_METHOD_PROPERTY(L"Priority", L"0") + END_TEST_CLASS() + + TEST_CLASS_SETUP(InitSupport); + + TEST_METHOD(CompileWhenDebugThenDIPresent) + TEST_METHOD(CompileDebugPDB) + + TEST_METHOD(DiaLoadBadBitcodeThenFail) + TEST_METHOD(DiaLoadDebugThenOK) + TEST_METHOD(DiaTableIndexThenOK) + TEST_METHOD(DiaLoadDebugSubrangeNegativeThenOK) + TEST_METHOD(DiaLoadRelocatedBitcode) + TEST_METHOD(DiaLoadBitcodePlusExtraData) + TEST_METHOD(DiaCompileArgs) + + TEST_METHOD(PixTypeManager_InheritancePointerStruct) + TEST_METHOD(PixTypeManager_InheritancePointerTypedef) + TEST_METHOD(PixTypeManager_MatricesInBase) + TEST_METHOD(PixTypeManager_SamplersAndResources) + TEST_METHOD(PixTypeManager_XBoxDiaAssert) + + TEST_METHOD(DxcPixDxilDebugInfo_InstructionOffsets) + + TEST_METHOD(PixDebugCompileInfo) + + TEST_METHOD(SymbolManager_Embedded2DArray) + + TEST_METHOD( + DxcPixDxilDebugInfo_GlobalBackedGlobalStaticEmbeddedArrays_NoDbgValue) + TEST_METHOD( + DxcPixDxilDebugInfo_GlobalBackedGlobalStaticEmbeddedArrays_WithDbgValue) + TEST_METHOD( + DxcPixDxilDebugInfo_GlobalBackedGlobalStaticEmbeddedArrays_ArrayInValues) + TEST_METHOD(DxcPixDxilDebugInfo_StructInheritance) + TEST_METHOD(DxcPixDxilDebugInfo_StructContainedResource) + TEST_METHOD(DxcPixDxilDebugInfo_StructStaticInit) + TEST_METHOD(DxcPixDxilDebugInfo_StructMemberFnFirst) + TEST_METHOD(DxcPixDxilDebugInfo_UnnamedConstStruct) + TEST_METHOD(DxcPixDxilDebugInfo_UnnamedStruct) + TEST_METHOD(DxcPixDxilDebugInfo_UnnamedArray) + TEST_METHOD(DxcPixDxilDebugInfo_UnnamedField) + TEST_METHOD(DxcPixDxilDebugInfo_SubProgramsInNamespaces) + TEST_METHOD(DxcPixDxilDebugInfo_SubPrograms) + + dxc::DxcDllSupport m_dllSupport; + VersionSupportInfo m_ver; + + void RunSubProgramsCase(const char *hlsl); + void TestUnnamedTypeCase(const char *hlsl, const wchar_t *expectedTypeName); + + template + void WriteIfValue(TIface *pSymbol, std::wstringstream &o, + TDefault defaultValue, LPCWSTR valueLabel, + HRESULT (__stdcall TIface::*pFn)(T *)) { + T value; + HRESULT hr = (pSymbol->*(pFn))(&value); + if (SUCCEEDED(hr) && value != (T)defaultValue) { + o << L", " << valueLabel << L": " << value; + } + } + + template + void WriteIfValue(TIface *pSymbol, std::wstringstream &o, LPCWSTR valueLabel, + HRESULT (__stdcall TIface::*pFn)(BSTR *)) { + CComBSTR value; + HRESULT hr = (pSymbol->*(pFn))(&value); + if (SUCCEEDED(hr) && value.Length()) { + o << L", " << valueLabel << L": " << (LPCWSTR)value; + } + } + template + void WriteIfValue(TIface *pSymbol, std::wstringstream &o, LPCWSTR valueLabel, + HRESULT (__stdcall TIface::*pFn)(VARIANT *)) { + CComVariant value; + HRESULT hr = (pSymbol->*(pFn))(&value); + if (SUCCEEDED(hr) && value.vt != VT_NULL && value.vt != VT_EMPTY) { + if (SUCCEEDED(value.ChangeType(VT_BSTR))) { + o << L", " << valueLabel << L": " << (LPCWSTR)value.bstrVal; + } + } + } + template + void WriteIfValue(TIface *pSymbol, std::wstringstream &o, LPCWSTR valueLabel, + HRESULT (__stdcall TIface::*pFn)(IDiaSymbol **)) { + CComPtr value; + HRESULT hr = (pSymbol->*(pFn))(&value); + if (SUCCEEDED(hr) && value.p != nullptr) { + DWORD symId; + value->get_symIndexId(&symId); + o << L", " << valueLabel << L": id=" << symId; + } + } + + std::wstring GetDebugInfoAsText(IDiaDataSource *pDataSource) { + CComPtr pSession; + CComPtr pTable; + CComPtr pEnumTables; + std::wstringstream o; + + VERIFY_SUCCEEDED(pDataSource->openSession(&pSession)); + VERIFY_SUCCEEDED(pSession->getEnumTables(&pEnumTables)); + LONG count; + VERIFY_SUCCEEDED(pEnumTables->get_Count(&count)); + for (LONG i = 0; i < count; ++i) { + pTable.Release(); + ULONG fetched; + VERIFY_SUCCEEDED(pEnumTables->Next(1, &pTable, &fetched)); + VERIFY_ARE_EQUAL(fetched, 1u); + CComBSTR tableName; + VERIFY_SUCCEEDED(pTable->get_name(&tableName)); + o << L"Table: " << (LPWSTR)tableName << std::endl; + LONG rowCount; + IFT(pTable->get_Count(&rowCount)); + o << L" Row count: " << rowCount << std::endl; + + for (LONG rowIndex = 0; rowIndex < rowCount; ++rowIndex) { + CComPtr item; + o << L'#' << rowIndex; + IFT(pTable->Item(rowIndex, &item)); + CComPtr pSymbol; + if (SUCCEEDED(item.QueryInterface(&pSymbol))) { + DWORD symTag; + DWORD dataKind; + DWORD locationType; + DWORD registerId; + pSymbol->get_symTag(&symTag); + pSymbol->get_dataKind(&dataKind); + pSymbol->get_locationType(&locationType); + pSymbol->get_registerId(®isterId); + // pSymbol->get_value(&value); + + WriteIfValue(pSymbol.p, o, 0, L"symIndexId", + &IDiaSymbol::get_symIndexId); + o << L", " << SymTagEnumText[symTag]; + if (dataKind != 0) + o << L", " << DataKindText[dataKind]; + WriteIfValue(pSymbol.p, o, L"name", &IDiaSymbol::get_name); + WriteIfValue(pSymbol.p, o, L"lexicalParent", + &IDiaSymbol::get_lexicalParent); + WriteIfValue(pSymbol.p, o, L"type", &IDiaSymbol::get_type); + WriteIfValue(pSymbol.p, o, 0, L"slot", &IDiaSymbol::get_slot); + WriteIfValue(pSymbol.p, o, 0, L"platform", &IDiaSymbol::get_platform); + WriteIfValue(pSymbol.p, o, 0, L"language", &IDiaSymbol::get_language); + WriteIfValue(pSymbol.p, o, 0, L"frontEndMajor", + &IDiaSymbol::get_frontEndMajor); + WriteIfValue(pSymbol.p, o, 0, L"frontEndMinor", + &IDiaSymbol::get_frontEndMinor); + WriteIfValue(pSymbol.p, o, 0, L"token", &IDiaSymbol::get_token); + WriteIfValue(pSymbol.p, o, L"value", &IDiaSymbol::get_value); + WriteIfValue(pSymbol.p, o, 0, L"code", &IDiaSymbol::get_code); + WriteIfValue(pSymbol.p, o, 0, L"function", &IDiaSymbol::get_function); + WriteIfValue(pSymbol.p, o, 0, L"udtKind", &IDiaSymbol::get_udtKind); + WriteIfValue(pSymbol.p, o, 0, L"hasDebugInfo", + &IDiaSymbol::get_hasDebugInfo); + WriteIfValue(pSymbol.p, o, L"compilerName", + &IDiaSymbol::get_compilerName); + WriteIfValue(pSymbol.p, o, 0, L"isLocationControlFlowDependent", + &IDiaSymbol::get_isLocationControlFlowDependent); + WriteIfValue(pSymbol.p, o, 0, L"numberOfRows", + &IDiaSymbol::get_numberOfRows); + WriteIfValue(pSymbol.p, o, 0, L"numberOfColumns", + &IDiaSymbol::get_numberOfColumns); + WriteIfValue(pSymbol.p, o, 0, L"length", &IDiaSymbol::get_length); + WriteIfValue(pSymbol.p, o, 0, L"isMatrixRowMajor", + &IDiaSymbol::get_isMatrixRowMajor); + WriteIfValue(pSymbol.p, o, 0, L"builtInKind", + &IDiaSymbol::get_builtInKind); + WriteIfValue(pSymbol.p, o, 0, L"textureSlot", + &IDiaSymbol::get_textureSlot); + WriteIfValue(pSymbol.p, o, 0, L"memorySpaceKind", + &IDiaSymbol::get_memorySpaceKind); + WriteIfValue(pSymbol.p, o, 0, L"isHLSLData", + &IDiaSymbol::get_isHLSLData); + } + + CComPtr pSourceFile; + if (SUCCEEDED(item.QueryInterface(&pSourceFile))) { + WriteIfValue(pSourceFile.p, o, 0, L"uniqueId", + &IDiaSourceFile::get_uniqueId); + WriteIfValue(pSourceFile.p, o, L"fileName", + &IDiaSourceFile::get_fileName); + } + + CComPtr pLineNumber; + if (SUCCEEDED(item.QueryInterface(&pLineNumber))) { + WriteIfValue(pLineNumber.p, o, L"compiland", + &IDiaLineNumber::get_compiland); + // WriteIfValue(pLineNumber.p, o, L"sourceFile", + // &IDiaLineNumber::get_sourceFile); + WriteIfValue(pLineNumber.p, o, 0, L"lineNumber", + &IDiaLineNumber::get_lineNumber); + WriteIfValue(pLineNumber.p, o, 0, L"lineNumberEnd", + &IDiaLineNumber::get_lineNumberEnd); + WriteIfValue(pLineNumber.p, o, 0, L"columnNumber", + &IDiaLineNumber::get_columnNumber); + WriteIfValue(pLineNumber.p, o, 0, L"columnNumberEnd", + &IDiaLineNumber::get_columnNumberEnd); + WriteIfValue(pLineNumber.p, o, 0, L"addressSection", + &IDiaLineNumber::get_addressSection); + WriteIfValue(pLineNumber.p, o, 0, L"addressOffset", + &IDiaLineNumber::get_addressOffset); + WriteIfValue(pLineNumber.p, o, 0, L"relativeVirtualAddress", + &IDiaLineNumber::get_relativeVirtualAddress); + WriteIfValue(pLineNumber.p, o, 0, L"virtualAddress", + &IDiaLineNumber::get_virtualAddress); + WriteIfValue(pLineNumber.p, o, 0, L"length", + &IDiaLineNumber::get_length); + WriteIfValue(pLineNumber.p, o, 0, L"sourceFileId", + &IDiaLineNumber::get_sourceFileId); + WriteIfValue(pLineNumber.p, o, 0, L"statement", + &IDiaLineNumber::get_statement); + WriteIfValue(pLineNumber.p, o, 0, L"compilandId", + &IDiaLineNumber::get_compilandId); + } + + CComPtr pSectionContrib; + if (SUCCEEDED(item.QueryInterface(&pSectionContrib))) { + WriteIfValue(pSectionContrib.p, o, L"compiland", + &IDiaSectionContrib::get_compiland); + WriteIfValue(pSectionContrib.p, o, 0, L"addressSection", + &IDiaSectionContrib::get_addressSection); + WriteIfValue(pSectionContrib.p, o, 0, L"addressOffset", + &IDiaSectionContrib::get_addressOffset); + WriteIfValue(pSectionContrib.p, o, 0, L"relativeVirtualAddress", + &IDiaSectionContrib::get_relativeVirtualAddress); + WriteIfValue(pSectionContrib.p, o, 0, L"virtualAddress", + &IDiaSectionContrib::get_virtualAddress); + WriteIfValue(pSectionContrib.p, o, 0, L"length", + &IDiaSectionContrib::get_length); + WriteIfValue(pSectionContrib.p, o, 0, L"notPaged", + &IDiaSectionContrib::get_notPaged); + WriteIfValue(pSectionContrib.p, o, 0, L"code", + &IDiaSectionContrib::get_code); + WriteIfValue(pSectionContrib.p, o, 0, L"initializedData", + &IDiaSectionContrib::get_initializedData); + WriteIfValue(pSectionContrib.p, o, 0, L"uninitializedData", + &IDiaSectionContrib::get_uninitializedData); + WriteIfValue(pSectionContrib.p, o, 0, L"remove", + &IDiaSectionContrib::get_remove); + WriteIfValue(pSectionContrib.p, o, 0, L"comdat", + &IDiaSectionContrib::get_comdat); + WriteIfValue(pSectionContrib.p, o, 0, L"discardable", + &IDiaSectionContrib::get_discardable); + WriteIfValue(pSectionContrib.p, o, 0, L"notCached", + &IDiaSectionContrib::get_notCached); + WriteIfValue(pSectionContrib.p, o, 0, L"share", + &IDiaSectionContrib::get_share); + WriteIfValue(pSectionContrib.p, o, 0, L"execute", + &IDiaSectionContrib::get_execute); + WriteIfValue(pSectionContrib.p, o, 0, L"read", + &IDiaSectionContrib::get_read); + WriteIfValue(pSectionContrib.p, o, 0, L"write", + &IDiaSectionContrib::get_write); + WriteIfValue(pSectionContrib.p, o, 0, L"dataCrc", + &IDiaSectionContrib::get_dataCrc); + WriteIfValue(pSectionContrib.p, o, 0, L"relocationsCrc", + &IDiaSectionContrib::get_relocationsCrc); + WriteIfValue(pSectionContrib.p, o, 0, L"compilandId", + &IDiaSectionContrib::get_compilandId); + } + + CComPtr pSegment; + if (SUCCEEDED(item.QueryInterface(&pSegment))) { + WriteIfValue(pSegment.p, o, 0, L"frame", &IDiaSegment::get_frame); + WriteIfValue(pSegment.p, o, 0, L"offset", &IDiaSegment::get_offset); + WriteIfValue(pSegment.p, o, 0, L"length", &IDiaSegment::get_length); + WriteIfValue(pSegment.p, o, 0, L"read", &IDiaSegment::get_read); + WriteIfValue(pSegment.p, o, 0, L"write", &IDiaSegment::get_write); + WriteIfValue(pSegment.p, o, 0, L"execute", &IDiaSegment::get_execute); + WriteIfValue(pSegment.p, o, 0, L"addressSection", + &IDiaSegment::get_addressSection); + WriteIfValue(pSegment.p, o, 0, L"relativeVirtualAddress", + &IDiaSegment::get_relativeVirtualAddress); + WriteIfValue(pSegment.p, o, 0, L"virtualAddress", + &IDiaSegment::get_virtualAddress); + } + + CComPtr pInjectedSource; + if (SUCCEEDED(item.QueryInterface(&pInjectedSource))) { + WriteIfValue(pInjectedSource.p, o, 0, L"crc", + &IDiaInjectedSource::get_crc); + WriteIfValue(pInjectedSource.p, o, 0, L"length", + &IDiaInjectedSource::get_length); + WriteIfValue(pInjectedSource.p, o, L"filename", + &IDiaInjectedSource::get_filename); + WriteIfValue(pInjectedSource.p, o, L"objectFilename", + &IDiaInjectedSource::get_objectFilename); + WriteIfValue(pInjectedSource.p, o, L"virtualFilename", + &IDiaInjectedSource::get_virtualFilename); + WriteIfValue(pInjectedSource.p, o, 0, L"sourceCompression", + &IDiaInjectedSource::get_sourceCompression); + // get_source is also available + } + + CComPtr pFrameData; + if (SUCCEEDED(item.QueryInterface(&pFrameData))) { + } + + o << std::endl; + } + } + + return o.str(); + } + std::wstring GetDebugFileContent(IDiaDataSource *pDataSource) { + CComPtr pSession; + CComPtr pTable; + + CComPtr pSourcesTable; + + CComPtr pEnumTables; + std::wstringstream o; + + VERIFY_SUCCEEDED(pDataSource->openSession(&pSession)); + VERIFY_SUCCEEDED(pSession->getEnumTables(&pEnumTables)); + + ULONG fetched = 0; + while (pEnumTables->Next(1, &pTable, &fetched) == S_OK && fetched == 1) { + CComBSTR name; + IFT(pTable->get_name(&name)); + + if (wcscmp(name, L"SourceFiles") == 0) { + pSourcesTable = pTable.Detach(); + continue; + } + + pTable.Release(); + } + + if (!pSourcesTable) { + return L"cannot find source"; + } + + // Get source file contents. + // NOTE: "SourceFiles" has the root file first while "InjectedSources" is in + // alphabetical order. + // It is important to keep the root file first for recompilation, so + // iterate "SourceFiles" and look up the corresponding injected + // source. + LONG count; + IFT(pSourcesTable->get_Count(&count)); + + CComPtr pSourceFile; + CComBSTR pName; + CComPtr pSymbolUnk; + CComPtr pEnumInjectedSources; + CComPtr pInjectedSource; + std::wstring sourceText, sourceFilename; + + while (SUCCEEDED(pSourcesTable->Next(1, &pSymbolUnk, &fetched)) && + fetched == 1) { + sourceText = sourceFilename = L""; + + IFT(pSymbolUnk->QueryInterface(&pSourceFile)); + IFT(pSourceFile->get_fileName(&pName)); + + IFT(pSession->findInjectedSource(pName, &pEnumInjectedSources)); + + if (SUCCEEDED(pEnumInjectedSources->get_Count(&count)) && count == 1) { + IFT(pEnumInjectedSources->Item(0, &pInjectedSource)); + + DWORD cbData = 0; + std::string tempString; + CComBSTR bstr; + IFT(pInjectedSource->get_filename(&bstr)); + IFT(pInjectedSource->get_source(0, &cbData, nullptr)); + + tempString.resize(cbData); + IFT(pInjectedSource->get_source( + cbData, &cbData, reinterpret_cast(&tempString[0]))); + + CA2W tempWString(tempString.data()); + o << tempWString.m_psz; + } + pSymbolUnk.Release(); + } + + return o.str(); + } + + struct LineNumber { + DWORD line; + DWORD rva; + }; + std::vector + ReadLineNumbers(IDiaEnumLineNumbers *pEnumLineNumbers) { + std::vector lines; + CComPtr pLineNumber; + DWORD lineCount; + while (SUCCEEDED(pEnumLineNumbers->Next(1, &pLineNumber, &lineCount)) && + lineCount == 1) { + DWORD line; + DWORD rva; + VERIFY_SUCCEEDED(pLineNumber->get_lineNumber(&line)); + VERIFY_SUCCEEDED(pLineNumber->get_relativeVirtualAddress(&rva)); + lines.push_back({line, rva}); + pLineNumber.Release(); + } + return lines; + } + + HRESULT CreateDiaSourceForCompile(const char *hlsl, + IDiaDataSource **ppDiaSource) { + if (!ppDiaSource) + return E_POINTER; + + CComPtr pCompiler; + CComPtr pResult; + CComPtr pSource; + CComPtr pProgram; + + VERIFY_SUCCEEDED(CreateCompiler(m_dllSupport, &pCompiler)); + CreateBlobFromText(m_dllSupport, hlsl, &pSource); + LPCWSTR args[] = {L"/Zi", L"/Qembed_debug", L"/Od"}; + VERIFY_SUCCEEDED(pCompiler->Compile(pSource, L"source.hlsl", L"main", + L"ps_6_0", args, _countof(args), + nullptr, 0, nullptr, &pResult)); + + HRESULT compilationStatus; + VERIFY_SUCCEEDED(pResult->GetStatus(&compilationStatus)); + if (FAILED(compilationStatus)) { + CComPtr pErrros; + VERIFY_SUCCEEDED(pResult->GetErrorBuffer(&pErrros)); + CA2W errorTextW(static_cast(pErrros->GetBufferPointer()), + CP_UTF8); + WEX::Logging::Log::Error(errorTextW); + } + + VERIFY_SUCCEEDED(pResult->GetResult(&pProgram)); + + // Disassemble the compiled (stripped) program. + { + CComPtr pDisassembly; + VERIFY_SUCCEEDED(pCompiler->Disassemble(pProgram, &pDisassembly)); + std::string disText = BlobToUtf8(pDisassembly); + CA2W disTextW(disText.c_str(), CP_UTF8); + // WEX::Logging::Log::Comment(disTextW); + } + + auto annotated = WrapInNewContainer( + m_dllSupport, RunAnnotationPasses(m_dllSupport, pProgram).blob); + + // CONSIDER: have the dia data source look for the part if passed a whole + // container. + CComPtr pDiaSource; + CComPtr pProgramStream; + CComPtr pLib; + VERIFY_SUCCEEDED(m_dllSupport.CreateInstance(CLSID_DxcLibrary, &pLib)); + const hlsl::DxilContainerHeader *pContainer = hlsl::IsDxilContainerLike( + annotated->GetBufferPointer(), annotated->GetBufferSize()); + VERIFY_IS_NOT_NULL(pContainer); + hlsl::DxilPartIterator partIter = + std::find_if(hlsl::begin(pContainer), hlsl::end(pContainer), + hlsl::DxilPartIsType(hlsl::DFCC_ShaderDebugInfoDXIL)); + const hlsl::DxilProgramHeader *pProgramHeader = + (const hlsl::DxilProgramHeader *)hlsl::GetDxilPartData(*partIter); + uint32_t bitcodeLength; + const char *pBitcode; + CComPtr pProgramPdb; + hlsl::GetDxilProgramBitcode(pProgramHeader, &pBitcode, &bitcodeLength); + VERIFY_SUCCEEDED(pLib->CreateBlobFromBlob( + annotated, pBitcode - (char *)annotated->GetBufferPointer(), + bitcodeLength, &pProgramPdb)); + + // Disassemble the program with debug information. + { + CComPtr pDbgDisassembly; + VERIFY_SUCCEEDED(pCompiler->Disassemble(pProgramPdb, &pDbgDisassembly)); + std::string disText = BlobToUtf8(pDbgDisassembly); + CA2W disTextW(disText.c_str(), CP_UTF8); + // WEX::Logging::Log::Comment(disTextW); + } + + // Create a short text dump of debug information. + VERIFY_SUCCEEDED( + pLib->CreateStreamFromBlobReadOnly(pProgramPdb, &pProgramStream)); + VERIFY_SUCCEEDED( + m_dllSupport.CreateInstance(CLSID_DxcDiaDataSource, &pDiaSource)); + VERIFY_SUCCEEDED(pDiaSource->loadDataFromIStream(pProgramStream)); + *ppDiaSource = pDiaSource.Detach(); + return S_OK; + } + + void CompileAndRunAnnotationAndGetDebugPart( + dxc::DxcDllSupport &dllSupport, const char *source, + const wchar_t *profile, IDxcIncludeHandler *includer, + IDxcBlob **ppDebugPart, std::vector extraArgs = {}); + void CompileAndRunAnnotationAndLoadDiaSource( + dxc::DxcDllSupport &dllSupport, const char *source, + const wchar_t *profile, IDxcIncludeHandler *includer, + IDiaDataSource **ppDataSource, + std::vector extraArgs = {}); + + struct VariableComponentInfo { + std::wstring Name; + std::wstring Type; + }; + + void TestGlobalStaticCase( + const char *hlsl, const wchar_t *profile, + const char *lineAtWhichToExamineVariables, + std::vector const &ExpectedVariables); + CComPtr + CompileAndCreateDxcDebug(const char *hlsl, const wchar_t *profile, + IDxcIncludeHandler *includer = nullptr); + + CComPtr + GetLiveVariablesAt(const char *hlsl, + const char *lineAtWhichToExamineVariables, + IDxcPixDxilDebugInfo *dxilDebugger); +}; + +static bool AddStorageComponents( + IDxcPixDxilStorage *pStorage, std::wstring Name, + std::vector &VariableComponents) { + CComPtr StorageType; + if (FAILED(pStorage->GetType(&StorageType))) { + return false; + } + + CComPtr UnAliasedType; + if (FAILED(UnAliasType(StorageType, &UnAliasedType))) { + return false; + } + + CComPtr ArrayType; + CComPtr ScalarType; + CComPtr StructType; + + if (!FAILED(UnAliasedType->QueryInterface(&ScalarType))) { + CComBSTR TypeName; + // StorageType is the type that the storage was defined in HLSL, i.e., + // it could be a typedef, const etc. + if (FAILED(StorageType->GetName(&TypeName))) { + return false; + } + + VariableComponents.emplace_back(PixDiaTest::VariableComponentInfo{ + std::move(Name), std::wstring(TypeName)}); + return true; + } else if (!FAILED(UnAliasedType->QueryInterface(&ArrayType))) { + DWORD NumElements; + if (FAILED(ArrayType->GetNumElements(&NumElements))) { + return false; + } + + std::wstring BaseName = Name + L'['; + for (DWORD i = 0; i < NumElements; ++i) { + CComPtr EntryStorage; + if (FAILED(pStorage->Index(i, &EntryStorage))) { + return false; + } + + if (!AddStorageComponents(EntryStorage, + BaseName + std::to_wstring(i) + L"]", + VariableComponents)) { + return false; + } + } + } else if (!FAILED(UnAliasedType->QueryInterface(&StructType))) { + DWORD NumFields; + if (FAILED(StructType->GetNumFields(&NumFields))) { + return false; + } + + std::wstring BaseName = Name + L'.'; + for (DWORD i = 0; i < NumFields; ++i) { + CComPtr Field; + if (FAILED(StructType->GetFieldByIndex(i, &Field))) { + return false; + } + + CComBSTR FieldName; + if (FAILED(Field->GetName(&FieldName))) { + return false; + } + + CComPtr FieldStorage; + if (FAILED(pStorage->AccessField(FieldName, &FieldStorage))) { + return false; + } + + if (!AddStorageComponents(FieldStorage, + BaseName + std::wstring(FieldName), + VariableComponents)) { + return false; + } + } + + CComPtr BaseType; + if (SUCCEEDED(StructType->GetBaseType(&BaseType))) { + CComPtr BaseStorage; + if (FAILED(pStorage->AccessField(L"", &BaseStorage))) { + return false; + } + if (!AddStorageComponents(BaseStorage, Name, VariableComponents)) { + return false; + } + } + } + + return true; +} + +bool PixDiaTest::InitSupport() { + if (!m_dllSupport.IsEnabled()) { + VERIFY_SUCCEEDED(m_dllSupport.Initialize()); + m_ver.Initialize(m_dllSupport); + } + return true; +} + +void PixDiaTest::CompileAndRunAnnotationAndGetDebugPart( + dxc::DxcDllSupport &dllSupport, const char *source, const wchar_t *profile, + IDxcIncludeHandler *includer, IDxcBlob **ppDebugPart, + std::vector extraArgs) { + + CComPtr pContainer; + std::vector args; + args.push_back(L"/Zi"); + args.push_back(L"/Qembed_debug"); + args.insert(args.end(), extraArgs.begin(), extraArgs.end()); + + CompileAndLogErrors(dllSupport, source, profile, args, includer, &pContainer); + + auto annotated = RunAnnotationPasses(m_dllSupport, pContainer); + + CComPtr pNewContainer = + WrapInNewContainer(m_dllSupport, annotated.blob); + + *ppDebugPart = GetDebugPart(dllSupport, pNewContainer).Detach(); +} + +CComPtr +PixDiaTest::CompileAndCreateDxcDebug(const char *hlsl, const wchar_t *profile, + IDxcIncludeHandler *includer) { + + CComPtr pDiaDataSource; + CompileAndRunAnnotationAndLoadDiaSource(m_dllSupport, hlsl, profile, includer, + &pDiaDataSource, {L"-Od"}); + + CComPtr session; + VERIFY_SUCCEEDED(pDiaDataSource->openSession(&session)); + + CComPtr Factory; + VERIFY_SUCCEEDED(session->QueryInterface(IID_PPV_ARGS(&Factory))); + + CComPtr dxilDebugger; + VERIFY_SUCCEEDED(Factory->NewDxcPixDxilDebugInfo(&dxilDebugger)); + return dxilDebugger; +} + +CComPtr +PixDiaTest::GetLiveVariablesAt(const char *hlsl, + const char *lineAtWhichToExamineVariables, + IDxcPixDxilDebugInfo *dxilDebugger) { + + auto lines = SplitAndPreserveEmptyLines(std::string(hlsl), '\n'); + auto FindInterestingLine = std::find_if( + lines.begin(), lines.end(), + [&lineAtWhichToExamineVariables](std::string const &line) { + return line.find(lineAtWhichToExamineVariables) != std::string::npos; + }); + auto InterestingLine = + static_cast(FindInterestingLine - lines.begin()) + 1; + + CComPtr liveVariables; + for (; InterestingLine <= static_cast(lines.size()); + ++InterestingLine) { + CComPtr instructionOffsets; + if (SUCCEEDED(dxilDebugger->InstructionOffsetsFromSourceLocation( + defaultFilename, InterestingLine, 0, &instructionOffsets))) { + if (instructionOffsets->GetCount() > 0) { + auto instructionOffset = instructionOffsets->GetOffsetByIndex(0); + if (SUCCEEDED(dxilDebugger->GetLiveVariablesAt(instructionOffset, + &liveVariables))) { + break; + } + } + } + } + VERIFY_IS_TRUE(liveVariables != nullptr); + + return liveVariables; +} + +static bool +ContainedBy(std::vector const &v1, + std::vector const &v2) { + for (auto const &c1 : v1) { + bool FoundThis = false; + for (auto const &c2 : v2) { + if (c1.Name == c2.Name && c1.Type == c2.Type) { + FoundThis = true; + break; + } + } + if (!FoundThis) { + return false; + } + } + return true; +} + +void PixDiaTest::TestGlobalStaticCase( + const char *hlsl, const wchar_t *profile, + const char *lineAtWhichToExamineVariables, + std::vector const &ExpectedVariables) { + + auto dxilDebugger = CompileAndCreateDxcDebug(hlsl, profile); + + auto liveVariables = + GetLiveVariablesAt(hlsl, lineAtWhichToExamineVariables, dxilDebugger); + + DWORD count; + VERIFY_SUCCEEDED(liveVariables->GetCount(&count)); + bool FoundGlobal = false; + for (DWORD i = 0; i < count; ++i) { + CComPtr variable; + VERIFY_SUCCEEDED(liveVariables->GetVariableByIndex(i, &variable)); + CComBSTR name; + variable->GetName(&name); + if (0 == wcscmp(name, L"global.globalStruct")) { + FoundGlobal = true; + CComPtr storage; + VERIFY_SUCCEEDED(variable->GetStorage(&storage)); + std::vector ActualVariableComponents; + VERIFY_IS_TRUE(AddStorageComponents(storage, L"global.globalStruct", + ActualVariableComponents)); + VERIFY_IS_TRUE(ContainedBy(ActualVariableComponents, ExpectedVariables)); + break; + } + } + VERIFY_IS_TRUE(FoundGlobal); +} + +TEST_F(PixDiaTest, CompileWhenDebugThenDIPresent) { + // BUG: the first test written was of this form: + // float4 local = 0; return local; + // + // However we get no numbers because of the _wrapper form + // that exports the zero initialization from main into + // a global can't be attributed to any particular location + // within main, and everything in main is eventually folded away. + // + // Making the function do a bit more work by calling an intrinsic + // helps this case. + CComPtr pDiaSource; + VERIFY_SUCCEEDED(CreateDiaSourceForCompile( + "float4 main(float4 pos : SV_Position) : SV_Target {\r\n" + " float4 local = abs(pos);\r\n" + " return local;\r\n" + "}", + &pDiaSource)); + std::wstring diaDump = GetDebugInfoAsText(pDiaSource).c_str(); + // WEX::Logging::Log::Comment(GetDebugInfoAsText(pDiaSource).c_str()); + + // Very basic tests - we have basic symbols, line numbers, and files with + // sources. + VERIFY_IS_NOT_NULL(wcsstr(diaDump.c_str(), + L"symIndexId: 5, CompilandEnv, name: hlslTarget, " + L"lexicalParent: id=2, value: ps_6_0")); + VERIFY_IS_NOT_NULL(wcsstr(diaDump.c_str(), L"lineNumber: 2")); + VERIFY_IS_NOT_NULL( + wcsstr(diaDump.c_str(), L"length: 99, filename: source.hlsl")); + std::wstring diaFileContent = GetDebugFileContent(pDiaSource).c_str(); + VERIFY_IS_NOT_NULL( + wcsstr(diaFileContent.c_str(), + L"loat4 main(float4 pos : SV_Position) : SV_Target")); +#if SUPPORT_FXC_PDB + // Now, fake it by loading from a .pdb! + VERIFY_SUCCEEDED(CoInitializeEx(0, COINITBASE_MULTITHREADED)); + const wchar_t path[] = L"path-to-fxc-blob.bin"; + pDiaSource.Release(); + pProgramStream.Release(); + CComPtr fxcBlob; + CComPtr pdbBlob; + VERIFY_SUCCEEDED(pLib->CreateBlobFromFile(path, nullptr, &fxcBlob)); + std::string s = DumpParts(fxcBlob); + CA2W sW(s.c_str(), CP_UTF8); + WEX::Logging::Log::Comment(sW); + VERIFY_SUCCEEDED(CreateDiaSourceFromDxbcBlob(pLib, fxcBlob, &pDiaSource)); + WEX::Logging::Log::Comment(GetDebugInfoAsText(pDiaSource).c_str()); +#endif +} + +// Test that the new PDB format still works with Dia +TEST_F(PixDiaTest, CompileDebugPDB) { + const char *hlsl = R"( + [RootSignature("")] + float main(float pos : A) : SV_Target { + float x = abs(pos); + float y = sin(pos); + float z = x + y; + return z; + } + )"; + CComPtr pLib; + VERIFY_SUCCEEDED(m_dllSupport.CreateInstance(CLSID_DxcLibrary, &pLib)); + + CComPtr pCompiler; + CComPtr pCompiler2; + + CComPtr pResult; + CComPtr pSource; + CComPtr pProgram; + CComPtr pPdbBlob; + CComHeapPtr pDebugName; + + VERIFY_SUCCEEDED(CreateCompiler(m_dllSupport, &pCompiler)); + VERIFY_SUCCEEDED(pCompiler.QueryInterface(&pCompiler2)); + CreateBlobFromText(m_dllSupport, hlsl, &pSource); + LPCWSTR args[] = {L"/Zi", L"/Qembed_debug"}; + VERIFY_SUCCEEDED(pCompiler2->CompileWithDebug( + pSource, L"source.hlsl", L"main", L"ps_6_0", args, _countof(args), + nullptr, 0, nullptr, &pResult, &pDebugName, &pPdbBlob)); + VERIFY_SUCCEEDED(pResult->GetResult(&pProgram)); + + CComPtr pDiaSource; + CComPtr pProgramStream; + + VERIFY_SUCCEEDED( + pLib->CreateStreamFromBlobReadOnly(pPdbBlob, &pProgramStream)); + VERIFY_SUCCEEDED( + m_dllSupport.CreateInstance(CLSID_DxcDiaDataSource, &pDiaSource)); + VERIFY_SUCCEEDED(pDiaSource->loadDataFromIStream(pProgramStream)); + + // Test that IDxcContainerReflection can consume a PDB container + CComPtr pReflection; + VERIFY_SUCCEEDED( + m_dllSupport.CreateInstance(CLSID_DxcContainerReflection, &pReflection)); + VERIFY_SUCCEEDED(pReflection->Load(pPdbBlob)); + + UINT32 uDebugInfoIndex = 0; + VERIFY_SUCCEEDED(pReflection->FindFirstPartKind( + hlsl::DFCC_ShaderDebugInfoDXIL, &uDebugInfoIndex)); +} + +TEST_F(PixDiaTest, DiaLoadBadBitcodeThenFail) { + CComPtr pBadBitcode; + CComPtr pDiaSource; + CComPtr pStream; + CComPtr pLib; + + Utf8ToBlob(m_dllSupport, "badcode", &pBadBitcode); + VERIFY_SUCCEEDED(m_dllSupport.CreateInstance(CLSID_DxcLibrary, &pLib)); + VERIFY_SUCCEEDED(pLib->CreateStreamFromBlobReadOnly(pBadBitcode, &pStream)); + VERIFY_SUCCEEDED( + m_dllSupport.CreateInstance(CLSID_DxcDiaDataSource, &pDiaSource)); + VERIFY_FAILED(pDiaSource->loadDataFromIStream(pStream)); +} + +static void CompileTestAndLoadDiaSource(dxc::DxcDllSupport &dllSupport, + const char *source, + const wchar_t *profile, + IDiaDataSource **ppDataSource) { + CComPtr pDebugContent; + CComPtr pStream; + CComPtr pDiaSource; + CComPtr pLib; + VERIFY_SUCCEEDED(dllSupport.CreateInstance(CLSID_DxcLibrary, &pLib)); + + CompileAndGetDebugPart(dllSupport, source, profile, &pDebugContent); + VERIFY_SUCCEEDED(pLib->CreateStreamFromBlobReadOnly(pDebugContent, &pStream)); + VERIFY_SUCCEEDED( + dllSupport.CreateInstance(CLSID_DxcDiaDataSource, &pDiaSource)); + VERIFY_SUCCEEDED(pDiaSource->loadDataFromIStream(pStream)); + if (ppDataSource) { + *ppDataSource = pDiaSource.Detach(); + } +} + +static void CompileTestAndLoadDia(dxc::DxcDllSupport &dllSupport, + IDiaDataSource **ppDataSource) { + CompileTestAndLoadDiaSource(dllSupport, "[numthreads(8,8,1)] void main() { }", + L"cs_6_0", ppDataSource); +} + +TEST_F(PixDiaTest, DiaLoadDebugSubrangeNegativeThenOK) { + static const char source[] = R"( + SamplerState samp0 : register(s0); + Texture2DArray tex0 : register(t0); + + float4 foo(Texture2DArray textures[], int idx, SamplerState samplerState, float3 uvw) { + return textures[NonUniformResourceIndex(idx)].Sample(samplerState, uvw); + } + + [RootSignature( "DescriptorTable(SRV(t0)), DescriptorTable(Sampler(s0)) " )] + float4 main(int index : INDEX, float3 uvw : TEXCOORD) : SV_Target { + Texture2DArray textures[] = { + tex0, + }; + return foo(textures, index, samp0, uvw); + } + )"; + + CComPtr pDiaDataSource; + CComPtr pDiaSession; + CompileTestAndLoadDiaSource(m_dllSupport, source, L"ps_6_0", &pDiaDataSource); + + VERIFY_SUCCEEDED(pDiaDataSource->openSession(&pDiaSession)); +} + +TEST_F(PixDiaTest, DiaLoadRelocatedBitcode) { + + static const char source[] = R"( + SamplerState samp0 : register(s0); + Texture2DArray tex0 : register(t0); + + float4 foo(Texture2DArray textures[], int idx, SamplerState samplerState, float3 uvw) { + return textures[NonUniformResourceIndex(idx)].Sample(samplerState, uvw); + } + + [RootSignature( "DescriptorTable(SRV(t0)), DescriptorTable(Sampler(s0)) " )] + float4 main(int index : INDEX, float3 uvw : TEXCOORD) : SV_Target { + Texture2DArray textures[] = { + tex0, + }; + return foo(textures, index, samp0, uvw); + } + )"; + + CComPtr pPart; + CComPtr pDiaSource; + CComPtr pStream; + + CComPtr pLib; + VERIFY_SUCCEEDED(m_dllSupport.CreateInstance(CLSID_DxcLibrary, &pLib)); + + CompileAndGetDebugPart(m_dllSupport, source, L"ps_6_0", &pPart); + const char *pPartData = (char *)pPart->GetBufferPointer(); + + // Get program header + const hlsl::DxilProgramHeader *programHeader = + (const hlsl::DxilProgramHeader *)pPartData; + + const char *pBitcode = nullptr; + uint32_t uBitcodeSize = 0; + hlsl::GetDxilProgramBitcode(programHeader, &pBitcode, &uBitcodeSize); + VERIFY_IS_TRUE(uBitcodeSize % sizeof(UINT32) == 0); + + size_t uNewGapSize = + 4 * 10; // Size of some bytes between program header and bitcode + size_t uNewSuffixeBytes = + 4 * 10; // Size of some random bytes after the program + + hlsl::DxilProgramHeader newProgramHeader = {}; + memcpy(&newProgramHeader, programHeader, sizeof(newProgramHeader)); + newProgramHeader.BitcodeHeader.BitcodeOffset = + uNewGapSize + sizeof(newProgramHeader.BitcodeHeader); + + unsigned uNewSizeInBytes = + sizeof(newProgramHeader) + uNewGapSize + uBitcodeSize + uNewSuffixeBytes; + VERIFY_IS_TRUE(uNewSizeInBytes % sizeof(UINT32) == 0); + newProgramHeader.SizeInUint32 = uNewSizeInBytes / sizeof(UINT32); + + llvm::SmallVector buffer; + llvm::raw_svector_ostream OS(buffer); + + // Write the header + OS.write((char *)&newProgramHeader, sizeof(newProgramHeader)); + + // Write some garbage between the header and the bitcode + for (unsigned i = 0; i < uNewGapSize; i++) { + OS.write(0xFF); + } + + // Write the actual bitcode + OS.write(pBitcode, uBitcodeSize); + + // Write some garbage after the bitcode + for (unsigned i = 0; i < uNewSuffixeBytes; i++) { + OS.write(0xFF); + } + OS.flush(); + + // Try to load this new program, make sure dia is still okay. + CComPtr pNewProgramBlob; + VERIFY_SUCCEEDED(pLib->CreateBlobWithEncodingFromPinned( + buffer.data(), buffer.size(), CP_ACP, &pNewProgramBlob)); + + CComPtr pNewProgramStream; + VERIFY_SUCCEEDED( + pLib->CreateStreamFromBlobReadOnly(pNewProgramBlob, &pNewProgramStream)); + + CComPtr pDiaDataSource; + VERIFY_SUCCEEDED( + m_dllSupport.CreateInstance(CLSID_DxcDiaDataSource, &pDiaDataSource)); + + VERIFY_SUCCEEDED(pDiaDataSource->loadDataFromIStream(pNewProgramStream)); +} + +TEST_F(PixDiaTest, DiaCompileArgs) { + static const char source[] = R"( + SamplerState samp0 : register(s0); + Texture2DArray tex0 : register(t0); + + float4 foo(Texture2DArray textures[], int idx, SamplerState samplerState, float3 uvw) { + return textures[NonUniformResourceIndex(idx)].Sample(samplerState, uvw); + } + + [RootSignature( "DescriptorTable(SRV(t0)), DescriptorTable(Sampler(s0)) " )] + float4 main(int index : INDEX, float3 uvw : TEXCOORD) : SV_Target { + Texture2DArray textures[] = { + tex0, + }; + return foo(textures, index, samp0, uvw); + } + )"; + + CComPtr pPart; + CComPtr pDiaSource; + CComPtr pStream; + + CComPtr pLib; + VERIFY_SUCCEEDED(m_dllSupport.CreateInstance(CLSID_DxcLibrary, &pLib)); + + const WCHAR *FlagList[] = { + L"/Zi", L"-Zpr", L"/Qembed_debug", L"/Fd", + L"F:\\my dir\\", L"-Fo", L"F:\\my dir\\file.dxc", + }; + const WCHAR *DefineList[] = { + L"MY_SPECIAL_DEFINE", + L"MY_OTHER_SPECIAL_DEFINE=\"MY_STRING\"", + }; + + std::vector args; + for (unsigned i = 0; i < _countof(FlagList); i++) { + args.push_back(FlagList[i]); + } + for (unsigned i = 0; i < _countof(DefineList); i++) { + args.push_back(L"/D"); + args.push_back(DefineList[i]); + } + auto CompileAndGetDebugPart = [&args](dxc::DxcDllSupport &dllSupport, + const char *source, + const wchar_t *profile, + IDxcBlob **ppDebugPart) { + CComPtr pContainer; + CComPtr pLib; + CComPtr pReflection; + UINT32 index; + + VerifyCompileOK(dllSupport, source, profile, args, &pContainer); + VERIFY_SUCCEEDED(dllSupport.CreateInstance(CLSID_DxcLibrary, &pLib)); + VERIFY_SUCCEEDED( + dllSupport.CreateInstance(CLSID_DxcContainerReflection, &pReflection)); + VERIFY_SUCCEEDED(pReflection->Load(pContainer)); + VERIFY_SUCCEEDED( + pReflection->FindFirstPartKind(hlsl::DFCC_ShaderDebugInfoDXIL, &index)); + VERIFY_SUCCEEDED(pReflection->GetPartContent(index, ppDebugPart)); + }; + CompileAndGetDebugPart(m_dllSupport, source, L"ps_6_0", &pPart); + + CComPtr pNewProgramStream; + VERIFY_SUCCEEDED( + pLib->CreateStreamFromBlobReadOnly(pPart, &pNewProgramStream)); + + CComPtr pDiaDataSource; + VERIFY_SUCCEEDED( + m_dllSupport.CreateInstance(CLSID_DxcDiaDataSource, &pDiaDataSource)); + + VERIFY_SUCCEEDED(pDiaDataSource->loadDataFromIStream(pNewProgramStream)); + + CComPtr pSession; + VERIFY_SUCCEEDED(pDiaDataSource->openSession(&pSession)); + + CComPtr pEnumTables; + VERIFY_SUCCEEDED(pSession->getEnumTables(&pEnumTables)); + + CComPtr pSymbolTable; + + LONG uCount = 0; + VERIFY_SUCCEEDED(pEnumTables->get_Count(&uCount)); + for (int i = 0; i < uCount; i++) { + CComPtr pTable; + VARIANT index = {}; + index.vt = VT_I4; + index.intVal = i; + VERIFY_SUCCEEDED(pEnumTables->Item(index, &pTable)); + + CComBSTR pName; + VERIFY_SUCCEEDED(pTable->get_name(&pName)); + + if (pName == "Symbols") { + pSymbolTable = pTable; + break; + } + } + + std::wstring Args; + std::wstring Entry; + std::wstring Target; + std::vector Defines; + std::vector Flags; + + auto ReadNullSeparatedTokens = [](BSTR Str) -> std::vector { + std::vector Result; + while (*Str) { + Result.push_back(std::wstring(Str)); + Str += wcslen(Str) + 1; + } + return Result; + }; + + VERIFY_SUCCEEDED(pSymbolTable->get_Count(&uCount)); + for (int i = 0; i < uCount; i++) { + CComPtr pSymbolUnk; + CComPtr pSymbol; + CComVariant pValue; + CComBSTR pName; + VERIFY_SUCCEEDED(pSymbolTable->Item(i, &pSymbolUnk)); + VERIFY_SUCCEEDED(pSymbolUnk->QueryInterface(&pSymbol)); + VERIFY_SUCCEEDED(pSymbol->get_name(&pName)); + VERIFY_SUCCEEDED(pSymbol->get_value(&pValue)); + if (pName == "hlslTarget") { + if (pValue.vt == VT_BSTR) + Target = pValue.bstrVal; + } else if (pName == "hlslEntry") { + if (pValue.vt == VT_BSTR) + Entry = pValue.bstrVal; + } else if (pName == "hlslFlags") { + if (pValue.vt == VT_BSTR) + Flags = ReadNullSeparatedTokens(pValue.bstrVal); + } else if (pName == "hlslArguments") { + if (pValue.vt == VT_BSTR) + Args = pValue.bstrVal; + } else if (pName == "hlslDefines") { + if (pValue.vt == VT_BSTR) + Defines = ReadNullSeparatedTokens(pValue.bstrVal); + } + } + + auto VectorContains = [](std::vector &Tokens, + std::wstring Sub) { + for (unsigned i = 0; i < Tokens.size(); i++) { + if (Tokens[i].find(Sub) != std::wstring::npos) + return true; + } + return false; + }; + + VERIFY_IS_TRUE(Target == L"ps_6_0"); + VERIFY_IS_TRUE(Entry == L"main"); + + VERIFY_IS_TRUE(_countof(FlagList) == Flags.size()); + for (unsigned i = 0; i < _countof(FlagList); i++) { + VERIFY_IS_TRUE(Flags[i] == FlagList[i]); + } + for (unsigned i = 0; i < _countof(DefineList); i++) { + VERIFY_IS_TRUE(VectorContains(Defines, DefineList[i])); + } +} + +TEST_F(PixDiaTest, DiaLoadBitcodePlusExtraData) { + // Test that dia doesn't crash when bitcode has unused extra data at the end + + static const char source[] = R"( + SamplerState samp0 : register(s0); + Texture2DArray tex0 : register(t0); + + float4 foo(Texture2DArray textures[], int idx, SamplerState samplerState, float3 uvw) { + return textures[NonUniformResourceIndex(idx)].Sample(samplerState, uvw); + } + + [RootSignature( "DescriptorTable(SRV(t0)), DescriptorTable(Sampler(s0)) " )] + float4 main(int index : INDEX, float3 uvw : TEXCOORD) : SV_Target { + Texture2DArray textures[] = { + tex0, + }; + return foo(textures, index, samp0, uvw); + } + )"; + + CComPtr pPart; + CComPtr pDiaSource; + CComPtr pStream; + + CComPtr pLib; + VERIFY_SUCCEEDED(m_dllSupport.CreateInstance(CLSID_DxcLibrary, &pLib)); + + CompileAndGetDebugPart(m_dllSupport, source, L"ps_6_0", &pPart); + const char *pPartData = (char *)pPart->GetBufferPointer(); + + // Get program header + const hlsl::DxilProgramHeader *programHeader = + (const hlsl::DxilProgramHeader *)pPartData; + + const char *pBitcode = nullptr; + uint32_t uBitcodeSize = 0; + hlsl::GetDxilProgramBitcode(programHeader, &pBitcode, &uBitcodeSize); + + llvm::SmallVector buffer; + llvm::raw_svector_ostream OS(buffer); + + // Write the bitcode + OS.write(pBitcode, uBitcodeSize); + for (unsigned i = 0; i < 12; i++) { + OS.write(0xFF); + } + OS.flush(); + + // Try to load this new program, make sure dia is still okay. + CComPtr pNewProgramBlob; + VERIFY_SUCCEEDED(pLib->CreateBlobWithEncodingFromPinned( + buffer.data(), buffer.size(), CP_ACP, &pNewProgramBlob)); + + CComPtr pNewProgramStream; + VERIFY_SUCCEEDED( + pLib->CreateStreamFromBlobReadOnly(pNewProgramBlob, &pNewProgramStream)); + + CComPtr pDiaDataSource; + VERIFY_SUCCEEDED( + m_dllSupport.CreateInstance(CLSID_DxcDiaDataSource, &pDiaDataSource)); + + VERIFY_SUCCEEDED(pDiaDataSource->loadDataFromIStream(pNewProgramStream)); +} + +TEST_F(PixDiaTest, DiaLoadDebugThenOK) { + CompileTestAndLoadDia(m_dllSupport, nullptr); +} + +TEST_F(PixDiaTest, DiaTableIndexThenOK) { + CComPtr pDiaSource; + CComPtr pDiaSession; + CComPtr pEnumTables; + CComPtr pTable; + VARIANT vtIndex; + CompileTestAndLoadDia(m_dllSupport, &pDiaSource); + VERIFY_SUCCEEDED(pDiaSource->openSession(&pDiaSession)); + VERIFY_SUCCEEDED(pDiaSession->getEnumTables(&pEnumTables)); + + vtIndex.vt = VT_EMPTY; + VERIFY_FAILED(pEnumTables->Item(vtIndex, &pTable)); + + vtIndex.vt = VT_I4; + vtIndex.intVal = 1; + VERIFY_SUCCEEDED(pEnumTables->Item(vtIndex, &pTable)); + VERIFY_IS_NOT_NULL(pTable.p); + pTable.Release(); + + vtIndex.vt = VT_UI4; + vtIndex.uintVal = 1; + VERIFY_SUCCEEDED(pEnumTables->Item(vtIndex, &pTable)); + VERIFY_IS_NOT_NULL(pTable.p); + pTable.Release(); + + vtIndex.uintVal = 100; + VERIFY_FAILED(pEnumTables->Item(vtIndex, &pTable)); +} + +TEST_F(PixDiaTest, PixDebugCompileInfo) { + static const char source[] = R"( + SamplerState samp0 : register(s0); + Texture2DArray tex0 : register(t0); + + float4 foo(Texture2DArray textures[], int idx, SamplerState samplerState, float3 uvw) { + return textures[NonUniformResourceIndex(idx)].Sample(samplerState, uvw); + } + + [RootSignature( "DescriptorTable(SRV(t0)), DescriptorTable(Sampler(s0)) " )] + float4 main(int index : INDEX, float3 uvw : TEXCOORD) : SV_Target { + Texture2DArray textures[] = { + tex0, + }; + return foo(textures, index, samp0, uvw); + } + )"; + + CComPtr pPart; + CComPtr pDiaSource; + CComPtr pStream; + + CComPtr pLib; + VERIFY_SUCCEEDED(m_dllSupport.CreateInstance(CLSID_DxcLibrary, &pLib)); + + const WCHAR *FlagList[] = { + L"/Zi", L"-Zpr", L"/Qembed_debug", L"/Fd", + L"F:\\my dir\\", L"-Fo", L"F:\\my dir\\file.dxc", + }; + const WCHAR *DefineList[] = { + L"MY_SPECIAL_DEFINE", + L"MY_OTHER_SPECIAL_DEFINE=\"MY_STRING\"", + }; + + std::vector args; + for (unsigned i = 0; i < _countof(FlagList); i++) { + args.push_back(FlagList[i]); + } + for (unsigned i = 0; i < _countof(DefineList); i++) { + args.push_back(L"/D"); + args.push_back(DefineList[i]); + } + + auto CompileAndGetDebugPart = [&args](dxc::DxcDllSupport &dllSupport, + const char *source, + const wchar_t *profile, + IDxcBlob **ppDebugPart) { + CComPtr pContainer; + CComPtr pLib; + CComPtr pReflection; + UINT32 index; + + VerifyCompileOK(dllSupport, source, profile, args, &pContainer); + VERIFY_SUCCEEDED(dllSupport.CreateInstance(CLSID_DxcLibrary, &pLib)); + VERIFY_SUCCEEDED( + dllSupport.CreateInstance(CLSID_DxcContainerReflection, &pReflection)); + VERIFY_SUCCEEDED(pReflection->Load(pContainer)); + VERIFY_SUCCEEDED( + pReflection->FindFirstPartKind(hlsl::DFCC_ShaderDebugInfoDXIL, &index)); + VERIFY_SUCCEEDED(pReflection->GetPartContent(index, ppDebugPart)); + }; + + const wchar_t *profile = L"ps_6_0"; + CompileAndGetDebugPart(m_dllSupport, source, profile, &pPart); + + CComPtr pNewProgramStream; + VERIFY_SUCCEEDED( + pLib->CreateStreamFromBlobReadOnly(pPart, &pNewProgramStream)); + + CComPtr pDiaDataSource; + VERIFY_SUCCEEDED( + m_dllSupport.CreateInstance(CLSID_DxcDiaDataSource, &pDiaDataSource)); + + VERIFY_SUCCEEDED(pDiaDataSource->loadDataFromIStream(pNewProgramStream)); + + CComPtr pSession; + VERIFY_SUCCEEDED(pDiaDataSource->openSession(&pSession)); + + CComPtr factory; + VERIFY_SUCCEEDED(pSession->QueryInterface(IID_PPV_ARGS(&factory))); + + CComPtr compilationInfo; + VERIFY_SUCCEEDED(factory->NewDxcPixCompilationInfo(&compilationInfo)); + + CComBSTR arguments; + VERIFY_SUCCEEDED(compilationInfo->GetArguments(&arguments)); + for (unsigned i = 0; i < _countof(FlagList); i++) { + VERIFY_IS_TRUE(nullptr != wcsstr(arguments, FlagList[i])); + } + + CComBSTR macros; + VERIFY_SUCCEEDED(compilationInfo->GetMacroDefinitions(¯os)); + for (unsigned i = 0; i < _countof(DefineList); i++) { + std::wstring MacroDef = std::wstring(L"-D") + DefineList[i]; + VERIFY_IS_TRUE(nullptr != wcsstr(macros, MacroDef.c_str())); + } + + CComBSTR entryPointFile; + VERIFY_SUCCEEDED(compilationInfo->GetEntryPointFile(&entryPointFile)); + VERIFY_ARE_EQUAL(std::wstring(L"source.hlsl"), std::wstring(entryPointFile)); + + CComBSTR entryPointFunction; + VERIFY_SUCCEEDED(compilationInfo->GetEntryPoint(&entryPointFunction)); + VERIFY_ARE_EQUAL(std::wstring(L"main"), std::wstring(entryPointFunction)); + + CComBSTR hlslTarget; + VERIFY_SUCCEEDED(compilationInfo->GetHlslTarget(&hlslTarget)); + VERIFY_ARE_EQUAL(std::wstring(profile), std::wstring(hlslTarget)); +} + +void PixDiaTest::CompileAndRunAnnotationAndLoadDiaSource( + dxc::DxcDllSupport &dllSupport, const char *source, const wchar_t *profile, + IDxcIncludeHandler *includer, IDiaDataSource **ppDataSource, + std::vector extraArgs) { + CComPtr pDebugContent; + CComPtr pStream; + CComPtr pDiaSource; + CComPtr pLib; + VERIFY_SUCCEEDED(dllSupport.CreateInstance(CLSID_DxcLibrary, &pLib)); + + CompileAndRunAnnotationAndGetDebugPart(dllSupport, source, profile, includer, + &pDebugContent, extraArgs); + VERIFY_SUCCEEDED(pLib->CreateStreamFromBlobReadOnly(pDebugContent, &pStream)); + VERIFY_SUCCEEDED( + dllSupport.CreateInstance(CLSID_DxcDiaDataSource, &pDiaSource)); + VERIFY_SUCCEEDED(pDiaSource->loadDataFromIStream(pStream)); + if (ppDataSource) { + *ppDataSource = pDiaSource.Detach(); + } +} + +TEST_F(PixDiaTest, PixTypeManager_InheritancePointerStruct) { + if (m_ver.SkipDxilVersion(1, 5)) + return; + + const char *hlsl = R"( +struct Base +{ + float floatValue; +}; + +struct Derived : Base +{ + int intValue; +}; + +RaytracingAccelerationStructure Scene : register(t0, space0); + +[shader("raygeneration")] +void main() +{ + RayDesc ray; + ray.Origin = float3(0,0,0); + ray.Direction = float3(0,0,1); + // Set TMin to a non-zero small value to avoid aliasing issues due to floating - point errors. + // TMin should be kept small to prevent missing geometry at close contact areas. + ray.TMin = 0.001; + ray.TMax = 10000.0; + Derived payload; + payload.floatValue = 1; + payload.intValue = 2; + TraceRay(Scene, RAY_FLAG_CULL_BACK_FACING_TRIANGLES, ~0, 0, 1, 0, ray, payload);} + +)"; + + CComPtr pDiaDataSource; + CComPtr pDiaSession; + CompileAndRunAnnotationAndLoadDiaSource(m_dllSupport, hlsl, L"lib_6_6", + nullptr, &pDiaDataSource); + + VERIFY_SUCCEEDED(pDiaDataSource->openSession(&pDiaSession)); +} + +TEST_F(PixDiaTest, PixTypeManager_MatricesInBase) { + if (m_ver.SkipDxilVersion(1, 5)) + return; + + const char *hlsl = R"( +struct Base +{ + float4x4 mat; +}; +typedef Base BaseTypedef; + +struct Derived : BaseTypedef +{ + int intValue; +}; + +RaytracingAccelerationStructure Scene : register(t0, space0); + +[shader("raygeneration")] +void main() +{ + RayDesc ray; + ray.Origin = float3(0,0,0); + ray.Direction = float3(0,0,1); + // Set TMin to a non-zero small value to avoid aliasing issues due to floating - point errors. + // TMin should be kept small to prevent missing geometry at close contact areas. + ray.TMin = 0.001; + ray.TMax = 10000.0; + Derived payload; + payload.mat[0][0] = 1; + payload.intValue = 2; + TraceRay(Scene, RAY_FLAG_CULL_BACK_FACING_TRIANGLES, ~0, 0, 1, 0, ray, payload);} + +)"; + + CComPtr pDiaDataSource; + CComPtr pDiaSession; + CompileAndRunAnnotationAndLoadDiaSource(m_dllSupport, hlsl, L"lib_6_6", + nullptr, &pDiaDataSource); + + VERIFY_SUCCEEDED(pDiaDataSource->openSession(&pDiaSession)); +} + +TEST_F(PixDiaTest, PixTypeManager_SamplersAndResources) { + if (m_ver.SkipDxilVersion(1, 5)) + return; + + const char *hlsl = R"( + +static const SamplerState SamplerRef = SamplerDescriptorHeap[1]; + +Texture3D Tex3DTemplated ; +Texture3D Tex3d ; +Texture2D Tex2D ; +Texture2D Tex2DTemplated ; +StructuredBuffer StructBuf ; +Texture2DArray Tex2DArray ; +Buffer Buff ; + +static const struct +{ + float AFloat; + SamplerState Samp1; + Texture3D Tex1; + Texture3D Tex2; + Texture2D Tex3; + Texture2D Tex4; + StructuredBuffer Buff1; + Texture2DArray Tex5; + Buffer Buff2; + float AnotherFloat; +} View = { +1, +SamplerRef, +Tex3DTemplated, +Tex3d, +Tex2D, +Tex2DTemplated, +StructBuf, +Tex2DArray, +Buff, +2 +}; + +struct Payload +{ + int intValue; +}; + +RaytracingAccelerationStructure Scene : register(t0, space0); + +[shader("raygeneration")] +void main() +{ + RayDesc ray; + ray.Origin = float3(0,0,0); + ray.Direction = float3(0,0,1); + ray.TMin = 0.001; + ray.TMax = 10000.0; + Payload payload; + payload.intValue = View.AFloat; + TraceRay(Scene, RAY_FLAG_CULL_BACK_FACING_TRIANGLES, ~0, 0, 1, 0, ray, payload);} +)"; + + CComPtr pDiaDataSource; + CComPtr pDiaSession; + CompileAndRunAnnotationAndLoadDiaSource(m_dllSupport, hlsl, L"lib_6_6", + nullptr, &pDiaDataSource); + + VERIFY_SUCCEEDED(pDiaDataSource->openSession(&pDiaSession)); +} + +TEST_F(PixDiaTest, PixTypeManager_XBoxDiaAssert) { + if (m_ver.SkipDxilVersion(1, 5)) + return; + + const char *hlsl = R"( +struct VSOut +{ + float4 vPosition : SV_POSITION; + float4 vLightAndFog : COLOR0_center; + float4 vTexCoords : TEXCOORD1; +}; + +struct HSPatchData +{ + float edges[3] : SV_TessFactor; + float inside : SV_InsideTessFactor; +}; + +HSPatchData HSPatchFunc(const InputPatch tri) +{ + + float dist = (tri[0].vPosition.w + tri[1].vPosition.w + tri[2].vPosition.w) / 3; + + + float tf = max(1, dist / 100.f); + + HSPatchData pd; + pd.edges[0] = pd.edges[1] = pd.edges[2] = tf; + pd.inside = tf; + + return pd; +} + +[domain("tri")] +[partitioning("fractional_odd")] +[outputtopology("triangle_cw")] +[patchconstantfunc("HSPatchFunc")] +[outputcontrolpoints(3)] +[RootSignature("RootFlags(ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT), " "DescriptorTable(SRV(t0, numDescriptors=2), visibility=SHADER_VISIBILITY_ALL)," "DescriptorTable(Sampler(s0, numDescriptors=2), visibility=SHADER_VISIBILITY_PIXEL)," "DescriptorTable(CBV(b0, numDescriptors=1), visibility=SHADER_VISIBILITY_ALL)," "DescriptorTable(CBV(b1, numDescriptors=1), visibility=SHADER_VISIBILITY_ALL)," "DescriptorTable(CBV(b2, numDescriptors=1), visibility=SHADER_VISIBILITY_ALL)," "DescriptorTable(SRV(t3, numDescriptors=1), visibility=SHADER_VISIBILITY_ALL)," "DescriptorTable(UAV(u9, numDescriptors=2), visibility=SHADER_VISIBILITY_ALL),")] +VSOut main( const uint id : SV_OutputControlPointID, + const InputPatch< VSOut, 3 > triIn ) +{ + return triIn[id]; +} +)"; + + CComPtr pDiaDataSource; + CComPtr pDiaSession; + CompileAndRunAnnotationAndLoadDiaSource(m_dllSupport, hlsl, L"hs_6_0", + nullptr, &pDiaDataSource); + + VERIFY_SUCCEEDED(pDiaDataSource->openSession(&pDiaSession)); +} + +TEST_F(PixDiaTest, DxcPixDxilDebugInfo_InstructionOffsets) { + + if (m_ver.SkipDxilVersion(1, 5)) + return; + + const char *hlsl = + R"(RaytracingAccelerationStructure Scene : register(t0, space0); +RWTexture2D RenderTarget : register(u0); + +struct SceneConstantBuffer +{ + float4x4 projectionToWorld; + float4 cameraPosition; + float4 lightPosition; + float4 lightAmbientColor; + float4 lightDiffuseColor; +}; + +ConstantBuffer g_sceneCB : register(b0); + +struct RayPayload +{ + float4 color; +}; + +inline void GenerateCameraRay(uint2 index, out float3 origin, out float3 direction) +{ + float2 xy = index + 0.5f; // center in the middle of the pixel. + float2 screenPos = xy;// / DispatchRaysDimensions().xy * 2.0 - 1.0; + + // Invert Y for DirectX-style coordinates. + screenPos.y = -screenPos.y; + + // Unproject the pixel coordinate into a ray. + float4 world = /*mul(*/float4(screenPos, 0, 1)/*, g_sceneCB.projectionToWorld)*/; + + //world.xyz /= world.w; + origin = world.xyz; //g_sceneCB.cameraPosition.xyz; + direction = float3(1,0,0);//normalize(world.xyz - origin); +} + +void RaygenCommon() +{ + float3 rayDir; + float3 origin; + + // Generate a ray for a camera pixel corresponding to an index from the dispatched 2D grid. + GenerateCameraRay(DispatchRaysIndex().xy, origin, rayDir); + + // Trace the ray. + // Set the ray's extents. + RayDesc ray; + ray.Origin = origin; + ray.Direction = rayDir; + // Set TMin to a non-zero small value to avoid aliasing issues due to floating - point errors. + // TMin should be kept small to prevent missing geometry at close contact areas. + ray.TMin = 0.001; + ray.TMax = 10000.0; + RayPayload payload = { float4(0, 0, 0, 0) }; + TraceRay(Scene, RAY_FLAG_CULL_BACK_FACING_TRIANGLES, ~0, 0, 1, 0, ray, payload); + + // Write the raytraced color to the output texture. + // RenderTarget[DispatchRaysIndex().xy] = payload.color; +} + +[shader("raygeneration")] +void Raygen() +{ + RaygenCommon(); +} + +typedef BuiltInTriangleIntersectionAttributes MyAttributes; + +namespace ANameSpace +{ + namespace AContainedNamespace + { + float4 RoundaboutWayToReturnAmbientColor() + { + return g_sceneCB.lightAmbientColor; + } + } +} + + +[shader("closesthit")] +void InnerClosestHitShader(inout RayPayload payload, in MyAttributes attr) +{ + payload.color = ANameSpace::AContainedNamespace::RoundaboutWayToReturnAmbientColor(); +} + + +[shader("miss")] +void MyMissShader(inout RayPayload payload) +{ + payload.color = float4(1, 0, 0, 0); +})"; + + auto lines = SplitAndPreserveEmptyLines(std::string(hlsl), '\n'); + DWORD countOfSourceLines = static_cast(lines.size()); + + CComPtr pDiaDataSource; + CompileAndRunAnnotationAndLoadDiaSource(m_dllSupport, hlsl, L"lib_6_6", + nullptr, &pDiaDataSource); + + CComPtr session; + VERIFY_SUCCEEDED(pDiaDataSource->openSession(&session)); + + CComPtr Factory; + VERIFY_SUCCEEDED(session->QueryInterface(IID_PPV_ARGS(&Factory))); + + CComPtr dxilDebugger; + VERIFY_SUCCEEDED(Factory->NewDxcPixDxilDebugInfo(&dxilDebugger)); + + // Quick crash test for wrong filename: + CComPtr garbageOffsets; + dxilDebugger->InstructionOffsetsFromSourceLocation(L"garbage", 0, 0, + &garbageOffsets); + + // Since the API offers both source-from-instruction and + // instruction-from-source, we'll compare them against each other: + for (size_t line = 0; line < lines.size(); ++line) { + + auto lineNumber = static_cast(line); + + constexpr DWORD sourceLocationReaderOnlySupportsColumnZero = 0; + CComPtr offsets; + dxilDebugger->InstructionOffsetsFromSourceLocation( + defaultFilename, lineNumber, sourceLocationReaderOnlySupportsColumnZero, + &offsets); + + auto offsetCount = offsets->GetCount(); + for (DWORD offsetOrdinal = 0; offsetOrdinal < offsetCount; + ++offsetOrdinal) { + + DWORD instructionOffsetFromSource = + offsets->GetOffsetByIndex(offsetOrdinal); + + CComPtr sourceLocations; + VERIFY_SUCCEEDED(dxilDebugger->SourceLocationsFromInstructionOffset( + instructionOffsetFromSource, &sourceLocations)); + + auto count = sourceLocations->GetCount(); + for (DWORD sourceLocationOrdinal = 0; sourceLocationOrdinal < count; + ++sourceLocationOrdinal) { + DWORD lineNumber = + sourceLocations->GetLineNumberByIndex(sourceLocationOrdinal); + DWORD column = sourceLocations->GetColumnByIndex(sourceLocationOrdinal); + CComBSTR filename; + VERIFY_SUCCEEDED(sourceLocations->GetFileNameByIndex( + sourceLocationOrdinal, &filename)); + + VERIFY_IS_TRUE(lineNumber < countOfSourceLines); + + constexpr DWORD lineNumbersAndColumnsStartAtOne = 1; + VERIFY_IS_TRUE( + column - lineNumbersAndColumnsStartAtOne <= + static_cast( + lines.at(lineNumber - lineNumbersAndColumnsStartAtOne).size())); + VERIFY_IS_TRUE(0 == wcscmp(filename, defaultFilename)); + } + } + } +} + +TEST_F(PixDiaTest, PixTypeManager_InheritancePointerTypedef) { + if (m_ver.SkipDxilVersion(1, 5)) + return; + + const char *hlsl = R"( +struct Base +{ + float floatValue; +}; +typedef Base BaseTypedef; + +struct Derived : BaseTypedef +{ + int intValue; +}; + +RaytracingAccelerationStructure Scene : register(t0, space0); + +[shader("raygeneration")] +void main() +{ + RayDesc ray; + ray.Origin = float3(0,0,0); + ray.Direction = float3(0,0,1); + // Set TMin to a non-zero small value to avoid aliasing issues due to floating - point errors. + // TMin should be kept small to prevent missing geometry at close contact areas. + ray.TMin = 0.001; + ray.TMax = 10000.0; + Derived payload; + payload.floatValue = 1; + payload.intValue = 2; + TraceRay(Scene, RAY_FLAG_CULL_BACK_FACING_TRIANGLES, ~0, 0, 1, 0, ray, payload);} + +)"; + + CComPtr pDiaDataSource; + CComPtr pDiaSession; + CompileAndRunAnnotationAndLoadDiaSource(m_dllSupport, hlsl, L"lib_6_6", + nullptr, &pDiaDataSource); + + VERIFY_SUCCEEDED(pDiaDataSource->openSession(&pDiaSession)); +} + +TEST_F(PixDiaTest, SymbolManager_Embedded2DArray) { + const char *code = R"x( +struct EmbeddedStruct +{ + uint32_t TwoDArray[2][2]; +}; + +struct smallPayload +{ + uint32_t OneInt; + EmbeddedStruct embeddedStruct; + uint64_t bigOne; +}; + +[numthreads(1, 1, 1)] +void ASMain() +{ + smallPayload p; + p.OneInt = -137; + p.embeddedStruct.TwoDArray[0][0] = 252; + p.embeddedStruct.TwoDArray[0][1] = 253; + p.embeddedStruct.TwoDArray[1][0] = 254; + p.embeddedStruct.TwoDArray[1][1] = 255; + p.bigOne = 123456789; + + DispatchMesh(2, 1, 1, p); +} + +)x"; + + auto compiled = Compile(m_dllSupport, code, L"as_6_5", {}, L"ASMain"); + + auto debugPart = GetDebugPart( + m_dllSupport, + WrapInNewContainer(m_dllSupport, + RunAnnotationPasses(m_dllSupport, compiled).blob)); + + CComPtr library; + VERIFY_SUCCEEDED(m_dllSupport.CreateInstance(CLSID_DxcLibrary, &library)); + + CComPtr programStream; + VERIFY_SUCCEEDED( + library->CreateStreamFromBlobReadOnly(debugPart, &programStream)); + + CComPtr diaDataSource; + VERIFY_SUCCEEDED( + m_dllSupport.CreateInstance(CLSID_DxcDiaDataSource, &diaDataSource)); + + VERIFY_SUCCEEDED(diaDataSource->loadDataFromIStream(programStream)); + + CComPtr session; + VERIFY_SUCCEEDED(diaDataSource->openSession(&session)); + + CComPtr Factory; + VERIFY_SUCCEEDED(session->QueryInterface(&Factory)); + CComPtr dxilDebugger; + VERIFY_SUCCEEDED(Factory->NewDxcPixDxilDebugInfo(&dxilDebugger)); + + auto lines = SplitAndPreserveEmptyLines(code, '\n'); + auto DispatchMeshLineFind = + std::find_if(lines.begin(), lines.end(), [](std::string const &line) { + return line.find("DispatchMesh") != std::string::npos; + }); + auto DispatchMeshLine = + static_cast(DispatchMeshLineFind - lines.begin()) + 2; + + CComPtr instructionOffsets; + VERIFY_SUCCEEDED(dxilDebugger->InstructionOffsetsFromSourceLocation( + L"source.hlsl", DispatchMeshLine, 0, &instructionOffsets)); + VERIFY_IS_TRUE(instructionOffsets->GetCount() > 0); + DWORD InstructionOrdinal = instructionOffsets->GetOffsetByIndex(0); + CComPtr liveVariables; + VERIFY_SUCCEEDED( + dxilDebugger->GetLiveVariablesAt(InstructionOrdinal, &liveVariables)); + CComPtr variable; + VERIFY_SUCCEEDED(liveVariables->GetVariableByIndex(0, &variable)); + CComBSTR name; + variable->GetName(&name); + VERIFY_ARE_EQUAL_WSTR(name, L"p"); + CComPtr type; + VERIFY_SUCCEEDED(variable->GetType(&type)); + CComPtr structType; + VERIFY_SUCCEEDED(type->QueryInterface(IID_PPV_ARGS(&structType))); + auto ValidateStructMember = [&structType](DWORD index, const wchar_t *name, + uint64_t offset) { + CComPtr member; + VERIFY_SUCCEEDED(structType->GetFieldByIndex(index, &member)); + CComBSTR actualName; + VERIFY_SUCCEEDED(member->GetName(&actualName)); + VERIFY_ARE_EQUAL_WSTR(actualName, name); + DWORD actualOffset = 0; + VERIFY_SUCCEEDED(member->GetOffsetInBits(&actualOffset)); + VERIFY_ARE_EQUAL(actualOffset, offset); + }; + + ValidateStructMember(0, L"OneInt", 0); + ValidateStructMember(1, L"embeddedStruct", 4 * 8); + ValidateStructMember(2, L"bigOne", 24 * 8); +} + +TEST_F(PixDiaTest, + DxcPixDxilDebugInfo_GlobalBackedGlobalStaticEmbeddedArrays_NoDbgValue) { + if (m_ver.SkipDxilVersion(1, 5)) + return; + + const char *hlsl = R"( +RWStructuredBuffer floatRWUAV: register(u0); + +struct GlobalStruct +{ + int IntArray[2]; + float FloatArray[2]; +}; + +static GlobalStruct globalStruct; +[noinline] +void fn() +{ + float Accumulator; + globalStruct.IntArray[0] = floatRWUAV[0]; + globalStruct.IntArray[1] = floatRWUAV[1]; + globalStruct.FloatArray[0] = floatRWUAV[4]; + globalStruct.FloatArray[1] = floatRWUAV[5]; + Accumulator = 0; + + uint killSwitch = 0; + + [loop] // do not unroll this + while (true) + { + Accumulator += globalStruct.FloatArray[killSwitch % 2]; + + if (killSwitch++ == 4) break; + } + + floatRWUAV[0] = Accumulator + globalStruct.IntArray[0] + globalStruct.IntArray[1]; +} + +[numthreads(1, 1, 1)] +void main() +{ + fn(); +} + +)"; + // The above HLSL should generate a module that represents the FloatArray + // member as a global, and the IntArray as an alloca. Since only embedded + // arrays are present in GlobalStruct, no dbg.value will be present for + // globalStruct. We expect the value-to-declare pass to generate its own + // dbg.value for stores into FloatArray. We will observe those dbg.value here + // via the PIX-specific debug data API. + + std::vector Expected; + Expected.push_back({L"global.globalStruct.IntArray[0]", L"int"}); + Expected.push_back({L"global.globalStruct.IntArray[1]", L"int"}); + Expected.push_back({L"global.globalStruct.FloatArray[0]", L"float"}); + Expected.push_back({L"global.globalStruct.FloatArray[1]", L"float"}); + TestGlobalStaticCase(hlsl, L"lib_6_6", "float Accumulator", Expected); +} + +TEST_F( + PixDiaTest, + DxcPixDxilDebugInfo_GlobalBackedGlobalStaticEmbeddedArrays_WithDbgValue) { + if (m_ver.SkipDxilVersion(1, 5)) + return; + + const char *hlsl = R"( +RWStructuredBuffer floatRWUAV: register(u0); + +struct GlobalStruct +{ + float Accumulator; + int IntArray[2]; + float FloatArray[2]; +}; + +static GlobalStruct globalStruct; +[numthreads(1, 1, 1)] +void main() +{ + globalStruct.IntArray[0] = floatRWUAV[0]; + globalStruct.IntArray[1] = floatRWUAV[1]; + globalStruct.FloatArray[0] = floatRWUAV[4]; + globalStruct.FloatArray[1] = floatRWUAV[5]; + globalStruct.Accumulator = 0; + + uint killSwitch = 0; + + [loop] // do not unroll this + while (true) + { + globalStruct.Accumulator += globalStruct.FloatArray[killSwitch % 2]; + + if (killSwitch++ == 4) break; + } + + floatRWUAV[0] = globalStruct.Accumulator + globalStruct.IntArray[0] + globalStruct.IntArray[1]; +} + +)"; + // The above HLSL should generate a module that represents the FloatArray + // member as a global, and the IntArray as an alloca. The presence of + // Accumulator in the GlobalStruct will force a dbg.value to be present for + // globalStruct. We expect the value-to-declare pass to find that dbg.value. + + std::vector Expected; + Expected.push_back({L"global.globalStruct.Accumulator", L"float"}); + Expected.push_back({L"global.globalStruct.IntArray[0]", L"int"}); + Expected.push_back({L"global.globalStruct.IntArray[1]", L"int"}); + Expected.push_back({L"global.globalStruct.FloatArray[0]", L"float"}); + Expected.push_back({L"global.globalStruct.FloatArray[1]", L"float"}); + TestGlobalStaticCase(hlsl, L"cs_6_6", "float Accumulator", Expected); +} + +TEST_F( + PixDiaTest, + DxcPixDxilDebugInfo_GlobalBackedGlobalStaticEmbeddedArrays_ArrayInValues) { + if (m_ver.SkipDxilVersion(1, 5)) + return; + + const char *hlsl = R"( +RWStructuredBuffer floatRWUAV: register(u0); + +struct GlobalStruct +{ + float Accumulator; + int IntArray[2]; + float FloatArray[2]; +}; + +static GlobalStruct globalStruct; +[numthreads(1, 1, 1)] +void main() +{ + globalStruct.IntArray[0] =0; + globalStruct.IntArray[1] =1; + globalStruct.FloatArray[0] = floatRWUAV[4]; + globalStruct.FloatArray[1] = floatRWUAV[5]; + globalStruct.Accumulator = 0; + + uint killSwitch = 0; + + [loop] // do not unroll this + while (true) + { + globalStruct.Accumulator += globalStruct.FloatArray[killSwitch % 2]; + + if (killSwitch++ == 4) break; + } + + floatRWUAV[0] = globalStruct.Accumulator + globalStruct.IntArray[0] + globalStruct.IntArray[1]; +} + +)"; + // The above HLSL should generate a module that represents the FloatArray + // member as a global, and the IntArray as individual values. + + std::vector Expected; + Expected.push_back({L"global.globalStruct.Accumulator", L"float"}); + Expected.push_back({L"global.globalStruct.IntArray[0]", L"int"}); + Expected.push_back({L"global.globalStruct.IntArray[1]", L"int"}); + Expected.push_back({L"global.globalStruct.FloatArray[0]", L"float"}); + Expected.push_back({L"global.globalStruct.FloatArray[1]", L"float"}); + TestGlobalStaticCase(hlsl, L"lib_6_6", "float Accumulator", Expected); +} + +TEST_F(PixDiaTest, DxcPixDxilDebugInfo_StructInheritance) { + if (m_ver.SkipDxilVersion(1, 5)) + return; + + const char *hlsl = R"( +RWStructuredBuffer floatRWUAV: register(u0); + +struct AStruct +{ + float f; + int i[2]; +}; + +struct ADerivedStruct : AStruct +{ + bool b[2]; +}; + +int AFunction(ADerivedStruct theStruct) +{ + return theStruct.i[0] + theStruct.i[1] + theStruct.f + (theStruct.b[0] ? 1 : 0) + (theStruct.b[1] ? 2 : 3); // InterestingLine +} + +[numthreads(1, 1, 1)] +void main() +{ + ADerivedStruct aStruct; + aStruct.f = floatRWUAV[1]; + aStruct.i[0] = floatRWUAV[2]; + aStruct.i[1] = floatRWUAV[3]; + aStruct.b[0] = floatRWUAV[4] != 0.0; + aStruct.b[1] = floatRWUAV[5] != 0.0; + floatRWUAV[0] = AFunction(aStruct); +} + +)"; + auto dxilDebugger = CompileAndCreateDxcDebug(hlsl, L"cs_6_6"); + + auto liveVariables = + GetLiveVariablesAt(hlsl, "InterestingLine", dxilDebugger); + + DWORD count; + VERIFY_SUCCEEDED(liveVariables->GetCount(&count)); + bool FoundTheStruct = false; + for (DWORD i = 0; i < count; ++i) { + CComPtr variable; + VERIFY_SUCCEEDED(liveVariables->GetVariableByIndex(i, &variable)); + CComBSTR name; + variable->GetName(&name); + if (0 == wcscmp(name, L"theStruct")) { + FoundTheStruct = true; + CComPtr storage; + VERIFY_SUCCEEDED(variable->GetStorage(&storage)); + std::vector ActualVariableComponents; + VERIFY_IS_TRUE(AddStorageComponents(storage, L"theStruct", + ActualVariableComponents)); + std::vector Expected; + Expected.push_back({L"theStruct.b[0]", L"bool"}); + Expected.push_back({L"theStruct.b[1]", L"bool"}); + Expected.push_back({L"theStruct.f", L"float"}); + Expected.push_back({L"theStruct.i[0]", L"int"}); + Expected.push_back({L"theStruct.i[1]", L"int"}); + VERIFY_IS_TRUE(ContainedBy(ActualVariableComponents, Expected)); + break; + } + } + VERIFY_IS_TRUE(FoundTheStruct); +} + +TEST_F(PixDiaTest, DxcPixDxilDebugInfo_StructContainedResource) { + if (m_ver.SkipDxilVersion(1, 5)) + return; + + const char *hlsl = R"( +RWStructuredBuffer floatRWUAV: register(u0); +Texture2D srv2DTexture : register(t0, space1); +struct AStruct +{ + float f; + Texture2D tex; +}; + +float4 AFunction(AStruct theStruct) +{ + return theStruct.tex.Load(int3(0, 0, 0)) + theStruct.f.xxxx; // InterestingLine +} + +[numthreads(1, 1, 1)] +void main() +{ + AStruct aStruct; + aStruct.f = floatRWUAV[1]; + aStruct.tex = srv2DTexture; + floatRWUAV[0] = AFunction(aStruct).x; +} + +)"; + auto dxilDebugger = CompileAndCreateDxcDebug(hlsl, L"cs_6_6"); + + auto liveVariables = + GetLiveVariablesAt(hlsl, "InterestingLine", dxilDebugger); + + DWORD count; + VERIFY_SUCCEEDED(liveVariables->GetCount(&count)); + bool FoundTheStruct = false; + for (DWORD i = 0; i < count; ++i) { + CComPtr variable; + VERIFY_SUCCEEDED(liveVariables->GetVariableByIndex(i, &variable)); + CComBSTR name; + variable->GetName(&name); + if (0 == wcscmp(name, L"theStruct")) { + FoundTheStruct = true; + CComPtr storage; + VERIFY_SUCCEEDED(variable->GetStorage(&storage)); + std::vector ActualVariableComponents; + VERIFY_IS_TRUE(AddStorageComponents(storage, L"theStruct", + ActualVariableComponents)); + std::vector Expected; + Expected.push_back({L"theStruct.f", L"float"}); + VERIFY_IS_TRUE(ContainedBy(ActualVariableComponents, Expected)); + break; + } + } + VERIFY_IS_TRUE(FoundTheStruct); +} + +TEST_F(PixDiaTest, DxcPixDxilDebugInfo_StructStaticInit) { + if (m_ver.SkipDxilVersion(1, 5)) + return; + + const char *hlsl = R"( +RWStructuredBuffer floatRWUAV: register(u0); +struct AStruct +{ + float f; + static AStruct Init(float fi) + { + AStruct ret; + ret.f = fi; + for(int i =0; i < 4; ++i) + { + ret.f += floatRWUAV[i+2]; + } + return ret; + } +}; + +[numthreads(1, 1, 1)] +void main() +{ + AStruct aStruct = AStruct::Init(floatRWUAV[1]); + floatRWUAV[0] = aStruct.f; // InterestingLine +} + +)"; + auto dxilDebugger = CompileAndCreateDxcDebug(hlsl, L"cs_6_6"); + + auto liveVariables = + GetLiveVariablesAt(hlsl, "InterestingLine", dxilDebugger); + + DWORD count; + VERIFY_SUCCEEDED(liveVariables->GetCount(&count)); + bool FoundTheStruct = false; + for (DWORD i = 0; i < count; ++i) { + CComPtr variable; + VERIFY_SUCCEEDED(liveVariables->GetVariableByIndex(i, &variable)); + CComBSTR name; + variable->GetName(&name); + if (0 == wcscmp(name, L"aStruct")) { + FoundTheStruct = true; + CComPtr storage; + VERIFY_SUCCEEDED(variable->GetStorage(&storage)); + std::vector ActualVariableComponents; + VERIFY_IS_TRUE( + AddStorageComponents(storage, L"aStruct", ActualVariableComponents)); + std::vector Expected; + Expected.push_back({L"aStruct.f", L"float"}); + VERIFY_IS_TRUE(ContainedBy(ActualVariableComponents, Expected)); + break; + } + } + VERIFY_IS_TRUE(FoundTheStruct); +} + +TEST_F(PixDiaTest, DxcPixDxilDebugInfo_StructMemberFnFirst) { + if (m_ver.SkipDxilVersion(1, 5)) + return; + + const char *hlsl = R"( +RWStructuredBuffer floatRWUAV: register(u0); +struct AStruct +{ + void Init(float fi); + float f; +}; + +void AStruct::Init(float fi) +{ + AStruct ret; + f = fi; + for(int i =0; i < 4; ++i) + { + f += floatRWUAV[i+2]; + } +} + +[numthreads(1, 1, 1)] +void main() +{ + AStruct aStruct; + aStruct.Init(floatRWUAV[1]); + floatRWUAV[0] = aStruct.f; // InterestingLine +} + +)"; + auto dxilDebugger = CompileAndCreateDxcDebug(hlsl, L"cs_6_6"); + + auto liveVariables = + GetLiveVariablesAt(hlsl, "InterestingLine", dxilDebugger); + + DWORD count; + VERIFY_SUCCEEDED(liveVariables->GetCount(&count)); + bool FoundTheStruct = false; + for (DWORD i = 0; i < count; ++i) { + CComPtr variable; + VERIFY_SUCCEEDED(liveVariables->GetVariableByIndex(i, &variable)); + CComBSTR name; + variable->GetName(&name); + if (0 == wcscmp(name, L"aStruct")) { + FoundTheStruct = true; + CComPtr storage; + VERIFY_SUCCEEDED(variable->GetStorage(&storage)); + std::vector ActualVariableComponents; + VERIFY_IS_TRUE( + AddStorageComponents(storage, L"aStruct", ActualVariableComponents)); + std::vector Expected; + Expected.push_back({L"aStruct.f", L"float"}); + VERIFY_IS_TRUE(ContainedBy(ActualVariableComponents, Expected)); + break; + } + } + VERIFY_IS_TRUE(FoundTheStruct); +} + +void PixDiaTest::TestUnnamedTypeCase(const char *hlsl, + const wchar_t *expectedTypeName) { + if (m_ver.SkipDxilVersion(1, 2)) + return; + auto dxilDebugger = CompileAndCreateDxcDebug(hlsl, L"cs_6_0"); + auto liveVariables = + GetLiveVariablesAt(hlsl, "InterestingLine", dxilDebugger); + DWORD count; + VERIFY_SUCCEEDED(liveVariables->GetCount(&count)); + bool FoundTheVariable = false; + for (DWORD i = 0; i < count; ++i) { + CComPtr variable; + VERIFY_SUCCEEDED(liveVariables->GetVariableByIndex(i, &variable)); + CComBSTR name; + variable->GetName(&name); + if (0 == wcscmp(name, L"glbl")) { + FoundTheVariable = true; + CComPtr type; + VERIFY_SUCCEEDED(variable->GetType(&type)); + CComBSTR typeName; + VERIFY_SUCCEEDED(type->GetName(&typeName)); + VERIFY_ARE_EQUAL(typeName, expectedTypeName); + break; + } + } + VERIFY_IS_TRUE(FoundTheVariable); +} + +TEST_F(PixDiaTest, DxcPixDxilDebugInfo_UnnamedConstStruct) { + const char *hlsl = R"( +RWStructuredBuffer floatRWUAV: register(u0); + +[numthreads(1, 1, 1)] +void main() +{ + const struct + { + float fg; + RWStructuredBuffer buf; + } glbl = {42.f, floatRWUAV}; + + float f = glbl.fg + glbl.buf[1]; // InterestingLine + floatRWUAV[0] = f; +} + +)"; + + TestUnnamedTypeCase(hlsl, L"const "); +} + +TEST_F(PixDiaTest, DxcPixDxilDebugInfo_UnnamedStruct) { + const char *hlsl = R"( +RWStructuredBuffer floatRWUAV: register(u0); + +[numthreads(1, 1, 1)] +void main() +{ + struct + { + float fg; + RWStructuredBuffer buf; + } glbl = {42.f, floatRWUAV}; + glbl.fg = 41.f; + float f = glbl.fg + glbl.buf[1]; // InterestingLine + floatRWUAV[0] = f; +} + +)"; + + TestUnnamedTypeCase(hlsl, L""); +} + +TEST_F(PixDiaTest, DxcPixDxilDebugInfo_UnnamedArray) { + const char *hlsl = R"( +RWStructuredBuffer floatRWUAV: register(u0); + +[numthreads(1, 1, 1)] +void main() +{ + struct + { + float fg; + RWStructuredBuffer buf; + } glbl[2] = {{42.f, floatRWUAV},{43.f, floatRWUAV}}; + float f = glbl[0].fg + glbl[1].buf[1]; // InterestingLine + floatRWUAV[0] = f; +} + +)"; + + TestUnnamedTypeCase(hlsl, L"[]"); +} + +TEST_F(PixDiaTest, DxcPixDxilDebugInfo_UnnamedField) { + const char *hlsl = R"( +RWStructuredBuffer floatRWUAV: register(u0); + +[numthreads(1, 1, 1)] +void main() +{ + struct + { + struct { + float fg; + RWStructuredBuffer buf; + } contained; + } glbl = { {42.f, floatRWUAV} }; + float f = glbl.contained.fg + glbl.contained.buf[1]; // InterestingLine + floatRWUAV[0] = f; +} + +)"; + + if (m_ver.SkipDxilVersion(1, 2)) + return; + auto dxilDebugger = CompileAndCreateDxcDebug(hlsl, L"cs_6_0"); + auto liveVariables = + GetLiveVariablesAt(hlsl, "InterestingLine", dxilDebugger); + DWORD count; + VERIFY_SUCCEEDED(liveVariables->GetCount(&count)); + bool FoundTheVariable = false; + for (DWORD i = 0; i < count; ++i) { + CComPtr variable; + VERIFY_SUCCEEDED(liveVariables->GetVariableByIndex(i, &variable)); + CComBSTR name; + variable->GetName(&name); + if (0 == wcscmp(name, L"glbl")) { + CComPtr type; + VERIFY_SUCCEEDED(variable->GetType(&type)); + CComPtr structType; + VERIFY_SUCCEEDED(type->QueryInterface(IID_PPV_ARGS(&structType))); + DWORD fieldCount = 0; + VERIFY_SUCCEEDED(structType->GetNumFields(&fieldCount)); + VERIFY_ARE_EQUAL(fieldCount, 1u); + // Just a crash test: + CComPtr structField; + structType->GetFieldByName(L"", &structField); + VERIFY_SUCCEEDED(structType->GetFieldByIndex(0, &structField)); + FoundTheVariable = true; + CComPtr fieldType; + VERIFY_SUCCEEDED(structField->GetType(&fieldType)); + CComBSTR typeName; + VERIFY_SUCCEEDED(fieldType->GetName(&typeName)); + VERIFY_ARE_EQUAL(typeName, L""); + break; + } + } + VERIFY_IS_TRUE(FoundTheVariable); +} + +class DxcIncludeHandlerForInjectedSourcesForPix : public IDxcIncludeHandler { +private: + DXC_MICROCOM_REF_FIELD(m_dwRef) + + std::vector> m_files; + PixDiaTest *m_pixTest; + +public: + DXC_MICROCOM_ADDREF_RELEASE_IMPL(m_dwRef) + DxcIncludeHandlerForInjectedSourcesForPix( + PixDiaTest *pixTest, + std::vector> files) + : m_dwRef(0), m_files(files), m_pixTest(pixTest){}; + + HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, + void **ppvObject) override { + return DoBasicQueryInterface(this, iid, ppvObject); + } + + HRESULT insertIncludeFile(LPCWSTR pFilename, IDxcBlobEncoding *pBlob, + UINT32 dataLen) { + return E_FAIL; + } + + HRESULT STDMETHODCALLTYPE LoadSource(LPCWSTR pFilename, + IDxcBlob **ppIncludeSource) override { + for (auto const &file : m_files) { + std::wstring prependedWithDotHack = L"./" + file.first; + if (prependedWithDotHack == std::wstring(pFilename)) { + CComPtr blob; + CreateBlobFromText(m_pixTest->m_dllSupport, file.second.c_str(), &blob); + *ppIncludeSource = blob.Detach(); + return S_OK; + } + } + return E_FAIL; + } +}; + +void PixDiaTest::RunSubProgramsCase(const char *hlsl) { + CComPtr pIncludeHandler = + new DxcIncludeHandlerForInjectedSourcesForPix( + this, {{L"../include1/samefilename.h", + "float fn1(int c, float v) { for(int i = 0; i< c; ++ i) v += " + "sqrt(v); return v; } "}, + {L"../include2/samefilename.h", + R"( +float4 fn2( float3 f3, float d, bool sanitize = true ) +{ + if (sanitize) + { + f3 = any(isnan(f3) | isinf(f3)) ? 0 : clamp(f3, 0, 1034.f); + d = (isnan(d) | isinf(d)) ? 0 : clamp(d, 0, 1024.f); + } + if( d != 0 ) d = max( d, -1024.f); + return float4( f3, d );} +)"}}); + + auto dxilDebugger = + CompileAndCreateDxcDebug(hlsl, L"cs_6_0", pIncludeHandler); + + struct SourceLocations { + CComBSTR Filename; + DWORD Column; + DWORD Line; + }; + + std::vector sourceLocations; + + DWORD instructionOffset = 0; + CComPtr DxcSourceLocations; + while (SUCCEEDED(dxilDebugger->SourceLocationsFromInstructionOffset( + instructionOffset++, &DxcSourceLocations))) { + auto count = DxcSourceLocations->GetCount(); + for (DWORD i = 0; i < count; ++i) { + sourceLocations.push_back({}); + DxcSourceLocations->GetFileNameByIndex(i, + &sourceLocations.back().Filename); + sourceLocations.back().Line = DxcSourceLocations->GetLineNumberByIndex(i); + sourceLocations.back().Column = DxcSourceLocations->GetColumnByIndex(i); + } + DxcSourceLocations = nullptr; + } + + auto it = sourceLocations.begin(); + VERIFY_IS_FALSE(it == sourceLocations.end()); + + // The list of source locations should start with the containing file: + while (it != sourceLocations.end() && it->Filename == L"source.hlsl") + it++; + VERIFY_IS_FALSE(it == sourceLocations.end()); + + // Then have a bunch of "../include2/samefilename.h" + VERIFY_ARE_EQUAL_WSTR(L"./../include2/samefilename.h", it->Filename); + while (it != sourceLocations.end() && + it->Filename == L"./../include2/samefilename.h") + it++; + VERIFY_IS_FALSE(it == sourceLocations.end()); + + // Then some more main file: + VERIFY_ARE_EQUAL_WSTR(L"source.hlsl", it->Filename); + while (it != sourceLocations.end() && it->Filename == L"source.hlsl") + it++; + + // And that should be the end: + VERIFY_IS_TRUE(it == sourceLocations.end()); +} + +TEST_F(PixDiaTest, DxcPixDxilDebugInfo_SubPrograms) { + if (m_ver.SkipDxilVersion(1, 2)) + return; + + const char *hlsl = R"( + +#include "../include1/samefilename.h" +namespace n1 { +#include "../include2/samefilename.h" +} +RWStructuredBuffer floatRWUAV: register(u0); + +[numthreads(1, 1, 1)] +void main() +{ + float4 result = n1::fn2( + float3(floatRWUAV[0], floatRWUAV[1], floatRWUAV[2]), + floatRWUAV[3]); + floatRWUAV[0] = result.x; + floatRWUAV[1] = result.y; + floatRWUAV[2] = result.z; + floatRWUAV[3] = result.w; +} + +)"; + RunSubProgramsCase(hlsl); +} + +TEST_F(PixDiaTest, DxcPixDxilDebugInfo_SubProgramsInNamespaces) { + if (m_ver.SkipDxilVersion(1, 2)) + return; + + const char *hlsl = R"( + +#include "../include1/samefilename.h" +#include "../include2/samefilename.h" + +RWStructuredBuffer floatRWUAV: register(u0); + +[numthreads(1, 1, 1)] +void main() +{ + float4 result = fn2( + float3(floatRWUAV[0], floatRWUAV[1], floatRWUAV[2]), + floatRWUAV[3]); + floatRWUAV[0] = result.x; + floatRWUAV[1] = result.y; + floatRWUAV[2] = result.z; + floatRWUAV[3] = result.w; +} + +)"; + RunSubProgramsCase(hlsl); +} + +#endif \ No newline at end of file diff --git a/tools/clang/unittests/HLSL/PixTest.cpp b/tools/clang/unittests/HLSL/PixTest.cpp index 984afcdf1a..3d64eace9c 100644 --- a/tools/clang/unittests/HLSL/PixTest.cpp +++ b/tools/clang/unittests/HLSL/PixTest.cpp @@ -9,9 +9,6 @@ // // /////////////////////////////////////////////////////////////////////////////// -// This whole file is win32-only -#ifdef _WIN32 - #ifndef UNICODE #define UNICODE #endif @@ -25,16 +22,15 @@ #include #include -#include "dxc/Support/WinIncludes.h" - -#include "dia2.h" #include "dxc/DxilContainer/DxilContainer.h" #include "dxc/DxilContainer/DxilRuntimeReflection.h" #include "dxc/DxilRootSignature/DxilRootSignature.h" #include "dxc/Support/WinIncludes.h" #include "dxc/dxcapi.h" #include "dxc/dxcpix.h" +#ifdef _WIN32 #include +#endif #include "dxc/DXIL/DxilModule.h" @@ -48,7 +44,6 @@ #include "dxc/Support/Unicode.h" #include "dxc/Support/dxcapi.use.h" #include "dxc/Support/microcom.h" -#include "llvm/Support/raw_os_ostream.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/StringSwitch.h" @@ -67,80 +62,15 @@ #include "llvm/Support/Path.h" #include -#include <../lib/DxilDia/DxcPixLiveVariables.h> #include <../lib/DxilDia/DxcPixLiveVariables_FragmentIterator.h> -#include <../lib/DxilDia/DxilDiaSession.h> #include +#include "PixTestUtils.h" + using namespace std; using namespace hlsl; using namespace hlsl_test; - -// Aligned to SymTagEnum. -const char *SymTagEnumText[] = { - "Null", // SymTagNull - "Exe", // SymTagExe - "Compiland", // SymTagCompiland - "CompilandDetails", // SymTagCompilandDetails - "CompilandEnv", // SymTagCompilandEnv - "Function", // SymTagFunction - "Block", // SymTagBlock - "Data", // SymTagData - "Annotation", // SymTagAnnotation - "Label", // SymTagLabel - "PublicSymbol", // SymTagPublicSymbol - "UDT", // SymTagUDT - "Enum", // SymTagEnum - "FunctionType", // SymTagFunctionType - "PointerType", // SymTagPointerType - "ArrayType", // SymTagArrayType - "BaseType", // SymTagBaseType - "Typedef", // SymTagTypedef - "BaseClass", // SymTagBaseClass - "Friend", // SymTagFriend - "FunctionArgType", // SymTagFunctionArgType - "FuncDebugStart", // SymTagFuncDebugStart - "FuncDebugEnd", // SymTagFuncDebugEnd - "UsingNamespace", // SymTagUsingNamespace - "VTableShape", // SymTagVTableShape - "VTable", // SymTagVTable - "Custom", // SymTagCustom - "Thunk", // SymTagThunk - "CustomType", // SymTagCustomType - "ManagedType", // SymTagManagedType - "Dimension", // SymTagDimension - "CallSite", // SymTagCallSite - "InlineSite", // SymTagInlineSite - "BaseInterface", // SymTagBaseInterface - "VectorType", // SymTagVectorType - "MatrixType", // SymTagMatrixType - "HLSLType", // SymTagHLSLType - "Caller", // SymTagCaller - "Callee", // SymTagCallee - "Export", // SymTagExport - "HeapAllocationSite", // SymTagHeapAllocationSite - "CoffGroup", // SymTagCoffGroup -}; - -// Aligned to LocationType. -const char *LocationTypeText[] = { - "Null", "Static", "TLS", "RegRel", "ThisRel", "Enregistered", - "BitField", "Slot", "IlRel", "MetaData", "Constant", -}; - -// Aligned to DataKind. -const char *DataKindText[] = { - "Unknown", "Local", "StaticLocal", "Param", "ObjectPtr", - "FileStatic", "Global", "Member", "StaticMember", "Constant", -}; - -// Aligned to UdtKind. -const char *UdtKindText[] = { - "Struct", - "Class", - "Union", - "Interface", -}; +using namespace pix_test; static std::vector Tokenize(const std::string &str, const char *delimiters) { @@ -155,7 +85,11 @@ static std::vector Tokenize(const std::string &str, return tokens; } +#ifdef _WIN32 class PixTest { +#else +class PixTest : public ::testing::Test { +#endif public: BEGIN_TEST_CLASS(PixTest) TEST_CLASS_PROPERTY(L"Parallel", L"true") @@ -164,20 +98,8 @@ class PixTest { TEST_CLASS_SETUP(InitSupport); - TEST_METHOD(CompileWhenDebugThenDIPresent) - - TEST_METHOD(CompileDebugPDB) TEST_METHOD(CompileDebugDisasmPDB) - TEST_METHOD(DiaLoadBadBitcodeThenFail) - TEST_METHOD(DiaLoadDebugThenOK) - TEST_METHOD(DiaTableIndexThenOK) - TEST_METHOD(DiaLoadDebugSubrangeNegativeThenOK) - TEST_METHOD(DiaLoadRelocatedBitcode) - TEST_METHOD(DiaLoadBitcodePlusExtraData) - TEST_METHOD(DiaCompileArgs) - TEST_METHOD(PixDebugCompileInfo) - TEST_METHOD(AddToASPayload) TEST_METHOD(PixStructAnnotation_Lib_DualRaygen) @@ -201,423 +123,21 @@ class PixTest { TEST_METHOD(PixStructAnnotation_ResourceAsMember) TEST_METHOD(PixStructAnnotation_WheresMyDbgValue) - TEST_METHOD(PixTypeManager_InheritancePointerStruct) - TEST_METHOD(PixTypeManager_InheritancePointerTypedef) - TEST_METHOD(PixTypeManager_MatricesInBase) - TEST_METHOD(PixTypeManager_SamplersAndResources) - TEST_METHOD(PixTypeManager_XBoxDiaAssert) - - TEST_METHOD(DxcPixDxilDebugInfo_InstructionOffsets) - TEST_METHOD( - DxcPixDxilDebugInfo_GlobalBackedGlobalStaticEmbeddedArrays_NoDbgValue) - TEST_METHOD( - DxcPixDxilDebugInfo_GlobalBackedGlobalStaticEmbeddedArrays_WithDbgValue) - TEST_METHOD( - DxcPixDxilDebugInfo_GlobalBackedGlobalStaticEmbeddedArrays_ArrayInValues) - TEST_METHOD(DxcPixDxilDebugInfo_StructInheritance) - TEST_METHOD(DxcPixDxilDebugInfo_StructContainedResource) - TEST_METHOD(DxcPixDxilDebugInfo_StructStaticInit) - TEST_METHOD(DxcPixDxilDebugInfo_StructMemberFnFirst) - TEST_METHOD(DxcPixDxilDebugInfo_UnnamedConstStruct) - TEST_METHOD(DxcPixDxilDebugInfo_UnnamedStruct) - TEST_METHOD(DxcPixDxilDebugInfo_UnnamedArray) - TEST_METHOD(DxcPixDxilDebugInfo_UnnamedField) - TEST_METHOD(DxcPixDxilDebugInfo_SubProgramsInNamespaces) - TEST_METHOD(DxcPixDxilDebugInfo_SubPrograms) - TEST_METHOD(VirtualRegisters_InstructionCounts) TEST_METHOD(VirtualRegisters_AlignedOffsets) TEST_METHOD(RootSignatureUpgrade_SubObjects) TEST_METHOD(RootSignatureUpgrade_Annotation) - TEST_METHOD(SymbolManager_Embedded2DArray) TEST_METHOD(DxilPIXDXRInvocationsLog_SanityTest) dxc::DxcDllSupport m_dllSupport; VersionSupportInfo m_ver; - void RunSubProgramsCase(const char *hlsl); - void TestUnnamedTypeCase(const char *hlsl, const wchar_t *expectedTypeName); - - void CreateBlobPinned(_In_bytecount_(size) LPCVOID data, SIZE_T size, - UINT32 codePage, IDxcBlobEncoding **ppBlob) { - CComPtr library; - IFT(m_dllSupport.CreateInstance(CLSID_DxcLibrary, &library)); - IFT(library->CreateBlobWithEncodingFromPinned(data, size, codePage, - ppBlob)); - } - - void CreateBlobFromFile(LPCWSTR name, IDxcBlobEncoding **ppBlob) { - CComPtr library; - IFT(m_dllSupport.CreateInstance(CLSID_DxcLibrary, &library)); - const std::wstring path = hlsl_test::GetPathToHlslDataFile(name); - IFT(library->CreateBlobFromFile(path.c_str(), nullptr, ppBlob)); - } - - void CreateBlobFromText(const char *pText, IDxcBlobEncoding **ppBlob) { - CreateBlobPinned(pText, strlen(pText) + 1, CP_UTF8, ppBlob); - } - - HRESULT CreateCompiler(IDxcCompiler **ppResult) { - return m_dllSupport.CreateInstance(CLSID_DxcCompiler, ppResult); - } - HRESULT CreateContainerBuilder(IDxcContainerBuilder **ppResult) { return m_dllSupport.CreateInstance(CLSID_DxcContainerBuilder, ppResult); } - template - void WriteIfValue(TIface *pSymbol, std::wstringstream &o, - TDefault defaultValue, LPCWSTR valueLabel, - HRESULT (__stdcall TIface::*pFn)(T *)) { - T value; - HRESULT hr = (pSymbol->*(pFn))(&value); - if (SUCCEEDED(hr) && value != (T)defaultValue) { - o << L", " << valueLabel << L": " << value; - } - } - - template - void WriteIfValue(TIface *pSymbol, std::wstringstream &o, LPCWSTR valueLabel, - HRESULT (__stdcall TIface::*pFn)(BSTR *)) { - CComBSTR value; - HRESULT hr = (pSymbol->*(pFn))(&value); - if (SUCCEEDED(hr) && value.Length()) { - o << L", " << valueLabel << L": " << (LPCWSTR)value; - } - } - template - void WriteIfValue(TIface *pSymbol, std::wstringstream &o, LPCWSTR valueLabel, - HRESULT (__stdcall TIface::*pFn)(VARIANT *)) { - CComVariant value; - HRESULT hr = (pSymbol->*(pFn))(&value); - if (SUCCEEDED(hr) && value.vt != VT_NULL && value.vt != VT_EMPTY) { - if (SUCCEEDED(value.ChangeType(VT_BSTR))) { - o << L", " << valueLabel << L": " << (LPCWSTR)value.bstrVal; - } - } - } - template - void WriteIfValue(TIface *pSymbol, std::wstringstream &o, LPCWSTR valueLabel, - HRESULT (__stdcall TIface::*pFn)(IDiaSymbol **)) { - CComPtr value; - HRESULT hr = (pSymbol->*(pFn))(&value); - if (SUCCEEDED(hr) && value.p != nullptr) { - DWORD symId; - value->get_symIndexId(&symId); - o << L", " << valueLabel << L": id=" << symId; - } - } - - std::wstring GetDebugInfoAsText(IDiaDataSource *pDataSource) { - CComPtr pSession; - CComPtr pTable; - CComPtr pEnumTables; - std::wstringstream o; - - VERIFY_SUCCEEDED(pDataSource->openSession(&pSession)); - VERIFY_SUCCEEDED(pSession->getEnumTables(&pEnumTables)); - LONG count; - VERIFY_SUCCEEDED(pEnumTables->get_Count(&count)); - for (LONG i = 0; i < count; ++i) { - pTable.Release(); - ULONG fetched; - VERIFY_SUCCEEDED(pEnumTables->Next(1, &pTable, &fetched)); - VERIFY_ARE_EQUAL(fetched, 1u); - CComBSTR tableName; - VERIFY_SUCCEEDED(pTable->get_name(&tableName)); - o << L"Table: " << (LPWSTR)tableName << std::endl; - LONG rowCount; - IFT(pTable->get_Count(&rowCount)); - o << L" Row count: " << rowCount << std::endl; - - for (LONG rowIndex = 0; rowIndex < rowCount; ++rowIndex) { - CComPtr item; - o << L'#' << rowIndex; - IFT(pTable->Item(rowIndex, &item)); - CComPtr pSymbol; - if (SUCCEEDED(item.QueryInterface(&pSymbol))) { - DWORD symTag; - DWORD dataKind; - DWORD locationType; - DWORD registerId; - pSymbol->get_symTag(&symTag); - pSymbol->get_dataKind(&dataKind); - pSymbol->get_locationType(&locationType); - pSymbol->get_registerId(®isterId); - // pSymbol->get_value(&value); - - WriteIfValue(pSymbol.p, o, 0, L"symIndexId", - &IDiaSymbol::get_symIndexId); - o << L", " << SymTagEnumText[symTag]; - if (dataKind != 0) - o << L", " << DataKindText[dataKind]; - WriteIfValue(pSymbol.p, o, L"name", &IDiaSymbol::get_name); - WriteIfValue(pSymbol.p, o, L"lexicalParent", - &IDiaSymbol::get_lexicalParent); - WriteIfValue(pSymbol.p, o, L"type", &IDiaSymbol::get_type); - WriteIfValue(pSymbol.p, o, 0, L"slot", &IDiaSymbol::get_slot); - WriteIfValue(pSymbol.p, o, 0, L"platform", &IDiaSymbol::get_platform); - WriteIfValue(pSymbol.p, o, 0, L"language", &IDiaSymbol::get_language); - WriteIfValue(pSymbol.p, o, 0, L"frontEndMajor", - &IDiaSymbol::get_frontEndMajor); - WriteIfValue(pSymbol.p, o, 0, L"frontEndMinor", - &IDiaSymbol::get_frontEndMinor); - WriteIfValue(pSymbol.p, o, 0, L"token", &IDiaSymbol::get_token); - WriteIfValue(pSymbol.p, o, L"value", &IDiaSymbol::get_value); - WriteIfValue(pSymbol.p, o, 0, L"code", &IDiaSymbol::get_code); - WriteIfValue(pSymbol.p, o, 0, L"function", &IDiaSymbol::get_function); - WriteIfValue(pSymbol.p, o, 0, L"udtKind", &IDiaSymbol::get_udtKind); - WriteIfValue(pSymbol.p, o, 0, L"hasDebugInfo", - &IDiaSymbol::get_hasDebugInfo); - WriteIfValue(pSymbol.p, o, L"compilerName", - &IDiaSymbol::get_compilerName); - WriteIfValue(pSymbol.p, o, 0, L"isLocationControlFlowDependent", - &IDiaSymbol::get_isLocationControlFlowDependent); - WriteIfValue(pSymbol.p, o, 0, L"numberOfRows", - &IDiaSymbol::get_numberOfRows); - WriteIfValue(pSymbol.p, o, 0, L"numberOfColumns", - &IDiaSymbol::get_numberOfColumns); - WriteIfValue(pSymbol.p, o, 0, L"length", &IDiaSymbol::get_length); - WriteIfValue(pSymbol.p, o, 0, L"isMatrixRowMajor", - &IDiaSymbol::get_isMatrixRowMajor); - WriteIfValue(pSymbol.p, o, 0, L"builtInKind", - &IDiaSymbol::get_builtInKind); - WriteIfValue(pSymbol.p, o, 0, L"textureSlot", - &IDiaSymbol::get_textureSlot); - WriteIfValue(pSymbol.p, o, 0, L"memorySpaceKind", - &IDiaSymbol::get_memorySpaceKind); - WriteIfValue(pSymbol.p, o, 0, L"isHLSLData", - &IDiaSymbol::get_isHLSLData); - } - - CComPtr pSourceFile; - if (SUCCEEDED(item.QueryInterface(&pSourceFile))) { - WriteIfValue(pSourceFile.p, o, 0, L"uniqueId", - &IDiaSourceFile::get_uniqueId); - WriteIfValue(pSourceFile.p, o, L"fileName", - &IDiaSourceFile::get_fileName); - } - - CComPtr pLineNumber; - if (SUCCEEDED(item.QueryInterface(&pLineNumber))) { - WriteIfValue(pLineNumber.p, o, L"compiland", - &IDiaLineNumber::get_compiland); - // WriteIfValue(pLineNumber.p, o, L"sourceFile", - // &IDiaLineNumber::get_sourceFile); - WriteIfValue(pLineNumber.p, o, 0, L"lineNumber", - &IDiaLineNumber::get_lineNumber); - WriteIfValue(pLineNumber.p, o, 0, L"lineNumberEnd", - &IDiaLineNumber::get_lineNumberEnd); - WriteIfValue(pLineNumber.p, o, 0, L"columnNumber", - &IDiaLineNumber::get_columnNumber); - WriteIfValue(pLineNumber.p, o, 0, L"columnNumberEnd", - &IDiaLineNumber::get_columnNumberEnd); - WriteIfValue(pLineNumber.p, o, 0, L"addressSection", - &IDiaLineNumber::get_addressSection); - WriteIfValue(pLineNumber.p, o, 0, L"addressOffset", - &IDiaLineNumber::get_addressOffset); - WriteIfValue(pLineNumber.p, o, 0, L"relativeVirtualAddress", - &IDiaLineNumber::get_relativeVirtualAddress); - WriteIfValue(pLineNumber.p, o, 0, L"virtualAddress", - &IDiaLineNumber::get_virtualAddress); - WriteIfValue(pLineNumber.p, o, 0, L"length", - &IDiaLineNumber::get_length); - WriteIfValue(pLineNumber.p, o, 0, L"sourceFileId", - &IDiaLineNumber::get_sourceFileId); - WriteIfValue(pLineNumber.p, o, 0, L"statement", - &IDiaLineNumber::get_statement); - WriteIfValue(pLineNumber.p, o, 0, L"compilandId", - &IDiaLineNumber::get_compilandId); - } - - CComPtr pSectionContrib; - if (SUCCEEDED(item.QueryInterface(&pSectionContrib))) { - WriteIfValue(pSectionContrib.p, o, L"compiland", - &IDiaSectionContrib::get_compiland); - WriteIfValue(pSectionContrib.p, o, 0, L"addressSection", - &IDiaSectionContrib::get_addressSection); - WriteIfValue(pSectionContrib.p, o, 0, L"addressOffset", - &IDiaSectionContrib::get_addressOffset); - WriteIfValue(pSectionContrib.p, o, 0, L"relativeVirtualAddress", - &IDiaSectionContrib::get_relativeVirtualAddress); - WriteIfValue(pSectionContrib.p, o, 0, L"virtualAddress", - &IDiaSectionContrib::get_virtualAddress); - WriteIfValue(pSectionContrib.p, o, 0, L"length", - &IDiaSectionContrib::get_length); - WriteIfValue(pSectionContrib.p, o, 0, L"notPaged", - &IDiaSectionContrib::get_notPaged); - WriteIfValue(pSectionContrib.p, o, 0, L"code", - &IDiaSectionContrib::get_code); - WriteIfValue(pSectionContrib.p, o, 0, L"initializedData", - &IDiaSectionContrib::get_initializedData); - WriteIfValue(pSectionContrib.p, o, 0, L"uninitializedData", - &IDiaSectionContrib::get_uninitializedData); - WriteIfValue(pSectionContrib.p, o, 0, L"remove", - &IDiaSectionContrib::get_remove); - WriteIfValue(pSectionContrib.p, o, 0, L"comdat", - &IDiaSectionContrib::get_comdat); - WriteIfValue(pSectionContrib.p, o, 0, L"discardable", - &IDiaSectionContrib::get_discardable); - WriteIfValue(pSectionContrib.p, o, 0, L"notCached", - &IDiaSectionContrib::get_notCached); - WriteIfValue(pSectionContrib.p, o, 0, L"share", - &IDiaSectionContrib::get_share); - WriteIfValue(pSectionContrib.p, o, 0, L"execute", - &IDiaSectionContrib::get_execute); - WriteIfValue(pSectionContrib.p, o, 0, L"read", - &IDiaSectionContrib::get_read); - WriteIfValue(pSectionContrib.p, o, 0, L"write", - &IDiaSectionContrib::get_write); - WriteIfValue(pSectionContrib.p, o, 0, L"dataCrc", - &IDiaSectionContrib::get_dataCrc); - WriteIfValue(pSectionContrib.p, o, 0, L"relocationsCrc", - &IDiaSectionContrib::get_relocationsCrc); - WriteIfValue(pSectionContrib.p, o, 0, L"compilandId", - &IDiaSectionContrib::get_compilandId); - } - - CComPtr pSegment; - if (SUCCEEDED(item.QueryInterface(&pSegment))) { - WriteIfValue(pSegment.p, o, 0, L"frame", &IDiaSegment::get_frame); - WriteIfValue(pSegment.p, o, 0, L"offset", &IDiaSegment::get_offset); - WriteIfValue(pSegment.p, o, 0, L"length", &IDiaSegment::get_length); - WriteIfValue(pSegment.p, o, 0, L"read", &IDiaSegment::get_read); - WriteIfValue(pSegment.p, o, 0, L"write", &IDiaSegment::get_write); - WriteIfValue(pSegment.p, o, 0, L"execute", &IDiaSegment::get_execute); - WriteIfValue(pSegment.p, o, 0, L"addressSection", - &IDiaSegment::get_addressSection); - WriteIfValue(pSegment.p, o, 0, L"relativeVirtualAddress", - &IDiaSegment::get_relativeVirtualAddress); - WriteIfValue(pSegment.p, o, 0, L"virtualAddress", - &IDiaSegment::get_virtualAddress); - } - - CComPtr pInjectedSource; - if (SUCCEEDED(item.QueryInterface(&pInjectedSource))) { - WriteIfValue(pInjectedSource.p, o, 0, L"crc", - &IDiaInjectedSource::get_crc); - WriteIfValue(pInjectedSource.p, o, 0, L"length", - &IDiaInjectedSource::get_length); - WriteIfValue(pInjectedSource.p, o, L"filename", - &IDiaInjectedSource::get_filename); - WriteIfValue(pInjectedSource.p, o, L"objectFilename", - &IDiaInjectedSource::get_objectFilename); - WriteIfValue(pInjectedSource.p, o, L"virtualFilename", - &IDiaInjectedSource::get_virtualFilename); - WriteIfValue(pInjectedSource.p, o, 0, L"sourceCompression", - &IDiaInjectedSource::get_sourceCompression); - // get_source is also available - } - - CComPtr pFrameData; - if (SUCCEEDED(item.QueryInterface(&pFrameData))) { - } - - o << std::endl; - } - } - - return o.str(); - } - std::wstring GetDebugFileContent(IDiaDataSource *pDataSource) { - CComPtr pSession; - CComPtr pTable; - - CComPtr pSourcesTable; - - CComPtr pEnumTables; - std::wstringstream o; - - VERIFY_SUCCEEDED(pDataSource->openSession(&pSession)); - VERIFY_SUCCEEDED(pSession->getEnumTables(&pEnumTables)); - - ULONG fetched = 0; - while (pEnumTables->Next(1, &pTable, &fetched) == S_OK && fetched == 1) { - CComBSTR name; - IFT(pTable->get_name(&name)); - - if (wcscmp(name, L"SourceFiles") == 0) { - pSourcesTable = pTable.Detach(); - continue; - } - - pTable.Release(); - } - - if (!pSourcesTable) { - return L"cannot find source"; - } - - // Get source file contents. - // NOTE: "SourceFiles" has the root file first while "InjectedSources" is in - // alphabetical order. - // It is important to keep the root file first for recompilation, so - // iterate "SourceFiles" and look up the corresponding injected - // source. - LONG count; - IFT(pSourcesTable->get_Count(&count)); - - CComPtr pSourceFile; - CComBSTR pName; - CComPtr pSymbolUnk; - CComPtr pEnumInjectedSources; - CComPtr pInjectedSource; - std::wstring sourceText, sourceFilename; - - while (SUCCEEDED(pSourcesTable->Next(1, &pSymbolUnk, &fetched)) && - fetched == 1) { - sourceText = sourceFilename = L""; - - IFT(pSymbolUnk->QueryInterface(&pSourceFile)); - IFT(pSourceFile->get_fileName(&pName)); - - IFT(pSession->findInjectedSource(pName, &pEnumInjectedSources)); - - if (SUCCEEDED(pEnumInjectedSources->get_Count(&count)) && count == 1) { - IFT(pEnumInjectedSources->Item(0, &pInjectedSource)); - - DWORD cbData = 0; - std::string tempString; - CComBSTR bstr; - IFT(pInjectedSource->get_filename(&bstr)); - IFT(pInjectedSource->get_source(0, &cbData, nullptr)); - - tempString.resize(cbData); - IFT(pInjectedSource->get_source( - cbData, &cbData, reinterpret_cast(&tempString[0]))); - - CA2W tempWString(tempString.data()); - o << tempWString.m_psz; - } - pSymbolUnk.Release(); - } - - return o.str(); - } - - struct LineNumber { - DWORD line; - DWORD rva; - }; - std::vector - ReadLineNumbers(IDiaEnumLineNumbers *pEnumLineNumbers) { - std::vector lines; - CComPtr pLineNumber; - DWORD lineCount; - while (SUCCEEDED(pEnumLineNumbers->Next(1, &pLineNumber, &lineCount)) && - lineCount == 1) { - DWORD line; - DWORD rva; - VERIFY_SUCCEEDED(pLineNumber->get_lineNumber(&line)); - VERIFY_SUCCEEDED(pLineNumber->get_relativeVirtualAddress(&rva)); - lines.push_back({line, rva}); - pLineNumber.Release(); - } - return lines; - } - std::string GetOption(std::string &cmd, char *opt) { std::string option = cmd.substr(cmd.find(opt)); option = option.substr(option.find_first_of(' ')); @@ -625,150 +145,6 @@ class PixTest { return option.substr(0, option.find_first_of(' ')); } - HRESULT CreateDiaSourceForCompile(const char *hlsl, - IDiaDataSource **ppDiaSource) { - if (!ppDiaSource) - return E_POINTER; - - CComPtr pCompiler; - CComPtr pResult; - CComPtr pSource; - CComPtr pProgram; - - VERIFY_SUCCEEDED(CreateCompiler(&pCompiler)); - CreateBlobFromText(hlsl, &pSource); - LPCWSTR args[] = {L"/Zi", L"/Qembed_debug", L"/Od"}; - VERIFY_SUCCEEDED(pCompiler->Compile(pSource, L"source.hlsl", L"main", - L"ps_6_0", args, _countof(args), - nullptr, 0, nullptr, &pResult)); - - HRESULT compilationStatus; - VERIFY_SUCCEEDED(pResult->GetStatus(&compilationStatus)); - if (FAILED(compilationStatus)) { - CComPtr pErrros; - VERIFY_SUCCEEDED(pResult->GetErrorBuffer(&pErrros)); - CA2W errorTextW(static_cast(pErrros->GetBufferPointer()), - CP_UTF8); - WEX::Logging::Log::Error(errorTextW); - } - - VERIFY_SUCCEEDED(pResult->GetResult(&pProgram)); - - // Disassemble the compiled (stripped) program. - { - CComPtr pDisassembly; - VERIFY_SUCCEEDED(pCompiler->Disassemble(pProgram, &pDisassembly)); - std::string disText = BlobToUtf8(pDisassembly); - CA2W disTextW(disText.c_str(), CP_UTF8); - // WEX::Logging::Log::Comment(disTextW); - } - - auto annotated = WrapInNewContainer(RunAnnotationPasses(pProgram).blob); - - // CONSIDER: have the dia data source look for the part if passed a whole - // container. - CComPtr pDiaSource; - CComPtr pProgramStream; - CComPtr pLib; - VERIFY_SUCCEEDED(m_dllSupport.CreateInstance(CLSID_DxcLibrary, &pLib)); - const hlsl::DxilContainerHeader *pContainer = hlsl::IsDxilContainerLike( - annotated->GetBufferPointer(), annotated->GetBufferSize()); - VERIFY_IS_NOT_NULL(pContainer); - hlsl::DxilPartIterator partIter = - std::find_if(hlsl::begin(pContainer), hlsl::end(pContainer), - hlsl::DxilPartIsType(hlsl::DFCC_ShaderDebugInfoDXIL)); - const hlsl::DxilProgramHeader *pProgramHeader = - (const hlsl::DxilProgramHeader *)hlsl::GetDxilPartData(*partIter); - uint32_t bitcodeLength; - const char *pBitcode; - CComPtr pProgramPdb; - hlsl::GetDxilProgramBitcode(pProgramHeader, &pBitcode, &bitcodeLength); - VERIFY_SUCCEEDED(pLib->CreateBlobFromBlob( - annotated, pBitcode - (char *)annotated->GetBufferPointer(), - bitcodeLength, &pProgramPdb)); - - // Disassemble the program with debug information. - { - CComPtr pDbgDisassembly; - VERIFY_SUCCEEDED(pCompiler->Disassemble(pProgramPdb, &pDbgDisassembly)); - std::string disText = BlobToUtf8(pDbgDisassembly); - CA2W disTextW(disText.c_str(), CP_UTF8); - // WEX::Logging::Log::Comment(disTextW); - } - - // Create a short text dump of debug information. - VERIFY_SUCCEEDED( - pLib->CreateStreamFromBlobReadOnly(pProgramPdb, &pProgramStream)); - VERIFY_SUCCEEDED( - m_dllSupport.CreateInstance(CLSID_DxcDiaDataSource, &pDiaSource)); - VERIFY_SUCCEEDED(pDiaSource->loadDataFromIStream(pProgramStream)); - *ppDiaSource = pDiaSource.Detach(); - return S_OK; - } - - CComPtr Compile(const char *hlsl, const wchar_t *target, - std::vector extraArgs = {}, - const wchar_t *entry = L"main") { - CComPtr pCompiler; - CComPtr pResult; - CComPtr pSource; - - VERIFY_SUCCEEDED(CreateCompiler(&pCompiler)); - CreateBlobFromText(hlsl, &pSource); - std::vector args = {L"/Zi", L"/Qembed_debug"}; - args.insert(args.end(), extraArgs.begin(), extraArgs.end()); - VERIFY_SUCCEEDED(pCompiler->Compile( - pSource, L"source.hlsl", entry, target, args.data(), - static_cast(args.size()), nullptr, 0, nullptr, &pResult)); - - HRESULT compilationStatus; - VERIFY_SUCCEEDED(pResult->GetStatus(&compilationStatus)); - if (FAILED(compilationStatus)) { - CComPtr pErrros; - VERIFY_SUCCEEDED(pResult->GetErrorBuffer(&pErrros)); - CA2W errorTextW(static_cast(pErrros->GetBufferPointer()), - CP_UTF8); - WEX::Logging::Log::Error(errorTextW); - return {}; - } - -#if 0 // handy for debugging - { - CComPtr pProgram; - CheckOperationSucceeded(pResult, &pProgram); - - CComPtr pLib; - VERIFY_SUCCEEDED(m_dllSupport.CreateInstance(CLSID_DxcLibrary, &pLib)); - const hlsl::DxilContainerHeader *pContainer = hlsl::IsDxilContainerLike( - pProgram->GetBufferPointer(), pProgram->GetBufferSize()); - VERIFY_IS_NOT_NULL(pContainer); - hlsl::DxilPartIterator partIter = - std::find_if(hlsl::begin(pContainer), hlsl::end(pContainer), - hlsl::DxilPartIsType(hlsl::DFCC_ShaderDebugInfoDXIL)); - const hlsl::DxilProgramHeader *pProgramHeader = - (const hlsl::DxilProgramHeader *)hlsl::GetDxilPartData(*partIter); - uint32_t bitcodeLength; - const char *pBitcode; - CComPtr pProgramPdb; - hlsl::GetDxilProgramBitcode(pProgramHeader, &pBitcode, &bitcodeLength); - VERIFY_SUCCEEDED(pLib->CreateBlobFromBlob( - pProgram, pBitcode - (char *)pProgram->GetBufferPointer(), - bitcodeLength, &pProgramPdb)); - - CComPtr pDbgDisassembly; - VERIFY_SUCCEEDED(pCompiler->Disassemble(pProgramPdb, &pDbgDisassembly)); - std::string disText = BlobToUtf8(pDbgDisassembly); - CA2W disTextW(disText.c_str(), CP_UTF8); - WEX::Logging::Log::Comment(disTextW); - } -#endif - - CComPtr pProgram; - VERIFY_SUCCEEDED(pResult->GetResult(&pProgram)); - - return pProgram; - } - CComPtr ExtractDxilPart(IDxcBlob *pProgram) { CComPtr pLib; VERIFY_SUCCEEDED(m_dllSupport.CreateInstance(CLSID_DxcLibrary, &pLib)); @@ -790,154 +166,6 @@ class PixTest { return pDxilBits; } - struct ValueLocation { - int base; - int count; - }; - - struct PassOutput { - CComPtr blob; - std::vector valueLocations; - std::vector lines; - }; - - std::string ExtractBracedSubstring(std::string const &line) { - auto open = line.find('{'); - auto close = line.find('}'); - if (open != std::string::npos && close != std::string::npos && - open + 1 < close) { - return line.substr(open + 1, close - open - 1); - } - return ""; - } - - int ExtractMetaInt32Value(std::string const &token) { - if (token.substr(0, 5) == " i32 ") { - return atoi(token.c_str() + 5); - } - return -1; - } - - std::map> - MetaDataKeyToRegisterNumber(std::vector const &lines) { - // Find lines of the exemplary form - // "!249 = !{i32 0, i32 20}" (in the case of a DXIL value) - // "!196 = !{i32 1, i32 5, i32 1}" (in the case of a DXIL alloca reg) - // The first i32 is a tag indicating what type of metadata this is. - // It doesn't matter if we parse poorly and find some data that don't match - // this pattern, as long as we do find all the data that do match (we won't - // be looking up the non-matchers in the resultant map anyway). - - const char *valueMetaDataAssignment = "= !{i32 0, "; - const char *allocaMetaDataAssignment = "= !{i32 1, "; - - std::map> ret; - for (auto const &line : lines) { - if (line[0] == '!') { - if (line.find(valueMetaDataAssignment) != std::string::npos || - line.find(allocaMetaDataAssignment) != std::string::npos) { - int key = atoi(line.c_str() + 1); - if (key != 0) { - std::string bitInBraces = ExtractBracedSubstring(line); - if (bitInBraces != "") { - auto tokens = Tokenize(bitInBraces.c_str(), ","); - if (tokens.size() == 2) { - auto value = ExtractMetaInt32Value(tokens[1]); - if (value != -1) { - ret[key] = {value, 1}; - } - } - if (tokens.size() == 3) { - auto value0 = ExtractMetaInt32Value(tokens[1]); - if (value0 != -1) { - auto value1 = ExtractMetaInt32Value(tokens[2]); - if (value1 != -1) { - ret[key] = {value0, value1}; - } - } - } - } - } - } - } - } - return ret; - } - - std::string ExtractValueName(std::string const &line) { - auto foundEquals = line.find('='); - if (foundEquals != std::string::npos && foundEquals > 4) { - return line.substr(2, foundEquals - 3); - } - return ""; - } - - using DxilRegisterToNameMap = std::map, std::string>; - - void CheckForAndInsertMapEntryIfFound( - DxilRegisterToNameMap ®isterToNameMap, - std::map> const &metaDataKeyToValue, - std::string const &line, char const *tag, size_t tagLength) { - auto foundAlloca = line.find(tag); - if (foundAlloca != std::string::npos) { - auto valueName = ExtractValueName(line); - if (valueName != "") { - int key = atoi(line.c_str() + foundAlloca + tagLength); - auto foundKey = metaDataKeyToValue.find(key); - if (foundKey != metaDataKeyToValue.end()) { - registerToNameMap[foundKey->second] = valueName; - } - } - } - } - - // Here's some exemplary DXIL to help understand what's going on: - // - // %5 = alloca [1 x float], i32 0, !pix-alloca-reg !196 - // %25 = call float @dx.op.loadInput.f32(...), !pix-dxil-reg !255 - // - // The %5 is an alloca name, and the %25 is a regular llvm value. - // The meta-data tags !pix-alloca-reg and !pix-dxil-reg denote this, - // and provide keys !196 and !255 respectively. - // Those keys are then given values later on in the DXIL like this: - // - // !196 = !{i32 1, i32 5, i32 1} (5 is the base alloca, 1 is the offset into - // it) !255 = !{i32 0, i32 23} - // - // So the task is first to find all of those key/value pairs and make a map - // from e.g. !196 to, e.g., (5,1), and then to find all of the alloca and reg - // tags and look up the keys in said map to build the map we're actually - // looking for, with key->values like e.g. "%5"->(5,1) and "%25"->(23) - - DxilRegisterToNameMap BuildDxilRegisterToNameMap(char const *disassembly) { - DxilRegisterToNameMap ret; - - auto lines = Tokenize(disassembly, "\n"); - - auto metaDataKeyToValue = MetaDataKeyToRegisterNumber(lines); - - for (auto const &line : lines) { - if (line[0] == '!') { - // Stop searching for values when we've run into the metadata region of - // the disassembly - break; - } - const char allocaTag[] = "!pix-alloca-reg !"; - CheckForAndInsertMapEntryIfFound(ret, metaDataKeyToValue, line, allocaTag, - _countof(allocaTag) - 1); - const char valueTag[] = "!pix-dxil-reg !"; - CheckForAndInsertMapEntryIfFound(ret, metaDataKeyToValue, line, valueTag, - _countof(valueTag) - 1); - } - return ret; - } - - static std::string ToString(std::wstring from) { - std::string ret; - ret.assign(from.data(), from.data() + from.size()); - return ret; - } - PassOutput RunValueToDeclarePass(IDxcBlob *dxil, int startingLineNumber = 0) { CComPtr pOptimizer; VERIFY_SUCCEEDED( @@ -960,53 +188,6 @@ class PixTest { std::move(pOptimizedModule), {}, Tokenize(outputText.c_str(), "\n")}; } - PassOutput RunAnnotationPasses(IDxcBlob *dxil, int startingLineNumber = 0) { - CComPtr pOptimizer; - VERIFY_SUCCEEDED( - m_dllSupport.CreateInstance(CLSID_DxcOptimizer, &pOptimizer)); - std::vector Options; - Options.push_back(L"-opt-mod-passes"); - Options.push_back(L"-dxil-dbg-value-to-dbg-declare"); - std::wstring annotationCommandLine = - L"-dxil-annotate-with-virtual-regs,startInstruction=" + - std::to_wstring(startingLineNumber); - Options.push_back(annotationCommandLine.c_str()); - - CComPtr pOptimizedModule; - CComPtr pText; - VERIFY_SUCCEEDED(pOptimizer->RunOptimizer( - dxil, Options.data(), Options.size(), &pOptimizedModule, &pText)); - - std::string outputText; - if (pText->GetBufferSize() != 0) { - outputText = reinterpret_cast(pText->GetBufferPointer()); - } - - auto disasm = ToString(Disassemble(pOptimizedModule)); - - auto registerToName = BuildDxilRegisterToNameMap(disasm.c_str()); - - std::vector valueLocations; - - for (auto const &r2n : registerToName) { - valueLocations.push_back({r2n.first.first, r2n.first.second}); - } - - return {std::move(pOptimizedModule), std::move(valueLocations), - Tokenize(outputText.c_str(), "\n")}; - } - - std::wstring Disassemble(IDxcBlob *pProgram) { - CComPtr pCompiler; - VERIFY_SUCCEEDED(CreateCompiler(&pCompiler)); - - CComPtr pDbgDisassembly; - VERIFY_SUCCEEDED(pCompiler->Disassemble(pProgram, &pDbgDisassembly)); - std::string disText = BlobToUtf8(pDbgDisassembly); - CA2W disTextW(disText.c_str(), CP_UTF8); - return std::wstring(disTextW); - } - CComPtr FindModule(hlsl::DxilFourCC fourCC, IDxcBlob *pSource) { const UINT32 BC_C0DE = ((INT32)(INT8)'B' | (INT32)(INT8)'C' << 8 | (INT32)0xDEC0 << 16); // BC0xc0de in big endian @@ -1048,2395 +229,206 @@ class PixTest { SIZE_T originalShaderLength, IDxcBlob *pNewDxilBlob, IDxcBlob **ppNewShaderOut) { CComPtr pLibrary; - IFT(m_dllSupport.CreateInstance(CLSID_DxcLibrary, &pLibrary)); - - CComPtr pNewContainer; - - // Use the container assembler to build a new container from the - // recently-modified DXIL bitcode. This container will contain new copies of - // things like input signature etc., which will supersede the ones from the - // original compiled shader's container. - { - CComPtr pAssembler; - IFT(m_dllSupport.CreateInstance(CLSID_DxcAssembler, &pAssembler)); - - CComPtr pAssembleResult; - VERIFY_SUCCEEDED( - pAssembler->AssembleToContainer(pNewDxilBlob, &pAssembleResult)); - - CComPtr pAssembleErrors; - VERIFY_SUCCEEDED(pAssembleResult->GetErrorBuffer(&pAssembleErrors)); - - if (pAssembleErrors && pAssembleErrors->GetBufferSize() != 0) { - OutputDebugStringA( - static_cast(pAssembleErrors->GetBufferPointer())); - VERIFY_SUCCEEDED(E_FAIL); - } - - VERIFY_SUCCEEDED(pAssembleResult->GetResult(&pNewContainer)); - } - - // Now copy over the blobs from the original container that won't have been - // invalidated by changing the shader code itself, using the container - // reflection API - { - // Wrap the original code in a container blob - CComPtr pContainer; - VERIFY_SUCCEEDED(pLibrary->CreateBlobWithEncodingFromPinned( - static_cast(const_cast(originalShaderBytecode)), - static_cast(originalShaderLength), CP_ACP, &pContainer)); - - CComPtr pReflection; - IFT(m_dllSupport.CreateInstance(CLSID_DxcContainerReflection, - &pReflection)); - - // Load the reflector from the original shader - VERIFY_SUCCEEDED(pReflection->Load(pContainer)); - - UINT32 partIndex; - - if (SUCCEEDED(pReflection->FindFirstPartKind(hlsl::DFCC_PrivateData, - &partIndex))) { - CComPtr pPart; - VERIFY_SUCCEEDED(pReflection->GetPartContent(partIndex, &pPart)); - - CComPtr pContainerBuilder; - IFT(m_dllSupport.CreateInstance(CLSID_DxcContainerBuilder, - &pContainerBuilder)); - - VERIFY_SUCCEEDED(pContainerBuilder->Load(pNewContainer)); - - VERIFY_SUCCEEDED( - pContainerBuilder->AddPart(hlsl::DFCC_PrivateData, pPart)); - - CComPtr pBuildResult; - - VERIFY_SUCCEEDED(pContainerBuilder->SerializeContainer(&pBuildResult)); - - CComPtr pBuildErrors; - VERIFY_SUCCEEDED(pBuildResult->GetErrorBuffer(&pBuildErrors)); - - if (pBuildErrors && pBuildErrors->GetBufferSize() != 0) { - OutputDebugStringA( - reinterpret_cast(pBuildErrors->GetBufferPointer())); - VERIFY_SUCCEEDED(E_FAIL); - } - - VERIFY_SUCCEEDED(pBuildResult->GetResult(&pNewContainer)); - } - } - - *ppNewShaderOut = pNewContainer.Detach(); - } - - class ModuleAndHangersOn { - std::unique_ptr llvmContext; - std::unique_ptr llvmModule; - DxilModule *dxilModule; - - public: - ModuleAndHangersOn(IDxcBlob *pBlob) { - // Verify we have a valid dxil container. - const DxilContainerHeader *pContainer = IsDxilContainerLike( - pBlob->GetBufferPointer(), pBlob->GetBufferSize()); - VERIFY_IS_NOT_NULL(pContainer); - VERIFY_IS_TRUE(IsValidDxilContainer(pContainer, pBlob->GetBufferSize())); - - // Get Dxil part from container. - DxilPartIterator it = - std::find_if(begin(pContainer), end(pContainer), - DxilPartIsType(DFCC_ShaderDebugInfoDXIL)); - VERIFY_IS_FALSE(it == end(pContainer)); - - const DxilProgramHeader *pProgramHeader = - reinterpret_cast(GetDxilPartData(*it)); - VERIFY_IS_TRUE(IsValidDxilProgramHeader(pProgramHeader, (*it)->PartSize)); - - // Get a pointer to the llvm bitcode. - const char *pIL; - uint32_t pILLength; - GetDxilProgramBitcode(pProgramHeader, &pIL, &pILLength); - - // Parse llvm bitcode into a module. - std::unique_ptr pBitcodeBuf( - llvm::MemoryBuffer::getMemBuffer(llvm::StringRef(pIL, pILLength), "", - false)); - - llvmContext.reset(new llvm::LLVMContext); - - llvm::ErrorOr> pModule( - llvm::parseBitcodeFile(pBitcodeBuf->getMemBufferRef(), *llvmContext)); - if (std::error_code ec = pModule.getError()) { - VERIFY_FAIL(); - } - - llvmModule = std::move(pModule.get()); - - dxilModule = DxilModule::TryGetDxilModule(llvmModule.get()); - } - - DxilModule &GetDxilModule() { return *dxilModule; } - }; - - struct AggregateOffsetAndSize { - unsigned countOfMembers; - unsigned offset; - unsigned size; - }; - struct AllocaWrite { - std::string memberName; - uint32_t regBase; - uint32_t regSize; - uint64_t index; - }; - struct TestableResults { - std::vector OffsetAndSizes; - std::vector AllocaWrites; - }; - - TestableResults TestStructAnnotationCase(const char *hlsl, - const wchar_t *optimizationLevel, - bool validateCoverage = true, - const wchar_t *profile = L"as_6_5"); - void ValidateAllocaWrite(std::vector const &allocaWrites, - size_t index, const char *name); - CComPtr RunShaderAccessTrackingPass(IDxcBlob *blob); - std::string RunDxilPIXAddTidToAmplificationShaderPayloadPass(IDxcBlob *blob); - CComPtr RunDxilPIXMeshShaderOutputPass(IDxcBlob *blob); - CComPtr RunDxilPIXDXRInvocationsLog(IDxcBlob *blob); - void CompileAndRunAnnotationAndGetDebugPart( - dxc::DxcDllSupport &dllSupport, const char *source, - const wchar_t *profile, IDxcIncludeHandler *includer, - IDxcBlob **ppDebugPart, std::vector extraArgs = {}); - void CompileAndRunValueToDeclareAndGetDebugPart( - dxc::DxcDllSupport &dllSupport, const char *source, wchar_t *profile, - IDxcIncludeHandler *includer, IDxcBlob **ppDebugPart); - void CompileAndRunAnnotationAndLoadDiaSource( - dxc::DxcDllSupport &dllSupport, const char *source, - const wchar_t *profile, IDxcIncludeHandler *includer, - IDiaDataSource **ppDataSource, - std::vector extraArgs = {}); - - struct VariableComponentInfo { - std::wstring Name; - std::wstring Type; - }; - void TestGlobalStaticCase( - const char *hlsl, const wchar_t *profile, - const char *lineAtWhichToExamineVariables, - std::vector const &ExpectedVariables); - CComPtr - CompileAndCreateDxcDebug(const char *hlsl, const wchar_t *profile, - IDxcIncludeHandler *includer = nullptr); - CComPtr - GetLiveVariablesAt(const char *hlsl, - const char *lineAtWhichToExamineVariables, - IDxcPixDxilDebugInfo *dxilDebugger); - -private: - CComPtr WrapInNewContainer(IDxcBlob *part); -}; - -bool PixTest::InitSupport() { - if (!m_dllSupport.IsEnabled()) { - VERIFY_SUCCEEDED(m_dllSupport.Initialize()); - m_ver.Initialize(m_dllSupport); - } - return true; -} - -TEST_F(PixTest, CompileWhenDebugThenDIPresent) { - // BUG: the first test written was of this form: - // float4 local = 0; return local; - // - // However we get no numbers because of the _wrapper form - // that exports the zero initialization from main into - // a global can't be attributed to any particular location - // within main, and everything in main is eventually folded away. - // - // Making the function do a bit more work by calling an intrinsic - // helps this case. - CComPtr pDiaSource; - VERIFY_SUCCEEDED(CreateDiaSourceForCompile( - "float4 main(float4 pos : SV_Position) : SV_Target {\r\n" - " float4 local = abs(pos);\r\n" - " return local;\r\n" - "}", - &pDiaSource)); - std::wstring diaDump = GetDebugInfoAsText(pDiaSource).c_str(); - // WEX::Logging::Log::Comment(GetDebugInfoAsText(pDiaSource).c_str()); - - // Very basic tests - we have basic symbols, line numbers, and files with - // sources. - VERIFY_IS_NOT_NULL(wcsstr(diaDump.c_str(), - L"symIndexId: 5, CompilandEnv, name: hlslTarget, " - L"lexicalParent: id=2, value: ps_6_0")); - VERIFY_IS_NOT_NULL(wcsstr(diaDump.c_str(), L"lineNumber: 2")); - VERIFY_IS_NOT_NULL( - wcsstr(diaDump.c_str(), L"length: 99, filename: source.hlsl")); - std::wstring diaFileContent = GetDebugFileContent(pDiaSource).c_str(); - VERIFY_IS_NOT_NULL( - wcsstr(diaFileContent.c_str(), - L"loat4 main(float4 pos : SV_Position) : SV_Target")); -#if SUPPORT_FXC_PDB - // Now, fake it by loading from a .pdb! - VERIFY_SUCCEEDED(CoInitializeEx(0, COINITBASE_MULTITHREADED)); - const wchar_t path[] = L"path-to-fxc-blob.bin"; - pDiaSource.Release(); - pProgramStream.Release(); - CComPtr fxcBlob; - CComPtr pdbBlob; - VERIFY_SUCCEEDED(pLib->CreateBlobFromFile(path, nullptr, &fxcBlob)); - std::string s = DumpParts(fxcBlob); - CA2W sW(s.c_str(), CP_UTF8); - WEX::Logging::Log::Comment(sW); - VERIFY_SUCCEEDED(CreateDiaSourceFromDxbcBlob(pLib, fxcBlob, &pDiaSource)); - WEX::Logging::Log::Comment(GetDebugInfoAsText(pDiaSource).c_str()); -#endif -} - -TEST_F(PixTest, CompileDebugDisasmPDB) { - const char *hlsl = R"( - [RootSignature("")] - float main(float pos : A) : SV_Target { - float x = abs(pos); - float y = sin(pos); - float z = x + y; - return z; - } - )"; - CComPtr pLib; - VERIFY_SUCCEEDED(m_dllSupport.CreateInstance(CLSID_DxcLibrary, &pLib)); - - CComPtr pCompiler; - CComPtr pCompiler2; - - CComPtr pResult; - CComPtr pSource; - CComPtr pProgram; - CComPtr pPdbBlob; - CComHeapPtr pDebugName; - - VERIFY_SUCCEEDED(CreateCompiler(&pCompiler)); - VERIFY_SUCCEEDED(pCompiler.QueryInterface(&pCompiler2)); - CreateBlobFromText(hlsl, &pSource); - LPCWSTR args[] = {L"/Zi", L"/Qembed_debug"}; - VERIFY_SUCCEEDED(pCompiler2->CompileWithDebug( - pSource, L"source.hlsl", L"main", L"ps_6_0", args, _countof(args), - nullptr, 0, nullptr, &pResult, &pDebugName, &pPdbBlob)); - VERIFY_SUCCEEDED(pResult->GetResult(&pProgram)); - - // Test that disassembler can consume a PDB container - CComPtr pDisasm; - VERIFY_SUCCEEDED(pCompiler->Disassemble(pPdbBlob, &pDisasm)); -} - -// Test that the new PDB format still works with Dia -TEST_F(PixTest, CompileDebugPDB) { - const char *hlsl = R"( - [RootSignature("")] - float main(float pos : A) : SV_Target { - float x = abs(pos); - float y = sin(pos); - float z = x + y; - return z; - } - )"; - CComPtr pLib; - VERIFY_SUCCEEDED(m_dllSupport.CreateInstance(CLSID_DxcLibrary, &pLib)); - - CComPtr pCompiler; - CComPtr pCompiler2; - - CComPtr pResult; - CComPtr pSource; - CComPtr pProgram; - CComPtr pPdbBlob; - CComHeapPtr pDebugName; - - VERIFY_SUCCEEDED(CreateCompiler(&pCompiler)); - VERIFY_SUCCEEDED(pCompiler.QueryInterface(&pCompiler2)); - CreateBlobFromText(hlsl, &pSource); - LPCWSTR args[] = {L"/Zi", L"/Qembed_debug"}; - VERIFY_SUCCEEDED(pCompiler2->CompileWithDebug( - pSource, L"source.hlsl", L"main", L"ps_6_0", args, _countof(args), - nullptr, 0, nullptr, &pResult, &pDebugName, &pPdbBlob)); - VERIFY_SUCCEEDED(pResult->GetResult(&pProgram)); - - CComPtr pDiaSource; - CComPtr pProgramStream; - - VERIFY_SUCCEEDED( - pLib->CreateStreamFromBlobReadOnly(pPdbBlob, &pProgramStream)); - VERIFY_SUCCEEDED( - m_dllSupport.CreateInstance(CLSID_DxcDiaDataSource, &pDiaSource)); - VERIFY_SUCCEEDED(pDiaSource->loadDataFromIStream(pProgramStream)); - - // Test that IDxcContainerReflection can consume a PDB container - CComPtr pReflection; - VERIFY_SUCCEEDED( - m_dllSupport.CreateInstance(CLSID_DxcContainerReflection, &pReflection)); - VERIFY_SUCCEEDED(pReflection->Load(pPdbBlob)); - - UINT32 uDebugInfoIndex = 0; - VERIFY_SUCCEEDED(pReflection->FindFirstPartKind( - hlsl::DFCC_ShaderDebugInfoDXIL, &uDebugInfoIndex)); -} - -TEST_F(PixTest, DiaLoadBadBitcodeThenFail) { - CComPtr pBadBitcode; - CComPtr pDiaSource; - CComPtr pStream; - CComPtr pLib; - - Utf8ToBlob(m_dllSupport, "badcode", &pBadBitcode); - VERIFY_SUCCEEDED(m_dllSupport.CreateInstance(CLSID_DxcLibrary, &pLib)); - VERIFY_SUCCEEDED(pLib->CreateStreamFromBlobReadOnly(pBadBitcode, &pStream)); - VERIFY_SUCCEEDED( - m_dllSupport.CreateInstance(CLSID_DxcDiaDataSource, &pDiaSource)); - VERIFY_FAILED(pDiaSource->loadDataFromIStream(pStream)); -} - -static void CompileAndGetDebugPart(dxc::DxcDllSupport &dllSupport, - const char *source, const wchar_t *profile, - IDxcBlob **ppDebugPart) { - CComPtr pContainer; - CComPtr pLib; - CComPtr pReflection; - UINT32 index; - std::vector args; - args.push_back(L"/Zi"); - args.push_back(L"/Qembed_debug"); - - VerifyCompileOK(dllSupport, source, profile, args, &pContainer); - VERIFY_SUCCEEDED(dllSupport.CreateInstance(CLSID_DxcLibrary, &pLib)); - VERIFY_SUCCEEDED( - dllSupport.CreateInstance(CLSID_DxcContainerReflection, &pReflection)); - VERIFY_SUCCEEDED(pReflection->Load(pContainer)); - VERIFY_SUCCEEDED( - pReflection->FindFirstPartKind(hlsl::DFCC_ShaderDebugInfoDXIL, &index)); - VERIFY_SUCCEEDED(pReflection->GetPartContent(index, ppDebugPart)); -} - -static void CompileTestAndLoadDiaSource(dxc::DxcDllSupport &dllSupport, - const char *source, - const wchar_t *profile, - IDiaDataSource **ppDataSource) { - CComPtr pDebugContent; - CComPtr pStream; - CComPtr pDiaSource; - CComPtr pLib; - VERIFY_SUCCEEDED(dllSupport.CreateInstance(CLSID_DxcLibrary, &pLib)); - - CompileAndGetDebugPart(dllSupport, source, profile, &pDebugContent); - VERIFY_SUCCEEDED(pLib->CreateStreamFromBlobReadOnly(pDebugContent, &pStream)); - VERIFY_SUCCEEDED( - dllSupport.CreateInstance(CLSID_DxcDiaDataSource, &pDiaSource)); - VERIFY_SUCCEEDED(pDiaSource->loadDataFromIStream(pStream)); - if (ppDataSource) { - *ppDataSource = pDiaSource.Detach(); - } -} - -static const char EmptyCompute[] = "[numthreads(8,8,1)] void main() { }"; - -static void CompileTestAndLoadDia(dxc::DxcDllSupport &dllSupport, - IDiaDataSource **ppDataSource) { - CompileTestAndLoadDiaSource(dllSupport, EmptyCompute, L"cs_6_0", - ppDataSource); -} - -TEST_F(PixTest, DiaLoadDebugSubrangeNegativeThenOK) { - static const char source[] = R"( - SamplerState samp0 : register(s0); - Texture2DArray tex0 : register(t0); - - float4 foo(Texture2DArray textures[], int idx, SamplerState samplerState, float3 uvw) { - return textures[NonUniformResourceIndex(idx)].Sample(samplerState, uvw); - } - - [RootSignature( "DescriptorTable(SRV(t0)), DescriptorTable(Sampler(s0)) " )] - float4 main(int index : INDEX, float3 uvw : TEXCOORD) : SV_Target { - Texture2DArray textures[] = { - tex0, - }; - return foo(textures, index, samp0, uvw); - } - )"; - - CComPtr pDiaDataSource; - CComPtr pDiaSession; - CompileTestAndLoadDiaSource(m_dllSupport, source, L"ps_6_0", &pDiaDataSource); - - VERIFY_SUCCEEDED(pDiaDataSource->openSession(&pDiaSession)); -} - -TEST_F(PixTest, DiaLoadRelocatedBitcode) { - - static const char source[] = R"( - SamplerState samp0 : register(s0); - Texture2DArray tex0 : register(t0); - - float4 foo(Texture2DArray textures[], int idx, SamplerState samplerState, float3 uvw) { - return textures[NonUniformResourceIndex(idx)].Sample(samplerState, uvw); - } - - [RootSignature( "DescriptorTable(SRV(t0)), DescriptorTable(Sampler(s0)) " )] - float4 main(int index : INDEX, float3 uvw : TEXCOORD) : SV_Target { - Texture2DArray textures[] = { - tex0, - }; - return foo(textures, index, samp0, uvw); - } - )"; - - CComPtr pPart; - CComPtr pDiaSource; - CComPtr pStream; - - CComPtr pLib; - VERIFY_SUCCEEDED(m_dllSupport.CreateInstance(CLSID_DxcLibrary, &pLib)); - - CompileAndGetDebugPart(m_dllSupport, source, L"ps_6_0", &pPart); - const char *pPartData = (char *)pPart->GetBufferPointer(); - - // Get program header - const hlsl::DxilProgramHeader *programHeader = - (const hlsl::DxilProgramHeader *)pPartData; - - const char *pBitcode = nullptr; - uint32_t uBitcodeSize = 0; - hlsl::GetDxilProgramBitcode(programHeader, &pBitcode, &uBitcodeSize); - VERIFY_IS_TRUE(uBitcodeSize % sizeof(UINT32) == 0); - - size_t uNewGapSize = - 4 * 10; // Size of some bytes between program header and bitcode - size_t uNewSuffixeBytes = - 4 * 10; // Size of some random bytes after the program - - hlsl::DxilProgramHeader newProgramHeader = {}; - memcpy(&newProgramHeader, programHeader, sizeof(newProgramHeader)); - newProgramHeader.BitcodeHeader.BitcodeOffset = - uNewGapSize + sizeof(newProgramHeader.BitcodeHeader); - - unsigned uNewSizeInBytes = - sizeof(newProgramHeader) + uNewGapSize + uBitcodeSize + uNewSuffixeBytes; - VERIFY_IS_TRUE(uNewSizeInBytes % sizeof(UINT32) == 0); - newProgramHeader.SizeInUint32 = uNewSizeInBytes / sizeof(UINT32); - - llvm::SmallVector buffer; - llvm::raw_svector_ostream OS(buffer); - - // Write the header - OS.write((char *)&newProgramHeader, sizeof(newProgramHeader)); - - // Write some garbage between the header and the bitcode - for (unsigned i = 0; i < uNewGapSize; i++) { - OS.write(0xFF); - } - - // Write the actual bitcode - OS.write(pBitcode, uBitcodeSize); - - // Write some garbage after the bitcode - for (unsigned i = 0; i < uNewSuffixeBytes; i++) { - OS.write(0xFF); - } - OS.flush(); - - // Try to load this new program, make sure dia is still okay. - CComPtr pNewProgramBlob; - VERIFY_SUCCEEDED(pLib->CreateBlobWithEncodingFromPinned( - buffer.data(), buffer.size(), CP_ACP, &pNewProgramBlob)); - - CComPtr pNewProgramStream; - VERIFY_SUCCEEDED( - pLib->CreateStreamFromBlobReadOnly(pNewProgramBlob, &pNewProgramStream)); - - CComPtr pDiaDataSource; - VERIFY_SUCCEEDED( - m_dllSupport.CreateInstance(CLSID_DxcDiaDataSource, &pDiaDataSource)); - - VERIFY_SUCCEEDED(pDiaDataSource->loadDataFromIStream(pNewProgramStream)); -} - -TEST_F(PixTest, DiaCompileArgs) { - static const char source[] = R"( - SamplerState samp0 : register(s0); - Texture2DArray tex0 : register(t0); - - float4 foo(Texture2DArray textures[], int idx, SamplerState samplerState, float3 uvw) { - return textures[NonUniformResourceIndex(idx)].Sample(samplerState, uvw); - } - - [RootSignature( "DescriptorTable(SRV(t0)), DescriptorTable(Sampler(s0)) " )] - float4 main(int index : INDEX, float3 uvw : TEXCOORD) : SV_Target { - Texture2DArray textures[] = { - tex0, - }; - return foo(textures, index, samp0, uvw); - } - )"; - - CComPtr pPart; - CComPtr pDiaSource; - CComPtr pStream; - - CComPtr pLib; - VERIFY_SUCCEEDED(m_dllSupport.CreateInstance(CLSID_DxcLibrary, &pLib)); - - const WCHAR *FlagList[] = { - L"/Zi", L"-Zpr", L"/Qembed_debug", L"/Fd", - L"F:\\my dir\\", L"-Fo", L"F:\\my dir\\file.dxc", - }; - const WCHAR *DefineList[] = { - L"MY_SPECIAL_DEFINE", - L"MY_OTHER_SPECIAL_DEFINE=\"MY_STRING\"", - }; - - std::vector args; - for (unsigned i = 0; i < _countof(FlagList); i++) { - args.push_back(FlagList[i]); - } - for (unsigned i = 0; i < _countof(DefineList); i++) { - args.push_back(L"/D"); - args.push_back(DefineList[i]); - } - - auto CompileAndGetDebugPart = [&args](dxc::DxcDllSupport &dllSupport, - const char *source, - const wchar_t *profile, - IDxcBlob **ppDebugPart) { - CComPtr pContainer; - CComPtr pLib; - CComPtr pReflection; - UINT32 index; - - VerifyCompileOK(dllSupport, source, profile, args, &pContainer); - VERIFY_SUCCEEDED(dllSupport.CreateInstance(CLSID_DxcLibrary, &pLib)); - VERIFY_SUCCEEDED( - dllSupport.CreateInstance(CLSID_DxcContainerReflection, &pReflection)); - VERIFY_SUCCEEDED(pReflection->Load(pContainer)); - VERIFY_SUCCEEDED( - pReflection->FindFirstPartKind(hlsl::DFCC_ShaderDebugInfoDXIL, &index)); - VERIFY_SUCCEEDED(pReflection->GetPartContent(index, ppDebugPart)); - }; - - CompileAndGetDebugPart(m_dllSupport, source, L"ps_6_0", &pPart); - - CComPtr pNewProgramStream; - VERIFY_SUCCEEDED( - pLib->CreateStreamFromBlobReadOnly(pPart, &pNewProgramStream)); - - CComPtr pDiaDataSource; - VERIFY_SUCCEEDED( - m_dllSupport.CreateInstance(CLSID_DxcDiaDataSource, &pDiaDataSource)); - - VERIFY_SUCCEEDED(pDiaDataSource->loadDataFromIStream(pNewProgramStream)); - - CComPtr pSession; - VERIFY_SUCCEEDED(pDiaDataSource->openSession(&pSession)); - - CComPtr pEnumTables; - VERIFY_SUCCEEDED(pSession->getEnumTables(&pEnumTables)); - - CComPtr pSymbolTable; - - LONG uCount = 0; - VERIFY_SUCCEEDED(pEnumTables->get_Count(&uCount)); - for (int i = 0; i < uCount; i++) { - CComPtr pTable; - VARIANT index = {}; - index.vt = VT_I4; - index.intVal = i; - VERIFY_SUCCEEDED(pEnumTables->Item(index, &pTable)); - - CComBSTR pName; - VERIFY_SUCCEEDED(pTable->get_name(&pName)); - - if (pName == "Symbols") { - pSymbolTable = pTable; - break; - } - } - - std::wstring Args; - std::wstring Entry; - std::wstring Target; - std::vector Defines; - std::vector Flags; - - auto ReadNullSeparatedTokens = [](BSTR Str) -> std::vector { - std::vector Result; - while (*Str) { - Result.push_back(std::wstring(Str)); - Str += wcslen(Str) + 1; - } - return Result; - }; - - VERIFY_SUCCEEDED(pSymbolTable->get_Count(&uCount)); - for (int i = 0; i < uCount; i++) { - CComPtr pSymbolUnk; - CComPtr pSymbol; - CComVariant pValue; - CComBSTR pName; - VERIFY_SUCCEEDED(pSymbolTable->Item(i, &pSymbolUnk)); - VERIFY_SUCCEEDED(pSymbolUnk->QueryInterface(&pSymbol)); - VERIFY_SUCCEEDED(pSymbol->get_name(&pName)); - VERIFY_SUCCEEDED(pSymbol->get_value(&pValue)); - if (pName == "hlslTarget") { - if (pValue.vt == VT_BSTR) - Target = pValue.bstrVal; - } else if (pName == "hlslEntry") { - if (pValue.vt == VT_BSTR) - Entry = pValue.bstrVal; - } else if (pName == "hlslFlags") { - if (pValue.vt == VT_BSTR) - Flags = ReadNullSeparatedTokens(pValue.bstrVal); - } else if (pName == "hlslArguments") { - if (pValue.vt == VT_BSTR) - Args = pValue.bstrVal; - } else if (pName == "hlslDefines") { - if (pValue.vt == VT_BSTR) - Defines = ReadNullSeparatedTokens(pValue.bstrVal); - } - } - - auto VectorContains = [](std::vector &Tokens, - std::wstring Sub) { - for (unsigned i = 0; i < Tokens.size(); i++) { - if (Tokens[i].find(Sub) != std::wstring::npos) - return true; - } - return false; - }; - - VERIFY_IS_TRUE(Target == L"ps_6_0"); - VERIFY_IS_TRUE(Entry == L"main"); - - VERIFY_IS_TRUE(_countof(FlagList) == Flags.size()); - for (unsigned i = 0; i < _countof(FlagList); i++) { - VERIFY_IS_TRUE(Flags[i] == FlagList[i]); - } - for (unsigned i = 0; i < _countof(DefineList); i++) { - VERIFY_IS_TRUE(VectorContains(Defines, DefineList[i])); - } -} - -TEST_F(PixTest, DiaLoadBitcodePlusExtraData) { - // Test that dia doesn't crash when bitcode has unused extra data at the end - - static const char source[] = R"( - SamplerState samp0 : register(s0); - Texture2DArray tex0 : register(t0); - - float4 foo(Texture2DArray textures[], int idx, SamplerState samplerState, float3 uvw) { - return textures[NonUniformResourceIndex(idx)].Sample(samplerState, uvw); - } - - [RootSignature( "DescriptorTable(SRV(t0)), DescriptorTable(Sampler(s0)) " )] - float4 main(int index : INDEX, float3 uvw : TEXCOORD) : SV_Target { - Texture2DArray textures[] = { - tex0, - }; - return foo(textures, index, samp0, uvw); - } - )"; - - CComPtr pPart; - CComPtr pDiaSource; - CComPtr pStream; - - CComPtr pLib; - VERIFY_SUCCEEDED(m_dllSupport.CreateInstance(CLSID_DxcLibrary, &pLib)); - - CompileAndGetDebugPart(m_dllSupport, source, L"ps_6_0", &pPart); - const char *pPartData = (char *)pPart->GetBufferPointer(); - - // Get program header - const hlsl::DxilProgramHeader *programHeader = - (const hlsl::DxilProgramHeader *)pPartData; - - const char *pBitcode = nullptr; - uint32_t uBitcodeSize = 0; - hlsl::GetDxilProgramBitcode(programHeader, &pBitcode, &uBitcodeSize); - - llvm::SmallVector buffer; - llvm::raw_svector_ostream OS(buffer); - - // Write the bitcode - OS.write(pBitcode, uBitcodeSize); - for (unsigned i = 0; i < 12; i++) { - OS.write(0xFF); - } - OS.flush(); - - // Try to load this new program, make sure dia is still okay. - CComPtr pNewProgramBlob; - VERIFY_SUCCEEDED(pLib->CreateBlobWithEncodingFromPinned( - buffer.data(), buffer.size(), CP_ACP, &pNewProgramBlob)); - - CComPtr pNewProgramStream; - VERIFY_SUCCEEDED( - pLib->CreateStreamFromBlobReadOnly(pNewProgramBlob, &pNewProgramStream)); - - CComPtr pDiaDataSource; - VERIFY_SUCCEEDED( - m_dllSupport.CreateInstance(CLSID_DxcDiaDataSource, &pDiaDataSource)); - - VERIFY_SUCCEEDED(pDiaDataSource->loadDataFromIStream(pNewProgramStream)); -} - -TEST_F(PixTest, DiaLoadDebugThenOK) { - CompileTestAndLoadDia(m_dllSupport, nullptr); -} - -TEST_F(PixTest, DiaTableIndexThenOK) { - CComPtr pDiaSource; - CComPtr pDiaSession; - CComPtr pEnumTables; - CComPtr pTable; - VARIANT vtIndex; - CompileTestAndLoadDia(m_dllSupport, &pDiaSource); - VERIFY_SUCCEEDED(pDiaSource->openSession(&pDiaSession)); - VERIFY_SUCCEEDED(pDiaSession->getEnumTables(&pEnumTables)); - - vtIndex.vt = VT_EMPTY; - VERIFY_FAILED(pEnumTables->Item(vtIndex, &pTable)); - - vtIndex.vt = VT_I4; - vtIndex.intVal = 1; - VERIFY_SUCCEEDED(pEnumTables->Item(vtIndex, &pTable)); - VERIFY_IS_NOT_NULL(pTable.p); - pTable.Release(); - - vtIndex.vt = VT_UI4; - vtIndex.uintVal = 1; - VERIFY_SUCCEEDED(pEnumTables->Item(vtIndex, &pTable)); - VERIFY_IS_NOT_NULL(pTable.p); - pTable.Release(); - - vtIndex.uintVal = 100; - VERIFY_FAILED(pEnumTables->Item(vtIndex, &pTable)); -} - -TEST_F(PixTest, PixDebugCompileInfo) { - static const char source[] = R"( - SamplerState samp0 : register(s0); - Texture2DArray tex0 : register(t0); - - float4 foo(Texture2DArray textures[], int idx, SamplerState samplerState, float3 uvw) { - return textures[NonUniformResourceIndex(idx)].Sample(samplerState, uvw); - } - - [RootSignature( "DescriptorTable(SRV(t0)), DescriptorTable(Sampler(s0)) " )] - float4 main(int index : INDEX, float3 uvw : TEXCOORD) : SV_Target { - Texture2DArray textures[] = { - tex0, - }; - return foo(textures, index, samp0, uvw); - } - )"; - - CComPtr pPart; - CComPtr pDiaSource; - CComPtr pStream; - - CComPtr pLib; - VERIFY_SUCCEEDED(m_dllSupport.CreateInstance(CLSID_DxcLibrary, &pLib)); - - const WCHAR *FlagList[] = { - L"/Zi", L"-Zpr", L"/Qembed_debug", L"/Fd", - L"F:\\my dir\\", L"-Fo", L"F:\\my dir\\file.dxc", - }; - const WCHAR *DefineList[] = { - L"MY_SPECIAL_DEFINE", - L"MY_OTHER_SPECIAL_DEFINE=\"MY_STRING\"", - }; - - std::vector args; - for (unsigned i = 0; i < _countof(FlagList); i++) { - args.push_back(FlagList[i]); - } - for (unsigned i = 0; i < _countof(DefineList); i++) { - args.push_back(L"/D"); - args.push_back(DefineList[i]); - } - - auto CompileAndGetDebugPart = [&args](dxc::DxcDllSupport &dllSupport, - const char *source, - const wchar_t *profile, - IDxcBlob **ppDebugPart) { - CComPtr pContainer; - CComPtr pLib; - CComPtr pReflection; - UINT32 index; - - VerifyCompileOK(dllSupport, source, profile, args, &pContainer); - VERIFY_SUCCEEDED(dllSupport.CreateInstance(CLSID_DxcLibrary, &pLib)); - VERIFY_SUCCEEDED( - dllSupport.CreateInstance(CLSID_DxcContainerReflection, &pReflection)); - VERIFY_SUCCEEDED(pReflection->Load(pContainer)); - VERIFY_SUCCEEDED( - pReflection->FindFirstPartKind(hlsl::DFCC_ShaderDebugInfoDXIL, &index)); - VERIFY_SUCCEEDED(pReflection->GetPartContent(index, ppDebugPart)); - }; - - const wchar_t *profile = L"ps_6_0"; - CompileAndGetDebugPart(m_dllSupport, source, profile, &pPart); - - CComPtr pNewProgramStream; - VERIFY_SUCCEEDED( - pLib->CreateStreamFromBlobReadOnly(pPart, &pNewProgramStream)); - - CComPtr pDiaDataSource; - VERIFY_SUCCEEDED( - m_dllSupport.CreateInstance(CLSID_DxcDiaDataSource, &pDiaDataSource)); - - VERIFY_SUCCEEDED(pDiaDataSource->loadDataFromIStream(pNewProgramStream)); - - CComPtr pSession; - VERIFY_SUCCEEDED(pDiaDataSource->openSession(&pSession)); - - CComPtr factory; - VERIFY_SUCCEEDED(pSession->QueryInterface(IID_PPV_ARGS(&factory))); - - CComPtr compilationInfo; - VERIFY_SUCCEEDED(factory->NewDxcPixCompilationInfo(&compilationInfo)); - - CComBSTR arguments; - VERIFY_SUCCEEDED(compilationInfo->GetArguments(&arguments)); - for (unsigned i = 0; i < _countof(FlagList); i++) { - VERIFY_IS_TRUE(nullptr != wcsstr(arguments, FlagList[i])); - } - - CComBSTR macros; - VERIFY_SUCCEEDED(compilationInfo->GetMacroDefinitions(¯os)); - for (unsigned i = 0; i < _countof(DefineList); i++) { - std::wstring MacroDef = std::wstring(L"-D") + DefineList[i]; - VERIFY_IS_TRUE(nullptr != wcsstr(macros, MacroDef.c_str())); - } - - CComBSTR entryPointFile; - VERIFY_SUCCEEDED(compilationInfo->GetEntryPointFile(&entryPointFile)); - VERIFY_ARE_EQUAL(std::wstring(L"source.hlsl"), std::wstring(entryPointFile)); - - CComBSTR entryPointFunction; - VERIFY_SUCCEEDED(compilationInfo->GetEntryPoint(&entryPointFunction)); - VERIFY_ARE_EQUAL(std::wstring(L"main"), std::wstring(entryPointFunction)); - - CComBSTR hlslTarget; - VERIFY_SUCCEEDED(compilationInfo->GetHlslTarget(&hlslTarget)); - VERIFY_ARE_EQUAL(std::wstring(profile), std::wstring(hlslTarget)); -} - -static LPCWSTR defaultFilename = L"source.hlsl"; - -static void CompileAndLogErrors(dxc::DxcDllSupport &dllSupport, LPCSTR pText, - LPCWSTR pTargetProfile, - std::vector &args, - IDxcIncludeHandler *includer, - _Outptr_ IDxcBlob **ppResult) { - CComPtr pCompiler; - CComPtr pSource; - CComPtr pResult; - HRESULT hrCompile; - *ppResult = nullptr; - VERIFY_SUCCEEDED(dllSupport.CreateInstance(CLSID_DxcCompiler, &pCompiler)); - Utf8ToBlob(dllSupport, pText, &pSource); - VERIFY_SUCCEEDED(pCompiler->Compile(pSource, defaultFilename, L"main", - pTargetProfile, args.data(), args.size(), - nullptr, 0, includer, &pResult)); - - VERIFY_SUCCEEDED(pResult->GetStatus(&hrCompile)); - if (FAILED(hrCompile)) { - CComPtr textBlob; - VERIFY_SUCCEEDED(pResult->GetErrorBuffer(&textBlob)); - std::wstring text = BlobToWide(textBlob); - WEX::Logging::Log::Comment(text.c_str()); - } - VERIFY_SUCCEEDED(hrCompile); - VERIFY_SUCCEEDED(pResult->GetResult(ppResult)); -} - -static CComPtr GetDebugPart(dxc::DxcDllSupport &dllSupport, - IDxcBlob *container) { - - CComPtr pLib; - VERIFY_SUCCEEDED(dllSupport.CreateInstance(CLSID_DxcLibrary, &pLib)); - CComPtr pReflection; - - VERIFY_SUCCEEDED( - dllSupport.CreateInstance(CLSID_DxcContainerReflection, &pReflection)); - VERIFY_SUCCEEDED(pReflection->Load(container)); - - UINT32 index; - VERIFY_SUCCEEDED( - pReflection->FindFirstPartKind(hlsl::DFCC_ShaderDebugInfoDXIL, &index)); - - CComPtr debugPart; - VERIFY_SUCCEEDED(pReflection->GetPartContent(index, &debugPart)); - - return debugPart; -} - -void PixTest::CompileAndRunValueToDeclareAndGetDebugPart( - dxc::DxcDllSupport &dllSupport, const char *source, wchar_t *profile, - IDxcIncludeHandler *includer, IDxcBlob **ppDebugPart) { - CComPtr pContainer; - std::vector args; - args.push_back(L"/Zi"); - args.push_back(L"/Od"); - args.push_back(L"/Qembed_debug"); - - CompileAndLogErrors(dllSupport, source, profile, args, includer, &pContainer); - - auto annotated = RunValueToDeclarePass(pContainer); - - CComPtr pNewContainer = WrapInNewContainer(annotated.blob); - - *ppDebugPart = GetDebugPart(dllSupport, pNewContainer).Detach(); -} - -void PixTest::CompileAndRunAnnotationAndGetDebugPart( - dxc::DxcDllSupport &dllSupport, const char *source, const wchar_t *profile, - IDxcIncludeHandler *includer, IDxcBlob **ppDebugPart, - std::vector extraArgs) { - - CComPtr pContainer; - std::vector args; - args.push_back(L"/Zi"); - args.push_back(L"/Qembed_debug"); - args.insert(args.end(), extraArgs.begin(), extraArgs.end()); - - CompileAndLogErrors(dllSupport, source, profile, args, includer, &pContainer); - - auto annotated = RunAnnotationPasses(pContainer); - - CComPtr pNewContainer = WrapInNewContainer(annotated.blob); - - *ppDebugPart = GetDebugPart(dllSupport, pNewContainer).Detach(); -} - -void PixTest::CompileAndRunAnnotationAndLoadDiaSource( - dxc::DxcDllSupport &dllSupport, const char *source, const wchar_t *profile, - IDxcIncludeHandler *includer, IDiaDataSource **ppDataSource, - std::vector extraArgs) { - CComPtr pDebugContent; - CComPtr pStream; - CComPtr pDiaSource; - CComPtr pLib; - VERIFY_SUCCEEDED(dllSupport.CreateInstance(CLSID_DxcLibrary, &pLib)); - - CompileAndRunAnnotationAndGetDebugPart(dllSupport, source, profile, includer, - &pDebugContent, extraArgs); - VERIFY_SUCCEEDED(pLib->CreateStreamFromBlobReadOnly(pDebugContent, &pStream)); - VERIFY_SUCCEEDED( - dllSupport.CreateInstance(CLSID_DxcDiaDataSource, &pDiaSource)); - VERIFY_SUCCEEDED(pDiaSource->loadDataFromIStream(pStream)); - if (ppDataSource) { - *ppDataSource = pDiaSource.Detach(); - } -} - -CComPtr PixTest::WrapInNewContainer(IDxcBlob *part) { - CComPtr pAssembler; - IFT(m_dllSupport.CreateInstance(CLSID_DxcAssembler, &pAssembler)); - - CComPtr pAssembleResult; - VERIFY_SUCCEEDED(pAssembler->AssembleToContainer(part, &pAssembleResult)); - - CComPtr pAssembleErrors; - VERIFY_SUCCEEDED(pAssembleResult->GetErrorBuffer(&pAssembleErrors)); - - if (pAssembleErrors && pAssembleErrors->GetBufferSize() != 0) { - OutputDebugStringA( - static_cast(pAssembleErrors->GetBufferPointer())); - VERIFY_SUCCEEDED(E_FAIL); - } - - CComPtr pNewContainer; - VERIFY_SUCCEEDED(pAssembleResult->GetResult(&pNewContainer)); - - return pNewContainer; -} - -TEST_F(PixTest, PixTypeManager_InheritancePointerStruct) { - if (m_ver.SkipDxilVersion(1, 5)) - return; - - const char *hlsl = R"( -struct Base -{ - float floatValue; -}; - -struct Derived : Base -{ - int intValue; -}; - -RaytracingAccelerationStructure Scene : register(t0, space0); - -[shader("raygeneration")] -void main() -{ - RayDesc ray; - ray.Origin = float3(0,0,0); - ray.Direction = float3(0,0,1); - // Set TMin to a non-zero small value to avoid aliasing issues due to floating - point errors. - // TMin should be kept small to prevent missing geometry at close contact areas. - ray.TMin = 0.001; - ray.TMax = 10000.0; - Derived payload; - payload.floatValue = 1; - payload.intValue = 2; - TraceRay(Scene, RAY_FLAG_CULL_BACK_FACING_TRIANGLES, ~0, 0, 1, 0, ray, payload);} - -)"; - - CComPtr pDiaDataSource; - CComPtr pDiaSession; - CompileAndRunAnnotationAndLoadDiaSource(m_dllSupport, hlsl, L"lib_6_6", - nullptr, &pDiaDataSource); - - VERIFY_SUCCEEDED(pDiaDataSource->openSession(&pDiaSession)); -} - -TEST_F(PixTest, PixTypeManager_InheritancePointerTypedef) { - if (m_ver.SkipDxilVersion(1, 5)) - return; - - const char *hlsl = R"( -struct Base -{ - float floatValue; -}; -typedef Base BaseTypedef; - -struct Derived : BaseTypedef -{ - int intValue; -}; - -RaytracingAccelerationStructure Scene : register(t0, space0); - -[shader("raygeneration")] -void main() -{ - RayDesc ray; - ray.Origin = float3(0,0,0); - ray.Direction = float3(0,0,1); - // Set TMin to a non-zero small value to avoid aliasing issues due to floating - point errors. - // TMin should be kept small to prevent missing geometry at close contact areas. - ray.TMin = 0.001; - ray.TMax = 10000.0; - Derived payload; - payload.floatValue = 1; - payload.intValue = 2; - TraceRay(Scene, RAY_FLAG_CULL_BACK_FACING_TRIANGLES, ~0, 0, 1, 0, ray, payload);} - -)"; - - CComPtr pDiaDataSource; - CComPtr pDiaSession; - CompileAndRunAnnotationAndLoadDiaSource(m_dllSupport, hlsl, L"lib_6_6", - nullptr, &pDiaDataSource); - - VERIFY_SUCCEEDED(pDiaDataSource->openSession(&pDiaSession)); -} - -TEST_F(PixTest, PixTypeManager_MatricesInBase) { - if (m_ver.SkipDxilVersion(1, 5)) - return; - - const char *hlsl = R"( -struct Base -{ - float4x4 mat; -}; -typedef Base BaseTypedef; - -struct Derived : BaseTypedef -{ - int intValue; -}; - -RaytracingAccelerationStructure Scene : register(t0, space0); - -[shader("raygeneration")] -void main() -{ - RayDesc ray; - ray.Origin = float3(0,0,0); - ray.Direction = float3(0,0,1); - // Set TMin to a non-zero small value to avoid aliasing issues due to floating - point errors. - // TMin should be kept small to prevent missing geometry at close contact areas. - ray.TMin = 0.001; - ray.TMax = 10000.0; - Derived payload; - payload.mat[0][0] = 1; - payload.intValue = 2; - TraceRay(Scene, RAY_FLAG_CULL_BACK_FACING_TRIANGLES, ~0, 0, 1, 0, ray, payload);} - -)"; - - CComPtr pDiaDataSource; - CComPtr pDiaSession; - CompileAndRunAnnotationAndLoadDiaSource(m_dllSupport, hlsl, L"lib_6_6", - nullptr, &pDiaDataSource); - - VERIFY_SUCCEEDED(pDiaDataSource->openSession(&pDiaSession)); -} - -TEST_F(PixTest, PixTypeManager_SamplersAndResources) { - if (m_ver.SkipDxilVersion(1, 5)) - return; - - const char *hlsl = R"( - -static const SamplerState SamplerRef = SamplerDescriptorHeap[1]; - -Texture3D Tex3DTemplated ; -Texture3D Tex3d ; -Texture2D Tex2D ; -Texture2D Tex2DTemplated ; -StructuredBuffer StructBuf ; -Texture2DArray Tex2DArray ; -Buffer Buff ; - -static const struct -{ - float AFloat; - SamplerState Samp1; - Texture3D Tex1; - Texture3D Tex2; - Texture2D Tex3; - Texture2D Tex4; - StructuredBuffer Buff1; - Texture2DArray Tex5; - Buffer Buff2; - float AnotherFloat; -} View = { -1, -SamplerRef, -Tex3DTemplated, -Tex3d, -Tex2D, -Tex2DTemplated, -StructBuf, -Tex2DArray, -Buff, -2 -}; - -struct Payload -{ - int intValue; -}; - -RaytracingAccelerationStructure Scene : register(t0, space0); - -[shader("raygeneration")] -void main() -{ - RayDesc ray; - ray.Origin = float3(0,0,0); - ray.Direction = float3(0,0,1); - ray.TMin = 0.001; - ray.TMax = 10000.0; - Payload payload; - payload.intValue = View.AFloat; - TraceRay(Scene, RAY_FLAG_CULL_BACK_FACING_TRIANGLES, ~0, 0, 1, 0, ray, payload);} -)"; - - CComPtr pDiaDataSource; - CComPtr pDiaSession; - CompileAndRunAnnotationAndLoadDiaSource(m_dllSupport, hlsl, L"lib_6_6", - nullptr, &pDiaDataSource); - - VERIFY_SUCCEEDED(pDiaDataSource->openSession(&pDiaSession)); -} - -TEST_F(PixTest, PixTypeManager_XBoxDiaAssert) { - if (m_ver.SkipDxilVersion(1, 5)) - return; - - const char *hlsl = R"( -struct VSOut -{ - float4 vPosition : SV_POSITION; - float4 vLightAndFog : COLOR0_center; - float4 vTexCoords : TEXCOORD1; -}; - -struct HSPatchData -{ - float edges[3] : SV_TessFactor; - float inside : SV_InsideTessFactor; -}; - -HSPatchData HSPatchFunc(const InputPatch tri) -{ - - float dist = (tri[0].vPosition.w + tri[1].vPosition.w + tri[2].vPosition.w) / 3; - - - float tf = max(1, dist / 100.f); - - HSPatchData pd; - pd.edges[0] = pd.edges[1] = pd.edges[2] = tf; - pd.inside = tf; - - return pd; -} - -[domain("tri")] -[partitioning("fractional_odd")] -[outputtopology("triangle_cw")] -[patchconstantfunc("HSPatchFunc")] -[outputcontrolpoints(3)] -[RootSignature("RootFlags(ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT), " "DescriptorTable(SRV(t0, numDescriptors=2), visibility=SHADER_VISIBILITY_ALL)," "DescriptorTable(Sampler(s0, numDescriptors=2), visibility=SHADER_VISIBILITY_PIXEL)," "DescriptorTable(CBV(b0, numDescriptors=1), visibility=SHADER_VISIBILITY_ALL)," "DescriptorTable(CBV(b1, numDescriptors=1), visibility=SHADER_VISIBILITY_ALL)," "DescriptorTable(CBV(b2, numDescriptors=1), visibility=SHADER_VISIBILITY_ALL)," "DescriptorTable(SRV(t3, numDescriptors=1), visibility=SHADER_VISIBILITY_ALL)," "DescriptorTable(UAV(u9, numDescriptors=2), visibility=SHADER_VISIBILITY_ALL),")] -VSOut main( const uint id : SV_OutputControlPointID, - const InputPatch< VSOut, 3 > triIn ) -{ - return triIn[id]; -} -)"; - - CComPtr pDiaDataSource; - CComPtr pDiaSession; - CompileAndRunAnnotationAndLoadDiaSource(m_dllSupport, hlsl, L"hs_6_0", - nullptr, &pDiaDataSource); - - VERIFY_SUCCEEDED(pDiaDataSource->openSession(&pDiaSession)); -} - -std::vector SplitAndPreserveEmptyLines(std::string const &str, - char delimeter) { - std::vector lines; - - auto const *p = str.data(); - auto const *justPastPreviousDelimiter = p; - while (p < str.data() + str.length()) { - if (*p == delimeter) { - lines.emplace_back(justPastPreviousDelimiter, - p - justPastPreviousDelimiter); - justPastPreviousDelimiter = p + 1; - p = justPastPreviousDelimiter; - } else { - p++; - } - } - - lines.emplace_back( - std::string(justPastPreviousDelimiter, p - justPastPreviousDelimiter)); - - return lines; -} - -TEST_F(PixTest, DxcPixDxilDebugInfo_InstructionOffsets) { - - if (m_ver.SkipDxilVersion(1, 5)) - return; - - const char *hlsl = - R"(RaytracingAccelerationStructure Scene : register(t0, space0); -RWTexture2D RenderTarget : register(u0); - -struct SceneConstantBuffer -{ - float4x4 projectionToWorld; - float4 cameraPosition; - float4 lightPosition; - float4 lightAmbientColor; - float4 lightDiffuseColor; -}; - -ConstantBuffer g_sceneCB : register(b0); - -struct RayPayload -{ - float4 color; -}; - -inline void GenerateCameraRay(uint2 index, out float3 origin, out float3 direction) -{ - float2 xy = index + 0.5f; // center in the middle of the pixel. - float2 screenPos = xy;// / DispatchRaysDimensions().xy * 2.0 - 1.0; - - // Invert Y for DirectX-style coordinates. - screenPos.y = -screenPos.y; - - // Unproject the pixel coordinate into a ray. - float4 world = /*mul(*/float4(screenPos, 0, 1)/*, g_sceneCB.projectionToWorld)*/; - - //world.xyz /= world.w; - origin = world.xyz; //g_sceneCB.cameraPosition.xyz; - direction = float3(1,0,0);//normalize(world.xyz - origin); -} - -void RaygenCommon() -{ - float3 rayDir; - float3 origin; - - // Generate a ray for a camera pixel corresponding to an index from the dispatched 2D grid. - GenerateCameraRay(DispatchRaysIndex().xy, origin, rayDir); - - // Trace the ray. - // Set the ray's extents. - RayDesc ray; - ray.Origin = origin; - ray.Direction = rayDir; - // Set TMin to a non-zero small value to avoid aliasing issues due to floating - point errors. - // TMin should be kept small to prevent missing geometry at close contact areas. - ray.TMin = 0.001; - ray.TMax = 10000.0; - RayPayload payload = { float4(0, 0, 0, 0) }; - TraceRay(Scene, RAY_FLAG_CULL_BACK_FACING_TRIANGLES, ~0, 0, 1, 0, ray, payload); - - // Write the raytraced color to the output texture. - // RenderTarget[DispatchRaysIndex().xy] = payload.color; -} - -[shader("raygeneration")] -void Raygen() -{ - RaygenCommon(); -} - -typedef BuiltInTriangleIntersectionAttributes MyAttributes; - -namespace ANameSpace -{ - namespace AContainedNamespace - { - float4 RoundaboutWayToReturnAmbientColor() - { - return g_sceneCB.lightAmbientColor; - } - } -} - - -[shader("closesthit")] -void InnerClosestHitShader(inout RayPayload payload, in MyAttributes attr) -{ - payload.color = ANameSpace::AContainedNamespace::RoundaboutWayToReturnAmbientColor(); -} - - -[shader("miss")] -void MyMissShader(inout RayPayload payload) -{ - payload.color = float4(1, 0, 0, 0); -})"; - - auto lines = SplitAndPreserveEmptyLines(std::string(hlsl), '\n'); - DWORD countOfSourceLines = static_cast(lines.size()); - - CComPtr pDiaDataSource; - CompileAndRunAnnotationAndLoadDiaSource(m_dllSupport, hlsl, L"lib_6_6", - nullptr, &pDiaDataSource); - - CComPtr session; - VERIFY_SUCCEEDED(pDiaDataSource->openSession(&session)); - - CComPtr Factory; - VERIFY_SUCCEEDED(session->QueryInterface(IID_PPV_ARGS(&Factory))); - - CComPtr dxilDebugger; - VERIFY_SUCCEEDED(Factory->NewDxcPixDxilDebugInfo(&dxilDebugger)); - - // Quick crash test for wrong filename: - CComPtr garbageOffsets; - dxilDebugger->InstructionOffsetsFromSourceLocation(L"garbage", 0, 0, - &garbageOffsets); - - // Since the API offers both source-from-instruction and - // instruction-from-source, we'll compare them against each other: - for (size_t line = 0; line < lines.size(); ++line) { - - auto lineNumber = static_cast(line); - - constexpr DWORD sourceLocationReaderOnlySupportsColumnZero = 0; - CComPtr offsets; - dxilDebugger->InstructionOffsetsFromSourceLocation( - defaultFilename, lineNumber, sourceLocationReaderOnlySupportsColumnZero, - &offsets); - - auto offsetCount = offsets->GetCount(); - for (DWORD offsetOrdinal = 0; offsetOrdinal < offsetCount; - ++offsetOrdinal) { - - DWORD instructionOffsetFromSource = - offsets->GetOffsetByIndex(offsetOrdinal); - - CComPtr sourceLocations; - VERIFY_SUCCEEDED(dxilDebugger->SourceLocationsFromInstructionOffset( - instructionOffsetFromSource, &sourceLocations)); - - auto count = sourceLocations->GetCount(); - for (DWORD sourceLocationOrdinal = 0; sourceLocationOrdinal < count; - ++sourceLocationOrdinal) { - DWORD lineNumber = - sourceLocations->GetLineNumberByIndex(sourceLocationOrdinal); - DWORD column = sourceLocations->GetColumnByIndex(sourceLocationOrdinal); - CComBSTR filename; - VERIFY_SUCCEEDED(sourceLocations->GetFileNameByIndex( - sourceLocationOrdinal, &filename)); - - VERIFY_IS_TRUE(lineNumber < countOfSourceLines); - - constexpr DWORD lineNumbersAndColumnsStartAtOne = 1; - VERIFY_IS_TRUE( - column - lineNumbersAndColumnsStartAtOne <= - static_cast( - lines.at(lineNumber - lineNumbersAndColumnsStartAtOne).size())); - VERIFY_IS_TRUE(0 == wcscmp(filename, defaultFilename)); - } - } - } -} - -static HRESULT UnAliasType(IDxcPixType *MaybeAlias, - IDxcPixType **OriginalType) { - *OriginalType = nullptr; - CComPtr Tmp(MaybeAlias); - - do { - HRESULT hr; - - CComPtr Alias; - hr = Tmp->UnAlias(&Alias); - if (FAILED(hr)) { - return hr; - } - if (hr == S_FALSE) { - break; - } - Tmp = Alias; - } while (true); - - *OriginalType = Tmp.Detach(); - return S_OK; -} - -static bool AddStorageComponents( - IDxcPixDxilStorage *pStorage, std::wstring Name, - std::vector &VariableComponents) { - CComPtr StorageType; - if (FAILED(pStorage->GetType(&StorageType))) { - return false; - } - - CComPtr UnAliasedType; - if (FAILED(UnAliasType(StorageType, &UnAliasedType))) { - return false; - } - - CComPtr ArrayType; - CComPtr ScalarType; - CComPtr StructType; - - if (!FAILED(UnAliasedType->QueryInterface(&ScalarType))) { - CComBSTR TypeName; - // StorageType is the type that the storage was defined in HLSL, i.e., - // it could be a typedef, const etc. - if (FAILED(StorageType->GetName(&TypeName))) { - return false; - } - - VariableComponents.emplace_back(PixTest::VariableComponentInfo{ - std::move(Name), std::wstring(TypeName)}); - return true; - } else if (!FAILED(UnAliasedType->QueryInterface(&ArrayType))) { - DWORD NumElements; - if (FAILED(ArrayType->GetNumElements(&NumElements))) { - return false; - } - - std::wstring BaseName = Name + L'['; - for (DWORD i = 0; i < NumElements; ++i) { - CComPtr EntryStorage; - if (FAILED(pStorage->Index(i, &EntryStorage))) { - return false; - } - - if (!AddStorageComponents(EntryStorage, - BaseName + std::to_wstring(i) + L"]", - VariableComponents)) { - return false; - } - } - } else if (!FAILED(UnAliasedType->QueryInterface(&StructType))) { - DWORD NumFields; - if (FAILED(StructType->GetNumFields(&NumFields))) { - return false; - } - - std::wstring BaseName = Name + L'.'; - for (DWORD i = 0; i < NumFields; ++i) { - CComPtr Field; - if (FAILED(StructType->GetFieldByIndex(i, &Field))) { - return false; - } - - CComBSTR FieldName; - if (FAILED(Field->GetName(&FieldName))) { - return false; - } - - CComPtr FieldStorage; - if (FAILED(pStorage->AccessField(FieldName, &FieldStorage))) { - return false; - } - - if (!AddStorageComponents(FieldStorage, - BaseName + std::wstring(FieldName), - VariableComponents)) { - return false; - } - } - - CComPtr BaseType; - if (SUCCEEDED(StructType->GetBaseType(&BaseType))) { - CComPtr BaseStorage; - if (FAILED(pStorage->AccessField(L"", &BaseStorage))) { - return false; - } - if (!AddStorageComponents(BaseStorage, Name, VariableComponents)) { - return false; - } - } - } - - return true; -} - -static bool ContainedBy(std::vector const &v1, - std::vector const &v2) { - for (auto const &c1 : v1) { - bool FoundThis = false; - for (auto const &c2 : v2) { - if (c1.Name == c2.Name && c1.Type == c2.Type) { - FoundThis = true; - break; - } - } - if (!FoundThis) { - return false; - } - } - return true; -} - -CComPtr -PixTest::CompileAndCreateDxcDebug(const char *hlsl, const wchar_t *profile, - IDxcIncludeHandler *includer) { - - CComPtr pDiaDataSource; - CompileAndRunAnnotationAndLoadDiaSource(m_dllSupport, hlsl, profile, includer, - &pDiaDataSource, {L"-Od"}); - - CComPtr session; - VERIFY_SUCCEEDED(pDiaDataSource->openSession(&session)); - - CComPtr Factory; - VERIFY_SUCCEEDED(session->QueryInterface(IID_PPV_ARGS(&Factory))); - - CComPtr dxilDebugger; - VERIFY_SUCCEEDED(Factory->NewDxcPixDxilDebugInfo(&dxilDebugger)); - return dxilDebugger; -} - -CComPtr -PixTest::GetLiveVariablesAt(const char *hlsl, - const char *lineAtWhichToExamineVariables, - IDxcPixDxilDebugInfo *dxilDebugger) { - - auto lines = SplitAndPreserveEmptyLines(std::string(hlsl), '\n'); - auto FindInterestingLine = std::find_if( - lines.begin(), lines.end(), - [&lineAtWhichToExamineVariables](std::string const &line) { - return line.find(lineAtWhichToExamineVariables) != std::string::npos; - }); - auto InterestingLine = - static_cast(FindInterestingLine - lines.begin()) + 1; - - CComPtr liveVariables; - for (; InterestingLine <= static_cast(lines.size()); - ++InterestingLine) { - CComPtr instructionOffsets; - if (SUCCEEDED(dxilDebugger->InstructionOffsetsFromSourceLocation( - defaultFilename, InterestingLine, 0, &instructionOffsets))) { - if (instructionOffsets->GetCount() > 0) { - auto instructionOffset = instructionOffsets->GetOffsetByIndex(0); - if (SUCCEEDED(dxilDebugger->GetLiveVariablesAt(instructionOffset, - &liveVariables))) { - break; - } - } - } - } - VERIFY_IS_TRUE(liveVariables != nullptr); - - return liveVariables; -} - -void PixTest::TestGlobalStaticCase( - const char *hlsl, const wchar_t *profile, - const char *lineAtWhichToExamineVariables, - std::vector const &ExpectedVariables) { - - auto dxilDebugger = CompileAndCreateDxcDebug(hlsl, profile); - - auto liveVariables = - GetLiveVariablesAt(hlsl, lineAtWhichToExamineVariables, dxilDebugger); - - DWORD count; - VERIFY_SUCCEEDED(liveVariables->GetCount(&count)); - bool FoundGlobal = false; - for (DWORD i = 0; i < count; ++i) { - CComPtr variable; - VERIFY_SUCCEEDED(liveVariables->GetVariableByIndex(i, &variable)); - CComBSTR name; - variable->GetName(&name); - if (0 == wcscmp(name, L"global.globalStruct")) { - FoundGlobal = true; - CComPtr storage; - VERIFY_SUCCEEDED(variable->GetStorage(&storage)); - std::vector ActualVariableComponents; - VERIFY_IS_TRUE(AddStorageComponents(storage, L"global.globalStruct", - ActualVariableComponents)); - VERIFY_IS_TRUE(ContainedBy(ActualVariableComponents, ExpectedVariables)); - break; - } - } - VERIFY_IS_TRUE(FoundGlobal); -} - -TEST_F(PixTest, - DxcPixDxilDebugInfo_GlobalBackedGlobalStaticEmbeddedArrays_NoDbgValue) { - if (m_ver.SkipDxilVersion(1, 5)) - return; - - const char *hlsl = R"( -RWStructuredBuffer floatRWUAV: register(u0); - -struct GlobalStruct -{ - int IntArray[2]; - float FloatArray[2]; -}; - -static GlobalStruct globalStruct; -[noinline] -void fn() -{ - float Accumulator; - globalStruct.IntArray[0] = floatRWUAV[0]; - globalStruct.IntArray[1] = floatRWUAV[1]; - globalStruct.FloatArray[0] = floatRWUAV[4]; - globalStruct.FloatArray[1] = floatRWUAV[5]; - Accumulator = 0; - - uint killSwitch = 0; - - [loop] // do not unroll this - while (true) - { - Accumulator += globalStruct.FloatArray[killSwitch % 2]; - - if (killSwitch++ == 4) break; - } - - floatRWUAV[0] = Accumulator + globalStruct.IntArray[0] + globalStruct.IntArray[1]; -} - -[numthreads(1, 1, 1)] -void main() -{ - fn(); -} - -)"; - // The above HLSL should generate a module that represents the FloatArray - // member as a global, and the IntArray as an alloca. Since only embedded - // arrays are present in GlobalStruct, no dbg.value will be present for - // globalStruct. We expect the value-to-declare pass to generate its own - // dbg.value for stores into FloatArray. We will observe those dbg.value here - // via the PIX-specific debug data API. - - std::vector Expected; - Expected.push_back({L"global.globalStruct.IntArray[0]", L"int"}); - Expected.push_back({L"global.globalStruct.IntArray[1]", L"int"}); - Expected.push_back({L"global.globalStruct.FloatArray[0]", L"float"}); - Expected.push_back({L"global.globalStruct.FloatArray[1]", L"float"}); - TestGlobalStaticCase(hlsl, L"lib_6_6", "float Accumulator", Expected); -} - -TEST_F( - PixTest, - DxcPixDxilDebugInfo_GlobalBackedGlobalStaticEmbeddedArrays_WithDbgValue) { - if (m_ver.SkipDxilVersion(1, 5)) - return; - - const char *hlsl = R"( -RWStructuredBuffer floatRWUAV: register(u0); - -struct GlobalStruct -{ - float Accumulator; - int IntArray[2]; - float FloatArray[2]; -}; - -static GlobalStruct globalStruct; -[numthreads(1, 1, 1)] -void main() -{ - globalStruct.IntArray[0] = floatRWUAV[0]; - globalStruct.IntArray[1] = floatRWUAV[1]; - globalStruct.FloatArray[0] = floatRWUAV[4]; - globalStruct.FloatArray[1] = floatRWUAV[5]; - globalStruct.Accumulator = 0; - - uint killSwitch = 0; - - [loop] // do not unroll this - while (true) - { - globalStruct.Accumulator += globalStruct.FloatArray[killSwitch % 2]; - - if (killSwitch++ == 4) break; - } - - floatRWUAV[0] = globalStruct.Accumulator + globalStruct.IntArray[0] + globalStruct.IntArray[1]; -} - -)"; - // The above HLSL should generate a module that represents the FloatArray - // member as a global, and the IntArray as an alloca. The presence of - // Accumulator in the GlobalStruct will force a dbg.value to be present for - // globalStruct. We expect the value-to-declare pass to find that dbg.value. - - std::vector Expected; - Expected.push_back({L"global.globalStruct.Accumulator", L"float"}); - Expected.push_back({L"global.globalStruct.IntArray[0]", L"int"}); - Expected.push_back({L"global.globalStruct.IntArray[1]", L"int"}); - Expected.push_back({L"global.globalStruct.FloatArray[0]", L"float"}); - Expected.push_back({L"global.globalStruct.FloatArray[1]", L"float"}); - TestGlobalStaticCase(hlsl, L"cs_6_6", "float Accumulator", Expected); -} - -TEST_F( - PixTest, - DxcPixDxilDebugInfo_GlobalBackedGlobalStaticEmbeddedArrays_ArrayInValues) { - if (m_ver.SkipDxilVersion(1, 5)) - return; - - const char *hlsl = R"( -RWStructuredBuffer floatRWUAV: register(u0); - -struct GlobalStruct -{ - float Accumulator; - int IntArray[2]; - float FloatArray[2]; -}; - -static GlobalStruct globalStruct; -[numthreads(1, 1, 1)] -void main() -{ - globalStruct.IntArray[0] =0; - globalStruct.IntArray[1] =1; - globalStruct.FloatArray[0] = floatRWUAV[4]; - globalStruct.FloatArray[1] = floatRWUAV[5]; - globalStruct.Accumulator = 0; - - uint killSwitch = 0; - - [loop] // do not unroll this - while (true) - { - globalStruct.Accumulator += globalStruct.FloatArray[killSwitch % 2]; - - if (killSwitch++ == 4) break; - } - - floatRWUAV[0] = globalStruct.Accumulator + globalStruct.IntArray[0] + globalStruct.IntArray[1]; -} - -)"; - // The above HLSL should generate a module that represents the FloatArray - // member as a global, and the IntArray as individual values. - - std::vector Expected; - Expected.push_back({L"global.globalStruct.Accumulator", L"float"}); - Expected.push_back({L"global.globalStruct.IntArray[0]", L"int"}); - Expected.push_back({L"global.globalStruct.IntArray[1]", L"int"}); - Expected.push_back({L"global.globalStruct.FloatArray[0]", L"float"}); - Expected.push_back({L"global.globalStruct.FloatArray[1]", L"float"}); - TestGlobalStaticCase(hlsl, L"lib_6_6", "float Accumulator", Expected); -} - -TEST_F(PixTest, DxcPixDxilDebugInfo_StructInheritance) { - if (m_ver.SkipDxilVersion(1, 5)) - return; - - const char *hlsl = R"( -RWStructuredBuffer floatRWUAV: register(u0); - -struct AStruct -{ - float f; - int i[2]; -}; - -struct ADerivedStruct : AStruct -{ - bool b[2]; -}; - -int AFunction(ADerivedStruct theStruct) -{ - return theStruct.i[0] + theStruct.i[1] + theStruct.f + (theStruct.b[0] ? 1 : 0) + (theStruct.b[1] ? 2 : 3); // InterestingLine -} - -[numthreads(1, 1, 1)] -void main() -{ - ADerivedStruct aStruct; - aStruct.f = floatRWUAV[1]; - aStruct.i[0] = floatRWUAV[2]; - aStruct.i[1] = floatRWUAV[3]; - aStruct.b[0] = floatRWUAV[4] != 0.0; - aStruct.b[1] = floatRWUAV[5] != 0.0; - floatRWUAV[0] = AFunction(aStruct); -} - -)"; - auto dxilDebugger = CompileAndCreateDxcDebug(hlsl, L"cs_6_6"); - - auto liveVariables = - GetLiveVariablesAt(hlsl, "InterestingLine", dxilDebugger); - - DWORD count; - VERIFY_SUCCEEDED(liveVariables->GetCount(&count)); - bool FoundTheStruct = false; - for (DWORD i = 0; i < count; ++i) { - CComPtr variable; - VERIFY_SUCCEEDED(liveVariables->GetVariableByIndex(i, &variable)); - CComBSTR name; - variable->GetName(&name); - if (0 == wcscmp(name, L"theStruct")) { - FoundTheStruct = true; - CComPtr storage; - VERIFY_SUCCEEDED(variable->GetStorage(&storage)); - std::vector ActualVariableComponents; - VERIFY_IS_TRUE(AddStorageComponents(storage, L"theStruct", - ActualVariableComponents)); - std::vector Expected; - Expected.push_back({L"theStruct.b[0]", L"bool"}); - Expected.push_back({L"theStruct.b[1]", L"bool"}); - Expected.push_back({L"theStruct.f", L"float"}); - Expected.push_back({L"theStruct.i[0]", L"int"}); - Expected.push_back({L"theStruct.i[1]", L"int"}); - VERIFY_IS_TRUE(ContainedBy(ActualVariableComponents, Expected)); - break; - } - } - VERIFY_IS_TRUE(FoundTheStruct); -} - -TEST_F(PixTest, DxcPixDxilDebugInfo_StructContainedResource) { - if (m_ver.SkipDxilVersion(1, 5)) - return; - - const char *hlsl = R"( -RWStructuredBuffer floatRWUAV: register(u0); -Texture2D srv2DTexture : register(t0, space1); -struct AStruct -{ - float f; - Texture2D tex; -}; - -float4 AFunction(AStruct theStruct) -{ - return theStruct.tex.Load(int3(0, 0, 0)) + theStruct.f.xxxx; // InterestingLine -} - -[numthreads(1, 1, 1)] -void main() -{ - AStruct aStruct; - aStruct.f = floatRWUAV[1]; - aStruct.tex = srv2DTexture; - floatRWUAV[0] = AFunction(aStruct).x; -} - -)"; - auto dxilDebugger = CompileAndCreateDxcDebug(hlsl, L"cs_6_6"); - - auto liveVariables = - GetLiveVariablesAt(hlsl, "InterestingLine", dxilDebugger); - - DWORD count; - VERIFY_SUCCEEDED(liveVariables->GetCount(&count)); - bool FoundTheStruct = false; - for (DWORD i = 0; i < count; ++i) { - CComPtr variable; - VERIFY_SUCCEEDED(liveVariables->GetVariableByIndex(i, &variable)); - CComBSTR name; - variable->GetName(&name); - if (0 == wcscmp(name, L"theStruct")) { - FoundTheStruct = true; - CComPtr storage; - VERIFY_SUCCEEDED(variable->GetStorage(&storage)); - std::vector ActualVariableComponents; - VERIFY_IS_TRUE(AddStorageComponents(storage, L"theStruct", - ActualVariableComponents)); - std::vector Expected; - Expected.push_back({L"theStruct.f", L"float"}); - VERIFY_IS_TRUE(ContainedBy(ActualVariableComponents, Expected)); - break; - } - } - VERIFY_IS_TRUE(FoundTheStruct); -} - -TEST_F(PixTest, DxcPixDxilDebugInfo_StructStaticInit) { - if (m_ver.SkipDxilVersion(1, 5)) - return; - - const char *hlsl = R"( -RWStructuredBuffer floatRWUAV: register(u0); -struct AStruct -{ - float f; - static AStruct Init(float fi) - { - AStruct ret; - ret.f = fi; - for(int i =0; i < 4; ++i) - { - ret.f += floatRWUAV[i+2]; - } - return ret; - } -}; - -[numthreads(1, 1, 1)] -void main() -{ - AStruct aStruct = AStruct::Init(floatRWUAV[1]); - floatRWUAV[0] = aStruct.f; // InterestingLine -} - -)"; - auto dxilDebugger = CompileAndCreateDxcDebug(hlsl, L"cs_6_6"); - - auto liveVariables = - GetLiveVariablesAt(hlsl, "InterestingLine", dxilDebugger); - - DWORD count; - VERIFY_SUCCEEDED(liveVariables->GetCount(&count)); - bool FoundTheStruct = false; - for (DWORD i = 0; i < count; ++i) { - CComPtr variable; - VERIFY_SUCCEEDED(liveVariables->GetVariableByIndex(i, &variable)); - CComBSTR name; - variable->GetName(&name); - if (0 == wcscmp(name, L"aStruct")) { - FoundTheStruct = true; - CComPtr storage; - VERIFY_SUCCEEDED(variable->GetStorage(&storage)); - std::vector ActualVariableComponents; - VERIFY_IS_TRUE( - AddStorageComponents(storage, L"aStruct", ActualVariableComponents)); - std::vector Expected; - Expected.push_back({L"aStruct.f", L"float"}); - VERIFY_IS_TRUE(ContainedBy(ActualVariableComponents, Expected)); - break; - } - } - VERIFY_IS_TRUE(FoundTheStruct); -} - -TEST_F(PixTest, DxcPixDxilDebugInfo_StructMemberFnFirst) { - if (m_ver.SkipDxilVersion(1, 5)) - return; - - const char *hlsl = R"( -RWStructuredBuffer floatRWUAV: register(u0); -struct AStruct -{ - void Init(float fi); - float f; -}; - -void AStruct::Init(float fi) -{ - AStruct ret; - f = fi; - for(int i =0; i < 4; ++i) - { - f += floatRWUAV[i+2]; - } -} - -[numthreads(1, 1, 1)] -void main() -{ - AStruct aStruct; - aStruct.Init(floatRWUAV[1]); - floatRWUAV[0] = aStruct.f; // InterestingLine -} - -)"; - auto dxilDebugger = CompileAndCreateDxcDebug(hlsl, L"cs_6_6"); - - auto liveVariables = - GetLiveVariablesAt(hlsl, "InterestingLine", dxilDebugger); - - DWORD count; - VERIFY_SUCCEEDED(liveVariables->GetCount(&count)); - bool FoundTheStruct = false; - for (DWORD i = 0; i < count; ++i) { - CComPtr variable; - VERIFY_SUCCEEDED(liveVariables->GetVariableByIndex(i, &variable)); - CComBSTR name; - variable->GetName(&name); - if (0 == wcscmp(name, L"aStruct")) { - FoundTheStruct = true; - CComPtr storage; - VERIFY_SUCCEEDED(variable->GetStorage(&storage)); - std::vector ActualVariableComponents; - VERIFY_IS_TRUE( - AddStorageComponents(storage, L"aStruct", ActualVariableComponents)); - std::vector Expected; - Expected.push_back({L"aStruct.f", L"float"}); - VERIFY_IS_TRUE(ContainedBy(ActualVariableComponents, Expected)); - break; - } - } - VERIFY_IS_TRUE(FoundTheStruct); -} - -void PixTest::TestUnnamedTypeCase(const char *hlsl, - const wchar_t *expectedTypeName) { - if (m_ver.SkipDxilVersion(1, 2)) - return; - auto dxilDebugger = CompileAndCreateDxcDebug(hlsl, L"cs_6_0"); - auto liveVariables = - GetLiveVariablesAt(hlsl, "InterestingLine", dxilDebugger); - DWORD count; - VERIFY_SUCCEEDED(liveVariables->GetCount(&count)); - bool FoundTheVariable = false; - for (DWORD i = 0; i < count; ++i) { - CComPtr variable; - VERIFY_SUCCEEDED(liveVariables->GetVariableByIndex(i, &variable)); - CComBSTR name; - variable->GetName(&name); - if (0 == wcscmp(name, L"glbl")) { - FoundTheVariable = true; - CComPtr type; - VERIFY_SUCCEEDED(variable->GetType(&type)); - CComBSTR typeName; - VERIFY_SUCCEEDED(type->GetName(&typeName)); - VERIFY_ARE_EQUAL(typeName, expectedTypeName); - break; - } - } - VERIFY_IS_TRUE(FoundTheVariable); -} - -TEST_F(PixTest, DxcPixDxilDebugInfo_UnnamedConstStruct) { - const char *hlsl = R"( -RWStructuredBuffer floatRWUAV: register(u0); - -[numthreads(1, 1, 1)] -void main() -{ - const struct - { - float fg; - RWStructuredBuffer buf; - } glbl = {42.f, floatRWUAV}; - - float f = glbl.fg + glbl.buf[1]; // InterestingLine - floatRWUAV[0] = f; -} - -)"; + IFT(m_dllSupport.CreateInstance(CLSID_DxcLibrary, &pLibrary)); - TestUnnamedTypeCase(hlsl, L"const "); -} + CComPtr pNewContainer; -TEST_F(PixTest, DxcPixDxilDebugInfo_UnnamedStruct) { - const char *hlsl = R"( -RWStructuredBuffer floatRWUAV: register(u0); + // Use the container assembler to build a new container from the + // recently-modified DXIL bitcode. This container will contain new copies of + // things like input signature etc., which will supersede the ones from the + // original compiled shader's container. + { + CComPtr pAssembler; + IFT(m_dllSupport.CreateInstance(CLSID_DxcAssembler, &pAssembler)); -[numthreads(1, 1, 1)] -void main() -{ - struct - { - float fg; - RWStructuredBuffer buf; - } glbl = {42.f, floatRWUAV}; - glbl.fg = 41.f; - float f = glbl.fg + glbl.buf[1]; // InterestingLine - floatRWUAV[0] = f; -} + CComPtr pAssembleResult; + VERIFY_SUCCEEDED( + pAssembler->AssembleToContainer(pNewDxilBlob, &pAssembleResult)); -)"; + CComPtr pAssembleErrors; + VERIFY_SUCCEEDED(pAssembleResult->GetErrorBuffer(&pAssembleErrors)); - TestUnnamedTypeCase(hlsl, L""); -} + if (pAssembleErrors && pAssembleErrors->GetBufferSize() != 0) { + OutputDebugStringA( + static_cast(pAssembleErrors->GetBufferPointer())); + VERIFY_SUCCEEDED(E_FAIL); + } -TEST_F(PixTest, DxcPixDxilDebugInfo_UnnamedArray) { - const char *hlsl = R"( -RWStructuredBuffer floatRWUAV: register(u0); + VERIFY_SUCCEEDED(pAssembleResult->GetResult(&pNewContainer)); + } -[numthreads(1, 1, 1)] -void main() -{ - struct - { - float fg; - RWStructuredBuffer buf; - } glbl[2] = {{42.f, floatRWUAV},{43.f, floatRWUAV}}; - float f = glbl[0].fg + glbl[1].buf[1]; // InterestingLine - floatRWUAV[0] = f; -} + // Now copy over the blobs from the original container that won't have been + // invalidated by changing the shader code itself, using the container + // reflection API + { + // Wrap the original code in a container blob + CComPtr pContainer; + VERIFY_SUCCEEDED(pLibrary->CreateBlobWithEncodingFromPinned( + static_cast(const_cast(originalShaderBytecode)), + static_cast(originalShaderLength), CP_ACP, &pContainer)); -)"; + CComPtr pReflection; + IFT(m_dllSupport.CreateInstance(CLSID_DxcContainerReflection, + &pReflection)); - TestUnnamedTypeCase(hlsl, L"[]"); -} + // Load the reflector from the original shader + VERIFY_SUCCEEDED(pReflection->Load(pContainer)); -TEST_F(PixTest, DxcPixDxilDebugInfo_UnnamedField) { - const char *hlsl = R"( -RWStructuredBuffer floatRWUAV: register(u0); + UINT32 partIndex; -[numthreads(1, 1, 1)] -void main() -{ - struct - { - struct { - float fg; - RWStructuredBuffer buf; - } contained; - } glbl = { {42.f, floatRWUAV} }; - float f = glbl.contained.fg + glbl.contained.buf[1]; // InterestingLine - floatRWUAV[0] = f; -} + if (SUCCEEDED(pReflection->FindFirstPartKind(hlsl::DFCC_PrivateData, + &partIndex))) { + CComPtr pPart; + VERIFY_SUCCEEDED(pReflection->GetPartContent(partIndex, &pPart)); -)"; + CComPtr pContainerBuilder; + IFT(m_dllSupport.CreateInstance(CLSID_DxcContainerBuilder, + &pContainerBuilder)); - if (m_ver.SkipDxilVersion(1, 2)) - return; - auto dxilDebugger = CompileAndCreateDxcDebug(hlsl, L"cs_6_0"); - auto liveVariables = - GetLiveVariablesAt(hlsl, "InterestingLine", dxilDebugger); - DWORD count; - VERIFY_SUCCEEDED(liveVariables->GetCount(&count)); - bool FoundTheVariable = false; - for (DWORD i = 0; i < count; ++i) { - CComPtr variable; - VERIFY_SUCCEEDED(liveVariables->GetVariableByIndex(i, &variable)); - CComBSTR name; - variable->GetName(&name); - if (0 == wcscmp(name, L"glbl")) { - CComPtr type; - VERIFY_SUCCEEDED(variable->GetType(&type)); - CComPtr structType; - VERIFY_SUCCEEDED(type->QueryInterface(IID_PPV_ARGS(&structType))); - DWORD fieldCount = 0; - VERIFY_SUCCEEDED(structType->GetNumFields(&fieldCount)); - VERIFY_ARE_EQUAL(fieldCount, 1); - // Just a crash test: - CComPtr structField; - structType->GetFieldByName(L"", &structField); - VERIFY_SUCCEEDED(structType->GetFieldByIndex(0, &structField)); - FoundTheVariable = true; - CComPtr fieldType; - VERIFY_SUCCEEDED(structField->GetType(&fieldType)); - CComBSTR typeName; - VERIFY_SUCCEEDED(fieldType->GetName(&typeName)); - VERIFY_ARE_EQUAL(typeName, L""); - break; - } - } - VERIFY_IS_TRUE(FoundTheVariable); -} + VERIFY_SUCCEEDED(pContainerBuilder->Load(pNewContainer)); -class DxcIncludeHandlerForInjectedSourcesForPix : public IDxcIncludeHandler { -private: - DXC_MICROCOM_REF_FIELD(m_dwRef) + VERIFY_SUCCEEDED( + pContainerBuilder->AddPart(hlsl::DFCC_PrivateData, pPart)); - std::vector> m_files; - PixTest *m_pixTest; + CComPtr pBuildResult; -public: - DXC_MICROCOM_ADDREF_RELEASE_IMPL(m_dwRef) - DxcIncludeHandlerForInjectedSourcesForPix( - PixTest *pixTest, std::vector> files) - : m_dwRef(0), m_pixTest(pixTest), m_files(files){}; + VERIFY_SUCCEEDED(pContainerBuilder->SerializeContainer(&pBuildResult)); - HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, void **ppvObject) { - return DoBasicQueryInterface(this, iid, ppvObject); - } + CComPtr pBuildErrors; + VERIFY_SUCCEEDED(pBuildResult->GetErrorBuffer(&pBuildErrors)); - HRESULT insertIncludeFile(LPCWSTR pFilename, IDxcBlobEncoding *pBlob, - UINT32 dataLen) { - return E_FAIL; - } + if (pBuildErrors && pBuildErrors->GetBufferSize() != 0) { + OutputDebugStringA( + reinterpret_cast(pBuildErrors->GetBufferPointer())); + VERIFY_SUCCEEDED(E_FAIL); + } - HRESULT STDMETHODCALLTYPE LoadSource(LPCWSTR pFilename, - IDxcBlob **ppIncludeSource) override { - for (auto const &file : m_files) { - std::wstring prependedWithDotHack = L"./" + file.first; - if (prependedWithDotHack == std::wstring(pFilename)) { - CComPtr blob; - m_pixTest->CreateBlobFromText(file.second.c_str(), &blob); - *ppIncludeSource = blob.Detach(); - return S_OK; + VERIFY_SUCCEEDED(pBuildResult->GetResult(&pNewContainer)); } } - return E_FAIL; - } -}; -void PixTest::RunSubProgramsCase(const char *hlsl) { - CComPtr pIncludeHandler = - new DxcIncludeHandlerForInjectedSourcesForPix( - this, {{L"../include1/samefilename.h", - "float fn1(int c, float v) { for(int i = 0; i< c; ++ i) v += " - "sqrt(v); return v; } "}, - {L"../include2/samefilename.h", - R"( -float4 fn2( float3 f3, float d, bool sanitize = true ) -{ - if (sanitize) - { - f3 = any(isnan(f3) | isinf(f3)) ? 0 : clamp(f3, 0, 1034.f); - d = (isnan(d) | isinf(d)) ? 0 : clamp(d, 0, 1024.f); + *ppNewShaderOut = pNewContainer.Detach(); } - if( d != 0 ) d = max( d, -1024.f); - return float4( f3, d );} -)"}}); - auto dxilDebugger = - CompileAndCreateDxcDebug(hlsl, L"cs_6_0", pIncludeHandler); + class ModuleAndHangersOn { + std::unique_ptr llvmContext; + std::unique_ptr llvmModule; + DxilModule *dxilModule; - struct SourceLocations { - CComBSTR Filename; - DWORD Column; - DWORD Line; - }; + public: + ModuleAndHangersOn(IDxcBlob *pBlob) { + // Verify we have a valid dxil container. + const DxilContainerHeader *pContainer = IsDxilContainerLike( + pBlob->GetBufferPointer(), pBlob->GetBufferSize()); + VERIFY_IS_NOT_NULL(pContainer); + VERIFY_IS_TRUE(IsValidDxilContainer(pContainer, pBlob->GetBufferSize())); - std::vector sourceLocations; - - DWORD instructionOffset = 0; - CComPtr DxcSourceLocations; - while (SUCCEEDED(dxilDebugger->SourceLocationsFromInstructionOffset( - instructionOffset++, &DxcSourceLocations))) { - auto count = DxcSourceLocations->GetCount(); - for (DWORD i = 0; i < count; ++i) { - sourceLocations.push_back({}); - DxcSourceLocations->GetFileNameByIndex(i, - &sourceLocations.back().Filename); - sourceLocations.back().Line = DxcSourceLocations->GetLineNumberByIndex(i); - sourceLocations.back().Column = DxcSourceLocations->GetColumnByIndex(i); - } - DxcSourceLocations = nullptr; - } + // Get Dxil part from container. + DxilPartIterator it = + std::find_if(begin(pContainer), end(pContainer), + DxilPartIsType(DFCC_ShaderDebugInfoDXIL)); + VERIFY_IS_FALSE(it == end(pContainer)); - auto it = sourceLocations.begin(); - VERIFY_IS_FALSE(it == sourceLocations.end()); + const DxilProgramHeader *pProgramHeader = + reinterpret_cast(GetDxilPartData(*it)); + VERIFY_IS_TRUE(IsValidDxilProgramHeader(pProgramHeader, (*it)->PartSize)); - // The list of source locations should start with the containing file: - while (it != sourceLocations.end() && it->Filename == L"source.hlsl") - it++; - VERIFY_IS_FALSE(it == sourceLocations.end()); + // Get a pointer to the llvm bitcode. + const char *pIL; + uint32_t pILLength; + GetDxilProgramBitcode(pProgramHeader, &pIL, &pILLength); - // Then have a bunch of "../include2/samefilename.h" - VERIFY_ARE_EQUAL_WSTR(L"./../include2/samefilename.h", it->Filename); - while (it != sourceLocations.end() && - it->Filename == L"./../include2/samefilename.h") - it++; - VERIFY_IS_FALSE(it == sourceLocations.end()); + // Parse llvm bitcode into a module. + std::unique_ptr pBitcodeBuf( + llvm::MemoryBuffer::getMemBuffer(llvm::StringRef(pIL, pILLength), "", + false)); - // Then some more main file: - VERIFY_ARE_EQUAL_WSTR(L"source.hlsl", it->Filename); - while (it != sourceLocations.end() && it->Filename == L"source.hlsl") - it++; + llvmContext.reset(new llvm::LLVMContext); - // And that should be the end: - VERIFY_IS_TRUE(it == sourceLocations.end()); -} + llvm::ErrorOr> pModule( + llvm::parseBitcodeFile(pBitcodeBuf->getMemBufferRef(), *llvmContext)); + if (std::error_code ec = pModule.getError()) { + VERIFY_FAIL(); + } -TEST_F(PixTest, DxcPixDxilDebugInfo_SubPrograms) { - if (m_ver.SkipDxilVersion(1, 2)) - return; + llvmModule = std::move(pModule.get()); - const char *hlsl = R"( + dxilModule = DxilModule::TryGetDxilModule(llvmModule.get()); + } -#include "../include1/samefilename.h" -namespace n1 { -#include "../include2/samefilename.h" -} -RWStructuredBuffer floatRWUAV: register(u0); + DxilModule &GetDxilModule() { return *dxilModule; } + }; -[numthreads(1, 1, 1)] -void main() -{ - float4 result = n1::fn2( - float3(floatRWUAV[0], floatRWUAV[1], floatRWUAV[2]), - floatRWUAV[3]); - floatRWUAV[0] = result.x; - floatRWUAV[1] = result.y; - floatRWUAV[2] = result.z; - floatRWUAV[3] = result.w; -} + struct AggregateOffsetAndSize { + unsigned countOfMembers; + unsigned offset; + unsigned size; + }; + struct AllocaWrite { + std::string memberName; + uint32_t regBase; + uint32_t regSize; + uint64_t index; + }; + struct TestableResults { + std::vector OffsetAndSizes; + std::vector AllocaWrites; + }; -)"; - RunSubProgramsCase(hlsl); -} + TestableResults TestStructAnnotationCase(const char *hlsl, + const wchar_t *optimizationLevel, + bool validateCoverage = true, + const wchar_t *profile = L"as_6_5"); + void ValidateAllocaWrite(std::vector const &allocaWrites, + size_t index, const char *name); + CComPtr RunShaderAccessTrackingPass(IDxcBlob *blob); + std::string RunDxilPIXAddTidToAmplificationShaderPayloadPass(IDxcBlob *blob); + CComPtr RunDxilPIXMeshShaderOutputPass(IDxcBlob *blob); + CComPtr RunDxilPIXDXRInvocationsLog(IDxcBlob *blob); +}; -TEST_F(PixTest, DxcPixDxilDebugInfo_SubProgramsInNamespaces) { - if (m_ver.SkipDxilVersion(1, 2)) - return; +bool PixTest::InitSupport() { + if (!m_dllSupport.IsEnabled()) { + VERIFY_SUCCEEDED(m_dllSupport.Initialize()); + m_ver.Initialize(m_dllSupport); + } + return true; +} +TEST_F(PixTest, CompileDebugDisasmPDB) { const char *hlsl = R"( + [RootSignature("")] + float main(float pos : A) : SV_Target { + float x = abs(pos); + float y = sin(pos); + float z = x + y; + return z; + } + )"; + CComPtr pLib; + VERIFY_SUCCEEDED(m_dllSupport.CreateInstance(CLSID_DxcLibrary, &pLib)); -#include "../include1/samefilename.h" -#include "../include2/samefilename.h" + CComPtr pCompiler; + CComPtr pCompiler2; -RWStructuredBuffer floatRWUAV: register(u0); + CComPtr pResult; + CComPtr pSource; + CComPtr pProgram; + CComPtr pPdbBlob; + CComHeapPtr pDebugName; -[numthreads(1, 1, 1)] -void main() -{ - float4 result = fn2( - float3(floatRWUAV[0], floatRWUAV[1], floatRWUAV[2]), - floatRWUAV[3]); - floatRWUAV[0] = result.x; - floatRWUAV[1] = result.y; - floatRWUAV[2] = result.z; - floatRWUAV[3] = result.w; -} + VERIFY_SUCCEEDED(CreateCompiler(m_dllSupport, &pCompiler)); + VERIFY_SUCCEEDED(pCompiler.QueryInterface(&pCompiler2)); + CreateBlobFromText(m_dllSupport, hlsl, &pSource); + LPCWSTR args[] = {L"/Zi", L"/Qembed_debug"}; + VERIFY_SUCCEEDED(pCompiler2->CompileWithDebug( + pSource, L"source.hlsl", L"main", L"ps_6_0", args, _countof(args), + nullptr, 0, nullptr, &pResult, &pDebugName, &pPdbBlob)); + VERIFY_SUCCEEDED(pResult->GetResult(&pProgram)); -)"; - RunSubProgramsCase(hlsl); + // Test that disassembler can consume a PDB container + CComPtr pDisasm; + VERIFY_SUCCEEDED(pCompiler->Disassemble(pPdbBlob, &pDisasm)); } CComPtr PixTest::RunShaderAccessTrackingPass(IDxcBlob *blob) { @@ -3580,12 +572,12 @@ void MSMain( )"; - auto as = - Compile(dynamicResourceDecriptorHeapAccess, L"as_6_6", {}, L"ASMain"); + auto as = Compile(m_dllSupport, dynamicResourceDecriptorHeapAccess, L"as_6_6", + {}, L"ASMain"); RunDxilPIXAddTidToAmplificationShaderPayloadPass(as); - auto ms = - Compile(dynamicResourceDecriptorHeapAccess, L"ms_6_6", {}, L"MSMain"); + auto ms = Compile(m_dllSupport, dynamicResourceDecriptorHeapAccess, L"ms_6_6", + {}, L"MSMain"); RunDxilPIXMeshShaderOutputPass(ms); } @@ -3807,12 +799,12 @@ PixTest::TestableResults PixTest::TestStructAnnotationCase( const char *hlsl, const wchar_t *optimizationLevel, bool validateCoverage, const wchar_t *profile) { CComPtr pBlob = - Compile(hlsl, profile, + Compile(m_dllSupport, hlsl, profile, {optimizationLevel, L"-HV", L"2018", L"-enable-16bit-types"}); CComPtr pDxil = FindModule(DFCC_ShaderDebugInfoDXIL, pBlob); - PassOutput passOutput = RunAnnotationPasses(pDxil); + PassOutput passOutput = RunAnnotationPasses(m_dllSupport, pDxil); auto pAnnotated = passOutput.blob; @@ -3913,7 +905,7 @@ PixTest::TestableResults PixTest::TestStructAnnotationCase( for (ValueLocation const &valueLocation : passOutput.valueLocations) // For each allocas and dxil values { - if (CurRegIdx == valueLocation.base && + if (CurRegIdx == (unsigned)valueLocation.base && (unsigned)valueLocation.count == cover.countOfMembers) { VERIFY_IS_FALSE(found); found = true; @@ -4049,9 +1041,10 @@ void Raygen1() )"; // This is just a crash test until we decide what the right way forward - CComPtr pBlob = Compile(hlsl, L"lib_6_6", {optimization}); + CComPtr pBlob = + Compile(m_dllSupport, hlsl, L"lib_6_6", {optimization}); CComPtr pDxil = FindModule(DFCC_ShaderDebugInfoDXIL, pBlob); - RunAnnotationPasses(pDxil); + RunAnnotationPasses(m_dllSupport, pDxil); } } @@ -4335,7 +1328,7 @@ void main() VERIFY_ARE_EQUAL(0u, Testables.OffsetAndSizes[0].offset); VERIFY_ARE_EQUAL(4u * 32u, Testables.OffsetAndSizes[0].size); } else { - VERIFY_ARE_EQUAL(4, Testables.OffsetAndSizes.size()); + VERIFY_ARE_EQUAL(4u, Testables.OffsetAndSizes.size()); for (unsigned i = 0; i < 4; i++) { VERIFY_ARE_EQUAL(1u, Testables.OffsetAndSizes[i].countOfMembers); VERIFY_ARE_EQUAL(i * 32u, Testables.OffsetAndSizes[i].offset); @@ -4381,7 +1374,7 @@ void main() VERIFY_ARE_EQUAL(0u, Testables.OffsetAndSizes[0].offset); VERIFY_ARE_EQUAL(2u * 32u, Testables.OffsetAndSizes[0].size); } else { - VERIFY_ARE_EQUAL(2, Testables.OffsetAndSizes.size()); + VERIFY_ARE_EQUAL(2u, Testables.OffsetAndSizes.size()); for (unsigned i = 0; i < 2; i++) { VERIFY_ARE_EQUAL(1u, Testables.OffsetAndSizes[i].countOfMembers); VERIFY_ARE_EQUAL(i * 32u, Testables.OffsetAndSizes[i].offset); @@ -4491,7 +1484,7 @@ void main() VERIFY_ARE_EQUAL(0u, Testables.OffsetAndSizes[0].offset); VERIFY_ARE_EQUAL(5u * 32u, Testables.OffsetAndSizes[0].size); } else { - VERIFY_ARE_EQUAL(5, Testables.OffsetAndSizes.size()); + VERIFY_ARE_EQUAL(5u, Testables.OffsetAndSizes.size()); for (unsigned i = 0; i < 5; i++) { VERIFY_ARE_EQUAL(1u, Testables.OffsetAndSizes[i].countOfMembers); VERIFY_ARE_EQUAL(i * 32u, Testables.OffsetAndSizes[i].offset); @@ -4650,7 +1643,7 @@ void main() VERIFY_ARE_EQUAL(32u * 3u, Testables.OffsetAndSizes[0].size); } - VERIFY_ARE_EQUAL(3, Testables.AllocaWrites.size()); + VERIFY_ARE_EQUAL(3u, Testables.AllocaWrites.size()); ValidateAllocaWrite(Testables.AllocaWrites, 0, "i32"); ValidateAllocaWrite(Testables.AllocaWrites, 1, "e.f2.x"); ValidateAllocaWrite(Testables.AllocaWrites, 2, "e.f2.y"); @@ -5189,9 +2182,10 @@ void MyMissShader(inout RayPayload payload) payload.color = float4(1, 0, 0, 0); })"; - CComPtr pBlob = Compile(hlsl, L"lib_6_6", {optimization}); + CComPtr pBlob = + Compile(m_dllSupport, hlsl, L"lib_6_6", {optimization}); CComPtr pDxil = FindModule(DFCC_ShaderDebugInfoDXIL, pBlob); - auto outputLines = RunAnnotationPasses(pDxil).lines; + auto outputLines = RunAnnotationPasses(m_dllSupport, pDxil).lines; const char instructionRangeLabel[] = "InstructionRange:"; @@ -5231,9 +2225,9 @@ void MyMissShader(inout RayPayload payload) return z; } )"; - pBlob = Compile(PixelShader, L"ps_6_6", {optimization}); + pBlob = Compile(m_dllSupport, PixelShader, L"ps_6_6", {optimization}); pDxil = FindModule(DFCC_ShaderDebugInfoDXIL, pBlob); - outputLines = RunAnnotationPasses(pDxil).lines; + outputLines = RunAnnotationPasses(m_dllSupport, pDxil).lines; countOfInstructionRangeLines = 0; for (auto const &line : outputLines) { @@ -5255,7 +2249,9 @@ void MyMissShader(inout RayPayload payload) // Now check that the initial value parameter works: const int startingInstructionOrdinal = 1234; - outputLines = RunAnnotationPasses(pDxil, startingInstructionOrdinal).lines; + outputLines = + RunAnnotationPasses(m_dllSupport, pDxil, startingInstructionOrdinal) + .lines; countOfInstructionRangeLines = 0; for (auto const &line : outputLines) { @@ -5316,9 +2312,10 @@ float4 main(VS_OUTPUT_ENV input) : SV_Target {L"ps_6_2", {L"-Od", L"-HV", L"2018", L"-enable-16bit-types"}}}; for (auto const &args : argSets) { - CComPtr pBlob = Compile(hlsl, args.first, args.second); + CComPtr pBlob = + Compile(m_dllSupport, hlsl, args.first, args.second); CComPtr pDxil = FindModule(DFCC_ShaderDebugInfoDXIL, pBlob); - RunAnnotationPasses(pDxil); + RunAnnotationPasses(m_dllSupport, pDxil); } } } @@ -5500,7 +2497,7 @@ float4 main(int i : A, float j : B) : SV_TARGET } )x"; - auto compiled = Compile(dynamicTextureAccess, L"ps_6_6"); + auto compiled = Compile(m_dllSupport, dynamicTextureAccess, L"ps_6_6"); auto pOptimizedContainer = RunShaderAccessTrackingPass(compiled); const char *pBlobContent = @@ -5540,104 +2537,6 @@ float4 main(int i : A, float j : B) : SV_TARGET VERIFY_IS_TRUE(foundGlobalRS); } -TEST_F(PixTest, SymbolManager_Embedded2DArray) { - const char *code = R"x( -struct EmbeddedStruct -{ - uint32_t TwoDArray[2][2]; -}; - -struct smallPayload -{ - uint32_t OneInt; - EmbeddedStruct embeddedStruct; - uint64_t bigOne; -}; - -[numthreads(1, 1, 1)] -void ASMain() -{ - smallPayload p; - p.OneInt = -137; - p.embeddedStruct.TwoDArray[0][0] = 252; - p.embeddedStruct.TwoDArray[0][1] = 253; - p.embeddedStruct.TwoDArray[1][0] = 254; - p.embeddedStruct.TwoDArray[1][1] = 255; - p.bigOne = 123456789; - - DispatchMesh(2, 1, 1, p); -} - -)x"; - - auto compiled = Compile(code, L"as_6_5", {}, L"ASMain"); - - auto debugPart = GetDebugPart( - m_dllSupport, WrapInNewContainer(RunAnnotationPasses(compiled).blob)); - - CComPtr library; - VERIFY_SUCCEEDED(m_dllSupport.CreateInstance(CLSID_DxcLibrary, &library)); - - CComPtr programStream; - VERIFY_SUCCEEDED( - library->CreateStreamFromBlobReadOnly(debugPart, &programStream)); - - CComPtr diaDataSource; - VERIFY_SUCCEEDED( - m_dllSupport.CreateInstance(CLSID_DxcDiaDataSource, &diaDataSource)); - - VERIFY_SUCCEEDED(diaDataSource->loadDataFromIStream(programStream)); - - CComPtr session; - VERIFY_SUCCEEDED(diaDataSource->openSession(&session)); - - CComPtr Factory; - VERIFY_SUCCEEDED(session->QueryInterface(&Factory)); - CComPtr dxilDebugger; - VERIFY_SUCCEEDED(Factory->NewDxcPixDxilDebugInfo(&dxilDebugger)); - - auto lines = SplitAndPreserveEmptyLines(code, '\n'); - auto DispatchMeshLineFind = - std::find_if(lines.begin(), lines.end(), [](std::string const &line) { - return line.find("DispatchMesh") != std::string::npos; - }); - auto DispatchMeshLine = - static_cast(DispatchMeshLineFind - lines.begin()) + 2; - - CComPtr instructionOffsets; - VERIFY_SUCCEEDED(dxilDebugger->InstructionOffsetsFromSourceLocation( - L"source.hlsl", DispatchMeshLine, 0, &instructionOffsets)); - VERIFY_IS_TRUE(instructionOffsets->GetCount() > 0); - DWORD InstructionOrdinal = instructionOffsets->GetOffsetByIndex(0); - CComPtr liveVariables; - VERIFY_SUCCEEDED( - dxilDebugger->GetLiveVariablesAt(InstructionOrdinal, &liveVariables)); - CComPtr variable; - VERIFY_SUCCEEDED(liveVariables->GetVariableByIndex(0, &variable)); - CComBSTR name; - variable->GetName(&name); - VERIFY_ARE_EQUAL_WSTR(name, L"p"); - CComPtr type; - VERIFY_SUCCEEDED(variable->GetType(&type)); - CComPtr structType; - VERIFY_SUCCEEDED(type->QueryInterface(IID_PPV_ARGS(&structType))); - auto ValidateStructMember = [&structType](DWORD index, const wchar_t *name, - uint64_t offset) { - CComPtr member; - VERIFY_SUCCEEDED(structType->GetFieldByIndex(index, &member)); - CComBSTR actualName; - VERIFY_SUCCEEDED(member->GetName(&actualName)); - VERIFY_ARE_EQUAL_WSTR(actualName, name); - DWORD actualOffset = 0; - VERIFY_SUCCEEDED(member->GetOffsetInBits(&actualOffset)); - VERIFY_ARE_EQUAL(actualOffset, offset); - }; - - ValidateStructMember(0, L"OneInt", 0); - ValidateStructMember(1, L"embeddedStruct", 4 * 8); - ValidateStructMember(2, L"bigOne", 24 * 8); -} - TEST_F(PixTest, DxilPIXDXRInvocationsLog_SanityTest) { const char *source = R"x( @@ -5668,8 +2567,6 @@ void MyMiss(inout MyPayload payload) )x"; - auto compiledLib = Compile(source, L"lib_6_6", {}); + auto compiledLib = Compile(m_dllSupport, source, L"lib_6_6", {}); RunDxilPIXDXRInvocationsLog(compiledLib); } - -#endif diff --git a/tools/clang/unittests/HLSL/PixTestUtils.cpp b/tools/clang/unittests/HLSL/PixTestUtils.cpp new file mode 100644 index 0000000000..01ded6093c --- /dev/null +++ b/tools/clang/unittests/HLSL/PixTestUtils.cpp @@ -0,0 +1,398 @@ +/////////////////////////////////////////////////////////////////////////////// +// // +// PixTestUtils.h // +// Copyright (C) Microsoft Corporation. All rights reserved. // +// This file is distributed under the University of Illinois Open Source // +// License. See LICENSE.TXT for details. // +// // +// Provides utility functions for PIX tests. // +// // +/////////////////////////////////////////////////////////////////////////////// + +#include "PixTestUtils.h" + +#include "dxc/DxilContainer/DxilContainer.h" +#include "dxc/Support/Global.h" +#include "dxc/Support/dxcapi.use.h" +#include "dxc/Test/DxcTestUtils.h" +#include "dxc/Test/HlslTestUtils.h" + +static std::vector Tokenize(const std::string &str, + const char *delimiters) { + std::vector tokens; + std::string copy = str; + + for (auto i = strtok(©[0], delimiters); i != nullptr; + i = strtok(nullptr, delimiters)) { + tokens.push_back(i); + } + + return tokens; +} + +// For RunAnnotationPasses +namespace { +std::string ToString(std::wstring from) { + std::string ret; + ret.assign(from.data(), from.data() + from.size()); + return ret; +} +std::string ExtractBracedSubstring(std::string const &line) { + auto open = line.find('{'); + auto close = line.find('}'); + if (open != std::string::npos && close != std::string::npos && + open + 1 < close) { + return line.substr(open + 1, close - open - 1); + } + return ""; +} + +int ExtractMetaInt32Value(std::string const &token) { + if (token.substr(0, 5) == " i32 ") { + return atoi(token.c_str() + 5); + } + return -1; +} +std::map> +MetaDataKeyToRegisterNumber(std::vector const &lines) { + // Find lines of the exemplary form + // "!249 = !{i32 0, i32 20}" (in the case of a DXIL value) + // "!196 = !{i32 1, i32 5, i32 1}" (in the case of a DXIL alloca reg) + // The first i32 is a tag indicating what type of metadata this is. + // It doesn't matter if we parse poorly and find some data that don't match + // this pattern, as long as we do find all the data that do match (we won't + // be looking up the non-matchers in the resultant map anyway). + + const char *valueMetaDataAssignment = "= !{i32 0, "; + const char *allocaMetaDataAssignment = "= !{i32 1, "; + + std::map> ret; + for (auto const &line : lines) { + if (line[0] == '!') { + if (line.find(valueMetaDataAssignment) != std::string::npos || + line.find(allocaMetaDataAssignment) != std::string::npos) { + int key = atoi(line.c_str() + 1); + if (key != 0) { + std::string bitInBraces = ExtractBracedSubstring(line); + if (bitInBraces != "") { + auto tokens = Tokenize(bitInBraces.c_str(), ","); + if (tokens.size() == 2) { + auto value = ExtractMetaInt32Value(tokens[1]); + if (value != -1) { + ret[key] = {value, 1}; + } + } + if (tokens.size() == 3) { + auto value0 = ExtractMetaInt32Value(tokens[1]); + if (value0 != -1) { + auto value1 = ExtractMetaInt32Value(tokens[2]); + if (value1 != -1) { + ret[key] = {value0, value1}; + } + } + } + } + } + } + } + } + return ret; +} + +std::string ExtractValueName(std::string const &line) { + auto foundEquals = line.find('='); + if (foundEquals != std::string::npos && foundEquals > 4) { + return line.substr(2, foundEquals - 3); + } + return ""; +} +using DxilRegisterToNameMap = std::map, std::string>; + +void CheckForAndInsertMapEntryIfFound( + DxilRegisterToNameMap ®isterToNameMap, + std::map> const &metaDataKeyToValue, + std::string const &line, char const *tag, size_t tagLength) { + auto foundAlloca = line.find(tag); + if (foundAlloca != std::string::npos) { + auto valueName = ExtractValueName(line); + if (valueName != "") { + int key = atoi(line.c_str() + foundAlloca + tagLength); + auto foundKey = metaDataKeyToValue.find(key); + if (foundKey != metaDataKeyToValue.end()) { + registerToNameMap[foundKey->second] = valueName; + } + } + } +} + +// Here's some exemplary DXIL to help understand what's going on: +// +// %5 = alloca [1 x float], i32 0, !pix-alloca-reg !196 +// %25 = call float @dx.op.loadInput.f32(...), !pix-dxil-reg !255 +// +// The %5 is an alloca name, and the %25 is a regular llvm value. +// The meta-data tags !pix-alloca-reg and !pix-dxil-reg denote this, +// and provide keys !196 and !255 respectively. +// Those keys are then given values later on in the DXIL like this: +// +// !196 = !{i32 1, i32 5, i32 1} (5 is the base alloca, 1 is the offset into +// it) !255 = !{i32 0, i32 23} +// +// So the task is first to find all of those key/value pairs and make a map +// from e.g. !196 to, e.g., (5,1), and then to find all of the alloca and reg +// tags and look up the keys in said map to build the map we're actually +// looking for, with key->values like e.g. "%5"->(5,1) and "%25"->(23) + +DxilRegisterToNameMap BuildDxilRegisterToNameMap(char const *disassembly) { + DxilRegisterToNameMap ret; + + auto lines = Tokenize(disassembly, "\n"); + + auto metaDataKeyToValue = MetaDataKeyToRegisterNumber(lines); + + for (auto const &line : lines) { + if (line[0] == '!') { + // Stop searching for values when we've run into the metadata region of + // the disassembly + break; + } + const char allocaTag[] = "!pix-alloca-reg !"; + CheckForAndInsertMapEntryIfFound(ret, metaDataKeyToValue, line, allocaTag, + _countof(allocaTag) - 1); + const char valueTag[] = "!pix-dxil-reg !"; + CheckForAndInsertMapEntryIfFound(ret, metaDataKeyToValue, line, valueTag, + _countof(valueTag) - 1); + } + return ret; +} + +std::wstring Disassemble(dxc::DxcDllSupport &dllSupport, IDxcBlob *pProgram) { + CComPtr pCompiler; + VERIFY_SUCCEEDED(pix_test::CreateCompiler(dllSupport, &pCompiler)); + + CComPtr pDbgDisassembly; + VERIFY_SUCCEEDED(pCompiler->Disassemble(pProgram, &pDbgDisassembly)); + std::string disText = BlobToUtf8(pDbgDisassembly); + CA2W disTextW(disText.c_str(), CP_UTF8); + return std::wstring(disTextW); +} + +} // namespace + +// For CreateBlobFromText +namespace { + +void CreateBlobPinned(dxc::DxcDllSupport &dllSupport, + _In_bytecount_(size) LPCVOID data, SIZE_T size, + UINT32 codePage, IDxcBlobEncoding **ppBlob) { + CComPtr library; + IFT(dllSupport.CreateInstance(CLSID_DxcLibrary, &library)); + IFT(library->CreateBlobWithEncodingFromPinned(data, size, codePage, ppBlob)); +} +} // namespace + +namespace pix_test { +std::vector SplitAndPreserveEmptyLines(std::string const &str, + char delimeter) { + std::vector lines; + + auto const *p = str.data(); + auto const *justPastPreviousDelimiter = p; + while (p < str.data() + str.length()) { + if (*p == delimeter) { + lines.emplace_back(justPastPreviousDelimiter, + p - justPastPreviousDelimiter); + justPastPreviousDelimiter = p + 1; + p = justPastPreviousDelimiter; + } else { + p++; + } + } + + lines.emplace_back( + std::string(justPastPreviousDelimiter, p - justPastPreviousDelimiter)); + + return lines; +} + +void CompileAndLogErrors(dxc::DxcDllSupport &dllSupport, LPCSTR pText, + LPCWSTR pTargetProfile, std::vector &args, + IDxcIncludeHandler *includer, + _Outptr_ IDxcBlob **ppResult) { + CComPtr pCompiler; + CComPtr pSource; + CComPtr pResult; + HRESULT hrCompile; + *ppResult = nullptr; + VERIFY_SUCCEEDED(dllSupport.CreateInstance(CLSID_DxcCompiler, &pCompiler)); + Utf8ToBlob(dllSupport, pText, &pSource); + VERIFY_SUCCEEDED(pCompiler->Compile(pSource, L"source.hlsl", L"main", + pTargetProfile, args.data(), args.size(), + nullptr, 0, includer, &pResult)); + + VERIFY_SUCCEEDED(pResult->GetStatus(&hrCompile)); + if (FAILED(hrCompile)) { + CComPtr textBlob; + VERIFY_SUCCEEDED(pResult->GetErrorBuffer(&textBlob)); + std::wstring text = BlobToWide(textBlob); + WEX::Logging::Log::Comment(text.c_str()); + } + VERIFY_SUCCEEDED(hrCompile); + VERIFY_SUCCEEDED(pResult->GetResult(ppResult)); +} + +PassOutput RunAnnotationPasses(dxc::DxcDllSupport &dllSupport, IDxcBlob *dxil, + int startingLineNumber) { + CComPtr pOptimizer; + VERIFY_SUCCEEDED(dllSupport.CreateInstance(CLSID_DxcOptimizer, &pOptimizer)); + std::vector Options; + Options.push_back(L"-opt-mod-passes"); + Options.push_back(L"-dxil-dbg-value-to-dbg-declare"); + std::wstring annotationCommandLine = + L"-dxil-annotate-with-virtual-regs,startInstruction=" + + std::to_wstring(startingLineNumber); + Options.push_back(annotationCommandLine.c_str()); + + CComPtr pOptimizedModule; + CComPtr pText; + VERIFY_SUCCEEDED(pOptimizer->RunOptimizer( + dxil, Options.data(), Options.size(), &pOptimizedModule, &pText)); + + std::string outputText; + if (pText->GetBufferSize() != 0) { + outputText = reinterpret_cast(pText->GetBufferPointer()); + } + + auto disasm = ToString(Disassemble(dllSupport, pOptimizedModule)); + + auto registerToName = BuildDxilRegisterToNameMap(disasm.c_str()); + + std::vector valueLocations; + + for (auto const &r2n : registerToName) { + valueLocations.push_back({r2n.first.first, r2n.first.second}); + } + + return {std::move(pOptimizedModule), std::move(valueLocations), + Tokenize(outputText.c_str(), "\n")}; +} + +CComPtr GetDebugPart(dxc::DxcDllSupport &dllSupport, + IDxcBlob *container) { + + CComPtr pLib; + VERIFY_SUCCEEDED(dllSupport.CreateInstance(CLSID_DxcLibrary, &pLib)); + CComPtr pReflection; + + VERIFY_SUCCEEDED( + dllSupport.CreateInstance(CLSID_DxcContainerReflection, &pReflection)); + VERIFY_SUCCEEDED(pReflection->Load(container)); + + UINT32 index; + VERIFY_SUCCEEDED( + pReflection->FindFirstPartKind(hlsl::DFCC_ShaderDebugInfoDXIL, &index)); + + CComPtr debugPart; + VERIFY_SUCCEEDED(pReflection->GetPartContent(index, &debugPart)); + + return debugPart; +} + +void CreateBlobFromText(dxc::DxcDllSupport &dllSupport, const char *pText, + IDxcBlobEncoding **ppBlob) { + CreateBlobPinned(dllSupport, pText, strlen(pText) + 1, CP_UTF8, ppBlob); +} + +HRESULT CreateCompiler(dxc::DxcDllSupport &dllSupport, + IDxcCompiler **ppResult) { + return dllSupport.CreateInstance(CLSID_DxcCompiler, ppResult); +} + +CComPtr Compile(dxc::DxcDllSupport &dllSupport, const char *hlsl, + const wchar_t *target, + std::vector extraArgs, + const wchar_t *entry) { + CComPtr pCompiler; + CComPtr pResult; + CComPtr pSource; + + VERIFY_SUCCEEDED(CreateCompiler(dllSupport, &pCompiler)); + CreateBlobFromText(dllSupport, hlsl, &pSource); + std::vector args = {L"/Zi", L"/Qembed_debug"}; + args.insert(args.end(), extraArgs.begin(), extraArgs.end()); + VERIFY_SUCCEEDED(pCompiler->Compile( + pSource, L"source.hlsl", entry, target, args.data(), + static_cast(args.size()), nullptr, 0, nullptr, &pResult)); + + HRESULT compilationStatus; + VERIFY_SUCCEEDED(pResult->GetStatus(&compilationStatus)); + if (FAILED(compilationStatus)) { + CComPtr pErrros; + VERIFY_SUCCEEDED(pResult->GetErrorBuffer(&pErrros)); + CA2W errorTextW(static_cast(pErrros->GetBufferPointer()), + CP_UTF8); + WEX::Logging::Log::Error(errorTextW); + return {}; + } + +#if 0 // handy for debugging + { + CComPtr pProgram; + CheckOperationSucceeded(pResult, &pProgram); + + CComPtr pLib; + VERIFY_SUCCEEDED(m_dllSupport.CreateInstance(CLSID_DxcLibrary, &pLib)); + const hlsl::DxilContainerHeader *pContainer = hlsl::IsDxilContainerLike( + pProgram->GetBufferPointer(), pProgram->GetBufferSize()); + VERIFY_IS_NOT_NULL(pContainer); + hlsl::DxilPartIterator partIter = + std::find_if(hlsl::begin(pContainer), hlsl::end(pContainer), + hlsl::DxilPartIsType(hlsl::DFCC_ShaderDebugInfoDXIL)); + const hlsl::DxilProgramHeader *pProgramHeader = + (const hlsl::DxilProgramHeader *)hlsl::GetDxilPartData(*partIter); + uint32_t bitcodeLength; + const char *pBitcode; + CComPtr pProgramPdb; + hlsl::GetDxilProgramBitcode(pProgramHeader, &pBitcode, &bitcodeLength); + VERIFY_SUCCEEDED(pLib->CreateBlobFromBlob( + pProgram, pBitcode - (char *)pProgram->GetBufferPointer(), + bitcodeLength, &pProgramPdb)); + + CComPtr pDbgDisassembly; + VERIFY_SUCCEEDED(pCompiler->Disassemble(pProgramPdb, &pDbgDisassembly)); + std::string disText = BlobToUtf8(pDbgDisassembly); + CA2W disTextW(disText.c_str(), CP_UTF8); + WEX::Logging::Log::Comment(disTextW); + } +#endif + + CComPtr pProgram; + VERIFY_SUCCEEDED(pResult->GetResult(&pProgram)); + + return pProgram; +} + +CComPtr WrapInNewContainer(dxc::DxcDllSupport &dllSupport, + IDxcBlob *part) { + CComPtr pAssembler; + IFT(dllSupport.CreateInstance(CLSID_DxcAssembler, &pAssembler)); + + CComPtr pAssembleResult; + VERIFY_SUCCEEDED(pAssembler->AssembleToContainer(part, &pAssembleResult)); + + CComPtr pAssembleErrors; + VERIFY_SUCCEEDED(pAssembleResult->GetErrorBuffer(&pAssembleErrors)); + + if (pAssembleErrors && pAssembleErrors->GetBufferSize() != 0) { + OutputDebugStringA( + static_cast(pAssembleErrors->GetBufferPointer())); + VERIFY_SUCCEEDED(E_FAIL); + } + + CComPtr pNewContainer; + VERIFY_SUCCEEDED(pAssembleResult->GetResult(&pNewContainer)); + + return pNewContainer; +} + +} // namespace pix_test diff --git a/tools/clang/unittests/HLSL/PixTestUtils.h b/tools/clang/unittests/HLSL/PixTestUtils.h new file mode 100644 index 0000000000..fd9ad9d736 --- /dev/null +++ b/tools/clang/unittests/HLSL/PixTestUtils.h @@ -0,0 +1,60 @@ +/////////////////////////////////////////////////////////////////////////////// +// // +// PixTestUtils.h // +// Copyright (C) Microsoft Corporation. All rights reserved. // +// This file is distributed under the University of Illinois Open Source // +// License. See LICENSE.TXT for details. // +// // +// Provides utility functions for PIX tests. // +// // +/////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "dxc/Support/WinIncludes.h" +#include "dxc/dxcapi.h" + +#include +#include + +namespace dxc { +class DxcDllSupport; +} + +namespace pix_test { + +std::vector SplitAndPreserveEmptyLines(std::string const &str, + char delimeter); + +CComPtr GetDebugPart(dxc::DxcDllSupport &dllSupport, + IDxcBlob *container); +void CreateBlobFromText(dxc::DxcDllSupport &dllSupport, const char *pText, + IDxcBlobEncoding **ppBlob); + +HRESULT CreateCompiler(dxc::DxcDllSupport &dllSupport, IDxcCompiler **ppResult); +CComPtr Compile(dxc::DxcDllSupport &dllSupport, const char *hlsl, + const wchar_t *target, + std::vector extraArgs = {}, + const wchar_t *entry = L"main"); + +void CompileAndLogErrors(dxc::DxcDllSupport &dllSupport, LPCSTR pText, + LPCWSTR pTargetProfile, std::vector &args, + IDxcIncludeHandler *includer, + _Outptr_ IDxcBlob **ppResult); + +CComPtr WrapInNewContainer(dxc::DxcDllSupport &dllSupport, + IDxcBlob *part); + +struct ValueLocation { + int base; + int count; +}; +struct PassOutput { + CComPtr blob; + std::vector valueLocations; + std::vector lines; +}; + +PassOutput RunAnnotationPasses(dxc::DxcDllSupport &dllSupport, IDxcBlob *dxil, + int startingLineNumber = 0); +} // namespace pix_test diff --git a/tools/clang/unittests/HLSL/RewriterTest.cpp b/tools/clang/unittests/HLSL/RewriterTest.cpp index 1cbc5b62bc..613c8561a3 100644 --- a/tools/clang/unittests/HLSL/RewriterTest.cpp +++ b/tools/clang/unittests/HLSL/RewriterTest.cpp @@ -28,13 +28,16 @@ #include #include #include +#ifdef _WIN32 #include #include +#endif #include "dxc/dxcapi.h" +#ifdef _WIN32 #include #include +#endif -#include "WexTestClass.h" #include "dxc/Test/HLSLTestData.h" #include "dxc/Test/HlslTestUtils.h" #include "dxc/Test/DxcTestUtils.h" @@ -48,50 +51,56 @@ using namespace std; using namespace hlsl_test; +#ifdef _WIN32 class RewriterTest { +#else +class RewriterTest : public ::testing::Test { +#endif public: BEGIN_TEST_CLASS(RewriterTest) TEST_CLASS_PROPERTY(L"Parallel", L"true") TEST_METHOD_PROPERTY(L"Priority", L"0") END_TEST_CLASS() - TEST_METHOD(RunArrayLength); - TEST_METHOD(RunAttributes); - TEST_METHOD(RunAnonymousStruct); - TEST_METHOD(RunCppErrors); - TEST_METHOD(RunForceExtern); - TEST_METHOD(RunIndexingOperator); - TEST_METHOD(RunIntrinsicExamples); - TEST_METHOD(RunMatrixAssignments); - TEST_METHOD(RunMatrixPackOrientation); - TEST_METHOD(RunMatrixSyntax); - TEST_METHOD(RunPackReg); - TEST_METHOD(RunScalarAssignments); - TEST_METHOD(RunShared); - TEST_METHOD(RunStructAssignments); - TEST_METHOD(RunTemplateChecks); - TEST_METHOD(RunTypemodsSyntax); - TEST_METHOD(RunVarmodsSyntax); - TEST_METHOD(RunVectorAssignments); - TEST_METHOD(RunVectorSyntaxMix); - TEST_METHOD(RunVectorSyntax); - TEST_METHOD(RunIncludes); - TEST_METHOD(RunSpirv); - TEST_METHOD(RunStructMethods); - TEST_METHOD(RunPredefines); - TEST_METHOD(RunWideOneByte); - TEST_METHOD(RunWideTwoByte); - TEST_METHOD(RunWideThreeByteBadChar); - TEST_METHOD(RunWideThreeByte); - TEST_METHOD(RunNonUnicode); - TEST_METHOD(RunEffect); - TEST_METHOD(RunSemanticDefines); - TEST_METHOD(RunNoFunctionBody); - TEST_METHOD(RunNoFunctionBodyInclude); - TEST_METHOD(RunNoStatic); - TEST_METHOD(RunKeepUserMacro); - TEST_METHOD(RunExtractUniforms); - TEST_METHOD(RunGlobalsUsedInMethod); + TEST_CLASS_SETUP(InitSupport); + + TEST_METHOD(RunArrayLength) + TEST_METHOD(RunAttributes) + TEST_METHOD(RunAnonymousStruct) + TEST_METHOD(RunCppErrors) + TEST_METHOD(RunForceExtern) + TEST_METHOD(RunIndexingOperator) + TEST_METHOD(RunIntrinsicExamples) + TEST_METHOD(RunMatrixAssignments) + TEST_METHOD(RunMatrixPackOrientation) + TEST_METHOD(RunMatrixSyntax) + TEST_METHOD(RunPackReg) + TEST_METHOD(RunScalarAssignments) + TEST_METHOD(RunShared) + TEST_METHOD(RunStructAssignments) + TEST_METHOD(RunTemplateChecks) + TEST_METHOD(RunTypemodsSyntax) + TEST_METHOD(RunVarmodsSyntax) + TEST_METHOD(RunVectorAssignments) + TEST_METHOD(RunVectorSyntaxMix) + TEST_METHOD(RunVectorSyntax) + TEST_METHOD(RunIncludes) + TEST_METHOD(RunSpirv) + TEST_METHOD(RunStructMethods) + TEST_METHOD(RunPredefines) + TEST_METHOD(RunWideOneByte) + TEST_METHOD(RunWideTwoByte) + TEST_METHOD(RunWideThreeByteBadChar) + TEST_METHOD(RunWideThreeByte) + TEST_METHOD(RunNonUnicode) + TEST_METHOD(RunEffect) + TEST_METHOD(RunSemanticDefines) + TEST_METHOD(RunNoFunctionBody) + TEST_METHOD(RunNoFunctionBodyInclude) + TEST_METHOD(RunNoStatic) + TEST_METHOD(RunKeepUserMacro) + TEST_METHOD(RunExtractUniforms) + TEST_METHOD(RunGlobalsUsedInMethod) TEST_METHOD(RunRewriterFails) dxc::DxcDllSupport m_dllSupport; @@ -142,13 +151,6 @@ class RewriterTest { } HRESULT CreateRewriter(IDxcRewriter **pRewriter) { - if (!m_dllSupport.IsEnabled()) { - VERIFY_SUCCEEDED(m_dllSupport.Initialize()); - - CComPtr library; - VERIFY_SUCCEEDED(m_dllSupport.CreateInstance(CLSID_DxcLibrary, &library)); - VERIFY_SUCCEEDED(library->CreateIncludeHandler(&m_pIncludeHandler)); - } return m_dllSupport.CreateInstance(CLSID_DxcRewriter, pRewriter); } @@ -169,33 +171,21 @@ class RewriterTest { } struct FileWithBlob { - CAtlFile file; - CAtlFileMapping mapping; CComPtr BlobEncoding; FileWithBlob(dxc::DxcDllSupport &support, LPCWSTR path) { - IFT(file.Create(path, GENERIC_READ, FILE_SHARE_READ, OPEN_EXISTING)); - IFT(mapping.MapFile(file)); CComPtr library; IFT(support.CreateInstance(CLSID_DxcLibrary, &library)); - IFT(library->CreateBlobWithEncodingFromPinned( - mapping.GetData(), mapping.GetMappingSize(), CP_UTF8, &BlobEncoding)); + UINT32 codePage = CP_UTF8; + IFT(library->CreateBlobFromFile(path, &codePage, &BlobEncoding)); } }; bool CompareGold(std::string &firstPass, LPCWSTR goldPath) { - HANDLE goldHandle = - CreateFileW(goldPath, GENERIC_READ, 0, 0, OPEN_EXISTING, 0, 0); - VERIFY_ARE_NOT_EQUAL(goldHandle, INVALID_HANDLE_VALUE); - CHandle checkedGoldHandle(goldHandle); - - DWORD gFileSize = GetFileSize(goldHandle, NULL); - CComHeapPtr gReadBuff; - VERIFY_IS_TRUE(gReadBuff.AllocateBytes(gFileSize)); - DWORD gnumActualRead; - VERIFY_WIN32_BOOL_SUCCEEDED(ReadFile(checkedGoldHandle, gReadBuff.m_pData, - gFileSize, &gnumActualRead, NULL)); - std::string gold = std::string((LPSTR)gReadBuff, gnumActualRead); + FileWithBlob goldBlob(m_dllSupport, goldPath); + std::string gold = + std::string((LPSTR)goldBlob.BlobEncoding->GetBufferPointer(), + goldBlob.BlobEncoding->GetBufferSize()); gold.erase(std::remove(gold.begin(), gold.end(), '\r'), gold.end()); // Kept because useful for debugging @@ -266,9 +256,16 @@ class RewriterTest { TestFileName = TestFileName.substr(index1 + 1, index2 - (index1 + 1)); wchar_t TempPath[MAX_PATH]; +#ifdef _WIN32 DWORD length = GetTempPathW(MAX_PATH, TempPath); VERIFY_WIN32_BOOL_SUCCEEDED(length != 0); - +#else + const char *TempDir = std::getenv("TMPDIR"); + if (TempDir == nullptr) { + TempDir = "/tmp"; + } + mbstowcs(TempPath, TempDir, strlen(TempDir) + 1); +#endif std::wstring PrintName(TempPath); PrintName += TestFileName; PrintName += L"_rewrite_test_pass.txt"; @@ -315,6 +312,16 @@ class RewriterTest { } }; +bool RewriterTest::InitSupport() { + if (!m_dllSupport.IsEnabled()) { + VERIFY_SUCCEEDED(m_dllSupport.Initialize()); + CComPtr library; + VERIFY_SUCCEEDED(m_dllSupport.CreateInstance(CLSID_DxcLibrary, &library)); + VERIFY_SUCCEEDED(library->CreateIncludeHandler(&m_pIncludeHandler)); + } + return true; +} + TEST_F(RewriterTest, RunArrayLength) { CheckVerifiesHLSL(L"rewriter\\array-length-rw.hlsl", L"rewriter\\correct_rewrites\\array-length-rw_gold.hlsl"); @@ -562,7 +569,12 @@ TEST_F(RewriterTest, RunWideThreeByte) { 0); // const added by default } +#ifdef _WIN32 TEST_F(RewriterTest, RunNonUnicode) { +#else +// Need to enable ANSI Greek support. +TEST_F(RewriterTest, DISABLED_RunNonUnicode) { +#endif CComPtr pRewriter; VERIFY_SUCCEEDED(CreateRewriter(&pRewriter)); CComPtr pRewriteResult; diff --git a/tools/clang/unittests/HLSL/VerifierTest.cpp b/tools/clang/unittests/HLSL/VerifierTest.cpp index c0721ab950..615993ae8a 100644 --- a/tools/clang/unittests/HLSL/VerifierTest.cpp +++ b/tools/clang/unittests/HLSL/VerifierTest.cpp @@ -17,7 +17,6 @@ #include #ifdef _WIN32 -#include "WexTestClass.h" #define TEST_CLASS_DERIVATION #else #define TEST_CLASS_DERIVATION : public ::testing::Test @@ -34,57 +33,9 @@ class VerifierTest TEST_CLASS_DERIVATION { TEST_METHOD_PROPERTY(L"Priority", L"0") END_TEST_CLASS() - TEST_METHOD(RunArrayIndexOutOfBounds) - TEST_METHOD(RunArrayLength) - TEST_METHOD(RunAtomicFloatErrors) - TEST_METHOD(RunAttributes) - TEST_METHOD(RunBuiltinTypesNoInheritance) - TEST_METHOD(RunConstExpr) - TEST_METHOD(RunConstAssign) - TEST_METHOD(RunConstDefault) - TEST_METHOD(RunConversionsBetweenTypeShapes) - TEST_METHOD(RunConversionsBetweenTypeShapesStrictUDT) - TEST_METHOD(RunConversionsNonNumericAggregates) TEST_METHOD(RunCppErrors) TEST_METHOD(RunCppErrorsHV2015) - TEST_METHOD(RunOperatorOverloadingForNewDelete) - TEST_METHOD(RunOperatorOverloadingNotDefinedBinaryOp) - TEST_METHOD(RunCXX11Attributes) - TEST_METHOD(RunEnums) - TEST_METHOD(RunFunctionTemplateDefault) - TEST_METHOD(RunFunctions) - TEST_METHOD(RunIncompleteType) - TEST_METHOD(RunIndexingOperator) TEST_METHOD(RunInOutTrunc) - TEST_METHOD(RunIntrinsicExamples) - TEST_METHOD(RunInvalidDeclTemplateArg) - TEST_METHOD(RunMatrixAssignments) - TEST_METHOD(RunMatrixSyntax) - TEST_METHOD(RunMatrixSyntaxExactPrecision) - TEST_METHOD(RunMintypesPromotionWarnings) - TEST_METHOD(RunMoreOperators) - TEST_METHOD(RunObjectOperators) - TEST_METHOD(RunOutParamDiags) - TEST_METHOD(RunPackReg) - TEST_METHOD(RunPragmaRegion) - TEST_METHOD(RunRayTracingEntryDiags) - TEST_METHOD(RunRayTracings) - TEST_METHOD(RunScalarAssignments) - TEST_METHOD(RunScalarAssignmentsExactPrecision) - TEST_METHOD(RunScalarOperatorsAssign) - TEST_METHOD(RunScalarOperatorsAssignExactPrecision) - TEST_METHOD(RunScalarOperators) - TEST_METHOD(RunScalarOperatorsExactPrecision) - TEST_METHOD(RunSizeof) - TEST_METHOD(RunString) - TEST_METHOD(RunStructAssignments) - TEST_METHOD(RunSubobjects) - TEST_METHOD(RunIncompleteArray) - TEST_METHOD(RunTemplateChecks) - TEST_METHOD(RunTemplateLiteralSubstitutionFailure) - TEST_METHOD(RunVarmodsSyntax) - TEST_METHOD(RunVectorAssignments) - TEST_METHOD(RunVectorSyntaxMix) TEST_METHOD(RunVectorSyntax) TEST_METHOD(RunVectorSyntaxExactPrecision) TEST_METHOD(RunTypemodsSyntax) @@ -189,193 +140,16 @@ class VerifierTest TEST_CLASS_DERIVATION { } }; -TEST_F(VerifierTest, RunArrayIndexOutOfBounds) { - CheckVerifiesHLSL(L"array-index-out-of-bounds.hlsl"); - CheckVerifiesHLSL(L"array-index-out-of-bounds-HV-2016.hlsl"); -} - -TEST_F(VerifierTest, RunArrayLength) { - CheckVerifiesHLSL(L"array-length.hlsl"); -} - -TEST_F(VerifierTest, RunAtomicFloatErrors) { - CheckVerifiesHLSL(L"atomic-float-errors.hlsl"); -} - -TEST_F(VerifierTest, RunAttributes) { CheckVerifiesHLSL(L"attributes.hlsl"); } - -TEST_F(VerifierTest, RunBuiltinTypesNoInheritance) { - CheckVerifiesHLSL(L"builtin-types-no-inheritance.hlsl"); -} - -TEST_F(VerifierTest, RunConstExpr) { CheckVerifiesHLSL(L"const-expr.hlsl"); } - -TEST_F(VerifierTest, RunConstAssign) { - CheckVerifiesHLSL(L"const-assign.hlsl"); -} - -TEST_F(VerifierTest, RunConstDefault) { - CheckVerifiesHLSL(L"const-default.hlsl"); -} - -TEST_F(VerifierTest, RunConversionsBetweenTypeShapes) { - CheckVerifiesHLSL(L"conversions-between-type-shapes.hlsl"); -} - -TEST_F(VerifierTest, RunConversionsBetweenTypeShapesStrictUDT) { - CheckVerifiesHLSL(L"conversions-between-type-shapes-strictudt.hlsl"); -} - -TEST_F(VerifierTest, RunConversionsNonNumericAggregates) { - CheckVerifiesHLSL(L"conversions-non-numeric-aggregates.hlsl"); -} - TEST_F(VerifierTest, RunCppErrors) { CheckVerifiesHLSL(L"cpp-errors.hlsl"); } TEST_F(VerifierTest, RunCppErrorsHV2015) { CheckVerifiesHLSL(L"cpp-errors-hv2015.hlsl"); } -TEST_F(VerifierTest, RunOperatorOverloadingForNewDelete) { - CheckVerifiesHLSL(L"overloading-new-delete-errors.hlsl"); -} - -TEST_F(VerifierTest, RunOperatorOverloadingNotDefinedBinaryOp) { - CheckVerifiesHLSL(L"use-undefined-overloaded-operator.hlsl"); -} - -TEST_F(VerifierTest, RunCXX11Attributes) { - CheckVerifiesHLSL(L"cxx11-attributes.hlsl"); -} - -TEST_F(VerifierTest, RunEnums) { CheckVerifiesHLSL(L"enums.hlsl"); } - -TEST_F(VerifierTest, RunFunctionTemplateDefault) { - CheckVerifiesHLSL(L"function-template-default.hlsl"); -} - -TEST_F(VerifierTest, RunFunctions) { CheckVerifiesHLSL(L"functions.hlsl"); } - -TEST_F(VerifierTest, RunIncompleteType) { - CheckVerifiesHLSL(L"incomplete-type.hlsl"); -} - -TEST_F(VerifierTest, RunIndexingOperator) { - CheckVerifiesHLSL(L"indexing-operator.hlsl"); -} - TEST_F(VerifierTest, RunInOutTrunc) { CheckVerifiesHLSL(L"inout_trunc.hlsl"); } -TEST_F(VerifierTest, RunIntrinsicExamples) { - CheckVerifiesHLSL(L"intrinsic-examples.hlsl"); -} - -TEST_F(VerifierTest, RunInvalidDeclTemplateArg) { - CheckVerifiesHLSL(L"invalid-decl-template-arg.hlsl"); -} - -TEST_F(VerifierTest, RunMatrixAssignments) { - CheckVerifiesHLSL(L"matrix-assignments.hlsl"); -} - -TEST_F(VerifierTest, RunMatrixSyntax) { - CheckVerifiesHLSL(L"matrix-syntax.hlsl"); -} - -TEST_F(VerifierTest, RunMatrixSyntaxExactPrecision) { - CheckVerifiesHLSL(L"matrix-syntax-exact-precision.hlsl"); -} - -TEST_F(VerifierTest, RunMintypesPromotionWarnings) { - CheckVerifiesHLSL(L"mintypes-promotion-warnings.hlsl"); -} - -TEST_F(VerifierTest, RunMoreOperators) { - CheckVerifiesHLSL(L"more-operators.hlsl"); -} - -TEST_F(VerifierTest, RunObjectOperators) { - CheckVerifiesHLSL(L"object-operators.hlsl"); -} - -TEST_F(VerifierTest, RunOutParamDiags) { - CheckVerifiesHLSL(L"out-param-diagnostics.hlsl"); -} - -TEST_F(VerifierTest, RunPackReg) { CheckVerifiesHLSL(L"packreg.hlsl"); } - -TEST_F(VerifierTest, RunPragmaRegion) { - CheckVerifiesHLSL(L"pragma-region.hlsl"); -} - -TEST_F(VerifierTest, RunRayTracingEntryDiags) { - CheckVerifiesHLSL(L"raytracing-entry-diags.hlsl"); -} - -TEST_F(VerifierTest, RunRayTracings) { CheckVerifiesHLSL(L"raytracings.hlsl"); } - -TEST_F(VerifierTest, RunScalarAssignments) { - CheckVerifiesHLSL(L"scalar-assignments.hlsl"); -} - -TEST_F(VerifierTest, RunScalarAssignmentsExactPrecision) { - CheckVerifiesHLSL(L"scalar-assignments-exact-precision.hlsl"); -} - -TEST_F(VerifierTest, RunScalarOperatorsAssign) { - CheckVerifiesHLSL(L"scalar-operators-assign.hlsl"); -} - -TEST_F(VerifierTest, RunScalarOperatorsAssignExactPrecision) { - CheckVerifiesHLSL(L"scalar-operators-assign-exact-precision.hlsl"); -} - -TEST_F(VerifierTest, RunScalarOperators) { - CheckVerifiesHLSL(L"scalar-operators.hlsl"); -} - -TEST_F(VerifierTest, RunScalarOperatorsExactPrecision) { - CheckVerifiesHLSL(L"scalar-operators-exact-precision.hlsl"); -} - -TEST_F(VerifierTest, RunSizeof) { CheckVerifiesHLSL(L"sizeof.hlsl"); } - -TEST_F(VerifierTest, RunString) { CheckVerifiesHLSL(L"string.hlsl"); } - -TEST_F(VerifierTest, RunStructAssignments) { - CheckVerifiesHLSL(L"struct-assignments.hlsl"); -} - -TEST_F(VerifierTest, RunSubobjects) { - CheckVerifiesHLSL(L"subobjects-syntax.hlsl"); -} - -TEST_F(VerifierTest, RunIncompleteArray) { - CheckVerifiesHLSL(L"incomp_array_err.hlsl"); -} - -TEST_F(VerifierTest, RunTemplateChecks) { - CheckVerifiesHLSL(L"template-checks.hlsl"); -} - -TEST_F(VerifierTest, RunTemplateLiteralSubstitutionFailure) { - CheckVerifiesHLSL(L"template-literal-substitution-failure.hlsl"); -} - -TEST_F(VerifierTest, RunVarmodsSyntax) { - CheckVerifiesHLSL(L"varmods-syntax.hlsl"); -} - -TEST_F(VerifierTest, RunVectorAssignments) { - CheckVerifiesHLSL(L"vector-assignments.hlsl"); -} - -TEST_F(VerifierTest, RunVectorSyntaxMix) { - CheckVerifiesHLSL(L"vector-syntax-mix.hlsl"); -} - TEST_F(VerifierTest, RunVectorSyntax) { CheckVerifiesHLSL(L"vector-syntax.hlsl"); } diff --git a/tools/clang/unittests/HLSLExec/ExecutionTest.cpp b/tools/clang/unittests/HLSLExec/ExecutionTest.cpp index 5c0a8b5da5..94eab51e32 100644 --- a/tools/clang/unittests/HLSLExec/ExecutionTest.cpp +++ b/tools/clang/unittests/HLSLExec/ExecutionTest.cpp @@ -35,7 +35,6 @@ #include #undef _read -#include "WexTestClass.h" #include "dxc/Test/DxcTestUtils.h" #include "dxc/Support/Global.h" #include "dxc/Support/WinIncludes.h" @@ -4416,7 +4415,10 @@ TEST_F(ExecutionTest, ATOWriteMSAATest) { } // Used to determine how an out of bounds offset should be converted -#define CLAMPOFFSET(offset) (((unsigned)(offset) << 28) >> 28) +constexpr int ClampOffset(int offset) { + unsigned shift = ((unsigned)offset) << 28; + return ((int)shift) >> 28; +} // Determine if the values in pPixels correspond to the expected locations // encoded into a uint based on the coordinates and offsets that were provided. @@ -4426,8 +4428,8 @@ void VerifyProgOffsetResults(unsigned *pPixels, bool bCheckDeriv) { int coords[18] = {100, 150, 200, 250, 300, 350, 400, 450, 500, 550, 600, 650, 700, 750, 800, 850, 900, 950}; int offsets[18] = { - CLAMPOFFSET(-9), -8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, - CLAMPOFFSET(8)}; + ClampOffset(-9), -8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, + ClampOffset(8)}; for (unsigned y = 0; y < _countof(coords); y++) { for (unsigned x = 0; x < _countof(coords); x++) { unsigned cmp = (coords[y] + offsets[y]) * 1000 + coords[x] + offsets[x]; @@ -9870,7 +9872,7 @@ TEST_F(ExecutionTest, ComputeRawBufferLdStHalf) { {256.0f, 105.17f, 980.0f}, {465.1652f, -1.5694e2f, -0.8543e-2f, 1333.5f}}; RawBufferLdStTestData halfData; - for (int i = 0; i < sizeof(floatData) / sizeof(float); i++) { + for (unsigned i = 0; i < sizeof(floatData) / sizeof(float); i++) { ((uint16_t *)&halfData)[i] = ConvertFloat32ToFloat16(((float *)&floatData)[i]); } @@ -9932,7 +9934,7 @@ TEST_F(ExecutionTest, GraphicsRawBufferLdStHalf) { {256.0f, 105.17f, 0.0f}, {465.1652f, -1.5694e2f, -0.8543e-2f, 1333.5f}}; RawBufferLdStTestData halfData; - for (int i = 0; i < sizeof(floatData) / sizeof(float); i++) { + for (unsigned i = 0; i < sizeof(floatData) / sizeof(float); i++) { ((uint16_t *)&halfData)[i] = ConvertFloat32ToFloat16(((float *)&floatData)[i]); } diff --git a/tools/clang/unittests/HLSLExec/ShaderOpArith.xml b/tools/clang/unittests/HLSLExec/ShaderOpArith.xml index 51e48d1d39..a8e761987b 100644 --- a/tools/clang/unittests/HLSLExec/ShaderOpArith.xml +++ b/tools/clang/unittests/HLSLExec/ShaderOpArith.xml @@ -1085,7 +1085,12 @@ -1.0f 1.0f 0, 1.0f 1.0f 0.0f, -1.0f -1.0f 0, - -inf, -1.5f, -denorm, -0, 0, denorm, 1.5f, inf, nan + -inf, -1.5f, -denorm, -0, 0, denorm, 1.5f, inf, nan, + 0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0 RootFlags(ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT) - + { { 0.0f, 0.25f , 0.0f }, { 1.0f, 0.0f, 0.0f, 1.0f } }, { { 0.25f, -0.25f , 0.0f }, { 0.0f, 1.0f, 0.0f, 1.0f } }, { { -0.25f, -0.25f , 0.0f }, { 0.0f, 0.0f, 1.0f, 1.0f } } @@ -1397,7 +1402,7 @@ RootFlags(ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT) - + { { 0.0h, 0.25h , 0.0h, 1.0h }, { 1.0h, 1.0h, 1.0h, 1.0h } }, { { 0.25h, -0.25h , 0.0h, 1.0h }, { 1.0h, 1.0h, 1.0h, 1.0h } }, { { -0.25h, -0.25h , 0.0h, 1.0h }, { 1.0h, 1.0h, 1.0h, 1.0h } } @@ -2229,7 +2234,7 @@ - { 0I, 0I, 99999999I, 99999999I, 0I, 0I, -1I, -1I, 0I, 0I, 0I, 0I, 42I, 42I, 42I, 42I } @@ -2245,12 +2250,12 @@ Flags="ALLOW_UNORDERED_ACCESS" InitialResourceState="COPY_DEST" Init="Zero" ReadBack="true" TransitionTo="UNORDERED_ACCESS" /> - { 0I, 0I, 99999999I, 99999999I, 0I, 0I, -1I, -1I, 0I, 0I, 0I, 0I, 42I, 42I, 42I, 42I } - { 0I, 0I, 99999999I, 99999999I, 0I, 0I, -1I, -1I, 0I, 0I, 0I, 0I, 42I, 42I, 42I, 42I } @@ -2272,12 +2277,12 @@ Flags="ALLOW_UNORDERED_ACCESS" InitialResourceState="COPY_DEST" Init="Zero" ReadBack="true" TransitionTo="UNORDERED_ACCESS" /> - { 0I, 0I, 99999999I, 99999999I, 0I, 0I, -1I, -1I, 0I, 0I, 0I, 0I, 42I, 42I, 42I, 42I } - { 0I, 0I, 99999999I, 99999999I, 0I, 0I, -1I, -1I, 0I, 0I, 0I, 0I, 42I, 42I, 42I, 42I } @@ -2285,12 +2290,12 @@ - { 0I, 0I, 99999999I, 99999999I, 0I, 0I, -1I, -1I, 0I, 0I, 0I, 0I, 42I, 42I, 42I, 42I } - { 0I, 0I, 99999999I, 99999999I, 0I, 0I, -1I, -1I, 0I, 0I, 0I, 0I, 42I, 42I, 42I, 42I } @@ -2331,15 +2336,15 @@ NumElements="128" Format="R32_UINT" /> + NumElements="8" Format="R32G32_UINT" /> + NumElements="8" Format="R32G32_UINT" /> + NumElements="8" Format="R32G32_UINT" /> + NumElements="8" Format="R32G32_UINT" /> diff --git a/tools/clang/unittests/HLSLExec/ShaderOpTest.cpp b/tools/clang/unittests/HLSLExec/ShaderOpTest.cpp index 79ebdd05de..adf69fbce7 100644 --- a/tools/clang/unittests/HLSLExec/ShaderOpTest.cpp +++ b/tools/clang/unittests/HLSLExec/ShaderOpTest.cpp @@ -23,7 +23,6 @@ #include "ShaderOpTest.h" #include "HlslTestUtils.h" // LogCommentFmt -#include "WexTestClass.h" // TAEF #include "dxc/DXIL/DxilConstants.h" // ComponentType #include "dxc/Support/Global.h" // OutputDebugBytes #include "dxc/Support/dxcapi.use.h" // DxcDllSupport diff --git a/tools/clang/unittests/HLSLTestLib/FileCheckerTest.cpp b/tools/clang/unittests/HLSLTestLib/FileCheckerTest.cpp index dce422c554..4f34f50252 100644 --- a/tools/clang/unittests/HLSLTestLib/FileCheckerTest.cpp +++ b/tools/clang/unittests/HLSLTestLib/FileCheckerTest.cpp @@ -552,7 +552,7 @@ FileRunCommandPart::RunDxc(dxc::DxcDllSupport &DllSupport, IFT(DllSupport.CreateInstance(CLSID_DxcLibrary, &pLibrary)); IFT(pLibrary->CreateBlobFromFile(CommandFileName, nullptr, &pSource)); - CComPtr pIncludeHandler = + CComPtr pIncludeHandler = AllocVFSIncludeHandler(pLibrary, pVFS); IFT(DllSupport.CreateInstance(CLSID_DxcCompiler, &pCompiler)); IFT(pCompiler->Compile(pSource, CommandFileName, entry.c_str(), @@ -873,7 +873,7 @@ FileRunCommandPart::RunDxr(dxc::DxcDllSupport &DllSupport, IFT(DllSupport.CreateInstance(CLSID_DxcLibrary, &pLibrary)); IFT(pLibrary->CreateBlobFromFile(CommandFileName, nullptr, &pSource)); - CComPtr pIncludeHandler = + CComPtr pIncludeHandler = AllocVFSIncludeHandler(pLibrary, pVFS); IFT(DllSupport.CreateInstance(CLSID_DxcRewriter, &pRewriter)); IFT(pRewriter->RewriteWithOptions(pSource, CommandFileName, flags.data(), @@ -969,7 +969,7 @@ FileRunCommandPart::RunLink(dxc::DxcDllSupport &DllSupport, HRESULT resultStatus; IFT(DllSupport.CreateInstance(CLSID_DxcLibrary, &pLibrary)); - CComPtr pIncludeHandler = + CComPtr pIncludeHandler = AllocVFSIncludeHandler(pLibrary, pVFS); IFT(DllSupport.CreateInstance(CLSID_DxcLinker, &pLinker)); IFT(DllSupport.CreateInstance(CLSID_DxcCompiler, &pCompiler)); diff --git a/tools/clang/unittests/SPIRV/CodeGenSpirvTest.cpp b/tools/clang/unittests/SPIRV/CodeGenSpirvTest.cpp index 8490274ea6..badc0cdf04 100644 --- a/tools/clang/unittests/SPIRV/CodeGenSpirvTest.cpp +++ b/tools/clang/unittests/SPIRV/CodeGenSpirvTest.cpp @@ -163,7 +163,6 @@ TEST_F(FileTest, LiteralVecTimesScalar) { // For variables TEST_F(FileTest, VarInitScalarVector) { runFileTest("var.init.hlsl"); } -TEST_F(FileTest, VarInitStruct) { runFileTest("var.init.struct.hlsl"); } TEST_F(FileTest, VarInitArray) { runFileTest("var.init.array.hlsl"); } TEST_F(FileTest, VarInitCrossStorageClass) { @@ -693,25 +692,6 @@ TEST_F(FileTest, SemanticViewportArrayIndexPS) { TEST_F(FileTest, SemanticViewportArrayIndexCoreVS) { runFileTest("semantic.viewport-array-index-core.vs.hlsl"); } -TEST_F(FileTest, SemanticBarycentricsSmoothPS) { - runFileTest("semantic.barycentrics.ps.s.hlsl"); -} -TEST_F(FileTest, SemanticBarycentricsSmoothCentroidPS) { - runFileTest("semantic.barycentrics.ps.s-c.hlsl"); -} -TEST_F(FileTest, SemanticBarycentricsSmoothSamplePS) { - runFileTest("semantic.barycentrics.ps.s-s.hlsl"); -} -TEST_F(FileTest, SemanticBarycentricsNoPerspectivePS) { - runFileTest("semantic.barycentrics.ps.np.hlsl"); -} -TEST_F(FileTest, SemanticBarycentricsNoPerspectiveCentroidPS) { - runFileTest("semantic.barycentrics.ps.np-c.hlsl"); -} -TEST_F(FileTest, SemanticBarycentricsNoPerspectiveSamplePS) { - runFileTest("semantic.barycentrics.ps.np-s.hlsl"); -} - TEST_F(FileTest, SemanticCoveragePS) { runFileTest("semantic.coverage.ps.hlsl"); } @@ -1105,7 +1085,6 @@ TEST_F(FileTest, IntrinsicsCheckAccessFullyMappedWithoutSampler) { TEST_F(FileTest, IntrinsicsNonUniformResourceIndex) { runFileTest("intrinsics.non-uniform-resource-index.hlsl"); } - // Vulkan-specific intrinsic functions TEST_F(FileTest, IntrinsicsVkCrossDeviceScope) { runFileTest("intrinsics.vkcrossdevicescope.hlsl"); @@ -1363,475 +1342,6 @@ TEST_F(FileTest, SpirvInterfacesForMultipleEntryPointsVulkan1p2) { runFileTest("spirv.interface.multiple.entries.vk.1p2.hlsl"); } -// For testing UserSemantic decoration -TEST_F(FileTest, SpirvUserSemanticVS) { - runFileTest("spirv.user-semantic.vs.hlsl"); -} - -TEST_F(FileTest, SpirvStageIO16bitTypes) { - runFileTest("spirv.stage-io.16bit.hlsl"); -} - -TEST_F(FileTest, SpirvStageIORelaxedPrecisionTypes) { - runFileTest("spirv.stage-io.relaxed-precision.hlsl"); -} - -TEST_F(FileTest, SpirvInterpolationPS) { - runFileTest("spirv.interpolation.ps.hlsl"); -} -TEST_F(FileTest, SpirvInterpolationVS) { - runFileTest("spirv.interpolation.vs.hlsl"); -} - -TEST_F(FileTest, SpirvLegalizationConstantBuffer) { - runFileTest("spirv.legal.cbuffer.hlsl"); -} -TEST_F(FileTest, SpirvLegalizationTextureBuffer) { - runFileTest("spirv.legal.tbuffer.hlsl"); -} - -TEST_F(FileTest, VulkanAttributeImageFormatO3) { - runFileTest("vk.attribute.image-format.o3.hlsl"); -} -TEST_F(FileTest, VulkanAttributeImageFormatSimple) { - runFileTest("vk.attribute.image-format.simple.hlsl", Expect::Success); -} -TEST_F(FileTest, VulkanAttributeImageFormatArray) { - runFileTest("vk.attribute.image-format.arrays.hlsl", Expect::Success); -} - -TEST_F(FileTest, VulkanCLOptionInvertYVS) { - runFileTest("vk.cloption.invert-y.vs.hlsl"); -} -TEST_F(FileTest, VulkanCLOptionInvertYDS) { - runFileTest("vk.cloption.invert-y.ds.hlsl"); -} -TEST_F(FileTest, VulkanCLOptionInvertYGS) { - runFileTest("vk.cloption.invert-y.gs.hlsl"); -} - -TEST_F(FileTest, VulkanCLOptionInvertWDS) { - runFileTest("vk.cloption.invert-w.ds.hlsl"); -} -TEST_F(FileTest, VulkanCLOptionInvertWPS) { - runFileTest("vk.cloption.invert-w.ps.hlsl"); -} - -// Vulkan specific -TEST_F(FileTest, VulkanLocation) { runFileTest("vk.location.hlsl"); } -TEST_F(FileTest, VulkanLocationInputExplicitOutputImplicit) { - runFileTest("vk.location.exp-in.hlsl"); -} -TEST_F(FileTest, VulkanLocationInputImplicitOutputExplicit) { - runFileTest("vk.location.exp-out.hlsl"); -} - -TEST_F(FileTest, VulkanExplicitBinding) { - // Resource binding from [[vk::binding()]] - runFileTest("vk.binding.explicit.hlsl"); -} -TEST_F(FileTest, VulkanImplicitBinding) { - // Resource binding from neither [[vk::binding()]] or :register() - runFileTest("vk.binding.implicit.hlsl"); -} -TEST_F(FileTest, VulkanPrecedenceBinding) { - // Bindings from vk::binding and :register competing for dominance - runFileTest("vk.binding.precedence.hlsl"); -} -TEST_F(FileTest, VulkanRegisterBinding) { - // Resource binding from :register(xX, spaceY) - runFileTest("vk.binding.register.hlsl"); -} -TEST_F(FileTest, VulkanSpaceOnlyRegisterBinding) { - // Resource binding from :register(spaceY) - runFileTest("vk.binding.register.space-only.hlsl"); -} -TEST_F(FileTest, VulkanRegisterBindingShift) { - // Resource binding from :register() with shift specified via - // command line option - runFileTest("vk.binding.cl.shift.hlsl"); -} -TEST_F(FileTest, VulkanRegisterBindingShiftAllSets) { - // Resource binding from :register() with shift specified for all sets via - // command line option - runFileTest("vk.binding.cl.shift.all-sets.hlsl"); -} -TEST_F(FileTest, VulkanRegisterBinding1to1Mapping) { - runFileTest("vk.binding.cl.register.hlsl"); -} -TEST_F(FileTest, VulkanGlobalsBinding) { - // Binding the $Globals buffer to a specific set/binding via command line - // option. - runFileTest("vk.binding.cl.globals.hlsl"); -} -TEST_F(FileTest, VulkanGlobalsBindingRegisterBinding) { - // Using command line option for specifying both the 1-1 register mapping as - // well as $Globals binding. - runFileTest("vk.binding.cl.register-and-globals.hlsl"); -} - -// For flattening array of resources -TEST_F(FileTest, FlattenResourceArrayBindings1) { - runFileTest("vk.binding.cl.flatten-arrays.example1.hlsl"); -} -TEST_F(FileTest, FlattenResourceArrayBindings1Optimized) { - runFileTest("vk.binding.cl.flatten-arrays.example1-optimized.hlsl"); -} -TEST_F(FileTest, FlattenResourceArrayBindings2) { - runFileTest("vk.binding.cl.flatten-arrays.example2.hlsl"); -} -TEST_F(FileTest, FlattenResourceArrayBindings2Optimized) { - runFileTest("vk.binding.cl.flatten-arrays.example2-optimized.hlsl"); -} -TEST_F(FileTest, FlattenResourceArrayBindings3) { - runFileTest("vk.binding.cl.flatten-arrays.example3.hlsl"); -} -TEST_F(FileTest, FlattenResourceArrayAccessedByVarIndex) { - runFileTest("vk.binding.flatten-arrays.var-index.hlsl"); -} - -// For testing the "-auto-binding-space" command line option which specifies the -// "default space" for resources. -TEST_F(FileTest, VulkanRegisterBindingDefaultSpaceImplicit) { - runFileTest("vk.binding.default-space.implicit.hlsl"); -} -TEST_F(FileTest, VulkanRegisterBindingDefaultSpaceExplicit) { - runFileTest("vk.binding.default-space.explicit.hlsl"); -} -// Testing combinations of "-auto-binding-space" and other options. -TEST_F(FileTest, VulkanRegisterBindingDefaultSpaceWithShift) { - runFileTest("vk.binding.default-space.with-shift.hlsl"); -} -TEST_F(FileTest, VulkanRegisterBindingDefaultSpaceWithShiftAll) { - runFileTest("vk.binding.default-space.with-shift-all.hlsl"); -} - -TEST_F(FileTest, VulkanStructuredBufferCounter) { - // [[vk::counter_binding()]] for RWStructuredBuffer, AppendStructuredBuffer, - // and ConsumeStructuredBuffer - runFileTest("vk.binding.counter.hlsl"); -} - -TEST_F(FileTest, AutoShiftBindings) { - // Checks the correctness for the "-fvk-auto-shift-bindings" command line - // option. - runFileTest("vk.binding.cl.auto-shift-bindings.hlsl"); -} - -TEST_F(FileTest, BindingStructureOfResourcesOptimized) { - // After optimization is performed, this binary should pass validation. - runFileTest("vk.binding.global-struct-of-resources.optimized.hlsl"); -} - -TEST_F(FileTest, BindingStructureOfResourcesPassLegalization) { - runFileTest("vk.binding.global-struct-of-resources.pass-legalization.hlsl", - Expect::Success); -} - -TEST_F(FileTest, VulkanPushConstant) { runFileTest("vk.push-constant.hlsl"); } -TEST_F(FileTest, VulkanPushConstantOffset) { - // Checks the behavior of [[vk::offset]] with [[vk::push_constant]] - runFileTest("vk.push-constant.offset.hlsl"); -} -TEST_F(FileTest, VulkanPushConstantAnonymousStruct) { - runFileTest("vk.push-constant.anon-struct.hlsl"); -} - -TEST_F(FileTest, VulkanPushConstantOnConstantBuffer) { - runFileTest("vk.push-constant.constantbuffer.hlsl"); -} - -TEST_F(FileTest, VulkanCombinedImageSampler) { - runFileTest("vk.combined-image-sampler.hlsl"); -} -TEST_F(FileTest, VulkanCombinedImageSamplerBindingShift) { - runFileTest("vk.combined-image-sampler.binding-shift.hlsl"); -} -TEST_F(FileTest, VulkanCombinedImageSamplerTextureArray) { - runFileTest("vk.combined-image-sampler.texture-array.hlsl"); -} - -TEST_F(FileTest, VulkanSpecConstantInit) { - runFileTest("vk.spec-constant.init.hlsl"); -} -TEST_F(FileTest, VulkanSpecConstantUsage) { - runFileTest("vk.spec-constant.usage.hlsl"); -} -TEST_F(FileTest, VulkanSpecConstantReuse) { - runFileTest("vk.spec-constant.reuse.hlsl"); -} - -TEST_F(FileTest, VulkanSpecConstantComposite) { - runFileTest("vk.spec-constant.composite.hlsl"); -} - -TEST_F(FileTest, VulkanLayoutCBufferMatrixZpr) { - runFileTest("vk.layout.cbuffer.zpr.hlsl"); -} -TEST_F(FileTest, VulkanLayoutCBufferMatrixZpc) { - runFileTest("vk.layout.cbuffer.zpc.hlsl"); -} -TEST_F(FileTest, VulkanLayoutCBufferBoolean) { - runFileTest("vk.layout.cbuffer.boolean.hlsl"); -} -TEST_F(FileTest, VulkanLayoutCBufferDerivedStruct) { - runFileTest("vk.layout.cbuffer.derived-struct.hlsl"); -} -TEST_F(FileTest, VulkanLayoutRWStructuredBufferBoolean) { - runFileTest("vk.layout.rwstructuredbuffer.boolean.hlsl"); -} -TEST_F(FileTest, VulkanLayout16BitTypesPushConstant) { - runFileTest("vk.layout.16bit-types.pc.hlsl"); -} -TEST_F(FileTest, VulkanLayout16BitTypesStructuredBuffer) { - runFileTest("vk.layout.16bit-types.sbuffer.hlsl"); -} -TEST_F(FileTest, VulkanLayoutVectorRelaxedLayout) { - // Allows vectors to be aligned according to their element types, if not - // causing improper straddle - runFileTest("vk.layout.vector.relaxed.hlsl"); -} -TEST_F(FileTest, VulkanLayoutStructRelaxedLayout) { - // Checks VK_KHR_relaxed_block_layout on struct types - runFileTest("vk.layout.struct.relaxed.hlsl"); -} -TEST_F(FileTest, VulkanLayoutStructBitfield) { - runFileTest("vk.layout.struct.bitfield.hlsl"); -} -TEST_F(FileTest, VulkanLayoutStructBitfieldAssignment) { - runFileTest("vk.layout.struct.bitfield.assignment.hlsl"); -} - -TEST_F(FileTest, VulkanLayoutCBufferPackOffset) { - runFileTest("vk.layout.cbuffer.packoffset.hlsl"); -} - -TEST_F(FileTest, VulkanSubpassInput) { runFileTest("vk.subpass-input.hlsl"); } -TEST_F(FileTest, VulkanSubpassInputUnused) { - runFileTest("vk.subpass-input.unused.hlsl"); -} -TEST_F(FileTest, VulkanSubpassInputBinding) { - runFileTest("vk.subpass-input.binding.hlsl"); -} - -TEST_F(FileTest, NamespaceFunctions) { - runFileTest("namespace.functions.hlsl"); -} -TEST_F(FileTest, NamespaceGlobals) { runFileTest("namespace.globals.hlsl"); } -TEST_F(FileTest, NamespaceResources) { - runFileTest("namespace.resources.hlsl"); -} - -// HS: for different Patch Constant Functions -TEST_F(FileTest, HullShaderPCFTakesViewId) { - runFileTest("hs.pcf.view-id.1.hlsl"); -} -TEST_F(FileTest, HullShaderPCFTakesViewIdButMainDoesnt) { - runFileTest("hs.pcf.view-id.2.hlsl"); -} -TEST_F(FileTest, HullShaderConstOutputPatch) { - runFileTest("hs.const.output-patch.hlsl"); -} - -// GS: emit vertex and emit primitive -TEST_F(FileTest, GeometryShaderEmit) { runFileTest("gs.emit.hlsl"); } - -// CS: groupshared -TEST_F(FileTest, ComputeShaderGroupShared) { - runFileTest("cs.groupshared.hlsl"); -} -TEST_F(FileTest, ComputeShaderGroupSharedNotInGlobals) { - runFileTest("cs.groupshared.not-in-globals.hlsl"); -} - -// === Raytracing NV examples === -TEST_F(FileTest, RayTracingNVRaygen) { - runFileTest("raytracing.nv.raygen.hlsl"); -} -TEST_F(FileTest, RayTracingNVEnum) { runFileTest("raytracing.nv.enum.hlsl"); } -TEST_F(FileTest, RayTracingNVIntersection) { - runFileTest("raytracing.nv.intersection.hlsl"); -} -TEST_F(FileTest, RayTracingNVAnyHit) { - runFileTest("raytracing.nv.anyhit.hlsl"); -} -TEST_F(FileTest, RayTracingNVClosestHit) { - runFileTest("raytracing.nv.closesthit.hlsl"); -} -TEST_F(FileTest, RayTracingNVMiss) { runFileTest("raytracing.nv.miss.hlsl"); } -TEST_F(FileTest, RayTracingNVCallable) { - runFileTest("raytracing.nv.callable.hlsl"); -} -TEST_F(FileTest, RayTracingNVLibrary) { - runFileTest("raytracing.nv.library.hlsl"); -} - -// === Raytracing KHR examples === -TEST_F(FileTest, RayTracingKHRClosestHit) { - runFileTest("raytracing.khr.closesthit.hlsl"); -} - -TEST_F(FileTest, RayTracingKHRClosestHitVulkan1p1Spirv1p4) { - runFileTest("raytracing.khr.closesthit.vulkan1.1spirv1.4.hlsl"); -} - -TEST_F(FileTest, RayTracingAccelerationStructure) { - runFileTest("raytracing.acceleration-structure.hlsl"); -} - -TEST_F(FileTest, RayTracingTerminate) { - runFileTest("raytracing.khr.terminate.hlsl"); -} - -// For decoration uniqueness -TEST_F(FileTest, DecorationUnique) { runFileTest("decoration.unique.hlsl"); } - -// For capability uniqueness -TEST_F(FileTest, CapabilityUnique) { runFileTest("capability.unique.hlsl"); } - -// For extension uniqueness -TEST_F(FileTest, ExtensionUnique) { runFileTest("extension.unique.hlsl"); } - -// For RelaxedPrecision decorations -TEST_F(FileTest, DecorationRelaxedPrecisionBasic) { - runFileTest("decoration.relaxed-precision.basic.hlsl"); -} -TEST_F(FileTest, DecorationRelaxedPrecisionStruct) { - runFileTest("decoration.relaxed-precision.struct.hlsl"); -} -TEST_F(FileTest, DecorationRelaxedPrecisionImage) { - runFileTest("decoration.relaxed-precision.image.hlsl"); -} -TEST_F(FileTest, DecorationRelaxedPrecisionBool) { - runFileTest("decoration.relaxed-precision.bool.hlsl"); -} -TEST_F(FileTest, DecorationRelaxedPrecisionArray) { - runFileTest("decoration.relaxed-precision.array.hlsl"); -} -TEST_F(FileTest, DecorationRelaxedPrecisionResourceInStruct) { - runFileTest("decoration.relaxed-precision.resource.in.struct.hlsl"); -} - -// For NoContraction decorations - -TEST_F(FileTest, DecorationNoContractionVariableReuse) { - runFileTest("decoration.no-contraction.variable-reuse.hlsl"); -} -TEST_F(FileTest, DecorationNoContractionStruct) { - runFileTest("decoration.no-contraction.struct.hlsl"); -} -TEST_F(FileTest, DecorationNoContractionStageVars) { - runFileTest("decoration.no-contraction.stage-vars.hlsl"); -} - -// For UserTypeGOOGLE decorations -TEST_F(FileTest, DecorationUserTypeGOOGLE) { - runFileTest("decoration.user-type.hlsl"); -} - -TEST_F(FileTest, DecorationCoherent) { - runFileTest("decoration.coherent.hlsl"); -} - -// For pragmas -TEST_F(FileTest, PragmaPackMatrix) { runFileTest("pragma.pack_matrix.hlsl"); } - -// Tests for [[vk::shader_record_nv]] -TEST_F(FileTest, VulkanShaderRecordBufferNV) { - runFileTest("vk.shader-record-nv.hlsl"); -} -TEST_F(FileTest, VulkanShaderRecordBufferNVOffset) { - // Checks the behavior of [[vk::offset]] with [[vk::shader_record_nv]] - runFileTest("vk.shader-record-nv.offset.hlsl"); -} -// Tests for [[vk::shader_record_ext]] -TEST_F(FileTest, VulkanShaderRecordBufferEXT) { - runFileTest("vk.shader-record-ext.hlsl"); -} -TEST_F(FileTest, VulkanShaderRecordBufferEXTOffset) { - // Checks the behavior of [[vk::offset]] with [[vk::shader_record_ext]] - runFileTest("vk.shader-record-ext.offset.hlsl"); -} -TEST_F(FileTest, VulkanShadingRateVs) { - runFileTest("vk.shading-rate.vs.hlsl"); -} -TEST_F(FileTest, VulkanShadingRatePs) { - runFileTest("vk.shading-rate.ps.hlsl"); -} -// Tests for [[vk::early_and_late_tests]] -TEST_F(FileTest, VulkanEarlyAndLateTests) { - runFileTest("vk.early-and-lates-tests.hlsl"); -} -TEST_F(FileTest, VulkanEarlyAndLateTestsDepthUnchanged) { - runFileTest("vk.early-and-lates-tests.depth-unchanged.hlsl"); -} -TEST_F(FileTest, VulkanEarlyAndLateTestsStencilRefUnchangedFront) { - runFileTest("vk.early-and-lates-tests.stencil-ref-unchanged-front.hlsl"); -} -TEST_F(FileTest, VulkanEarlyAndLateTestsStencilRefGreaterEqualFront) { - runFileTest("vk.early-and-lates-tests.stencil-ref-greater-equal-front.hlsl"); -} -TEST_F(FileTest, VulkanEarlyAndLateTestsStencilRefLessEqualFront) { - runFileTest("vk.early-and-lates-tests.stencil-ref-less-equal-front.hlsl"); -} -TEST_F(FileTest, VulkanEarlyAndLateTestsStencilRefUnchangedBack) { - runFileTest("vk.early-and-lates-tests.stencil-ref-unchanged-back.hlsl"); -} -TEST_F(FileTest, VulkanEarlyAndLateTestsStencilRefGreaterEqualBack) { - runFileTest("vk.early-and-lates-tests.stencil-ref-greater-equal-back.hlsl"); -} -TEST_F(FileTest, VulkanEarlyAndLateTestsStencilRefLessEqualBack) { - runFileTest("vk.early-and-lates-tests.stencil-ref-less-equal-back.hlsl"); -} - -// === MeshShading EXT examples === -TEST_F(FileTest, MeshShadingEXTMeshTriangle) { - runFileTest("meshshading.ext.triangle.mesh.hlsl"); -} - -TEST_F(FileTest, MeshShadingEXTAmplification) { - runFileTest("meshshading.ext.amplification.hlsl"); -} - -// === MeshShading NV examples === -TEST_F(FileTest, MeshShadingNVMeshTriangle) { - runFileTest("meshshading.nv.triangle.mesh.hlsl", Expect::Success); -} -TEST_F(FileTest, MeshShadingNVMeshLine) { - runFileTest("meshshading.nv.line.mesh.hlsl"); -} -TEST_F(FileTest, MeshShadingNVMeshPoint) { - runFileTest("meshshading.nv.point.mesh.hlsl"); -} -TEST_F(FileTest, MeshShadingNVMeshBuffer) { - runFileTest("meshshading.nv.buffer.mesh.hlsl", Expect::Success); -} -TEST_F(FileTest, MeshShadingNVAmplification) { - runFileTest("meshshading.nv.amplification.hlsl", Expect::Success); -} -TEST_F(FileTest, MeshShadingNVAmplificationFunCall) { - runFileTest("meshshading.nv.fncall.amplification.hlsl", Expect::Success); -} - -TEST_F(FileTest, UseRValueForMemberExprOfArraySubscriptExpr) { - setBeforeHLSLLegalization(); - runFileTest("use.rvalue.for.member-expr.of.array-subscript.hlsl", - Expect::Success); -} - -TEST_F(FileTest, ReduceLoadSize) { runFileTest("reduce.load.size.hlsl"); } - -// Test OpEntryPoint in the Vulkan1.2 target environment -TEST_F(FileTest, Vk1p2EntryPoint) { runFileTest("vk.1p2.entry-point.hlsl"); } - -// Test deprecation of BufferBlock decoration after SPIR-V 1.3. -TEST_F(FileTest, Vk1p2BlockDecoration) { - runFileTest("vk.1p2.block-decoration.hlsl"); -} -TEST_F(FileTest, Vk1p2RemoveBufferBlockRuntimeArray) { - runFileTest("vk.1p2.remove.bufferblock.runtimearray.hlsl"); -} - // Test shaders that require Vulkan1.1 support with // -fspv-target-env=vulkan1.2 option to make sure that enabling // Vulkan1.2 also enables Vulkan1.1. @@ -1863,11 +1373,6 @@ TEST_F(FileTest, CompatibilityWithVk1p1) { runFileTest("sm6.wave.builtin.no-dup.vulkan1.2.hlsl"); } -// Test the Vulkan1.3 target environment -TEST_F(FileTest, Vk1p3DiscardToDemote) { - runFileTest("vk.1p3.discard.to-demote.hlsl"); -} - TEST_F(FileTest, InlinedCodeTest) { const std::string command(R"(// RUN: %dxc -T ps_6_0 -E PSMain)"); const std::string code = command + R"( @@ -2009,22 +1514,6 @@ TEST_F(FileTest, PositionInVSWithInvalidMin10Float4Type) { "", "min10float4 x;", kInvalidPositionTypeForVSErrorMessage, true), Expect::Failure); } -TEST_F(FileTest, RayQueryInitExpr) { runFileTest("rayquery_init_expr.hlsl"); } - -TEST_F(FileTest, VolatileInterfaceInRayGenVk1p1) { - runFileTest("volatile.interface.raygen.vk1p1.hlsl"); -} -TEST_F(FileTest, VolatileInterfaceInRayGenVk1p2) { - runFileTest("volatile.interface.raygen.vk1p2.hlsl"); -} -TEST_F(FileTest, VolatileInterfaceInRayGenVk1p3) { - runFileTest("volatile.interface.raygen.vk1p3.hlsl"); -} - -TEST_F(FileTest, SignaturePacking) { runFileTest("signature.packing.hlsl"); } -TEST_F(FileTest, SignaturePackingHS) { - runFileTest("signature.packing.hs.hlsl"); -} TEST_F(FileTest, SourceCodeWithoutFilePath) { const std::string command(R"(// RUN: %dxc -T ps_6_0 -E PSMain -Zi)"); const std::string code = command + R"( @@ -2034,8 +1523,4 @@ float4 PSMain(float4 color : COLOR) : SV_TARGET { return color; } runCodeTest(code); } -TEST_F(FileTest, RenameEntrypoint) { runFileTest("fspv-entrypoint-name.hlsl"); } - -TEST_F(FileTest, PrintAll) { runFileTest("fspv-print-all.hlsl"); } - } // namespace diff --git a/tools/dxexp/dxexp.cpp b/tools/dxexp/dxexp.cpp index 02f54ad366..b237dea077 100644 --- a/tools/dxexp/dxexp.cpp +++ b/tools/dxexp/dxexp.cpp @@ -414,7 +414,7 @@ int main(int argc, const char *argv[]) { text_printf("Experimental shader model feature failed with unexpected " "HRESULT 0x%08x.\n", (unsigned int)hr); - json_printf("{ \"err\": \"0x%08x\" }", hr); + json_printf("{ \"err\": \"0x%08x\" }", (unsigned int)hr); json_printf("\n}\n"); return 4; } diff --git a/utils/git/requirements_formatting.txt b/utils/git/requirements_formatting.txt index ff744f0d42..52bd3d0563 100644 --- a/utils/git/requirements_formatting.txt +++ b/utils/git/requirements_formatting.txt @@ -18,7 +18,7 @@ charset-normalizer==3.2.0 # via requests click==8.1.7 # via black -cryptography==41.0.3 +cryptography==41.0.4 # via pyjwt darker==1.7.2 # via -r llvm/utils/git/requirements_formatting.txt.in @@ -46,7 +46,7 @@ requests==2.31.0 # via pygithub toml==0.10.2 # via darker -urllib3==2.0.4 +urllib3==2.0.6 # via requests wrapt==1.15.0 # via deprecated diff --git a/utils/hct/CodeTags.py b/utils/hct/CodeTags.py index 75c19e6ccf..e13faa903f 100644 --- a/utils/hct/CodeTags.py +++ b/utils/hct/CodeTags.py @@ -36,42 +36,52 @@ Would be easier with some exposed anchor point system """ import sys + is_py3 = sys.version_info[0] == 3 if is_py3: - basestring = (str,bytes) + basestring = (str, bytes) import re import hctdb_instrhelp + def SelectTaggedLines(tag, start, doc=None): "Select lines between tag:BEGIN and tag:END" - if doc is None: doc = app.current_doc + if doc is None: + doc = app.current_doc text = doc.text - begin = text.find(tag+':BEGIN', doc.get_selection_range()[1]) + begin = text.find(tag + ":BEGIN", doc.get_selection_range()[1]) if begin == -1: - raise StandardError('Could not find tag %s:BEGIN' % tag) + raise StandardError("Could not find tag %s:BEGIN" % tag) begin = text.find(native_endl, begin) - end = text.find(tag+':END', begin) + end = text.find(tag + ":END", begin) if end == -1: - raise StandardError('Could not find tag %s:END' % tag) + raise StandardError("Could not find tag %s:END" % tag) end = text.rfind(native_endl, begin, end) + len(native_endl) doc.select(begin, end) -rxWhitespace = re.compile(r'\s+') + +rxWhitespace = re.compile(r"\s+") + + def GetIndent(text, pos): "Get indent for line in text at pos" end = text.find(native_endl, pos) begin = text.rfind(native_endl, 0, end) - if begin == -1: begin = 0 - else: begin += len(native_endl) + if begin == -1: + begin = 0 + else: + begin += len(native_endl) m = rxWhitespace.match(text, begin, end) if m: return m.group(0) - return '' + return "" -def ReplaceTaggedLines(text_or_lines, tag='GENERATED_CODE', doc=None, tagrange=None): + +def ReplaceTaggedLines(text_or_lines, tag="GENERATED_CODE", doc=None, tagrange=None): "Replace lines between tag:BEGIN and tag:END with text_or_lines, start searching forward from selection or end of tagrange" - if doc is None: doc = app.current_doc + if doc is None: + doc = app.current_doc if tagrange is None: tagrange = doc.get_selection_range() SelectTaggedLines(tag, tagrange[1], doc) @@ -82,21 +92,26 @@ def ReplaceTaggedLines(text_or_lines, tag='GENERATED_CODE', doc=None, tagrange=N text_or_lines = text_or_lines.splitlines() text_or_lines = [indent + line for line in text_or_lines] delta = ReplaceSelection(text_or_lines) - doc.select(begin, end + delta) # reselect replacement so search may continue + doc.select(begin, end + delta) # reselect replacement so search may continue + def StripIndent(lines, indent): "Remove indent from lines of text" + def strip_indent(line): if line.startswith(indent): - return line[len(indent):] + return line[len(indent) :] return line + if isinstance(lines, basestring): lines = lines.splitlines() return map(strip_indent, lines) -def UpdateTaggedLines(fn, tag='GENERATED_CODE', doc=None, tagrange=None): + +def UpdateTaggedLines(fn, tag="GENERATED_CODE", doc=None, tagrange=None): "Call supplied function with list of lines found between tag:BEGIN and tag:END. Replace with result." - if doc is None: doc = app.current_doc + if doc is None: + doc = app.current_doc if tagrange is None: tagrange = doc.get_selection_range() SelectTaggedLines(tag, tagrange[1], doc) @@ -109,12 +124,14 @@ def UpdateTaggedLines(fn, tag='GENERATED_CODE', doc=None, tagrange=None): lines = lines.splitlines() lines = [indent + line for line in lines] delta = ReplaceSelection(lines) - doc.select(begin, end + delta) # reselect replacement so search may continue + doc.select(begin, end + delta) # reselect replacement so search may continue + -def UpdateEachTaggedLine(fn, tag='GENERATED_CODE', doc=None, begin=None): +def UpdateEachTaggedLine(fn, tag="GENERATED_CODE", doc=None, begin=None): "Call fn for each line of text between tag:BEGIN and tag:END" UpdateTaggedLines(lambda lines: map(fn, lines), tag, doc, begin) + def _make_transform_lines(tag): """Makes an operation for tag processing The 'lines' operation will select lines with your tag and execute your code with a @@ -122,33 +139,45 @@ def _make_transform_lines(tag): to replace the current selection: ['// %s' % line for line in lines] """ + def _transform(code, doc=app.current_doc): def _transformer(lines): return eval(code) + return UpdateTaggedLines(_transformer, tag, doc=doc) + return _transform + + def _make_output(arg): def _print_fn(expression_text, doc=app.current_doc): - print('%s = %s' % (expression_text, arg)) + print("%s = %s" % (expression_text, arg)) + return _print_fn + + def _make_eval(arg): def _eval(expression_text, doc=app.current_doc): print(arg) + return _eval + PyOperations = { - 'lines': _make_transform_lines, - 'output': _make_output, - 'eval': _make_eval, - } -rxPyTag = re.compile(r'\') + "lines": _make_transform_lines, + "output": _make_output, + "eval": _make_eval, +} +rxPyTag = re.compile(r"\") + + def FindPyTag(doc, begin=0): text = doc.text _operation_function_ = None - tag_code = '' + tag_code = "" end = -1 while begin != -1: - begin = text.find(' # whole tag selected currently + tag = "" + if m.group( + 5 + ): # we have form: # whole tag selected currently if m.group(4): # we have - begin, end = m.span(4) # Select the arguments to 'something' + begin, end = m.span(4) # Select the arguments to 'something' break begin = end - end = text.find('', end) + end = text.find("", end) if end == -1: - print('%s(%d): Error: Could not find matching ' % (doc.name, text.count(native_endl, 0, begin) + 1)) + print( + "%s(%d): Error: Could not find matching " + % (doc.name, text.count(native_endl, 0, begin) + 1) + ) begin = -1 break else: # "' % (repr(self._selection), repr(self.text[self._selection[0]:self._selection[1]]), repr(self.text)) + return "" % ( + repr(self._selection), + repr(self.text[self._selection[0] : self._selection[1]]), + repr(self.text), + ) + def __init__(self, text, selection=None): - self.name = 'TestDoc' + self.name = "TestDoc" self.text = text - self._selection = (0,0) + self._selection = (0, 0) + def get_selected_text(self): - return self.text[self._selection[0]:self._selection[1]] + return self.text[self._selection[0] : self._selection[1]] + def select(self, start, end): self._selection = start, end + def get_selection_range(self): return self._selection + def set_selected_text(self, text): begin, end = self.get_selection_range() self.text = self.text[:begin] + text + self.text[end:] - #self._selection = (0,0) + # self._selection = (0,0) + selected_text = property(get_selected_text, set_selected_text) + def __init__(self, before, expected): self.before, self.expected = before, expected - self.after = '' + self.after = "" + def test(self, selection=None): doc = Test.TestDoc(self.before, selection) app.current_doc = doc @@ -253,46 +324,59 @@ def test(self, selection=None): return 0 except: import sys + _stderr = sys.stderr sys.stderr = self sys.excepthook(*sys.exc_info()) sys.stderr = _stderr return 1 + def write(self, text): self.after += text + def verify(self): "Returns nothing if passed, or failure message if failed." if self.after == self.expected: return - return '==================== Verify failed!\n--- Before:%s+++ After:%s=== Expected:%s====================\n' % ( - self.before, self.after, self.expected - ) + return ( + "==================== Verify failed!\n--- Before:%s+++ After:%s=== Expected:%s====================\n" + % (self.before, self.after, self.expected) + ) + @staticmethod def NormalizeForVSText(text_or_lines): if isinstance(text_or_lines, basestring): - text = str(text_or_lines).replace(native_endl, '\n') + text = str(text_or_lines).replace(native_endl, "\n") else: - text = '\n'.join([str(item).replace(native_endl, '\n') for item in text_or_lines]) - return text.replace('\n', native_endl) + text = "\n".join( + [str(item).replace(native_endl, "\n") for item in text_or_lines] + ) + return text.replace("\n", native_endl) + @staticmethod def NormalizeForPython(text): - return str(text).replace(native_endl, '\n').replace('\r', '\n') + return str(text).replace(native_endl, "\n").replace("\r", "\n") + @staticmethod def TerminateTextForVS(text): if text.endswith(native_endl): return text return text + native_endl + @staticmethod def WrapFunctionForExceptionHandling(fn): import sys + def wrapperfn(*args, **kwargs): try: return fn(*args, **kwargs) except: sys.excepthook(*sys.exc_info()) - sys.stderr.write('\n') + sys.stderr.write("\n") raise + return wrapperfn + @staticmethod def ReplaceSelection(text_or_lines, doc=None): if doc is None: @@ -303,15 +387,28 @@ def ReplaceSelection(text_or_lines, doc=None): result = native_endl + result doc.selected_text = result return len(result) - len(original) + @staticmethod def SetDependencies(): global app global NormalizeForVSText, NormalizeForPython, TerminateTextForVS, WrapFunctionForExceptionHandling, ReplaceSelection - if not hasattr(globals(), 'app'): - NormalizeForVSText, NormalizeForPython, TerminateTextForVS, WrapFunctionForExceptionHandling, ReplaceSelection = ( - Test.NormalizeForVSText, Test.NormalizeForPython, Test.TerminateTextForVS, Test.WrapFunctionForExceptionHandling, Test.ReplaceSelection) + if not hasattr(globals(), "app"): + ( + NormalizeForVSText, + NormalizeForPython, + TerminateTextForVS, + WrapFunctionForExceptionHandling, + ReplaceSelection, + ) = ( + Test.NormalizeForVSText, + Test.NormalizeForPython, + Test.TerminateTextForVS, + Test.WrapFunctionForExceptionHandling, + Test.ReplaceSelection, + ) app = Test.TestApp() + _tests = r""" app.current_doc.text = '\nfoo\n' -------------------- @@ -340,18 +437,21 @@ def SetDependencies(): -------------------- -""".split('====================') +""".split( + "====================" +) -_tests = [text.split('--------------------') for text in _tests] +_tests = [text.split("--------------------") for text in _tests] if not is_py3: del text -def test_module(tests = _tests): + +def test_module(tests=_tests): global native_endl Test.SetDependencies() - native_endl = '\n' + native_endl = "\n" failed = 0 - print('Testing CodeTags.py') + print("Testing CodeTags.py") for before, expected in tests: test = Test(before, expected) test.test() @@ -360,31 +460,35 @@ def test_module(tests = _tests): print(result) failed += 1 if failed: - print('%d Test(s) Failed!' % failed) + print("%d Test(s) Failed!" % failed) else: - print('All Tests Passed!') + print("All Tests Passed!") return failed + def _TraceFunctions(): global _tablevel _tablevel = 0 + def _trace(fn): def _wrapper(*args, **kwargs): global _tablevel _tablevel += 1 _args = map(repr, args) - _args += ['%s=%s' % (key, repr(value)) for key, value in kwargs.items()] - print('%s%s(%s)' % (_tablevel*' ', fn.__name__, ', '.join(_args))) + _args += ["%s=%s" % (key, repr(value)) for key, value in kwargs.items()] + print("%s%s(%s)" % (_tablevel * " ", fn.__name__, ", ".join(_args))) result = fn(*args, **kwargs) if result: - print('%s= %s' % (_tablevel*' ', repr(result))) + print("%s= %s" % (_tablevel * " ", repr(result))) _tablevel -= 1 return result + return _wrapper import types + for key, value in globals().items(): - if key[:1] != '_': + if key[:1] != "_": if type(value) == types.FunctionType: globals()[key] = _trace(value) elif type(value) == types.ClassType: @@ -398,28 +502,32 @@ def _wrapper(*args, **kwargs): ################################################ # For running from the command-line + def usage(): - print("""CodeTags.py - Templatize and generate code with python tags. + print( + """CodeTags.py - Templatize and generate code with python tags. Usage: CodeTags.py [] - file with tags to expand - optional output file (expand in place if unspecified) -""") +""" + ) return 1 + def main(argv, newline=None): trace = False test = False args = [] for arg in argv: - if arg[0] in '/-': + if arg[0] in "/-": opt = arg[1:].lower() - if opt == 'trace': + if opt == "trace": trace = True continue - elif opt == 'test': + elif opt == "test": test = True continue args.append(arg) @@ -438,14 +546,14 @@ def main(argv, newline=None): if len(args) == 2: global native_endl Test.SetDependencies() - native_endl = '\n' - with open(args[0], 'rt') as f: + native_endl = "\n" + with open(args[0], "rt") as f: # Use test harness to do work, but we don't care about the comparison # with expected, since we're not actually in testing mode: - test = Test(f.read(), 'expected not used.') + test = Test(f.read(), "expected not used.") result = test.test() if result == 0: - with open(args[1], 'wt', newline=newline) as f: + with open(args[1], "wt", newline=newline) as f: f.write(test.after) else: sys.stderr.write(test.after) @@ -454,6 +562,8 @@ def main(argv, newline=None): return result -if __name__ == '__main__': + +if __name__ == "__main__": import sys + exit(main(sys.argv[1:])) diff --git a/utils/hct/ExtractIRForPassTest.py b/utils/hct/ExtractIRForPassTest.py index 72c55ef103..639e2602f0 100644 --- a/utils/hct/ExtractIRForPassTest.py +++ b/utils/hct/ExtractIRForPassTest.py @@ -25,108 +25,141 @@ import tempfile import argparse + def ParseArgs(): - parser = argparse.ArgumentParser( - formatter_class=argparse.RawDescriptionHelpFormatter, description=__doc__) - parser.add_argument( - '-p', dest='desired_pass', metavar='', required=True, - help='stop before this module pass (per-function prepass not supported).') - parser.add_argument( - '-n', dest='invocation', metavar='', type=int, default=1, - help='pass invocation number on which to stop (default=1)') - parser.add_argument( - 'hlsl_file', metavar='', - help='input HLSL file path to compile') - parser.add_argument( - '-o', dest='output_file', metavar='', required=True, - help='output file name') - parser.add_argument( - 'compilation_options', nargs='*', - metavar='-- ', - help='set of compilation options needed to compile the HLSL file with DXC') - return parser.parse_args() - -def SplitAtPass(passes, pass_name, invocation = 1): - pass_name = '-' + pass_name - before = [] - fn_passes = True - count = 0 - after = None - for line in passes: - line = line.strip() - if not line or line.startswith('#'): - continue - if line == '-opt-mod-passes': - fn_passes = False - if after: - after.append(line) - continue - if not fn_passes: - if line == pass_name: - count += 1 - if count >= invocation: - after = [line] - continue - before.append(line) - return before, after + parser = argparse.ArgumentParser( + formatter_class=argparse.RawDescriptionHelpFormatter, description=__doc__ + ) + parser.add_argument( + "-p", + dest="desired_pass", + metavar="", + required=True, + help="stop before this module pass (per-function prepass not supported).", + ) + parser.add_argument( + "-n", + dest="invocation", + metavar="", + type=int, + default=1, + help="pass invocation number on which to stop (default=1)", + ) + parser.add_argument( + "hlsl_file", metavar="", help="input HLSL file path to compile" + ) + parser.add_argument( + "-o", + dest="output_file", + metavar="", + required=True, + help="output file name", + ) + parser.add_argument( + "compilation_options", + nargs="*", + metavar="-- ", + help="set of compilation options needed to compile the HLSL file with DXC", + ) + return parser.parse_args() + + +def SplitAtPass(passes, pass_name, invocation=1): + pass_name = "-" + pass_name + before = [] + fn_passes = True + count = 0 + after = None + for line in passes: + line = line.strip() + if not line or line.startswith("#"): + continue + if line == "-opt-mod-passes": + fn_passes = False + if after: + after.append(line) + continue + if not fn_passes: + if line == pass_name: + count += 1 + if count >= invocation: + after = [line] + continue + before.append(line) + return before, after + def GetTempFilename(*args, **kwargs): - "Get temp filename and close the file handle for use by others" - fd, name = tempfile.mkstemp(*args, **kwargs) - os.close(fd) - return name + "Get temp filename and close the file handle for use by others" + fd, name = tempfile.mkstemp(*args, **kwargs) + os.close(fd) + return name + def main(args): - try: - # 1. Gets the pass list for an HLSL compilation using -Odump - cmd = ['dxc', '/Odump', args.hlsl_file] + args.compilation_options - # print(cmd) - all_passes = subprocess.check_output(cmd, text=True) - all_passes = all_passes.splitlines() - - # 2. Compiles HLSL with -fcgl and outputs to intermediate IR - fcgl_file = GetTempFilename('.ll') - cmd = (['dxc', '-fcgl', '-Fc', fcgl_file, args.hlsl_file] - + args.compilation_options) - # print(cmd) - subprocess.check_call(cmd) - - # 3. Collects list of passes before the desired pass and adds - # -hlsl-passes-pause to write correct metadata - passes_before, passes_after = SplitAtPass( - all_passes, args.desired_pass, args.invocation) - print('\nPasses before: {}\n\nRemaining passes: {}' - .format(' '.join(passes_before), ' '.join(passes_after))) - passes_before.append('-hlsl-passes-pause') - - # 4. Invokes dxopt to run passes on -fcgl output and write bitcode result - bitcode_file = GetTempFilename('.bc') - cmd = ['dxopt', '-o=' + bitcode_file, fcgl_file] + passes_before - # print(cmd) - subprocess.check_call(cmd) - - # 5. Disassembles bitcode to .ll file for use as a test - temp_out = GetTempFilename('.ll') - cmd = ['dxc', '/dumpbin', '-Fc', temp_out, bitcode_file] - # print(cmd) - subprocess.check_call(cmd) - - # 6. Inserts RUN line with -hlsl-passes-resume and desired pass - with open(args.output_file, 'wt') as f: - f.write('; RUN: %opt %s -hlsl-passes-resume {} -S | FileCheck %s\n\n' - .format(args.desired_pass)) - with open(temp_out, 'rt') as f_in: - f.write(f_in.read()) - - # Clean up temp files - os.unlink(fcgl_file) - os.unlink(bitcode_file) - os.unlink(temp_out) - except: - print(f'\nSomething went wrong!\nMost recent command and arguments: {cmd}\n') - raise - -if __name__=='__main__': - args = ParseArgs() - main(args) - print('\nSuccess! See output file:\n{}'.format(args.output_file)) + try: + # 1. Gets the pass list for an HLSL compilation using -Odump + cmd = ["dxc", "/Odump", args.hlsl_file] + args.compilation_options + # print(cmd) + all_passes = subprocess.check_output(cmd, text=True) + all_passes = all_passes.splitlines() + + # 2. Compiles HLSL with -fcgl and outputs to intermediate IR + fcgl_file = GetTempFilename(".ll") + cmd = [ + "dxc", + "-fcgl", + "-Fc", + fcgl_file, + args.hlsl_file, + ] + args.compilation_options + # print(cmd) + subprocess.check_call(cmd) + + # 3. Collects list of passes before the desired pass and adds + # -hlsl-passes-pause to write correct metadata + passes_before, passes_after = SplitAtPass( + all_passes, args.desired_pass, args.invocation + ) + print( + "\nPasses before: {}\n\nRemaining passes: {}".format( + " ".join(passes_before), " ".join(passes_after) + ) + ) + passes_before.append("-hlsl-passes-pause") + + # 4. Invokes dxopt to run passes on -fcgl output and write bitcode result + bitcode_file = GetTempFilename(".bc") + cmd = ["dxopt", "-o=" + bitcode_file, fcgl_file] + passes_before + # print(cmd) + subprocess.check_call(cmd) + + # 5. Disassembles bitcode to .ll file for use as a test + temp_out = GetTempFilename(".ll") + cmd = ["dxc", "/dumpbin", "-Fc", temp_out, bitcode_file] + # print(cmd) + subprocess.check_call(cmd) + + # 6. Inserts RUN line with -hlsl-passes-resume and desired pass + with open(args.output_file, "wt") as f: + f.write( + "; RUN: %opt %s -hlsl-passes-resume -{} -S | FileCheck %s\n\n".format( + args.desired_pass + ) + ) + with open(temp_out, "rt") as f_in: + f.write(f_in.read()) + + # Clean up temp files + os.unlink(fcgl_file) + os.unlink(bitcode_file) + os.unlink(temp_out) + except: + print(f"\nSomething went wrong!\nMost recent command and arguments: {cmd}\n") + raise + + +if __name__ == "__main__": + args = ParseArgs() + main(args) + print("\nSuccess! See output file:\n{}".format(args.output_file)) diff --git a/utils/hct/VerifierHelper.py b/utils/hct/VerifierHelper.py index 72774dfa17..c750dfae52 100644 --- a/utils/hct/VerifierHelper.py +++ b/utils/hct/VerifierHelper.py @@ -41,138 +41,150 @@ import os, sys, re import subprocess -try: DiffTool = os.environ['HLSL_DIFF_TOOL'] -except: DiffTool = None -try: FxcPath = os.environ['HLSL_FXC_PATH'] -except: FxcPath = 'fxc' -HlslVerifierTestCpp = os.path.expandvars(r'${HLSL_SRC_DIR}\tools\clang\unittests\HLSL\VerifierTest.cpp') -HlslDataDir = os.path.expandvars(r'${HLSL_SRC_DIR}\tools\clang\test\HLSL') -HlslBinDir = os.path.expandvars(r'${HLSL_BLD_DIR}\Debug\bin') +try: + DiffTool = os.environ["HLSL_DIFF_TOOL"] +except: + DiffTool = None +try: + FxcPath = os.environ["HLSL_FXC_PATH"] +except: + FxcPath = "fxc" +HlslVerifierTestCpp = os.path.expandvars( + r"${HLSL_SRC_DIR}\tools\clang\unittests\HLSL\VerifierTest.cpp" +) +HlslDataDir = os.path.expandvars(r"${HLSL_SRC_DIR}\tools\clang\test\HLSL") +HlslBinDir = os.path.expandvars(r"${HLSL_BLD_DIR}\Debug\bin") VerifierTests = { - 'RunArrayConstAssign': 'array-const-assign.hlsl', - 'RunArrayIndexOutOfBounds': 'array-index-out-of-bounds-HV-2016.hlsl', - 'RunArrayLength': 'array-length.hlsl', - 'RunAttributes': 'attributes.hlsl', - 'RunBadInclude': 'bad-include.hlsl', - 'RunBinopDims': 'binop-dims.hlsl', - 'RunBitfields': 'bitfields.hlsl', - 'RunBuiltinTypesNoInheritance': 'builtin-types-no-inheritance.hlsl', - 'RunCXX11Attributes': 'cxx11-attributes.hlsl', - 'RunConstAssign': 'const-assign.hlsl', - 'RunConstDefault': 'const-default.hlsl', - 'RunConstExpr': 'const-expr.hlsl', - 'RunConversionsBetweenTypeShapes': 'conversions-between-type-shapes.hlsl', - 'RunConversionsBetweenTypeShapesStrictUDT': 'conversions-between-type-shapes-strictudt.hlsl', - 'RunConversionsNonNumericAggregates': 'conversions-non-numeric-aggregates.hlsl', - 'RunCppErrors': 'cpp-errors.hlsl', - 'RunCppErrorsHV2015': 'cpp-errors-hv2015.hlsl', - 'RunDerivedToBaseCasts': 'derived-to-base.hlsl', - 'RunEffectsSyntax': 'effects-syntax.hlsl', - 'RunEnums': 'enums.hlsl', - 'RunFunctions': 'functions.hlsl', - 'RunImplicitCasts': 'implicit-casts.hlsl', - 'RunIncompleteArray': 'incomp_array_err.hlsl', - 'RunIncompleteType': 'incomplete-type.hlsl', - 'RunIndexingOperator': 'indexing-operator.hlsl', - 'RunInputPatchConst': 'InputPatch-const.hlsl', - 'RunIntrinsicExamples': 'intrinsic-examples.hlsl', - 'RunLiterals': 'literals.hlsl', - 'RunMatrixAssignments': 'matrix-assignments.hlsl', - 'RunMatrixSyntax': 'matrix-syntax.hlsl', - 'RunMatrixSyntaxExactPrecision': 'matrix-syntax-exact-precision.hlsl', - 'RunMintypesPromotionWarnings': 'mintypes-promotion-warnings.hlsl', - 'RunMoreOperators': 'more-operators.hlsl', - 'RunObjectOperators': 'object-operators.hlsl', - 'RunObjectTemplateDiagDeferred': 'object-template-diag-deferred.hlsl', - 'RunOperatorOverloadingForNewDelete': 'overloading-new-delete-errors.hlsl', - 'RunOperatorOverloadingNotDefinedBinaryOp': 'use-undefined-overloaded-operator.hlsl', - 'RunPackReg': 'packreg.hlsl', - 'RunRayTracings': 'raytracings.hlsl', - 'RunScalarAssignments': 'scalar-assignments.hlsl', - 'RunScalarAssignmentsExactPrecision': 'scalar-assignments-exact-precision.hlsl', - 'RunScalarOperators': 'scalar-operators.hlsl', - 'RunScalarOperatorsAssign': 'scalar-operators-assign.hlsl', - 'RunScalarOperatorsAssignExactPrecision': 'scalar-operators-assign-exact-precision.hlsl', - 'RunScalarOperatorsExactPrecision': 'scalar-operators-exact-precision.hlsl', - 'RunSemantics': 'semantics.hlsl', - 'RunSizeof': 'sizeof.hlsl', - 'RunString': 'string.hlsl', - 'RunStructAssignments': 'struct-assignments.hlsl', - 'RunSubobjects': 'subobjects-syntax.hlsl', - 'RunTemplateChecks': 'template-checks.hlsl', - 'RunTemplateLiteralSubstitutionFailure': 'template-literal-substitution-failure.hlsl', - 'RunTypemodsSyntax': 'typemods-syntax.hlsl', - 'RunUint4Add3': 'uint4_add3.hlsl', - 'RunVarmodsSyntax': 'varmods-syntax.hlsl', - 'RunVectorAnd': 'vector-and.hlsl', - 'RunVectorAssignments': 'vector-assignments.hlsl', - 'RunVectorConditional': 'vector-conditional.hlsl', - 'RunVectorOr': 'vector-or.hlsl', - 'RunVectorSelect': 'vector-select.hlsl', - 'RunVectorSyntax': 'vector-syntax.hlsl', - 'RunVectorSyntaxExactPrecision': 'vector-syntax-exact-precision.hlsl', - 'RunVectorSyntaxMix': 'vector-syntax-mix.hlsl', - 'RunWave': 'wave.hlsl', - 'RunWriteConstArrays': 'write-const-arrays.hlsl', - 'RunAtomicsOnBitfields': 'atomics-on-bitfields.hlsl', - 'RunUnboundedResourceArrays': 'invalid-unbounded-resource-arrays.hlsl', + "RunArrayConstAssign": "array-const-assign.hlsl", + "RunArrayIndexOutOfBounds": "array-index-out-of-bounds-HV-2016.hlsl", + "RunArrayLength": "array-length.hlsl", + "RunAttributes": "attributes.hlsl", + "RunBadInclude": "bad-include.hlsl", + "RunBinopDims": "binop-dims.hlsl", + "RunBitfields": "bitfields.hlsl", + "RunBuiltinTypesNoInheritance": "builtin-types-no-inheritance.hlsl", + "RunCXX11Attributes": "cxx11-attributes.hlsl", + "RunConstAssign": "const-assign.hlsl", + "RunConstDefault": "const-default.hlsl", + "RunConstExpr": "const-expr.hlsl", + "RunConversionsBetweenTypeShapes": "conversions-between-type-shapes.hlsl", + "RunConversionsBetweenTypeShapesStrictUDT": "conversions-between-type-shapes-strictudt.hlsl", + "RunConversionsNonNumericAggregates": "conversions-non-numeric-aggregates.hlsl", + "RunCppErrors": "cpp-errors.hlsl", + "RunCppErrorsHV2015": "cpp-errors-hv2015.hlsl", + "RunDerivedToBaseCasts": "derived-to-base.hlsl", + "RunEffectsSyntax": "effects-syntax.hlsl", + "RunEnums": "enums.hlsl", + "RunFunctions": "functions.hlsl", + "RunImplicitCasts": "implicit-casts.hlsl", + "RunIncompleteArray": "incomp_array_err.hlsl", + "RunIncompleteType": "incomplete-type.hlsl", + "RunIndexingOperator": "indexing-operator.hlsl", + "RunInputPatchConst": "InputPatch-const.hlsl", + "RunIntrinsicExamples": "intrinsic-examples.hlsl", + "RunLiterals": "literals.hlsl", + "RunMatrixAssignments": "matrix-assignments.hlsl", + "RunMatrixSyntax": "matrix-syntax.hlsl", + "RunMatrixSyntaxExactPrecision": "matrix-syntax-exact-precision.hlsl", + "RunMintypesPromotionWarnings": "mintypes-promotion-warnings.hlsl", + "RunMoreOperators": "more-operators.hlsl", + "RunObjectOperators": "object-operators.hlsl", + "RunObjectTemplateDiagDeferred": "object-template-diag-deferred.hlsl", + "RunOperatorOverloadingForNewDelete": "overloading-new-delete-errors.hlsl", + "RunOperatorOverloadingNotDefinedBinaryOp": "use-undefined-overloaded-operator.hlsl", + "RunPackReg": "packreg.hlsl", + "RunRayTracings": "raytracings.hlsl", + "RunScalarAssignments": "scalar-assignments.hlsl", + "RunScalarAssignmentsExactPrecision": "scalar-assignments-exact-precision.hlsl", + "RunScalarOperators": "scalar-operators.hlsl", + "RunScalarOperatorsAssign": "scalar-operators-assign.hlsl", + "RunScalarOperatorsAssignExactPrecision": "scalar-operators-assign-exact-precision.hlsl", + "RunScalarOperatorsExactPrecision": "scalar-operators-exact-precision.hlsl", + "RunSemantics": "semantics.hlsl", + "RunSizeof": "sizeof.hlsl", + "RunString": "string.hlsl", + "RunStructAssignments": "struct-assignments.hlsl", + "RunSubobjects": "subobjects-syntax.hlsl", + "RunTemplateChecks": "template-checks.hlsl", + "RunTemplateLiteralSubstitutionFailure": "template-literal-substitution-failure.hlsl", + "RunTypemodsSyntax": "typemods-syntax.hlsl", + "RunUint4Add3": "uint4_add3.hlsl", + "RunVarmodsSyntax": "varmods-syntax.hlsl", + "RunVectorAnd": "vector-and.hlsl", + "RunVectorAssignments": "vector-assignments.hlsl", + "RunVectorConditional": "vector-conditional.hlsl", + "RunVectorOr": "vector-or.hlsl", + "RunVectorSelect": "vector-select.hlsl", + "RunVectorSyntax": "vector-syntax.hlsl", + "RunVectorSyntaxExactPrecision": "vector-syntax-exact-precision.hlsl", + "RunVectorSyntaxMix": "vector-syntax-mix.hlsl", + "RunWave": "wave.hlsl", + "RunWriteConstArrays": "write-const-arrays.hlsl", + "RunAtomicsOnBitfields": "atomics-on-bitfields.hlsl", + "RunUnboundedResourceArrays": "invalid-unbounded-resource-arrays.hlsl", } # The following test(s) do not work in fxc mode: fxcExcludedTests = [ - 'RunArrayLength', - 'RunBitfields', - 'RunCppErrors', - 'RunCppErrorsHV2015', - 'RunCXX11Attributes', - 'RunConversionsBetweenTypeShapesStrictUDT', - 'RunEnums', - 'RunIncompleteType', - 'RunIntrinsicExamples', - 'RunMatrixSyntaxExactPrecision', - 'RunObjectTemplateDiagDeferred', - 'RunOperatorOverloadingForNewDelete', - 'RunOperatorOverloadingNotDefinedBinaryOp', - 'RunRayTracings', - 'RunScalarAssignmentsExactPrecision', - 'RunScalarOperatorsAssignExactPrecision', - 'RunScalarOperatorsExactPrecision', - 'RunSizeof', - 'RunSubobjects', - 'RunTemplateChecks', - 'RunTemplateLiteralSubstitutionFailure', - 'RunVectorSyntaxExactPrecision', - 'RunWave', - 'RunAtomicsOnBitfields', + "RunArrayLength", + "RunBitfields", + "RunCppErrors", + "RunCppErrorsHV2015", + "RunCXX11Attributes", + "RunConversionsBetweenTypeShapesStrictUDT", + "RunEnums", + "RunIncompleteType", + "RunIntrinsicExamples", + "RunMatrixSyntaxExactPrecision", + "RunObjectTemplateDiagDeferred", + "RunOperatorOverloadingForNewDelete", + "RunOperatorOverloadingNotDefinedBinaryOp", + "RunRayTracings", + "RunScalarAssignmentsExactPrecision", + "RunScalarOperatorsAssignExactPrecision", + "RunScalarOperatorsExactPrecision", + "RunSizeof", + "RunSubobjects", + "RunTemplateChecks", + "RunTemplateLiteralSubstitutionFailure", + "RunVectorSyntaxExactPrecision", + "RunWave", + "RunAtomicsOnBitfields", ] # rxRUN = re.compile(r'[ RUN ] VerifierTest.(\w+)') # gtest syntax -rxRUN = re.compile(r'StartGroup: VerifierTest::(\w+)') # TAEF syntax -rxEndGroup = re.compile(r'EndGroup: VerifierTest::(\w+)\s+\[(\w+)\]') # TAEF syntax -rxForProgram = re.compile(r'^for program (.*?) with errors\:$') +rxRUN = re.compile(r"StartGroup: VerifierTest::(\w+)") # TAEF syntax +rxEndGroup = re.compile(r"EndGroup: VerifierTest::(\w+)\s+\[(\w+)\]") # TAEF syntax +rxForProgram = re.compile(r"^for program (.*?) with errors\:$") # rxExpected = re.compile(r"^error\: \'(\w+)\' diagnostics (expected but not seen|seen but not expected)\: $") # gtest syntax -rxExpected = re.compile(r"^\'(\w+)\' diagnostics (expected but not seen|seen but not expected)\: $") # TAEF syntax -rxDiagReport = re.compile(r' (?:File (.*?) )?Line (\d+): (.*)$') +rxExpected = re.compile( + r"^\'(\w+)\' diagnostics (expected but not seen|seen but not expected)\: $" +) # TAEF syntax +rxDiagReport = re.compile(r" (?:File (.*?) )?Line (\d+): (.*)$") -rxDiag = re.compile(r'((expected|fxc)-(error|warning|note|pass)\s*\{\{(.*?)\}\}\s*)') +rxDiag = re.compile(r"((expected|fxc)-(error|warning|note|pass)\s*\{\{(.*?)\}\}\s*)") -rxFxcErr = re.compile(r'(.+)\((\d+)(?:,(\d+)(?:\-(\d+))?)?\)\: (error|warning) (.*?)\: (.*)') +rxFxcErr = re.compile( + r"(.+)\((\d+)(?:,(\d+)(?:\-(\d+))?)?\)\: (error|warning) (.*?)\: (.*)" +) # groups = (filename, line, colstart, colend, ew, error_code, error_message) -rxCommentStart = re.compile(r'(//|/\*)') -rxStrings = re.compile(r'(\'|\").*?((?\) | + r"""\<(?:(?P\) | (?: (?:(?:(?Pline|\S*):(?P\d+):(?P\d+)) | col:(?P\d+) @@ -183,12 +195,13 @@ ) )? ) - )\>''', - re.VERBOSE) -rxAstHexAddress = re.compile(r'\b(0x[0-9a-f]+) ?') -rxAstNode = re.compile(r'((?:\<\<\\>\>)|(?:\w+))\s*(.*)') + )\>""", + re.VERBOSE, +) +rxAstHexAddress = re.compile(r"\b(0x[0-9a-f]+) ?") +rxAstNode = re.compile(r"((?:\<\<\\>\>)|(?:\w+))\s*(.*)") # matches ignored portion of line for first AST node in subgraph to match -rxAstIgnoredIndent = re.compile(r'^(\s+|\||\`|\-)*') +rxAstIgnoredIndent = re.compile(r"^(\s+|\||\`|\-)*") # The purpose of StripComments and CountBraces is to be used when commenting lines of code out to allow # Fxc testing to continue even when it doesn't recover as well as clang. Some error lines are on the @@ -205,37 +218,42 @@ # This still does not handle preprocessor directives, or escaped characters (like line ends or escaped # quotes), or other cases that a real parser would handle. -def StripComments(line, multiline_comment_continued = False): + +def StripComments(line, multiline_comment_continued=False): "Remove comments from line, returns stripped line and multiline_comment_continued if a multiline comment continues beyond the line" if multiline_comment_continued: # in multiline comment, only look for end of that - idx = line.find('*/') + idx = line.find("*/") if idx < 0: - return '', True - return StripComments(line[idx+2:]) + return "", True + return StripComments(line[idx + 2 :]) # look for start of multiline comment or eol comment: m = rxCommentStart.search(line) if m: - if m.group(1) == '/*': - line_end, multiline_comment_continued = StripComments(line[m.end(1):], True) - return line[:m.start(1)] + line_end, multiline_comment_continued - elif m.group(1) == '//': - return line[:m.start(1)], False + if m.group(1) == "/*": + line_end, multiline_comment_continued = StripComments( + line[m.end(1) :], True + ) + return line[: m.start(1)] + line_end, multiline_comment_continued + elif m.group(1) == "//": + return line[: m.start(1)], False return line, False + def CountBraces(line, bracestacks): m = rxStrings.search(line) if m: - CountBraces(line[:m.start(1)], bracestacks) - CountBraces(line[m.end(2):], bracestacks) + CountBraces(line[: m.start(1)], bracestacks) + CountBraces(line[m.end(2) :], bracestacks) return for b in rxBraces.findall(line): - if b in '()': - bracestacks['()'] = bracestacks.get('()', 0) + ((b == '(') and 1 or -1) - elif b in '{}': - bracestacks['{}'] = bracestacks.get('{}', 0) + ((b == '{') and 1 or -1) - elif b in '[]': - bracestacks['[]'] = bracestacks.get('[]', 0) + ((b == '[') and 1 or -1) + if b in "()": + bracestacks["()"] = bracestacks.get("()", 0) + ((b == "(") and 1 or -1) + elif b in "{}": + bracestacks["{}"] = bracestacks.get("{}", 0) + ((b == "{") and 1 or -1) + elif b in "[]": + bracestacks["[]"] = bracestacks.get("[]", 0) + ((b == "[") and 1 or -1) + def ProcessStatementOrBlock(lines, start, fn_process): num = 0 @@ -244,35 +262,43 @@ def ProcessStatementOrBlock(lines, start, fn_process): # Assumes start of line is not inside multiline comment multiline_comment_continued = False bracestacks = {} - while start+num < len(lines): - line = lines[start+num] - lines[start+num] = fn_process(line) + while start + num < len(lines): + line = lines[start + num] + lines[start + num] = fn_process(line) num += 1 - line, multiline_comment_continued = StripComments(line, multiline_comment_continued) + line, multiline_comment_continued = StripComments( + line, multiline_comment_continued + ) CountBraces(line, bracestacks) - if (statement_continued and - not rxStatementEndOrBlockBegin.search(line) ): + if statement_continued and not rxStatementEndOrBlockBegin.search(line): continue statement_continued = False if rxLineContinued.match(line): continue - if (bracestacks.get('{}', 0) < 1 and - bracestacks.get('()', 0) < 1 and - bracestacks.get('[]', 0) < 1 ): + if ( + bracestacks.get("{}", 0) < 1 + and bracestacks.get("()", 0) < 1 + and bracestacks.get("[]", 0) < 1 + ): break return num + def CommentStatementOrBlock(lines, start): def fn_process(line): - return '// ' + line + return "// " + line + return ProcessStatementOrBlock(lines, start, fn_process) + def ParseVerifierTestCpp(): "Returns dictionary mapping Run* test name to hlsl filename by parsing VerifierTest.cpp" tests = {} FoundTest = None + def fn_null(line): return line + def fn_process(line): searching = FoundTest is not None if searching: @@ -281,7 +307,8 @@ def fn_process(line): tests[FoundTest] = m.group(1) searching = False return line - with open(HlslVerifierTestCpp, 'rt') as f: + + with open(HlslVerifierTestCpp, "rt") as f: lines = f.readlines() start = 0 while start < len(lines): @@ -290,25 +317,29 @@ def fn_process(line): FoundTest = m.group(1) start += ProcessStatementOrBlock(lines, start, fn_process) if FoundTest not in tests: - print('Could not parse file for test %s' % FoundTest) + print("Could not parse file for test %s" % FoundTest) FoundTest = None else: start += ProcessStatementOrBlock(lines, start, fn_null) return tests + class SourceLocation(object): def __init__(self, line=None, **kwargs): if not kwargs: - self.Invalid = '' + self.Invalid = "" return for key, value in kwargs.items(): - try: value = int(value) - except: pass + try: + value = int(value) + except: + pass setattr(self, key, value) if line and not self.FromLine: self.FromLine = line self.FromCol = self.FromCol or self.FromLineCol self.ToCol = self.ToCol or self.ToLineCol + def Offset(self, offset): "Offset From/To Lines by specified value" if self.Invalid: @@ -317,32 +348,45 @@ def Offset(self, offset): self.FromLine = self.FromLine + offset if self.ToLine: self.ToLine = self.ToLine + offset + def ToStringAtLine(self, line): "convert to string relative to specified line" if self.Invalid: sloc = self.Invalid else: if self.FromLine and line != self.FromLine: - sloc = 'line:%d:%d' % (self.FromLine, self.FromCol) + sloc = "line:%d:%d" % (self.FromLine, self.FromCol) line = self.FromLine else: - sloc = 'col:%d' % self.FromCol + sloc = "col:%d" % self.FromCol if self.ToCol: if self.ToLine and line != self.ToLine: - sloc += ', line:%d:%d' % (self.ToLine, self.ToCol) + sloc += ", line:%d:%d" % (self.ToLine, self.ToCol) else: - sloc += ', col:%d' % self.ToCol - return '<' + sloc + '>' + sloc += ", col:%d" % self.ToCol + return "<" + sloc + ">" + class AstNode(object): - def __init__(self, name, sloc, prefix, text, indent=''): - self.name, self.sloc, self.prefix, self.text, self.indent = name, sloc, prefix, text, indent + def __init__(self, name, sloc, prefix, text, indent=""): + self.name, self.sloc, self.prefix, self.text, self.indent = ( + name, + sloc, + prefix, + text, + indent, + ) self.children = [] + def ToStringAtLine(self, line): "convert to string relative to specified line" - if self.name == '<<>>': + if self.name == "<<>>": return self.name - return ('%s %s%s %s' % (self.name, self.prefix, self.sloc.ToStringAtLine(line), self.text)).strip() + return ( + "%s %s%s %s" + % (self.name, self.prefix, self.sloc.ToStringAtLine(line), self.text) + ).strip() + def WalkAstChildren(ast_root): "yield each child node in the ast tree in depth-first order" @@ -351,23 +395,31 @@ def WalkAstChildren(ast_root): for child in WalkAstChildren(node): yield child -def WriteAstSubtree(ast_root, line, indent=''): + +def WriteAstSubtree(ast_root, line, indent=""): output = [] output.append(indent + ast_root.ToStringAtLine(line)) if not ast_root.sloc.Invalid and ast_root.sloc.FromLine: line = ast_root.sloc.FromLine root_indent_len = len(ast_root.indent) for child in WalkAstChildren(ast_root): - output.append(indent + child.indent[root_indent_len:] + child.ToStringAtLine(line)) + output.append( + indent + child.indent[root_indent_len:] + child.ToStringAtLine(line) + ) if not child.sloc.Invalid and child.sloc.FromLine: line = child.sloc.FromLine return output + def FindAstNodesByLine(ast_root, line): nodes = [] if not ast_root.sloc.Invalid and ast_root.sloc.FromLine == line: return [ast_root] - if not ast_root.sloc.Invalid and ast_root.sloc.ToLine and ast_root.sloc.ToLine < line: + if ( + not ast_root.sloc.Invalid + and ast_root.sloc.ToLine + and ast_root.sloc.ToLine < line + ): return [] for child in ast_root.children: sub_nodes = FindAstNodesByLine(child, line) @@ -375,47 +427,52 @@ def FindAstNodesByLine(ast_root, line): nodes += sub_nodes return nodes + def ParseAst(astlines): - cur_line = 0 # current source line + cur_line = 0 # current source line root_node = None - ast_stack = [] # stack of nodes and column numbers so we can pop the right number of nodes up the stack - i = 0 # ast line index + ast_stack = ( + [] + ) # stack of nodes and column numbers so we can pop the right number of nodes up the stack + i = 0 # ast line index def push(node, col): if ast_stack: cur_node, prior_col = ast_stack[-1] cur_node.children.append(node) ast_stack.append((node, col)) + def popto(col): cur_node, prior_col = ast_stack[-1] while ast_stack and col <= prior_col: ast_stack.pop() cur_node, prior_col = ast_stack[-1] assert ast_stack + def parsenode(text, indent): m = rxAstNode.match(text) if m: name = m.group(1) - text = text[m.end(1):].strip() + text = text[m.end(1) :].strip() else: - print('rxAstNode match failed on:\n %s' % text) - return AstNode('ast-parse-failed', SourceLocation(), '', '', indent) - text = rxAstHexAddress.sub('', text).strip() + print("rxAstNode match failed on:\n %s" % text) + return AstNode("ast-parse-failed", SourceLocation(), "", "", indent) + text = rxAstHexAddress.sub("", text).strip() m = rxAstSourceLocation.search(text) if m: - prefix = text[:m.start()] + prefix = text[: m.start()] sloc = SourceLocation(cur_line, **m.groupdict()) - text = text[m.end():].strip() + text = text[m.end() :].strip() else: - prefix = '' + prefix = "" sloc = SourceLocation() return AstNode(name, sloc, prefix, text, indent) # Look for TranslationUnitDecl and start from there while i < len(astlines): text = astlines[i] - if text.startswith('TranslationUnitDecl'): - root_node = parsenode(text, '') + if text.startswith("TranslationUnitDecl"): + root_node = parsenode(text, "") push(root_node, 0) break i += 1 @@ -427,20 +484,20 @@ def parsenode(text, indent): # get starting column and update stack m = rxAstIgnoredIndent.match(line) - indent = '' + indent = "" col = 0 if m: indent = m.group(0) col = m.end() if col == 0: - break # at this point we should be done parsing the translation unit! + break # at this point we should be done parsing the translation unit! popto(col) # parse and add the node node = parsenode(line[col:], indent) if not node: - print('error parsing line %d:\n%s' % (i+1, line)) + print("error parsing line %d:\n%s" % (i + 1, line)) assert False push(node, col) @@ -453,18 +510,25 @@ def parsenode(text, indent): return root_node + class File(object): def __init__(self, filename): self.filename = filename - self.expected = {} # {line_num: [('error' or 'warning', 'error or warning message'), ...], ...} - self.unexpected = {} # {line_num: [('error' or 'warning', 'error or warning message'), ...], ...} + self.expected = ( + {} + ) # {line_num: [('error' or 'warning', 'error or warning message'), ...], ...} + self.unexpected = ( + {} + ) # {line_num: [('error' or 'warning', 'error or warning message'), ...], ...} self.last_diag_col = None + def AddExpected(self, line_num, ew, message): self.expected.setdefault(line_num, []).append((ew, message)) + def AddUnexpected(self, line_num, ew, message): self.unexpected.setdefault(line_num, []).append((ew, message)) - def MatchDiags(self, line, diags=[], prefix='expected', matchall=False): + def MatchDiags(self, line, diags=[], prefix="expected", matchall=False): diags = diags[:] diag_col = None matches = [] @@ -484,7 +548,8 @@ def MatchDiags(self, line, diags=[], prefix='expected', matchall=False): continue del diags[idx] return sorted(matches, key=lambda m: m.start()), diags, diag_col - def RemoveDiags(self, line, diags, prefix='expected', removeall=False): + + def RemoveDiags(self, line, diags, prefix="expected", removeall=False): """Removes expected-* diags from line, returns result_line, remaining_diags, diag_col Where, result_line is the line without the matching diagnostics, remaining is the list of diags not found on the line, @@ -492,54 +557,79 @@ def RemoveDiags(self, line, diags, prefix='expected', removeall=False): """ matches, diags, diag_col = self.MatchDiags(line, diags, prefix, removeall) for m in reversed(matches): - line = line[:m.start()] + line[m.end():] + line = line[: m.start()] + line[m.end() :] return line, diags, diag_col - def AddDiags(self, line, diags, diag_col=None, prefix='expected'): + + def AddDiags(self, line, diags, diag_col=None, prefix="expected"): "Adds expected-* diags to line." if diags: if diag_col is None: - if self.last_diag_col is not None and self.last_diag_col-3 > len(line): + if self.last_diag_col is not None and self.last_diag_col - 3 > len( + line + ): diag_col = self.last_diag_col else: - diag_col = max(len(line) + 7, 63) # 4 spaces + '/* ' or at column 63, whichever is greater - line = line + (' ' * ((diag_col - 3) - len(line))) + '/* */' + diag_col = max( + len(line) + 7, 63 + ) # 4 spaces + '/* ' or at column 63, whichever is greater + line = line + (" " * ((diag_col - 3) - len(line))) + "/* */" for ew, message in reversed(diags): - line = line[:diag_col] + ('%s-%s {{%s}} ' % (prefix, ew, message)) + line[diag_col:] + line = ( + line[:diag_col] + + ("%s-%s {{%s}} " % (prefix, ew, message)) + + line[diag_col:] + ) return line.rstrip() + def SortDiags(self, line): matches = list(rxDiag.finditer(line)) if matches: for m in sorted(matches, key=lambda m: m.start(), reverse=True): - line = line[:m.start()] + line[m.end():] + line = line[: m.start()] + line[m.end() :] diag_col = m.start() for m in sorted(matches, key=lambda m: m.groups()[1:], reverse=True): - line = line[:diag_col] + ('%s-%s {{%s}} ' % m.groups()[1:]) + line[diag_col:] + line = ( + line[:diag_col] + + ("%s-%s {{%s}} " % m.groups()[1:]) + + line[diag_col:] + ) return line.rstrip() def OutputResult(self): - temp_filename = os.path.expandvars(r'${TEMP}\%s' % os.path.split(self.filename)[1]) - with open(self.filename, 'rt') as fin: - with open(temp_filename+'.result', 'wt') as fout: + temp_filename = os.path.expandvars( + r"${TEMP}\%s" % os.path.split(self.filename)[1] + ) + with open(self.filename, "rt") as fin: + with open(temp_filename + ".result", "wt") as fout: line_num = 0 for line in fin.readlines(): - if line[-1] == '\n': + if line[-1] == "\n": line = line[:-1] line_num += 1 - line, expected, diag_col = self.RemoveDiags(line, self.expected.get(line_num, [])) + line, expected, diag_col = self.RemoveDiags( + line, self.expected.get(line_num, []) + ) for ew, message in expected: - print('Error: Line %d: Could not find: expected-%s {{%s}}!!' % (line_num, ew, message)) - line = self.AddDiags(line, self.unexpected.get(line_num, []), diag_col) + print( + "Error: Line %d: Could not find: expected-%s {{%s}}!!" + % (line_num, ew, message) + ) + line = self.AddDiags( + line, self.unexpected.get(line_num, []), diag_col + ) line = self.SortDiags(line) - fout.write(line + '\n') + fout.write(line + "\n") def TryFxc(self, result_filename=None): - temp_filename = os.path.expandvars(r'${TEMP}\%s' % os.path.split(self.filename)[1]) + temp_filename = os.path.expandvars( + r"${TEMP}\%s" % os.path.split(self.filename)[1] + ) if result_filename is None: - result_filename = temp_filename + '.fxc' + result_filename = temp_filename + ".fxc" inlines = [] - with open(self.filename, 'rt') as fin: + with open(self.filename, "rt") as fin: for line in fin.readlines(): - if line[-1] == '\n': + if line[-1] == "\n": line = line[:-1] inlines.append(line) verify_arguments = None @@ -547,21 +637,25 @@ def TryFxc(self, result_filename=None): m = rxVerifyArguments.search(line) if m: verify_arguments = m.group(1) - print('Found :FXC_VERIFY_ARGUMENTS: %s' % verify_arguments) + print("Found :FXC_VERIFY_ARGUMENTS: %s" % verify_arguments) break # result will hold the final result after adding fxc error messages # initialize it by removing all the expected diagnostics result = [(line, None, False) for line in inlines] for n, (line, diag_col, expected) in enumerate(result): - line, diags, diag_col = self.RemoveDiags(line, [], prefix='fxc', removeall=True) - matches, diags, diag_col2 = self.MatchDiags(line, [], prefix='expected', matchall=True) + line, diags, diag_col = self.RemoveDiags( + line, [], prefix="fxc", removeall=True + ) + matches, diags, diag_col2 = self.MatchDiags( + line, [], prefix="expected", matchall=True + ) if matches: expected = True -## if diag_col is None: -## diag_col = diag_col2 -## elif diag_col2 < diag_col: -## diag_col = diag_col2 + ## if diag_col is None: + ## diag_col = diag_col2 + ## elif diag_col2 < diag_col: + ## diag_col = diag_col2 result[n] = (line, diag_col, expected) # commented holds the version that gets progressively commented as fxc reports errors @@ -570,33 +664,44 @@ def TryFxc(self, result_filename=None): # diags_by_line is a dictionary of a set of errors and warnings keyed off line_num diags_by_line = {} while True: - with open(temp_filename+'.fxc_temp', 'wt') as fout: - fout.write('\n'.join(commented)) + with open(temp_filename + ".fxc_temp", "wt") as fout: + fout.write("\n".join(commented)) if verify_arguments is None: fout.write("\n[numthreads(1,1,1)] void _test_main() { }\n") if verify_arguments is None: - args = '/E _test_main /T cs_5_1'.split() + args = "/E _test_main /T cs_5_1".split() else: args = verify_arguments.split() - fxcres = subprocess.run(['%s' % FxcPath, - temp_filename + '.fxc_temp', - *args, "/nologo", "/DVERIFY_FXC=1", - "/Fo", temp_filename + '.fxo', - "/Fe", temp_filename + '.err'], - capture_output=True, text=True) - with open(temp_filename+'.err', 'rt') as f: + fxcres = subprocess.run( + [ + "%s" % FxcPath, + temp_filename + ".fxc_temp", + *args, + "/nologo", + "/DVERIFY_FXC=1", + "/Fo", + temp_filename + ".fxo", + "/Fe", + temp_filename + ".err", + ], + capture_output=True, + text=True, + ) + with open(temp_filename + ".err", "rt") as f: errors = [m for m in map(rxFxcErr.match, f.readlines()) if m] errors = sorted(errors, key=lambda m: int(m.group(2))) first_error = None for m in errors: line_num = int(m.group(2)) - if not first_error and m.group(5) == 'error': + if not first_error and m.group(5) == "error": first_error = line_num elif first_error and line_num > first_error: break - diags_by_line.setdefault(line_num, set()).add((m.group(5), m.group(6) + ': ' + m.group(7))) + diags_by_line.setdefault(line_num, set()).add( + (m.group(5), m.group(6) + ": " + m.group(7)) + ) if first_error and first_error <= len(commented): - CommentStatementOrBlock(commented, first_error-1) + CommentStatementOrBlock(commented, first_error - 1) else: break @@ -609,26 +714,39 @@ def TryFxc(self, result_filename=None): diags = diags_by_line.get(line_num, set()) if not diags: if expected: - diags.add(('pass', '')) + diags.add(("pass", "")) else: continue diags = sorted(list(diags)) - line = self.SortDiags(self.AddDiags(line, diags, diag_col, prefix='fxc')) + line = self.SortDiags(self.AddDiags(line, diags, diag_col, prefix="fxc")) result[i] = line, diag_col, expected - with open(result_filename, 'wt') as f: - f.write('\n'.join(map((lambda res: res[0]), result))) + with open(result_filename, "wt") as f: + f.write("\n".join(map((lambda res: res[0]), result))) def TryAst(self, result_filename=None): - temp_filename = os.path.expandvars(r'${TEMP}\%s' % os.path.split(self.filename)[1]) + temp_filename = os.path.expandvars( + r"${TEMP}\%s" % os.path.split(self.filename)[1] + ) if result_filename is None: - result_filename = temp_filename + '.ast' - try: os.unlink(result_filename) - except: pass - result = subprocess.run(['%s\\dxc.exe' % HlslBinDir, - "-ast-dump", "-E", "main", "-T", "ps_5_0", - self.filename], - capture_output=True, text=True) + result_filename = temp_filename + ".ast" + try: + os.unlink(result_filename) + except: + pass + result = subprocess.run( + [ + "%s\\dxc.exe" % HlslBinDir, + "-ast-dump", + "-E", + "main", + "-T", + "ps_5_0", + self.filename, + ], + capture_output=True, + text=True, + ) # dxc dumps ast even if there exists any syntax error. If there is any error, dxc returns some nonzero errorcode. if not result.stdout: with open("%s.log" % temp_filename, "wt") as f: @@ -643,9 +761,9 @@ def TryAst(self, result_filename=None): print('ParseAst failed on "%s"' % (result_filename)) raise inlines = [] - with open(self.filename, 'rt') as fin: + with open(self.filename, "rt") as fin: for line in fin.readlines(): - if line[-1] == '\n': + if line[-1] == "\n": line = line[:-1] inlines.append(line) outlines = [] @@ -655,33 +773,34 @@ def TryAst(self, result_filename=None): outlines.append(line) m = rxVerifyAst.match(line) if m: - indent = line[:m.start(1)] + ' ' + indent = line[: m.start(1)] + " " # at this point i is the ONE based source line number # (since it's one past the line we want to verify in zero based index) ast_nodes = FindAstNodesByLine(ast_root, i) if not ast_nodes: - outlines += [indent + 'No matching AST found for line!'] + outlines += [indent + "No matching AST found for line!"] else: for ast in ast_nodes: outlines += WriteAstSubtree(ast, i, indent) - while i+1 < len(inlines) and not rxEndVerifyAst.match(inlines[i+1]): + while i + 1 < len(inlines) and not rxEndVerifyAst.match(inlines[i + 1]): i += 1 i += 1 - with open(result_filename, 'wt') as f: - f.write('\n'.join(outlines)) + with open(result_filename, "wt") as f: + f.write("\n".join(outlines)) + def ProcessVerifierOutput(lines): files = {} cur_filename = None cur_test = None - state = 'WaitingForFile' - ew = '' + state = "WaitingForFile" + ew = "" expected = None for line in lines: if not line: continue - if line[-1] == '\n': + if line[-1] == "\n": line = line[:-1] m = rxRUN.match(line) if m: @@ -690,21 +809,23 @@ def ProcessVerifierOutput(lines): if m: cur_filename = m.group(1) files[cur_filename] = File(cur_filename) - state = 'WaitingForCategory' + state = "WaitingForCategory" continue - if state == 'WaitingForFile': + if state == "WaitingForFile": m = rxEndGroup.match(line) - if m and m.group(2) == 'Failed': + if m and m.group(2) == "Failed": # This usually happens when compiler crashes - print('Fatal Error: test %s failed without verifier results.' % cur_test) - if state == 'WaitingForCategory' or state == 'ReadingErrors': + print( + "Fatal Error: test %s failed without verifier results." % cur_test + ) + if state == "WaitingForCategory" or state == "ReadingErrors": m = rxExpected.match(line) if m: ew = m.group(1) - expected = m.group(2) == 'expected but not seen' - state = 'ReadingErrors' + expected = m.group(2) == "expected but not seen" + state = "ReadingErrors" continue - if state == 'ReadingErrors': + if state == "ReadingErrors": m = rxDiagReport.match(line) if m: line_num = int(m.group(2)) @@ -719,53 +840,72 @@ def ProcessVerifierOutput(lines): def maybe_compare(filename1, filename2): - with open(filename1, 'rt') as fbefore: - with open(filename2, 'rt') as fafter: + with open(filename1, "rt") as fbefore: + with open(filename2, "rt") as fafter: before = fbefore.read() after = fafter.read() if before.strip() != after.strip(): - print('Differences found. Compare:\n %s\nwith:\n %s' % (filename1, filename2)) + print( + "Differences found. Compare:\n %s\nwith:\n %s" % (filename1, filename2) + ) if DiffTool: - subprocess.Popen([DiffTool, filename1, filename2], - creationflags=subprocess.DETACHED_PROCESS) + subprocess.Popen( + [DiffTool, filename1, filename2], + creationflags=subprocess.DETACHED_PROCESS, + ) return True return False + def PrintUsage(): print(__doc__) - print('Available tests and corresponding files:') + print("Available tests and corresponding files:") tests = sorted(VerifierTests.keys()) width = len(max(tests, key=len)) for name in tests: - print((' %%-%ds %%s' % width) % (name, VerifierTests[name])) - print('Tests incompatible with fxc mode:') + print((" %%-%ds %%s" % width) % (name, VerifierTests[name])) + print("Tests incompatible with fxc mode:") for name in fxcExcludedTests: - print(' %s' % name) + print(" %s" % name) + def RunVerifierTest(test, HlslDataDir=HlslDataDir): import codecs - temp_filename = os.path.expandvars(r'${TEMP}\VerifierHelper_temp.txt') - cmd = ('te %s\\ClangHLSLTests.dll /p:"HlslDataDir=%s" /name:VerifierTest::%s > %s' % - (HlslBinDir, HlslDataDir, test, temp_filename)) + + temp_filename = os.path.expandvars(r"${TEMP}\VerifierHelper_temp.txt") + cmd = ( + 'te %s\\ClangHLSLTests.dll /p:"HlslDataDir=%s" /name:VerifierTest::%s > %s' + % (HlslBinDir, HlslDataDir, test, temp_filename) + ) print(cmd) - os.system(cmd) # TAEF test + os.system(cmd) # TAEF test # TAEF outputs unicode, so read as binary and convert: - with open(temp_filename, 'rb') as f: - return codecs.decode(f.read(), 'UTF-16').replace(u'\x7f', u'').replace(u'\r\n', u'\n').splitlines() + with open(temp_filename, "rb") as f: + return ( + codecs.decode(f.read(), "UTF-16") + .replace("\x7f", "") + .replace("\r\n", "\n") + .splitlines() + ) + def main(*args): global VerifierTests try: VerifierTests = ParseVerifierTestCpp() except: - print('Unable to parse tests from VerifierTest.cpp; using defaults') - if len(args) < 1 or (args[0][0] in '-/' and args[0][1:].lower() in ('h', '?', 'help')): + print("Unable to parse tests from VerifierTest.cpp; using defaults") + if len(args) < 1 or ( + args[0][0] in "-/" and args[0][1:].lower() in ("h", "?", "help") + ): PrintUsage() return -1 mode = args[0] - if mode == 'fxc': - allFxcTests = sorted(filter(lambda key: key not in fxcExcludedTests, VerifierTests.keys())) - if args[1] == '*': + if mode == "fxc": + allFxcTests = sorted( + filter(lambda key: key not in fxcExcludedTests, VerifierTests.keys()) + ) + if args[1] == "*": tests = allFxcTests else: if args[1] not in allFxcTests: @@ -774,15 +914,17 @@ def main(*args): tests = [args[1]] differences = False for test in tests: - print('---- %s ----' % test) + print("---- %s ----" % test) filename = os.path.join(HlslDataDir, VerifierTests[test]) - result_filename = os.path.expandvars(r'${TEMP}\%s.fxc' % os.path.split(filename)[1]) + result_filename = os.path.expandvars( + r"${TEMP}\%s.fxc" % os.path.split(filename)[1] + ) File(filename).TryFxc() differences = maybe_compare(filename, result_filename) or differences if not differences: - print('No differences found!') - elif mode == 'clang': - if args[1] != '*' and args[1] not in VerifierTests: + print("No differences found!") + elif mode == "clang": + if args[1] != "*" and args[1] not in VerifierTests: PrintUsage() return -1 files = ProcessVerifierOutput(RunVerifierTest(args[1])) @@ -790,13 +932,17 @@ def main(*args): if files: for f in files.values(): if f.expected or f.unexpected: - result_filename = os.path.expandvars(r'${TEMP}\%s.result' % os.path.split(f.filename)[1]) - differences = maybe_compare(f.filename, result_filename) or differences + result_filename = os.path.expandvars( + r"${TEMP}\%s.result" % os.path.split(f.filename)[1] + ) + differences = ( + maybe_compare(f.filename, result_filename) or differences + ) if not differences: - print('No differences found!') - elif mode == 'ast': + print("No differences found!") + elif mode == "ast": allAstTests = sorted(VerifierTests.keys()) - if args[1] == '*': + if args[1] == "*": tests = allAstTests else: if args[1] not in allAstTests: @@ -805,16 +951,18 @@ def main(*args): tests = [args[1]] differences = False for test in tests: - print('---- %s ----' % test) + print("---- %s ----" % test) filename = os.path.join(HlslDataDir, VerifierTests[test]) - result_filename = os.path.expandvars(r'${TEMP}\%s.ast' % os.path.split(filename)[1]) + result_filename = os.path.expandvars( + r"${TEMP}\%s.ast" % os.path.split(filename)[1] + ) File(filename).TryAst() differences = maybe_compare(filename, result_filename) or differences if not differences: - print('No differences found!') - elif mode == 'all': + print("No differences found!") + elif mode == "all": allTests = sorted(VerifierTests.keys()) - if args[1] == '*': + if args[1] == "*": tests = allTests else: if args[1] not in allTests: @@ -823,17 +971,22 @@ def main(*args): tests = [args[1]] # Do clang verifier tests, updating source file paths for changed files: - sourceFiles = dict([(VerifierTests[test], os.path.join(HlslDataDir, VerifierTests[test])) for test in tests]) + sourceFiles = dict( + [ + (VerifierTests[test], os.path.join(HlslDataDir, VerifierTests[test])) + for test in tests + ] + ) files = ProcessVerifierOutput(RunVerifierTest(args[1])) if files: for f in files.values(): if f.expected or f.unexpected: name = os.path.split(f.filename)[1] - sourceFiles[name] = os.path.expandvars(r'${TEMP}\%s.result' % name) + sourceFiles[name] = os.path.expandvars(r"${TEMP}\%s.result" % name) # update verify-ast blocks: for name, sourceFile in sourceFiles.items(): - result_filename = os.path.expandvars(r'${TEMP}\%s.ast' % name) + result_filename = os.path.expandvars(r"${TEMP}\%s.ast" % name) File(sourceFile).TryAst(result_filename) sourceFiles[name] = result_filename @@ -844,19 +997,23 @@ def main(*args): for test in tests: name = VerifierTests[test] sourceFile = sourceFiles[name] - print(('Test %%-%ds - %%s' % width) % (test, name)) - result_filename = os.path.expandvars(r'${TEMP}\%s.fxc' % name) + print(("Test %%-%ds - %%s" % width) % (test, name)) + result_filename = os.path.expandvars(r"${TEMP}\%s.fxc" % name) if name not in fxcExcludedFiles: File(sourceFile).TryFxc(result_filename) sourceFiles[name] = result_filename - differences = maybe_compare(os.path.join(HlslDataDir, name), sourceFiles[name]) or differences + differences = ( + maybe_compare(os.path.join(HlslDataDir, name), sourceFiles[name]) + or differences + ) if not differences: - print('No differences found!') + print("No differences found!") else: PrintUsage() return -1 return 0 -if __name__ == '__main__': + +if __name__ == "__main__": sys.exit(main(*sys.argv[1:])) diff --git a/utils/hct/hctbuild.cmd b/utils/hct/hctbuild.cmd index d248bf55b0..19e32c4731 100644 --- a/utils/hct/hctbuild.cmd +++ b/utils/hct/hctbuild.cmd @@ -204,6 +204,12 @@ if "%1"=="-default-adapter" ( shift /1 shift /1 & goto :parse_args ) +if "%1"=="-sanitizer" ( + set CMAKE_OPTS=%CMAKE_OPTS% -DLLVM_USE_SANITIZER:STRING=Address + shift /1 & goto :parse_args +) + + rem Begin SPIRV change if "%1"=="-spirv" ( echo SPIR-V codegen is enabled. @@ -225,6 +231,10 @@ if "%1"=="-clang" ( set CMAKE_OPTS=%CMAKE_OPTS% -DCMAKE_C_COMPILER=clang-cl -DCMAKE_CXX_COMPILER=clang-cl shift /1 & goto :parse_args ) +if "%1"=="-clang-cl" ( + set CMAKE_OPTS=%CMAKE_OPTS% -T ClangCL + shift /1 & goto :parse_args +) if "%1"=="-update-generated-sources" ( set CMAKE_OPTS=%CMAKE_OPTS% -DHLSL_COPY_GENERATED_SOURCES=1 shift /1 & goto :parse_args @@ -461,10 +471,10 @@ if "%DO_SETUP%"=="1" ( echo Running "%CMAKE_PATH%" -DCMAKE_BUILD_TYPE:STRING=%1 %CMAKE_OPTS% -G %4 %HLSL_SRC_DIR% > %3\cmake-log.txt "%CMAKE_PATH%" -DCMAKE_BUILD_TYPE:STRING=%1 %CMAKE_OPTS% -G %4 %HLSL_SRC_DIR% >> %3\cmake-log.txt 2>&1 ) else ( - rem -DCMAKE_BUILD_TYPE:STRING=%1 is not necessary for multi-config generators like VS - rem but need CMAKE_BUILD_TYPE to generate lit cfg. + rem BUILD_TYPE is mostly ignored in this path as VS generates multiple targets + rem it is still needed to satisfy cmake file expectations echo Running "%CMAKE_PATH%" -DCMAKE_BUILD_TYPE:STRING=%1 %CMAKE_OPTS% -G %4 %5 %HLSL_SRC_DIR% > %3\cmake-log.txt - "%CMAKE_PATH%" %CMAKE_OPTS% -G %4 %5 %HLSL_SRC_DIR% >> %3\cmake-log.txt 2>&1 + "%CMAKE_PATH%" -DCMAKE_BUILD_TYPE:STRING=%1 %CMAKE_OPTS% -G %4 %5 %HLSL_SRC_DIR% >> %3\cmake-log.txt 2>&1 ) if %SHOW_CMAKE_LOG%==1 ( echo ------- Start of %3\cmake-log.txt ------- diff --git a/utils/hct/hctdb.py b/utils/hct/hctdb.py index ff09ddf390..cb6e490399 100644 --- a/utils/hct/hctdb.py +++ b/utils/hct/hctdb.py @@ -6,170 +6,194 @@ import os all_stages = ( - 'vertex', - 'pixel', - 'geometry', - 'compute', - 'hull', - 'domain', - 'library', - 'raygeneration', - 'intersection', - 'anyhit', - 'closesthit', - 'miss', - 'callable', - 'mesh', - 'amplification', - ) + "vertex", + "pixel", + "geometry", + "compute", + "hull", + "domain", + "library", + "raygeneration", + "intersection", + "anyhit", + "closesthit", + "miss", + "callable", + "mesh", + "amplification", +) # These counters aren't collected directly from instructions, # so they need to be added manually so they can be accessed # with custom code in DxilCounters.cpp. extra_counters = [ - 'insts', - 'branches', - 'array_tgsm_bytes', - 'array_static_bytes', - 'array_local_bytes', - 'array_tgsm_ldst', - 'array_static_ldst', - 'array_local_ldst', - ] + "insts", + "branches", + "array_tgsm_bytes", + "array_static_bytes", + "array_local_bytes", + "array_tgsm_ldst", + "array_static_ldst", + "array_local_ldst", +] + class db_dxil_enum_value(object): "A representation for a value in an enumeration type" + def __init__(self, name, value, doc): - self.name = name # Name (identifier) - self.value = value # Numeric value - self.doc = doc # Documentation string + self.name = name # Name (identifier) + self.value = value # Numeric value + self.doc = doc # Documentation string self.category = None + class db_dxil_enum(object): "A representation for an enumeration type" + def __init__(self, name, doc, valNameDocTuples=()): self.name = name self.doc = doc - self.values = [db_dxil_enum_value(n,v,d) for v,n,d in valNameDocTuples] # Note transmutation - self.is_internal = False # whether this is never serialized + self.values = [ + db_dxil_enum_value(n, v, d) for v, n, d in valNameDocTuples + ] # Note transmutation + self.is_internal = False # whether this is never serialized def value_names(self): return [i.name for i in self.values] + class db_dxil_inst(object): "A representation for a DXIL instruction" + def __init__(self, name, **kwargs): - self.name = name # short, unique name - self.llvm_id = 0 # ID of LLVM instruction - self.llvm_name = "" # name of LLVM instruction type - - self.is_dxil_op = False # whether this is a call into a built-in DXIL function - self.dxil_op = "" # name of DXIL operation - self.dxil_opid = 0 # ID of DXIL operation - self.dxil_class = "" # name of the opcode class - self.category = "" # classification for this instruction - self.doc = "" # the documentation description of this instruction - self.remarks = "" # long-form remarks on this instruction - self.ops = [] # the operands that this instruction takes - self.is_allowed = True # whether this instruction is allowed in a DXIL program - self.oload_types = "" # overload types if applicable - self.fn_attr = "" # attribute shorthands: rn=does not access memory,ro=only reads from memory, - self.is_deriv = False # whether this is some kind of derivative - self.is_gradient = False # whether this requires a gradient calculation - self.is_feedback = False # whether this is a sampler feedback op - self.is_wave = False # whether this requires in-wave, cross-lane functionality + self.name = name # short, unique name + self.llvm_id = 0 # ID of LLVM instruction + self.llvm_name = "" # name of LLVM instruction type + + self.is_dxil_op = False # whether this is a call into a built-in DXIL function + self.dxil_op = "" # name of DXIL operation + self.dxil_opid = 0 # ID of DXIL operation + self.dxil_class = "" # name of the opcode class + self.category = "" # classification for this instruction + self.doc = "" # the documentation description of this instruction + self.remarks = "" # long-form remarks on this instruction + self.ops = [] # the operands that this instruction takes + self.is_allowed = True # whether this instruction is allowed in a DXIL program + self.oload_types = "" # overload types if applicable + self.fn_attr = "" # attribute shorthands: rn=does not access memory,ro=only reads from memory, + self.is_deriv = False # whether this is some kind of derivative + self.is_gradient = False # whether this requires a gradient calculation + self.is_feedback = False # whether this is a sampler feedback op + self.is_wave = False # whether this requires in-wave, cross-lane functionality self.requires_uniform_inputs = False # whether this operation requires that all of its inputs are uniform across the wave - self.shader_stages = () # shader stages to which this applies, empty for all. - self.shader_model = 6,0 # minimum shader model required + self.shader_stages = () # shader stages to which this applies, empty for all. + self.shader_model = 6, 0 # minimum shader model required self.inst_helper_prefix = None self.fully_qualified_name_prefix = "hlsl::OP::OpCode" - for k,v in list(kwargs.items()): + for k, v in list(kwargs.items()): setattr(self, k, v) - self.is_dxil_op = self.dxil_op != "" # whether this is a DXIL operation + self.is_dxil_op = self.dxil_op != "" # whether this is a DXIL operation self.is_reserved = self.dxil_class == "Reserved" - self.shader_model_translated = () # minimum shader model required with translation by linker - self.props = {} # extra properties + self.shader_model_translated = () # minimum shader model required with translation by linker + self.props = {} # extra properties def __str__(self): return self.name - + def fully_qualified_name(self): return "{}::{}".format(self.fully_qualified_name_prefix, self.name) + class db_dxil_metadata(object): "A representation for a metadata record" + def __init__(self, name, doc, **kwargs): - self.name = name # named metadata, possibly empty - self.doc = doc # the documentation description of this record - for k,v in list(kwargs.items()): + self.name = name # named metadata, possibly empty + self.doc = doc # the documentation description of this record + for k, v in list(kwargs.items()): setattr(self, k, v) + class db_dxil_param(object): "The parameter description for a DXIL instruction" + def __init__(self, pos, llvm_type, name, doc, **kwargs): - self.pos = pos # position in parameter list - self.llvm_type = llvm_type # llvm type name, $o for overload, $r for resource type, $cb for legacy cbuffer, $u4 for u4 struct - self.name = name # short, unique name - self.doc = doc # the documentation description of this parameter - self.is_const = False # whether this argument requires a constant value in the IR - self.enum_name = "" # the name of the enum type if applicable - self.max_value = None # the maximum value for this parameter if applicable - for k,v in kwargs.items(): + self.pos = pos # position in parameter list + self.llvm_type = llvm_type # llvm type name, $o for overload, $r for resource type, $cb for legacy cbuffer, $u4 for u4 struct + self.name = name # short, unique name + self.doc = doc # the documentation description of this parameter + self.is_const = ( + False # whether this argument requires a constant value in the IR + ) + self.enum_name = "" # the name of the enum type if applicable + self.max_value = None # the maximum value for this parameter if applicable + for k, v in kwargs.items(): setattr(self, k, v) + class db_dxil_pass(object): "The description for a DXIL optimization pass" + def __init__(self, name, **kwargs): - self.name = name # name for the option, typically the command-line switch name - self.args = [] # modifiers for the option - self.type_name = "" # name of the class that implements the pass - self.doc = "" # documentation for the pass - self.category_lib = "" # lib which pass belongs to - for k,v in kwargs.items(): + self.name = name # name for the option, typically the command-line switch name + self.args = [] # modifiers for the option + self.type_name = "" # name of the class that implements the pass + self.doc = "" # documentation for the pass + self.category_lib = "" # lib which pass belongs to + for k, v in kwargs.items(): setattr(self, k, v) + class db_dxil_pass_arg(object): "An argument to a DXIL optimization pass" + def __init__(self, name, **kwargs): - self.name = name # name for the option, typically the command-line switch name - self.ident = "" # identifier for a parameter or global switch + self.name = name # name for the option, typically the command-line switch name + self.ident = "" # identifier for a parameter or global switch self.is_ctor_param = False # whether this is a constructor parameter - for k,v in kwargs.items(): + for k, v in kwargs.items(): setattr(self, k, v) if self.is_ctor_param: self.is_ctor_param = True + class db_dxil_valrule(object): "The description of a validation rule." + def __init__(self, name, id, **kwargs): - self.name = name.upper() # short, unique name, eg META.KNOWN - self.rule_id = id # unique identifier - self.enum_name = name.replace(".", "") # remove period for enum name - self.group_name = self.name[:self.name.index(".")] # group name, eg META - self.rule_name = self.name[self.name.index(".")+1:] # rule name, eg KNOWN - self.definition = "Check" + self.group_name + self.rule_name # function name that defines this constraint - self.is_disabled = False # True if the validation rule does not apply - self.err_msg = "" # error message associated with rule - self.category = "" # classification for this rule - self.doc = "" # the documentation description of this rule - self.shader_stages = () # shader stages to which this applies, empty for all. - self.shader_model = 6,0 # minimum shader model required - for k,v in list(kwargs.items()): + self.name = name.upper() # short, unique name, eg META.KNOWN + self.rule_id = id # unique identifier + self.enum_name = name.replace(".", "") # remove period for enum name + self.group_name = self.name[: self.name.index(".")] # group name, eg META + self.rule_name = self.name[self.name.index(".") + 1 :] # rule name, eg KNOWN + self.definition = ( + "Check" + self.group_name + self.rule_name + ) # function name that defines this constraint + self.is_disabled = False # True if the validation rule does not apply + self.err_msg = "" # error message associated with rule + self.category = "" # classification for this rule + self.doc = "" # the documentation description of this rule + self.shader_stages = () # shader stages to which this applies, empty for all. + self.shader_model = 6, 0 # minimum shader model required + for k, v in list(kwargs.items()): setattr(self, k, v) def __str__(self): return self.name + class db_dxil(object): "A database of DXIL instruction data" + def __init__(self): - self.instr = [] # DXIL instructions - self.enums = [] # enumeration types - self.val_rules = [] # validation rules - self.metadata = [] # named metadata (db_dxil_metadata) - self.passes = [] # inventory of available passes (db_dxil_pass) - self.name_idx = {} # DXIL instructions by name - self.enum_idx = {} # enumerations by name + self.instr = [] # DXIL instructions + self.enums = [] # enumeration types + self.val_rules = [] # validation rules + self.metadata = [] # named metadata (db_dxil_metadata) + self.passes = [] # inventory of available passes (db_dxil_pass) + self.name_idx = {} # DXIL instructions by name + self.enum_idx = {} # enumerations by name self.dxil_version_info = {} # list of counters for instructions and dxil ops, # starting with extra ones specified here @@ -191,7 +215,7 @@ def __init__(self): self.populate_counters() def __str__(self): - return '\n'.join(str(i) for i in self.instr) + return "\n".join(str(i) for i in self.instr) def add_enum_type(self, name, doc, valNameDocTuples): "Adds a new enumeration type with name/value/doc tuples" @@ -208,7 +232,9 @@ def build_indices(self): def build_opcode_enum(self): # Build enumeration from instructions - OpCodeEnum = db_dxil_enum("OpCode", "Enumeration for operations specified by DXIL") + OpCodeEnum = db_dxil_enum( + "OpCode", "Enumeration for operations specified by DXIL" + ) class_dict = {} class_dict["LlvmInst"] = "LLVM Instructions" for i in self.instr: @@ -217,14 +243,17 @@ def build_opcode_enum(self): v.category = i.category class_dict[i.dxil_class] = i.category OpCodeEnum.values.append(v) - self.enums.append(OpCodeEnum); - OpCodeClass = db_dxil_enum("OpCodeClass", "Groups for DXIL operations with equivalent function templates") + self.enums.append(OpCodeEnum) + OpCodeClass = db_dxil_enum( + "OpCodeClass", + "Groups for DXIL operations with equivalent function templates", + ) OpCodeClass.is_internal = True - for (k, v) in iter(class_dict.items()): + for k, v in iter(class_dict.items()): ev = db_dxil_enum_value(k, 0, None) ev.category = v OpCodeClass.values.append(ev) - self.enums.append(OpCodeClass); + self.enums.append(OpCodeClass) def mark_disallowed_operations(self): # Disallow indirect branching, unreachable instructions and support for exception unwinding. @@ -243,19 +272,30 @@ def verify_dense(self, it, pred, name_proj): for i in it: i_val = pred(i) if not val is None: - assert val + 1 == i_val, "values in predicate are not sequential and dense, %d follows %d for %s" % (i_val, val, name_proj(i)) + assert val + 1 == i_val, ( + "values in predicate are not sequential and dense, %d follows %d for %s" + % (i_val, val, name_proj(i)) + ) val = i_val def set_op_count_for_version(self, major, minor, op_count): info = self.dxil_version_info.setdefault((major, minor), dict()) - info['NumOpCodes'] = op_count - info['NumOpClasses'] = len(set([op.dxil_class for op in self.instr])) + info["NumOpCodes"] = op_count + info["NumOpClasses"] = len(set([op.dxil_class for op in self.instr])) def populate_categories_and_models(self): "Populate the category and shader_stages member of instructions." - for i in "TempRegLoad,TempRegStore,MinPrecXRegLoad,MinPrecXRegStore,LoadInput,StoreOutput".split(","): + for ( + i + ) in "TempRegLoad,TempRegStore,MinPrecXRegLoad,MinPrecXRegStore,LoadInput,StoreOutput".split( + "," + ): self.name_idx[i].category = "Temporary, indexable, input, output registers" - for i in "FAbs,Saturate,IsNaN,IsInf,IsFinite,IsNormal,Cos,Sin,Tan,Acos,Asin,Atan,Hcos,Hsin,Htan,Exp,Frc,Log,Sqrt,Rsqrt".split(","): + for ( + i + ) in "FAbs,Saturate,IsNaN,IsInf,IsFinite,IsNormal,Cos,Sin,Tan,Acos,Asin,Atan,Hcos,Hsin,Htan,Exp,Frc,Log,Sqrt,Rsqrt".split( + "," + ): self.name_idx[i].category = "Unary float" for i in "Round_ne,Round_ni,Round_pi,Round_z".split(","): self.name_idx[i].category = "Unary float - rounding" @@ -271,7 +311,7 @@ def populate_categories_and_models(self): self.name_idx[i].category = "Binary uint" for i in "IMul".split(","): self.name_idx[i].category = "Binary int with two outputs" - for i in "UMul,UDiv".split(","): # Rename this UDiv OpCode to UDivMod + for i in "UMul,UDiv".split(","): # Rename this UDiv OpCode to UDivMod self.name_idx[i].category = "Binary uint with two outputs" for i in "UAddc,USubb".split(","): self.name_idx[i].category = "Binary uint with carry or borrow" @@ -285,22 +325,48 @@ def populate_categories_and_models(self): self.name_idx[i].category = "Quaternary" for i in "Dot2,Dot3,Dot4".split(","): self.name_idx[i].category = "Dot" - for i in "CreateHandle,CBufferLoad,CBufferLoadLegacy,TextureLoad,TextureStore,TextureStoreSample,BufferLoad,BufferStore,BufferUpdateCounter,CheckAccessFullyMapped,GetDimensions,RawBufferLoad,RawBufferStore".split(","): + for ( + i + ) in "CreateHandle,CBufferLoad,CBufferLoadLegacy,TextureLoad,TextureStore,TextureStoreSample,BufferLoad,BufferStore,BufferUpdateCounter,CheckAccessFullyMapped,GetDimensions,RawBufferLoad,RawBufferStore".split( + "," + ): self.name_idx[i].category = "Resources" - for i in "Sample,SampleBias,SampleLevel,SampleGrad,SampleCmp,SampleCmpLevelZero,SampleCmpLevel,Texture2DMSGetSamplePosition,RenderTargetGetSamplePosition,RenderTargetGetSampleCount".split(","): + for ( + i + ) in "Sample,SampleBias,SampleLevel,SampleGrad,SampleCmp,SampleCmpLevelZero,SampleCmpLevel,Texture2DMSGetSamplePosition,RenderTargetGetSamplePosition,RenderTargetGetSampleCount".split( + "," + ): self.name_idx[i].category = "Resources - sample" for i in "Sample,SampleBias,SampleCmp".split(","): - self.name_idx[i].shader_stages = ("library", "pixel", "compute", "amplification", "mesh") + self.name_idx[i].shader_stages = ( + "library", + "pixel", + "compute", + "amplification", + "mesh", + ) for i in "RenderTargetGetSamplePosition,RenderTargetGetSampleCount".split(","): self.name_idx[i].shader_stages = ("pixel",) for i in "TextureGather,TextureGatherCmp,TextureGatherRaw".split(","): self.name_idx[i].category = "Resources - gather" for i in "AtomicBinOp,AtomicCompareExchange,Barrier".split(","): self.name_idx[i].category = "Synchronization" - for i in "CalculateLOD,DerivCoarseX,DerivCoarseY,DerivFineX,DerivFineY".split(","): + for i in "CalculateLOD,DerivCoarseX,DerivCoarseY,DerivFineX,DerivFineY".split( + "," + ): self.name_idx[i].category = "Derivatives" - self.name_idx[i].shader_stages = ("library", "pixel", "compute", "amplification", "mesh") - for i in "Discard,EvalSnapped,EvalSampleIndex,EvalCentroid,SampleIndex,Coverage,InnerCoverage,AttributeAtVertex".split(","): + self.name_idx[i].shader_stages = ( + "library", + "pixel", + "compute", + "amplification", + "mesh", + ) + for ( + i + ) in "Discard,EvalSnapped,EvalSampleIndex,EvalCentroid,SampleIndex,Coverage,InnerCoverage,AttributeAtVertex".split( + "," + ): self.name_idx[i].category = "Pixel shader" self.name_idx[i].shader_stages = ("pixel",) for i in "ThreadId,GroupId,ThreadIdInGroup,FlattenedThreadIdInGroup".split(","): @@ -323,8 +389,19 @@ def populate_categories_and_models(self): self.name_idx[i].shader_stages = ("geometry", "domain", "hull") for i in "ViewID".split(","): self.name_idx[i].category = "Graphics shader" - self.name_idx[i].shader_stages = ("vertex", "hull", "domain", "geometry", "pixel", "mesh") - for i in "MakeDouble,SplitDouble,LegacyDoubleToFloat,LegacyDoubleToSInt32,LegacyDoubleToUInt32".split(","): + self.name_idx[i].shader_stages = ( + "vertex", + "hull", + "domain", + "geometry", + "pixel", + "mesh", + ) + for ( + i + ) in "MakeDouble,SplitDouble,LegacyDoubleToFloat,LegacyDoubleToSInt32,LegacyDoubleToUInt32".split( + "," + ): self.name_idx[i].category = "Double precision" for i in "CycleCounterLegacy".split(","): self.name_idx[i].category = "Other" @@ -335,126 +412,228 @@ def populate_categories_and_models(self): i.category = "Wave" i.is_wave = True i.shader_stages = ( - "library", "compute", "amplification", "mesh", - "pixel", "vertex", "hull", "domain", "geometry", - "raygeneration", "intersection", "anyhit", "closesthit", "miss", "callable") + "library", + "compute", + "amplification", + "mesh", + "pixel", + "vertex", + "hull", + "domain", + "geometry", + "raygeneration", + "intersection", + "anyhit", + "closesthit", + "miss", + "callable", + ) elif i.name.startswith("Quad"): i.category = "Quad Wave Ops" i.is_wave = True - i.shader_stages = ("library", "compute", "amplification", "mesh", "pixel") + i.shader_stages = ( + "library", + "compute", + "amplification", + "mesh", + "pixel", + ) elif i.name.startswith("Bitcast"): i.category = "Bitcasts with different sizes" for i in "ViewID,AttributeAtVertex".split(","): - self.name_idx[i].shader_model = 6,1 + self.name_idx[i].shader_model = 6, 1 for i in "RawBufferLoad,RawBufferStore".split(","): - self.name_idx[i].shader_model = 6,2 - self.name_idx[i].shader_model_translated = 6,0 + self.name_idx[i].shader_model = 6, 2 + self.name_idx[i].shader_model_translated = 6, 0 for i in "DispatchRaysIndex,DispatchRaysDimensions".split(","): self.name_idx[i].category = "Ray Dispatch Arguments" - self.name_idx[i].shader_model = 6,3 - self.name_idx[i].shader_stages = ("library", "raygeneration","intersection","anyhit", "closesthit","miss","callable") + self.name_idx[i].shader_model = 6, 3 + self.name_idx[i].shader_stages = ( + "library", + "raygeneration", + "intersection", + "anyhit", + "closesthit", + "miss", + "callable", + ) for i in "InstanceID,InstanceIndex,PrimitiveIndex".split(","): self.name_idx[i].category = "Raytracing object space uint System Values" - self.name_idx[i].shader_model = 6,3 - self.name_idx[i].shader_stages = ("library","intersection","anyhit","closesthit") + self.name_idx[i].shader_model = 6, 3 + self.name_idx[i].shader_stages = ( + "library", + "intersection", + "anyhit", + "closesthit", + ) for i in "GeometryIndex".split(","): - self.name_idx[i].category = "Raytracing object space uint System Values, raytracing tier 1.1" - self.name_idx[i].shader_model = 6,5 - self.name_idx[i].shader_stages = ("library","intersection","anyhit","closesthit") + self.name_idx[ + i + ].category = ( + "Raytracing object space uint System Values, raytracing tier 1.1" + ) + self.name_idx[i].shader_model = 6, 5 + self.name_idx[i].shader_stages = ( + "library", + "intersection", + "anyhit", + "closesthit", + ) for i in "HitKind".split(","): self.name_idx[i].category = "Raytracing hit uint System Values" - self.name_idx[i].shader_model = 6,3 - self.name_idx[i].shader_stages = ("library","intersection","anyhit","closesthit",) + self.name_idx[i].shader_model = 6, 3 + self.name_idx[i].shader_stages = ( + "library", + "intersection", + "anyhit", + "closesthit", + ) for i in "RayFlags".split(","): self.name_idx[i].category = "Raytracing uint System Values" - self.name_idx[i].shader_model = 6,3 - self.name_idx[i].shader_stages = ("library","intersection","anyhit","closesthit","miss") + self.name_idx[i].shader_model = 6, 3 + self.name_idx[i].shader_stages = ( + "library", + "intersection", + "anyhit", + "closesthit", + "miss", + ) for i in "WorldRayOrigin,WorldRayDirection".split(","): self.name_idx[i].category = "Ray Vectors" - self.name_idx[i].shader_model = 6,3 - self.name_idx[i].shader_stages = ("library","intersection","anyhit","closesthit","miss") + self.name_idx[i].shader_model = 6, 3 + self.name_idx[i].shader_stages = ( + "library", + "intersection", + "anyhit", + "closesthit", + "miss", + ) for i in "ObjectRayOrigin,ObjectRayDirection".split(","): self.name_idx[i].category = "Ray object space Vectors" - self.name_idx[i].shader_model = 6,3 - self.name_idx[i].shader_stages = ("library","intersection","anyhit","closesthit") + self.name_idx[i].shader_model = 6, 3 + self.name_idx[i].shader_stages = ( + "library", + "intersection", + "anyhit", + "closesthit", + ) for i in "ObjectToWorld,WorldToObject".split(","): self.name_idx[i].category = "Ray Transforms" - self.name_idx[i].shader_model = 6,3 - self.name_idx[i].shader_stages = ("library","intersection","anyhit","closesthit") + self.name_idx[i].shader_model = 6, 3 + self.name_idx[i].shader_stages = ( + "library", + "intersection", + "anyhit", + "closesthit", + ) for i in "RayTMin,RayTCurrent".split(","): self.name_idx[i].category = "RayT" - self.name_idx[i].shader_model = 6,3 - self.name_idx[i].shader_stages = ("library","intersection","anyhit","closesthit", "miss") + self.name_idx[i].shader_model = 6, 3 + self.name_idx[i].shader_stages = ( + "library", + "intersection", + "anyhit", + "closesthit", + "miss", + ) 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_model = 6, 3 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 - self.name_idx[i].shader_stages = ("library", "closesthit","raygeneration","miss","callable") + self.name_idx[i].shader_model = 6, 3 + self.name_idx[i].shader_stages = ( + "library", + "closesthit", + "raygeneration", + "miss", + "callable", + ) for i in "TraceRay".split(","): self.name_idx[i].category = "Indirect Shader Invocation" - self.name_idx[i].shader_model = 6,3 - self.name_idx[i].shader_stages = ("library", "raygeneration","closesthit","miss") + self.name_idx[i].shader_model = 6, 3 + self.name_idx[i].shader_stages = ( + "library", + "raygeneration", + "closesthit", + "miss", + ) for i in "ReportHit".split(","): self.name_idx[i].category = "Indirect Shader Invocation" - self.name_idx[i].shader_model = 6,3 + self.name_idx[i].shader_model = 6, 3 self.name_idx[i].shader_stages = ("library", "intersection") for i in "CreateHandleForLib".split(","): - self.name_idx[i].category = "Library create handle from resource struct (like HL intrinsic)" - self.name_idx[i].shader_model = 6,3 - self.name_idx[i].shader_model_translated = 6,0 - for i in "AnnotateHandle,CreateHandleFromBinding,CreateHandleFromHeap".split(","): + self.name_idx[ + i + ].category = ( + "Library create handle from resource struct (like HL intrinsic)" + ) + self.name_idx[i].shader_model = 6, 3 + self.name_idx[i].shader_model_translated = 6, 0 + for i in "AnnotateHandle,CreateHandleFromBinding,CreateHandleFromHeap".split( + "," + ): self.name_idx[i].category = "Get handle from heap" - self.name_idx[i].shader_model = 6,6 + self.name_idx[i].shader_model = 6, 6 for i in "AnnotateHandle,CreateHandleFromBinding".split(","): - self.name_idx[i].shader_model_translated = 6,0 + self.name_idx[i].shader_model_translated = 6, 0 for i in "Dot4AddU8Packed,Dot4AddI8Packed,Dot2AddHalf".split(","): self.name_idx[i].category = "Dot product with accumulate" - self.name_idx[i].shader_model = 6,4 + self.name_idx[i].shader_model = 6, 4 for i in "WaveMatch,WaveMultiPrefixOp,WaveMultiPrefixBitCount".split(","): self.name_idx[i].category = "Wave" - self.name_idx[i].shader_model = 6,5 - for i in "SetMeshOutputCounts,EmitIndices,GetMeshPayload,StoreVertexOutput,StorePrimitiveOutput".split(","): + self.name_idx[i].shader_model = 6, 5 + for ( + i + ) in "SetMeshOutputCounts,EmitIndices,GetMeshPayload,StoreVertexOutput,StorePrimitiveOutput".split( + "," + ): self.name_idx[i].category = "Mesh shader instructions" self.name_idx[i].shader_stages = ("mesh",) - self.name_idx[i].shader_model = 6,5 + self.name_idx[i].shader_model = 6, 5 for i in "DispatchMesh".split(","): self.name_idx[i].category = "Amplification shader instructions" self.name_idx[i].shader_stages = ("amplification",) - self.name_idx[i].shader_model = 6,5 + self.name_idx[i].shader_model = 6, 5 for i in "WriteSamplerFeedback,WriteSamplerFeedbackBias".split(","): self.name_idx[i].category = "Sampler Feedback" self.name_idx[i].is_feedback = True self.name_idx[i].is_gradient = True - self.name_idx[i].shader_model = 6,5 - self.name_idx[i].shader_stages = ("library", "pixel",) + self.name_idx[i].shader_model = 6, 5 + self.name_idx[i].shader_stages = ( + "library", + "pixel", + ) for i in "WriteSamplerFeedbackLevel,WriteSamplerFeedbackGrad".split(","): self.name_idx[i].category = "Sampler Feedback" self.name_idx[i].is_feedback = True - self.name_idx[i].shader_model = 6,5 - for i in ("AllocateRayQuery,RayQuery_TraceRayInline,RayQuery_Proceed,RayQuery_Abort,RayQuery_CommitNonOpaqueTriangleHit,RayQuery_CommitProceduralPrimitiveHit,RayQuery_RayFlags,RayQuery_WorldRayOrigin,RayQuery_WorldRayDirection,RayQuery_RayTMin,"+ - "RayQuery_CandidateTriangleRayT,RayQuery_CommittedRayT,RayQuery_CandidateInstanceIndex,RayQuery_CandidateInstanceID,RayQuery_CandidateGeometryIndex,RayQuery_CandidatePrimitiveIndex,"+ - "RayQuery_CandidateObjectRayOrigin,RayQuery_CandidateObjectRayDirection,RayQuery_CommittedInstanceIndex,RayQuery_CommittedInstanceID,RayQuery_CommittedGeometryIndex,RayQuery_CommittedPrimitiveIndex,"+ - "RayQuery_CommittedObjectRayOrigin,RayQuery_CommittedObjectRayDirection,RayQuery_CandidateProceduralPrimitiveNonOpaque,RayQuery_CandidateTriangleFrontFace,RayQuery_CommittedTriangleFrontFace,"+ - "RayQuery_CandidateTriangleBarycentrics,RayQuery_CommittedTriangleBarycentrics,RayQuery_CommittedStatus,RayQuery_CandidateType,RayQuery_CandidateObjectToWorld3x4,"+ - "RayQuery_CandidateWorldToObject3x4,RayQuery_CommittedObjectToWorld3x4,RayQuery_CommittedWorldToObject3x4,RayQuery_CandidateInstanceContributionToHitGroupIndex,RayQuery_CommittedInstanceContributionToHitGroupIndex").split(","): + self.name_idx[i].shader_model = 6, 5 + for i in ( + "AllocateRayQuery,RayQuery_TraceRayInline,RayQuery_Proceed,RayQuery_Abort,RayQuery_CommitNonOpaqueTriangleHit,RayQuery_CommitProceduralPrimitiveHit,RayQuery_RayFlags,RayQuery_WorldRayOrigin,RayQuery_WorldRayDirection,RayQuery_RayTMin," + + "RayQuery_CandidateTriangleRayT,RayQuery_CommittedRayT,RayQuery_CandidateInstanceIndex,RayQuery_CandidateInstanceID,RayQuery_CandidateGeometryIndex,RayQuery_CandidatePrimitiveIndex," + + "RayQuery_CandidateObjectRayOrigin,RayQuery_CandidateObjectRayDirection,RayQuery_CommittedInstanceIndex,RayQuery_CommittedInstanceID,RayQuery_CommittedGeometryIndex,RayQuery_CommittedPrimitiveIndex," + + "RayQuery_CommittedObjectRayOrigin,RayQuery_CommittedObjectRayDirection,RayQuery_CandidateProceduralPrimitiveNonOpaque,RayQuery_CandidateTriangleFrontFace,RayQuery_CommittedTriangleFrontFace," + + "RayQuery_CandidateTriangleBarycentrics,RayQuery_CommittedTriangleBarycentrics,RayQuery_CommittedStatus,RayQuery_CandidateType,RayQuery_CandidateObjectToWorld3x4," + + "RayQuery_CandidateWorldToObject3x4,RayQuery_CommittedObjectToWorld3x4,RayQuery_CommittedWorldToObject3x4,RayQuery_CandidateInstanceContributionToHitGroupIndex,RayQuery_CommittedInstanceContributionToHitGroupIndex" + ).split(","): self.name_idx[i].category = "Inline Ray Query" - self.name_idx[i].shader_model = 6,5 + self.name_idx[i].shader_model = 6, 5 for i in "Unpack4x8".split(","): self.name_idx[i].category = "Unpacking intrinsics" - self.name_idx[i].shader_model = 6,6 + self.name_idx[i].shader_model = 6, 6 for i in "Pack4x8".split(","): self.name_idx[i].category = "Packing intrinsics" - self.name_idx[i].shader_model = 6,6 + self.name_idx[i].shader_model = 6, 6 for i in "IsHelperLane".split(","): self.name_idx[i].category = "Helper Lanes" - self.name_idx[i].shader_model = 6,6 - for i in "QuadVote,TextureGatherRaw,SampleCmpLevel,TextureStoreSample".split(","): - self.name_idx[i].shader_model = 6,7 + self.name_idx[i].shader_model = 6, 6 + for i in "QuadVote,TextureGatherRaw,SampleCmpLevel,TextureStoreSample".split( + "," + ): + self.name_idx[i].shader_model = 6, 7 for i in "QuadVote".split(","): - self.name_idx[i].shader_model_translated = 6,0 + self.name_idx[i].shader_model_translated = 6, 0 def populate_llvm_instructions(self): # Add instructions that map to LLVM instructions. @@ -465,76 +644,491 @@ def populate_llvm_instructions(self): # branching refers to basic block arguments. retvoid_param = db_dxil_param(0, "v", "", "no return value") retoload_param = db_dxil_param(0, "$o", "", "no return value") - oload_all_arith = "hfd1wil" # note that 8 is missing + oload_all_arith = "hfd1wil" # note that 8 is missing oload_all_arith_v = "v" + oload_all_arith - oload_int_arith = "wil" # note that 8 is missing - oload_int_arith_b = "1wil" # note that 8 is missing + oload_int_arith = "wil" # note that 8 is missing + oload_int_arith_b = "1wil" # note that 8 is missing oload_float_arith = "hfd" - oload_cast_params = [retoload_param, db_dxil_param(1, "$o", "value", "Value to cast/convert")] - oload_binary_params = [retoload_param, - db_dxil_param(1, "$o", "a", "first value"), - db_dxil_param(2, "$o", "b", "second value")] - self.add_llvm_instr("TERM", 1, "Ret", "ReturnInst", "returns a value (possibly void), from a function.", oload_all_arith_v, [retoload_param]) - self.add_llvm_instr("TERM", 2, "Br", "BranchInst", "branches (conditional or unconditional)", "", []) - self.add_llvm_instr("TERM", 3, "Switch", "SwitchInst", "performs a multiway switch", "", []) - self.add_llvm_instr("TERM", 4, "IndirectBr", "IndirectBrInst", "branches indirectly", "", []) - self.add_llvm_instr("TERM", 5, "Invoke", "InvokeInst", "invokes function with normal and exceptional returns", "", []) - self.add_llvm_instr("TERM", 6, "Resume", "ResumeInst", "resumes the propagation of an exception", "", []) - self.add_llvm_instr("TERM", 7, "Unreachable", "UnreachableInst", "is unreachable", "", []) - - self.add_llvm_instr("BINARY", 8, "Add" , "BinaryOperator", "returns the sum of its two operands", oload_int_arith, oload_binary_params, counters=('ints',)) - self.add_llvm_instr("BINARY", 9, "FAdd" , "BinaryOperator", "returns the sum of its two operands", oload_float_arith, oload_binary_params, counters=('floats',)) - self.add_llvm_instr("BINARY", 10, "Sub" , "BinaryOperator", "returns the difference of its two operands", oload_int_arith, oload_binary_params, counters=('ints',)) - self.add_llvm_instr("BINARY", 11, "FSub" , "BinaryOperator", "returns the difference of its two operands", oload_float_arith, oload_binary_params, counters=('floats',)) - self.add_llvm_instr("BINARY", 12, "Mul" , "BinaryOperator", "returns the product of its two operands", oload_int_arith, oload_binary_params, counters=('ints',)) - self.add_llvm_instr("BINARY", 13, "FMul" , "BinaryOperator", "returns the product of its two operands", oload_float_arith, oload_binary_params, counters=('floats',)) - self.add_llvm_instr("BINARY", 14, "UDiv" , "BinaryOperator", "returns the quotient of its two unsigned operands", oload_int_arith, oload_binary_params, counters=('uints',)) - self.add_llvm_instr("BINARY", 15, "SDiv" , "BinaryOperator", "returns the quotient of its two signed operands", oload_int_arith, oload_binary_params, counters=('ints',)) - self.add_llvm_instr("BINARY", 16, "FDiv" , "BinaryOperator", "returns the quotient of its two operands", oload_float_arith, oload_binary_params, counters=('floats',)) - self.add_llvm_instr("BINARY", 17, "URem" , "BinaryOperator", "returns the remainder from the unsigned division of its two operands", oload_int_arith, oload_binary_params, counters=('uints',)) - self.add_llvm_instr("BINARY", 18, "SRem" , "BinaryOperator", "returns the remainder from the signed division of its two operands", oload_int_arith, oload_binary_params, counters=('ints',)) - self.add_llvm_instr("BINARY", 19, "FRem" , "BinaryOperator", "returns the remainder from the division of its two operands", oload_float_arith, oload_binary_params, counters=('floats',)) - - self.add_llvm_instr("BINARY", 20, "Shl", "BinaryOperator", "shifts left (logical)", oload_int_arith, oload_binary_params, counters=('uints',)) - self.add_llvm_instr("BINARY", 21, "LShr", "BinaryOperator", "shifts right (logical), with zero bit fill", oload_int_arith, oload_binary_params, counters=('uints',)) - self.add_llvm_instr("BINARY", 22, "AShr", "BinaryOperator", "shifts right (arithmetic), with 'a' operand sign bit fill", oload_int_arith, oload_binary_params, counters=('ints',)) - self.add_llvm_instr("BINARY", 23, "And", "BinaryOperator", "returns a bitwise logical and of its two operands", oload_int_arith_b, oload_binary_params, counters=('uints',)) - self.add_llvm_instr("BINARY", 24, "Or", "BinaryOperator", "returns a bitwise logical or of its two operands", oload_int_arith_b, oload_binary_params, counters=('uints',)) - self.add_llvm_instr("BINARY", 25, "Xor", "BinaryOperator", "returns a bitwise logical xor of its two operands", oload_int_arith_b, oload_binary_params, counters=('uints',)) - - self.add_llvm_instr("MEMORY", 26, "Alloca", "AllocaInst", "allocates memory on the stack frame of the currently executing function", "", []) - self.add_llvm_instr("MEMORY", 27, "Load", "LoadInst", "reads from memory", "", []) - self.add_llvm_instr("MEMORY", 28, "Store", "StoreInst", "writes to memory", "", []) - self.add_llvm_instr("MEMORY", 29, "GetElementPtr", "GetElementPtrInst", "gets the address of a subelement of an aggregate value", "", []) - self.add_llvm_instr("MEMORY", 30, "Fence", "FenceInst", "introduces happens-before edges between operations", "", [], counters=('fence',)) - self.add_llvm_instr("MEMORY", 31, "AtomicCmpXchg", "AtomicCmpXchgInst" , "atomically modifies memory", "", [], counters=('atomic',)) - self.add_llvm_instr("MEMORY", 32, "AtomicRMW", "AtomicRMWInst", "atomically modifies memory", "", [], counters=('atomic',)) - - self.add_llvm_instr("CAST", 33, "Trunc", "TruncInst", "truncates an integer", oload_int_arith_b, oload_cast_params, counters=('ints',)) - self.add_llvm_instr("CAST", 34, "ZExt", "ZExtInst", "zero extends an integer", oload_int_arith_b, oload_cast_params, counters=('uints',)) - self.add_llvm_instr("CAST", 35, "SExt", "SExtInst", "sign extends an integer", oload_int_arith_b, oload_cast_params, counters=('ints',)) - self.add_llvm_instr("CAST", 36, "FPToUI", "FPToUIInst", "converts a floating point to UInt", oload_all_arith, oload_cast_params, counters=('floats',)) - self.add_llvm_instr("CAST", 37, "FPToSI", "FPToSIInst", "converts a floating point to SInt", oload_all_arith, oload_cast_params, counters=('floats',)) - self.add_llvm_instr("CAST", 38, "UIToFP", "UIToFPInst", "converts a UInt to floating point", oload_all_arith, oload_cast_params, counters=('floats',)) - self.add_llvm_instr("CAST", 39, "SIToFP" , "SIToFPInst", "converts a SInt to floating point", oload_all_arith, oload_cast_params, counters=('floats',)) - self.add_llvm_instr("CAST", 40, "FPTrunc", "FPTruncInst", "truncates a floating point", oload_float_arith, oload_cast_params, counters=('floats',)) - self.add_llvm_instr("CAST", 41, "FPExt", "FPExtInst", "extends a floating point", oload_float_arith, oload_cast_params, counters=('floats',)) - self.add_llvm_instr("CAST", 42, "PtrToInt", "PtrToIntInst", "converts a pointer to integer", "i", oload_cast_params) - self.add_llvm_instr("CAST", 43, "IntToPtr", "IntToPtrInst", "converts an integer to Pointer", "i", oload_cast_params) - self.add_llvm_instr("CAST", 44, "BitCast", "BitCastInst", "performs a bit-preserving type cast", oload_all_arith, oload_cast_params) - self.add_llvm_instr("CAST", 45, "AddrSpaceCast", "AddrSpaceCastInst", "casts a value addrspace", "", oload_cast_params) - - self.add_llvm_instr("OTHER", 46, "ICmp", "ICmpInst", "compares integers", oload_int_arith_b, oload_binary_params, counters=('ints',)) - self.add_llvm_instr("OTHER", 47, "FCmp", "FCmpInst", "compares floating points", oload_float_arith, oload_binary_params, counters=('floats',)) - self.add_llvm_instr("OTHER", 48, "PHI", "PHINode", "is a PHI node instruction", "", []) + oload_cast_params = [ + retoload_param, + db_dxil_param(1, "$o", "value", "Value to cast/convert"), + ] + oload_binary_params = [ + retoload_param, + db_dxil_param(1, "$o", "a", "first value"), + db_dxil_param(2, "$o", "b", "second value"), + ] + self.add_llvm_instr( + "TERM", + 1, + "Ret", + "ReturnInst", + "returns a value (possibly void), from a function.", + oload_all_arith_v, + [retoload_param], + ) + self.add_llvm_instr( + "TERM", + 2, + "Br", + "BranchInst", + "branches (conditional or unconditional)", + "", + [], + ) + self.add_llvm_instr( + "TERM", 3, "Switch", "SwitchInst", "performs a multiway switch", "", [] + ) + self.add_llvm_instr( + "TERM", 4, "IndirectBr", "IndirectBrInst", "branches indirectly", "", [] + ) + self.add_llvm_instr( + "TERM", + 5, + "Invoke", + "InvokeInst", + "invokes function with normal and exceptional returns", + "", + [], + ) + self.add_llvm_instr( + "TERM", + 6, + "Resume", + "ResumeInst", + "resumes the propagation of an exception", + "", + [], + ) + self.add_llvm_instr( + "TERM", 7, "Unreachable", "UnreachableInst", "is unreachable", "", [] + ) + + self.add_llvm_instr( + "BINARY", + 8, + "Add", + "BinaryOperator", + "returns the sum of its two operands", + oload_int_arith, + oload_binary_params, + counters=("ints",), + ) + self.add_llvm_instr( + "BINARY", + 9, + "FAdd", + "BinaryOperator", + "returns the sum of its two operands", + oload_float_arith, + oload_binary_params, + counters=("floats",), + ) + self.add_llvm_instr( + "BINARY", + 10, + "Sub", + "BinaryOperator", + "returns the difference of its two operands", + oload_int_arith, + oload_binary_params, + counters=("ints",), + ) + self.add_llvm_instr( + "BINARY", + 11, + "FSub", + "BinaryOperator", + "returns the difference of its two operands", + oload_float_arith, + oload_binary_params, + counters=("floats",), + ) + self.add_llvm_instr( + "BINARY", + 12, + "Mul", + "BinaryOperator", + "returns the product of its two operands", + oload_int_arith, + oload_binary_params, + counters=("ints",), + ) + self.add_llvm_instr( + "BINARY", + 13, + "FMul", + "BinaryOperator", + "returns the product of its two operands", + oload_float_arith, + oload_binary_params, + counters=("floats",), + ) + self.add_llvm_instr( + "BINARY", + 14, + "UDiv", + "BinaryOperator", + "returns the quotient of its two unsigned operands", + oload_int_arith, + oload_binary_params, + counters=("uints",), + ) + self.add_llvm_instr( + "BINARY", + 15, + "SDiv", + "BinaryOperator", + "returns the quotient of its two signed operands", + oload_int_arith, + oload_binary_params, + counters=("ints",), + ) + self.add_llvm_instr( + "BINARY", + 16, + "FDiv", + "BinaryOperator", + "returns the quotient of its two operands", + oload_float_arith, + oload_binary_params, + counters=("floats",), + ) + self.add_llvm_instr( + "BINARY", + 17, + "URem", + "BinaryOperator", + "returns the remainder from the unsigned division of its two operands", + oload_int_arith, + oload_binary_params, + counters=("uints",), + ) + self.add_llvm_instr( + "BINARY", + 18, + "SRem", + "BinaryOperator", + "returns the remainder from the signed division of its two operands", + oload_int_arith, + oload_binary_params, + counters=("ints",), + ) + self.add_llvm_instr( + "BINARY", + 19, + "FRem", + "BinaryOperator", + "returns the remainder from the division of its two operands", + oload_float_arith, + oload_binary_params, + counters=("floats",), + ) + + self.add_llvm_instr( + "BINARY", + 20, + "Shl", + "BinaryOperator", + "shifts left (logical)", + oload_int_arith, + oload_binary_params, + counters=("uints",), + ) + self.add_llvm_instr( + "BINARY", + 21, + "LShr", + "BinaryOperator", + "shifts right (logical), with zero bit fill", + oload_int_arith, + oload_binary_params, + counters=("uints",), + ) + self.add_llvm_instr( + "BINARY", + 22, + "AShr", + "BinaryOperator", + "shifts right (arithmetic), with 'a' operand sign bit fill", + oload_int_arith, + oload_binary_params, + counters=("ints",), + ) + self.add_llvm_instr( + "BINARY", + 23, + "And", + "BinaryOperator", + "returns a bitwise logical and of its two operands", + oload_int_arith_b, + oload_binary_params, + counters=("uints",), + ) + self.add_llvm_instr( + "BINARY", + 24, + "Or", + "BinaryOperator", + "returns a bitwise logical or of its two operands", + oload_int_arith_b, + oload_binary_params, + counters=("uints",), + ) + self.add_llvm_instr( + "BINARY", + 25, + "Xor", + "BinaryOperator", + "returns a bitwise logical xor of its two operands", + oload_int_arith_b, + oload_binary_params, + counters=("uints",), + ) + + self.add_llvm_instr( + "MEMORY", + 26, + "Alloca", + "AllocaInst", + "allocates memory on the stack frame of the currently executing function", + "", + [], + ) + self.add_llvm_instr( + "MEMORY", 27, "Load", "LoadInst", "reads from memory", "", [] + ) + self.add_llvm_instr( + "MEMORY", 28, "Store", "StoreInst", "writes to memory", "", [] + ) + self.add_llvm_instr( + "MEMORY", + 29, + "GetElementPtr", + "GetElementPtrInst", + "gets the address of a subelement of an aggregate value", + "", + [], + ) + self.add_llvm_instr( + "MEMORY", + 30, + "Fence", + "FenceInst", + "introduces happens-before edges between operations", + "", + [], + counters=("fence",), + ) + self.add_llvm_instr( + "MEMORY", + 31, + "AtomicCmpXchg", + "AtomicCmpXchgInst", + "atomically modifies memory", + "", + [], + counters=("atomic",), + ) + self.add_llvm_instr( + "MEMORY", + 32, + "AtomicRMW", + "AtomicRMWInst", + "atomically modifies memory", + "", + [], + counters=("atomic",), + ) + + self.add_llvm_instr( + "CAST", + 33, + "Trunc", + "TruncInst", + "truncates an integer", + oload_int_arith_b, + oload_cast_params, + counters=("ints",), + ) + self.add_llvm_instr( + "CAST", + 34, + "ZExt", + "ZExtInst", + "zero extends an integer", + oload_int_arith_b, + oload_cast_params, + counters=("uints",), + ) + self.add_llvm_instr( + "CAST", + 35, + "SExt", + "SExtInst", + "sign extends an integer", + oload_int_arith_b, + oload_cast_params, + counters=("ints",), + ) + self.add_llvm_instr( + "CAST", + 36, + "FPToUI", + "FPToUIInst", + "converts a floating point to UInt", + oload_all_arith, + oload_cast_params, + counters=("floats",), + ) + self.add_llvm_instr( + "CAST", + 37, + "FPToSI", + "FPToSIInst", + "converts a floating point to SInt", + oload_all_arith, + oload_cast_params, + counters=("floats",), + ) + self.add_llvm_instr( + "CAST", + 38, + "UIToFP", + "UIToFPInst", + "converts a UInt to floating point", + oload_all_arith, + oload_cast_params, + counters=("floats",), + ) + self.add_llvm_instr( + "CAST", + 39, + "SIToFP", + "SIToFPInst", + "converts a SInt to floating point", + oload_all_arith, + oload_cast_params, + counters=("floats",), + ) + self.add_llvm_instr( + "CAST", + 40, + "FPTrunc", + "FPTruncInst", + "truncates a floating point", + oload_float_arith, + oload_cast_params, + counters=("floats",), + ) + self.add_llvm_instr( + "CAST", + 41, + "FPExt", + "FPExtInst", + "extends a floating point", + oload_float_arith, + oload_cast_params, + counters=("floats",), + ) + self.add_llvm_instr( + "CAST", + 42, + "PtrToInt", + "PtrToIntInst", + "converts a pointer to integer", + "i", + oload_cast_params, + ) + self.add_llvm_instr( + "CAST", + 43, + "IntToPtr", + "IntToPtrInst", + "converts an integer to Pointer", + "i", + oload_cast_params, + ) + self.add_llvm_instr( + "CAST", + 44, + "BitCast", + "BitCastInst", + "performs a bit-preserving type cast", + oload_all_arith, + oload_cast_params, + ) + self.add_llvm_instr( + "CAST", + 45, + "AddrSpaceCast", + "AddrSpaceCastInst", + "casts a value addrspace", + "", + oload_cast_params, + ) + + self.add_llvm_instr( + "OTHER", + 46, + "ICmp", + "ICmpInst", + "compares integers", + oload_int_arith_b, + oload_binary_params, + counters=("ints",), + ) + self.add_llvm_instr( + "OTHER", + 47, + "FCmp", + "FCmpInst", + "compares floating points", + oload_float_arith, + oload_binary_params, + counters=("floats",), + ) + self.add_llvm_instr( + "OTHER", 48, "PHI", "PHINode", "is a PHI node instruction", "", [] + ) self.add_llvm_instr("OTHER", 49, "Call", "CallInst", "calls a function", "", []) - self.add_llvm_instr("OTHER", 50, "Select", "SelectInst", "selects an instruction", "", []) - self.add_llvm_instr("OTHER", 51, "UserOp1", "Instruction", "may be used internally in a pass", "", []) - self.add_llvm_instr("OTHER", 52, "UserOp2", "Instruction", "internal to passes only", "", []) - self.add_llvm_instr("OTHER", 53, "VAArg", "VAArgInst", "vaarg instruction", "", []) - self.add_llvm_instr("OTHER", 57, "ExtractValue", "ExtractValueInst", "extracts from aggregate", "", []) - self.add_llvm_instr("OTHER", 59, "LandingPad", "LandingPadInst", "represents a landing pad", "", []) - + self.add_llvm_instr( + "OTHER", 50, "Select", "SelectInst", "selects an instruction", "", [] + ) + self.add_llvm_instr( + "OTHER", + 51, + "UserOp1", + "Instruction", + "may be used internally in a pass", + "", + [], + ) + self.add_llvm_instr( + "OTHER", 52, "UserOp2", "Instruction", "internal to passes only", "", [] + ) + self.add_llvm_instr( + "OTHER", 53, "VAArg", "VAArgInst", "vaarg instruction", "", [] + ) + self.add_llvm_instr( + "OTHER", + 57, + "ExtractValue", + "ExtractValueInst", + "extracts from aggregate", + "", + [], + ) + self.add_llvm_instr( + "OTHER", + 59, + "LandingPad", + "LandingPadInst", + "represents a landing pad", + "", + [], + ) + def populate_dxil_operations(self): # $o in a parameter type means the overload type # $r in a parameter type means the resource type @@ -543,1422 +1137,3837 @@ def populate_dxil_operations(self): self.opcode_param = db_dxil_param(1, "i32", "opcode", "DXIL opcode") retvoid_param = db_dxil_param(0, "v", "", "no return value") next_op_idx = 0 - self.add_dxil_op("TempRegLoad", next_op_idx, "TempRegLoad", "helper load operation", "hfwi", "ro", [ - db_dxil_param(0, "$o", "", "register value"), - db_dxil_param(2, "u32", "index", "linearized register index")]) - next_op_idx += 1 - self.add_dxil_op("TempRegStore", next_op_idx, "TempRegStore", "helper store operation", "hfwi", "", [ - retvoid_param, - db_dxil_param(2, "u32", "index", "linearized register index"), - db_dxil_param(3, "$o", "value", "value to store")]) - next_op_idx += 1 - self.add_dxil_op("MinPrecXRegLoad", next_op_idx, "MinPrecXRegLoad", "helper load operation for minprecision", "hw", "ro", [ - db_dxil_param(0, "$o", "", "register value"), - db_dxil_param(2, "pf32", "regIndex", "pointer to indexable register"), - db_dxil_param(3, "i32", "index", "index"), - db_dxil_param(4, "u8", "component", "component")]) - next_op_idx += 1 - self.add_dxil_op("MinPrecXRegStore", next_op_idx, "MinPrecXRegStore", "helper store operation for minprecision", "hw", "", [ - retvoid_param, - db_dxil_param(2, "pf32", "regIndex", "pointer to indexable register"), - db_dxil_param(3, "i32", "index", "index"), - db_dxil_param(4, "u8", "component", "component"), - db_dxil_param(5, "$o", "value", "value to store")]) - next_op_idx += 1 - self.add_dxil_op("LoadInput", next_op_idx, "LoadInput", "loads the value from shader input", "hfwi", "rn", [ - db_dxil_param(0, "$o", "", "input value"), - db_dxil_param(2, "u32", "inputSigId", "input signature element ID"), - db_dxil_param(3, "u32", "rowIndex", "row index relative to element"), - db_dxil_param(4, "u8", "colIndex", "column index relative to element"), - db_dxil_param(5, "i32", "gsVertexAxis", "gsVertexAxis")], - counters=('sig_ld',)) - next_op_idx += 1 - self.add_dxil_op("StoreOutput", next_op_idx, "StoreOutput", "stores the value to shader output", "hfwi", "", [ # note, cannot store bit even though load supports it - retvoid_param, - db_dxil_param(2, "u32", "outputSigId", "output signature element ID"), - db_dxil_param(3, "u32", "rowIndex", "row index relative to element"), - db_dxil_param(4, "u8", "colIndex", "column index relative to element"), - db_dxil_param(5, "$o", "value", "value to store")], - counters=('sig_st',)) + self.add_dxil_op( + "TempRegLoad", + next_op_idx, + "TempRegLoad", + "helper load operation", + "hfwi", + "ro", + [ + db_dxil_param(0, "$o", "", "register value"), + db_dxil_param(2, "u32", "index", "linearized register index"), + ], + ) + next_op_idx += 1 + self.add_dxil_op( + "TempRegStore", + next_op_idx, + "TempRegStore", + "helper store operation", + "hfwi", + "", + [ + retvoid_param, + db_dxil_param(2, "u32", "index", "linearized register index"), + db_dxil_param(3, "$o", "value", "value to store"), + ], + ) + next_op_idx += 1 + self.add_dxil_op( + "MinPrecXRegLoad", + next_op_idx, + "MinPrecXRegLoad", + "helper load operation for minprecision", + "hw", + "ro", + [ + db_dxil_param(0, "$o", "", "register value"), + db_dxil_param(2, "pf32", "regIndex", "pointer to indexable register"), + db_dxil_param(3, "i32", "index", "index"), + db_dxil_param(4, "u8", "component", "component"), + ], + ) + next_op_idx += 1 + self.add_dxil_op( + "MinPrecXRegStore", + next_op_idx, + "MinPrecXRegStore", + "helper store operation for minprecision", + "hw", + "", + [ + retvoid_param, + db_dxil_param(2, "pf32", "regIndex", "pointer to indexable register"), + db_dxil_param(3, "i32", "index", "index"), + db_dxil_param(4, "u8", "component", "component"), + db_dxil_param(5, "$o", "value", "value to store"), + ], + ) + next_op_idx += 1 + self.add_dxil_op( + "LoadInput", + next_op_idx, + "LoadInput", + "loads the value from shader input", + "hfwi", + "rn", + [ + db_dxil_param(0, "$o", "", "input value"), + db_dxil_param(2, "u32", "inputSigId", "input signature element ID"), + db_dxil_param(3, "u32", "rowIndex", "row index relative to element"), + db_dxil_param(4, "u8", "colIndex", "column index relative to element"), + db_dxil_param(5, "i32", "gsVertexAxis", "gsVertexAxis"), + ], + counters=("sig_ld",), + ) + next_op_idx += 1 + self.add_dxil_op( + "StoreOutput", + next_op_idx, + "StoreOutput", + "stores the value to shader output", + "hfwi", + "", + [ # note, cannot store bit even though load supports it + retvoid_param, + db_dxil_param(2, "u32", "outputSigId", "output signature element ID"), + db_dxil_param(3, "u32", "rowIndex", "row index relative to element"), + db_dxil_param(4, "u8", "colIndex", "column index relative to element"), + db_dxil_param(5, "$o", "value", "value to store"), + ], + counters=("sig_st",), + ) next_op_idx += 1 def UFI(name, **mappings): name = name.upper() - for k,v in mappings.items(): + for k, v in mappings.items(): if name.startswith(k): return v - if name.upper().startswith('F'): - return 'floats' - elif name.upper().startswith('U'): - return 'uints' + if name.upper().startswith("F"): + return "floats" + elif name.upper().startswith("U"): + return "uints" else: - return 'ints' + return "ints" # Unary float operations are regular. for i in "FAbs,Saturate".split(","): - self.add_dxil_op(i, next_op_idx, "Unary", "returns the " + i, "hfd", "rn", [ - db_dxil_param(0, "$o", "", "operation result"), - db_dxil_param(2, "$o", "value", "input value")], - counters=('floats',)) + self.add_dxil_op( + i, + next_op_idx, + "Unary", + "returns the " + i, + "hfd", + "rn", + [ + db_dxil_param(0, "$o", "", "operation result"), + db_dxil_param(2, "$o", "value", "input value"), + ], + counters=("floats",), + ) next_op_idx += 1 for i in "IsNaN,IsInf,IsFinite,IsNormal".split(","): - self.add_dxil_op(i, next_op_idx, "IsSpecialFloat", "returns the " + i, "hf", "rn", [ - db_dxil_param(0, "i1", "", "operation result"), - db_dxil_param(2, "$o", "value", "input value")], - counters=('floats',)) + self.add_dxil_op( + i, + next_op_idx, + "IsSpecialFloat", + "returns the " + i, + "hf", + "rn", + [ + db_dxil_param(0, "i1", "", "operation result"), + db_dxil_param(2, "$o", "value", "input value"), + ], + counters=("floats",), + ) next_op_idx += 1 - for i in "Cos,Sin,Tan,Acos,Asin,Atan,Hcos,Hsin,Htan,Exp,Frc,Log,Sqrt,Rsqrt,Round_ne,Round_ni,Round_pi,Round_z".split(","): - self.add_dxil_op(i, next_op_idx, "Unary", "returns the " + i, "hf", "rn", [ - db_dxil_param(0, "$o", "", "operation result"), - db_dxil_param(2, "$o", "value", "input value")], - counters=('floats',)) + for ( + i + ) in "Cos,Sin,Tan,Acos,Asin,Atan,Hcos,Hsin,Htan,Exp,Frc,Log,Sqrt,Rsqrt,Round_ne,Round_ni,Round_pi,Round_z".split( + "," + ): + self.add_dxil_op( + i, + next_op_idx, + "Unary", + "returns the " + i, + "hf", + "rn", + [ + db_dxil_param(0, "$o", "", "operation result"), + db_dxil_param(2, "$o", "value", "input value"), + ], + counters=("floats",), + ) next_op_idx += 1 # Unary int operations are regular. for i in "Bfrev".split(","): - self.add_dxil_op(i, next_op_idx, "Unary", "returns the reverse bit pattern of the input value", "wil", "rn", [ - db_dxil_param(0, "$o", "", "operation result"), - db_dxil_param(2, "$o", "value", "input value")], - counters=('uints',)) + self.add_dxil_op( + i, + next_op_idx, + "Unary", + "returns the reverse bit pattern of the input value", + "wil", + "rn", + [ + db_dxil_param(0, "$o", "", "operation result"), + db_dxil_param(2, "$o", "value", "input value"), + ], + counters=("uints",), + ) next_op_idx += 1 for i in "Countbits,FirstbitLo".split(","): - self.add_dxil_op(i, next_op_idx, "UnaryBits", "returns the " + i, "wil", "rn", [ - db_dxil_param(0, "i32", "", "operation result"), - db_dxil_param(2, "$o", "value", "input value")], - counters=('uints',)) + self.add_dxil_op( + i, + next_op_idx, + "UnaryBits", + "returns the " + i, + "wil", + "rn", + [ + db_dxil_param(0, "i32", "", "operation result"), + db_dxil_param(2, "$o", "value", "input value"), + ], + counters=("uints",), + ) next_op_idx += 1 for i in "FirstbitHi,FirstbitSHi".split(","): - self.add_dxil_op(i, next_op_idx, "UnaryBits", "returns src != 0? (BitWidth-1 - " + i + ") : -1", "wil", "rn", [ - db_dxil_param(0, "i32", "", "operation result"), - db_dxil_param(2, "$o", "value", "input value")], - counters=('uints',)) + self.add_dxil_op( + i, + next_op_idx, + "UnaryBits", + "returns src != 0? (BitWidth-1 - " + i + ") : -1", + "wil", + "rn", + [ + db_dxil_param(0, "i32", "", "operation result"), + db_dxil_param(2, "$o", "value", "input value"), + ], + counters=("uints",), + ) next_op_idx += 1 # Binary float operations for i in "FMax,FMin".split(","): - self.add_dxil_op(i, next_op_idx, "Binary", "returns the " + i + " of the input values", "hfd", "rn", [ - db_dxil_param(0, "$o", "", "operation result"), - db_dxil_param(2, "$o", "a", "input value"), - db_dxil_param(3, "$o", "b", "input value")], - counters=('floats',)) + self.add_dxil_op( + i, + next_op_idx, + "Binary", + "returns the " + i + " of the input values", + "hfd", + "rn", + [ + db_dxil_param(0, "$o", "", "operation result"), + db_dxil_param(2, "$o", "a", "input value"), + db_dxil_param(3, "$o", "b", "input value"), + ], + counters=("floats",), + ) next_op_idx += 1 # Binary int operations for i in "IMax,IMin,UMax,UMin".split(","): - self.add_dxil_op(i, next_op_idx, "Binary", "returns the " + i + " of the input values", "wil", "rn", [ - db_dxil_param(0, "$o", "", "operation result"), - db_dxil_param(2, "$o", "a", "input value"), - db_dxil_param(3, "$o", "b", "input value")], - counters=(UFI(i),)) + self.add_dxil_op( + i, + next_op_idx, + "Binary", + "returns the " + i + " of the input values", + "wil", + "rn", + [ + db_dxil_param(0, "$o", "", "operation result"), + db_dxil_param(2, "$o", "a", "input value"), + db_dxil_param(3, "$o", "b", "input value"), + ], + counters=(UFI(i),), + ) next_op_idx += 1 # Binary int operations with two outputs for i in "IMul,UMul,UDiv".split(","): - self.add_dxil_op(i, next_op_idx, "BinaryWithTwoOuts", "returns the " + i + " of the input values", "i", "rn", [ - db_dxil_param(0, "twoi32", "", "operation result"), - db_dxil_param(2, "$o", "a", "input value"), - db_dxil_param(3, "$o", "b", "input value")], - counters=(UFI(i),)) + self.add_dxil_op( + i, + next_op_idx, + "BinaryWithTwoOuts", + "returns the " + i + " of the input values", + "i", + "rn", + [ + db_dxil_param(0, "twoi32", "", "operation result"), + db_dxil_param(2, "$o", "a", "input value"), + db_dxil_param(3, "$o", "b", "input value"), + ], + counters=(UFI(i),), + ) next_op_idx += 1 # Binary int operations with carry for i in "UAddc,USubb".split(","): - self.add_dxil_op(i, next_op_idx, "BinaryWithCarryOrBorrow", "returns the " + i + " of the input values", "i", "rn", [ - db_dxil_param(0, "i32c", "", "operation result with carry/borrow value"), - db_dxil_param(2, "$o", "a", "input value"), - db_dxil_param(3, "$o", "b", "input value")], - counters=('uints',)) + self.add_dxil_op( + i, + next_op_idx, + "BinaryWithCarryOrBorrow", + "returns the " + i + " of the input values", + "i", + "rn", + [ + db_dxil_param( + 0, "i32c", "", "operation result with carry/borrow value" + ), + db_dxil_param(2, "$o", "a", "input value"), + db_dxil_param(3, "$o", "b", "input value"), + ], + counters=("uints",), + ) next_op_idx += 1 # Tertiary float. - self.add_dxil_op("FMad", next_op_idx, "Tertiary", "performs a fused multiply add (FMA) of the form a * b + c", "hfd", "rn", [ - db_dxil_param(0, "$o", "", "the fused multiply-addition of parameters a * b + c"), - db_dxil_param(2, "$o", "a", "first value for FMA, the first factor"), - db_dxil_param(3, "$o", "b", "second value for FMA, the second factor"), - db_dxil_param(4, "$o", "c", "third value for FMA, the addend")]) - next_op_idx += 1 - self.add_dxil_op("Fma", next_op_idx, "Tertiary", "performs a fused multiply add (FMA) of the form a * b + c", "d", "rn", [ - db_dxil_param(0, "$o", "", "the double-precision fused multiply-addition of parameters a * b + c, accurate to 0.5 units of least precision (ULP)"), - db_dxil_param(2, "$o", "a", "first value for FMA, the first factor"), - db_dxil_param(3, "$o", "b", "second value for FMA, the second factor"), - db_dxil_param(4, "$o", "c", "third value for FMA, the addend")], - counters=('floats',)) + self.add_dxil_op( + "FMad", + next_op_idx, + "Tertiary", + "performs a fused multiply add (FMA) of the form a * b + c", + "hfd", + "rn", + [ + db_dxil_param( + 0, "$o", "", "the fused multiply-addition of parameters a * b + c" + ), + db_dxil_param(2, "$o", "a", "first value for FMA, the first factor"), + db_dxil_param(3, "$o", "b", "second value for FMA, the second factor"), + db_dxil_param(4, "$o", "c", "third value for FMA, the addend"), + ], + ) + next_op_idx += 1 + self.add_dxil_op( + "Fma", + next_op_idx, + "Tertiary", + "performs a fused multiply add (FMA) of the form a * b + c", + "d", + "rn", + [ + db_dxil_param( + 0, + "$o", + "", + "the double-precision fused multiply-addition of parameters a * b + c, accurate to 0.5 units of least precision (ULP)", + ), + db_dxil_param(2, "$o", "a", "first value for FMA, the first factor"), + db_dxil_param(3, "$o", "b", "second value for FMA, the second factor"), + db_dxil_param(4, "$o", "c", "third value for FMA, the addend"), + ], + counters=("floats",), + ) next_op_idx += 1 # Tertiary int. for i in "IMad,UMad".split(","): - self.add_dxil_op(i, next_op_idx, "Tertiary", "performs an integral " + i, "wil", "rn", [ - db_dxil_param(0, "$o", "", "the operation result"), - db_dxil_param(2, "$o", "a", "first value for FMA, the first factor"), - db_dxil_param(3, "$o", "b", "second value for FMA, the second factor"), - db_dxil_param(4, "$o", "c", "third value for FMA, the addend")], - counters=(UFI(i),)) + self.add_dxil_op( + i, + next_op_idx, + "Tertiary", + "performs an integral " + i, + "wil", + "rn", + [ + db_dxil_param(0, "$o", "", "the operation result"), + db_dxil_param( + 2, "$o", "a", "first value for FMA, the first factor" + ), + db_dxil_param( + 3, "$o", "b", "second value for FMA, the second factor" + ), + db_dxil_param(4, "$o", "c", "third value for FMA, the addend"), + ], + counters=(UFI(i),), + ) next_op_idx += 1 for i in "Msad,Ibfe,Ubfe".split(","): - self.add_dxil_op(i, next_op_idx, "Tertiary", "performs an integral " + i, "il", "rn", [ - db_dxil_param(0, "$o", "", "the operation result"), - db_dxil_param(2, "$o", "a", "first value for FMA, the first factor"), - db_dxil_param(3, "$o", "b", "second value for FMA, the second factor"), - db_dxil_param(4, "$o", "c", "third value for FMA, the addend")], - counters=(UFI(i, M='uints'),)) + self.add_dxil_op( + i, + next_op_idx, + "Tertiary", + "performs an integral " + i, + "il", + "rn", + [ + db_dxil_param(0, "$o", "", "the operation result"), + db_dxil_param( + 2, "$o", "a", "first value for FMA, the first factor" + ), + db_dxil_param( + 3, "$o", "b", "second value for FMA, the second factor" + ), + db_dxil_param(4, "$o", "c", "third value for FMA, the addend"), + ], + counters=(UFI(i, M="uints"),), + ) next_op_idx += 1 # Quaternary - self.add_dxil_op("Bfi", next_op_idx, "Quaternary", "given a bit range from the LSB of a number, places that number of bits in another number at any offset", "i", "rn", [ - db_dxil_param(0, "$o", "", "the operation result"), - db_dxil_param(2, "$o", "width", "the bitfield width to take from the value"), - db_dxil_param(3, "$o", "offset", "the bitfield offset to replace in the value"), - db_dxil_param(4, "$o", "value", "the number the bits are taken from"), - db_dxil_param(5, "$o", "replacedValue", "the number with bits to be replaced")], - counters=('uints',)) + self.add_dxil_op( + "Bfi", + next_op_idx, + "Quaternary", + "given a bit range from the LSB of a number, places that number of bits in another number at any offset", + "i", + "rn", + [ + db_dxil_param(0, "$o", "", "the operation result"), + db_dxil_param( + 2, "$o", "width", "the bitfield width to take from the value" + ), + db_dxil_param( + 3, "$o", "offset", "the bitfield offset to replace in the value" + ), + db_dxil_param(4, "$o", "value", "the number the bits are taken from"), + db_dxil_param( + 5, "$o", "replacedValue", "the number with bits to be replaced" + ), + ], + counters=("uints",), + ) next_op_idx += 1 # Dot - self.add_dxil_op("Dot2", next_op_idx, "Dot2", "two-dimensional vector dot-product", "hf", "rn", [ - db_dxil_param(0, "$o", "", "the operation result"), - db_dxil_param(2, "$o", "ax", "the first component of the first vector"), - db_dxil_param(3, "$o", "ay", "the second component of the first vector"), - db_dxil_param(4, "$o", "bx", "the first component of the second vector"), - db_dxil_param(5, "$o", "by", "the second component of the second vector")], - counters=('floats',)) - next_op_idx += 1 - self.add_dxil_op("Dot3", next_op_idx, "Dot3", "three-dimensional vector dot-product", "hf", "rn", [ - db_dxil_param(0, "$o", "", "the operation result"), - db_dxil_param(2, "$o", "ax", "the first component of the first vector"), - db_dxil_param(3, "$o", "ay", "the second component of the first vector"), - db_dxil_param(4, "$o", "az", "the third component of the first vector"), - db_dxil_param(5, "$o", "bx", "the first component of the second vector"), - db_dxil_param(6, "$o", "by", "the second component of the second vector"), - db_dxil_param(7, "$o", "bz", "the third component of the second vector")], - counters=('floats',)) - next_op_idx += 1 - self.add_dxil_op("Dot4", next_op_idx, "Dot4", "four-dimensional vector dot-product", "hf", "rn", [ - db_dxil_param(0, "$o", "", "the operation result"), - db_dxil_param(2, "$o", "ax", "the first component of the first vector"), - db_dxil_param(3, "$o", "ay", "the second component of the first vector"), - db_dxil_param(4, "$o", "az", "the third component of the first vector"), - db_dxil_param(5, "$o", "aw", "the fourth component of the first vector"), - db_dxil_param(6, "$o", "bx", "the first component of the second vector"), - db_dxil_param(7, "$o", "by", "the second component of the second vector"), - db_dxil_param(8, "$o", "bz", "the third component of the second vector"), - db_dxil_param(9, "$o", "bw", "the fourth component of the second vector")], - counters=('floats',)) + self.add_dxil_op( + "Dot2", + next_op_idx, + "Dot2", + "two-dimensional vector dot-product", + "hf", + "rn", + [ + db_dxil_param(0, "$o", "", "the operation result"), + db_dxil_param(2, "$o", "ax", "the first component of the first vector"), + db_dxil_param( + 3, "$o", "ay", "the second component of the first vector" + ), + db_dxil_param( + 4, "$o", "bx", "the first component of the second vector" + ), + db_dxil_param( + 5, "$o", "by", "the second component of the second vector" + ), + ], + counters=("floats",), + ) + next_op_idx += 1 + self.add_dxil_op( + "Dot3", + next_op_idx, + "Dot3", + "three-dimensional vector dot-product", + "hf", + "rn", + [ + db_dxil_param(0, "$o", "", "the operation result"), + db_dxil_param(2, "$o", "ax", "the first component of the first vector"), + db_dxil_param( + 3, "$o", "ay", "the second component of the first vector" + ), + db_dxil_param(4, "$o", "az", "the third component of the first vector"), + db_dxil_param( + 5, "$o", "bx", "the first component of the second vector" + ), + db_dxil_param( + 6, "$o", "by", "the second component of the second vector" + ), + db_dxil_param( + 7, "$o", "bz", "the third component of the second vector" + ), + ], + counters=("floats",), + ) + next_op_idx += 1 + self.add_dxil_op( + "Dot4", + next_op_idx, + "Dot4", + "four-dimensional vector dot-product", + "hf", + "rn", + [ + db_dxil_param(0, "$o", "", "the operation result"), + db_dxil_param(2, "$o", "ax", "the first component of the first vector"), + db_dxil_param( + 3, "$o", "ay", "the second component of the first vector" + ), + db_dxil_param(4, "$o", "az", "the third component of the first vector"), + db_dxil_param( + 5, "$o", "aw", "the fourth component of the first vector" + ), + db_dxil_param( + 6, "$o", "bx", "the first component of the second vector" + ), + db_dxil_param( + 7, "$o", "by", "the second component of the second vector" + ), + db_dxil_param( + 8, "$o", "bz", "the third component of the second vector" + ), + db_dxil_param( + 9, "$o", "bw", "the fourth component of the second vector" + ), + ], + counters=("floats",), + ) next_op_idx += 1 # Resources. - self.add_dxil_op("CreateHandle", next_op_idx, "CreateHandle", "creates the handle to a resource", "v", "ro", [ - db_dxil_param(0, "res", "", "the handle to the resource"), - db_dxil_param(2, "i8", "resourceClass", "the class of resource to create (SRV, UAV, CBuffer, Sampler)", is_const=True), # maps to DxilResourceBase::Class - db_dxil_param(3, "i32", "rangeId", "range identifier for resource", is_const=True), - db_dxil_param(4, "i32", "index", "zero-based index into range"), - db_dxil_param(5, "i1", "nonUniformIndex", "non-uniform resource index", is_const=True)]) - next_op_idx += 1 - self.add_dxil_op("CBufferLoad", next_op_idx, "CBufferLoad", "loads a value from a constant buffer resource", "hfd8wil", "ro", [ - db_dxil_param(0, "$o", "", "the value for the constant buffer variable"), - db_dxil_param(2, "res", "handle", "cbuffer handle"), - db_dxil_param(3, "u32", "byteOffset", "linear byte offset of value"), - db_dxil_param(4, "u32", "alignment", "load access alignment", is_const=True)]) - next_op_idx += 1 - self.add_dxil_op("CBufferLoadLegacy", next_op_idx, "CBufferLoadLegacy", "loads a value from a constant buffer resource", "hfdwil", "ro", [ - db_dxil_param(0, "$cb", "", "the value for the constant buffer variable"), - db_dxil_param(2, "res", "handle", "cbuffer handle"), - db_dxil_param(3, "u32", "regIndex", "0-based index into cbuffer instance")]) - next_op_idx += 1 - self.add_dxil_op("Sample", next_op_idx, "Sample", "samples a texture", "hfwi", "ro", [ - db_dxil_param(0, "$r", "", "the sampled value"), - db_dxil_param(2, "res", "srv", "handle of SRV to sample"), - db_dxil_param(3, "res", "sampler", "handle of sampler to use"), - db_dxil_param(4, "f", "coord0", "coordinate"), - db_dxil_param(5, "f", "coord1", "coordinate, undef for Texture1D"), - db_dxil_param(6, "f", "coord2", "coordinate, undef for Texture1D, Texture1DArray or Texture2D"), - db_dxil_param(7, "f", "coord3", "coordinate, defined only for TextureCubeArray"), - db_dxil_param(8, "i32", "offset0", "optional offset, applicable to Texture1D, Texture1DArray, and as part of offset1"), - db_dxil_param(9, "i32", "offset1", "optional offset, applicable to Texture2D, Texture2DArray, and as part of offset2"), - db_dxil_param(10, "i32", "offset2", "optional offset, applicable to Texture3D"), - db_dxil_param(11, "f", "clamp", "clamp value")], - counters=('tex_norm',)) - next_op_idx += 1 - self.add_dxil_op("SampleBias", next_op_idx, "SampleBias", "samples a texture after applying the input bias to the mipmap level", "hfwi", "ro", [ - db_dxil_param(0, "$r", "", "the sampled value"), - db_dxil_param(2, "res", "srv", "handle of SRV to sample"), - db_dxil_param(3, "res", "sampler", "handle of sampler to use"), - db_dxil_param(4, "f", "coord0", "coordinate"), - db_dxil_param(5, "f", "coord1", "coordinate, undef for Texture1D"), - db_dxil_param(6, "f", "coord2", "coordinate, undef for Texture1D, Texture1DArray or Texture2D"), - db_dxil_param(7, "f", "coord3", "coordinate, defined only for TextureCubeArray"), - db_dxil_param(8, "i32", "offset0", "optional offset, applicable to Texture1D, Texture1DArray, and as part of offset1"), - db_dxil_param(9, "i32", "offset1", "optional offset, applicable to Texture2D, Texture2DArray, and as part of offset2"), - db_dxil_param(10, "i32", "offset2", "optional offset, applicable to Texture3D"), - db_dxil_param(11, "f", "bias", "bias value"), - db_dxil_param(12, "f", "clamp", "clamp value")], - counters=('tex_bias',)) - next_op_idx += 1 - self.add_dxil_op("SampleLevel", next_op_idx, "SampleLevel", "samples a texture using a mipmap-level offset", "hfwi", "ro", [ - db_dxil_param(0, "$r", "", "the sampled value"), - db_dxil_param(2, "res", "srv", "handle of SRV to sample"), - db_dxil_param(3, "res", "sampler", "handle of sampler to use"), - db_dxil_param(4, "f", "coord0", "coordinate"), - db_dxil_param(5, "f", "coord1", "coordinate, undef for Texture1D"), - db_dxil_param(6, "f", "coord2", "coordinate, undef for Texture1D, Texture1DArray or Texture2D"), - db_dxil_param(7, "f", "coord3", "coordinate, defined only for TextureCubeArray"), - db_dxil_param(8, "i32", "offset0", "optional offset, applicable to Texture1D, Texture1DArray, and as part of offset1"), - db_dxil_param(9, "i32", "offset1", "optional offset, applicable to Texture2D, Texture2DArray, and as part of offset2"), - db_dxil_param(10, "i32", "offset2", "optional offset, applicable to Texture3D"), - db_dxil_param(11, "f", "LOD", "level of detail, biggest map if less than or equal to zero; fraction used to interpolate across levels")], - counters=('tex_norm',)) - next_op_idx += 1 - self.add_dxil_op("SampleGrad", next_op_idx, "SampleGrad", "samples a texture using a gradient to influence the way the sample location is calculated", "hfwi", "ro", [ - db_dxil_param(0, "$r", "", "the sampled value"), - db_dxil_param(2, "res", "srv", "handle of SRV to sample"), - db_dxil_param(3, "res", "sampler", "handle of sampler to use"), - db_dxil_param(4, "f", "coord0", "coordinate"), - db_dxil_param(5, "f", "coord1", "coordinate, undef for Texture1D"), - db_dxil_param(6, "f", "coord2", "coordinate, undef for Texture1D, Texture1DArray or Texture2D"), - db_dxil_param(7, "f", "coord3", "coordinate, defined only for TextureCubeArray"), - db_dxil_param(8, "i32", "offset0", "optional offset, applicable to Texture1D, Texture1DArray, and as part of offset1"), - db_dxil_param(9, "i32", "offset1", "optional offset, applicable to Texture2D, Texture2DArray, and as part of offset2"), - db_dxil_param(10, "i32", "offset2", "optional offset, applicable to Texture3D"), - db_dxil_param(11, "f", "ddx0", "rate of change of the texture coordinate in the x direction"), - db_dxil_param(12, "f", "ddx1", "rate of change of the texture coordinate in the x direction"), - db_dxil_param(13, "f", "ddx2", "rate of change of the texture coordinate in the x direction"), - db_dxil_param(14, "f", "ddy0", "rate of change of the texture coordinate in the y direction"), - db_dxil_param(15, "f", "ddy1", "rate of change of the texture coordinate in the y direction"), - db_dxil_param(16, "f", "ddy2", "rate of change of the texture coordinate in the y direction"), - db_dxil_param(17, "f", "clamp", "clamp value")], - counters=('tex_grad',)) - next_op_idx += 1 - self.add_dxil_op("SampleCmp", next_op_idx, "SampleCmp", "samples a texture and compares a single component against the specified comparison value", "hfwi", "ro", [ - db_dxil_param(0, "$r", "", "the value for the constant buffer variable"), - db_dxil_param(2, "res", "srv", "handle of SRV to sample"), - db_dxil_param(3, "res", "sampler", "handle of sampler to use"), - db_dxil_param(4, "f", "coord0", "coordinate"), - db_dxil_param(5, "f", "coord1", "coordinate, undef for Texture1D"), - db_dxil_param(6, "f", "coord2", "coordinate, undef for Texture1D, Texture1DArray or Texture2D"), - db_dxil_param(7, "f", "coord3", "coordinate, defined only for TextureCubeArray"), - db_dxil_param(8, "i32", "offset0", "optional offset, applicable to Texture1D, Texture1DArray, and as part of offset1"), - db_dxil_param(9, "i32", "offset1", "optional offset, applicable to Texture2D, Texture2DArray, and as part of offset2"), - db_dxil_param(10, "i32", "offset2", "optional offset, applicable to Texture3D"), - db_dxil_param(11, "f", "compareValue", "the value to compare with"), - db_dxil_param(12, "f", "clamp", "clamp value")], - counters=('tex_cmp',)) - next_op_idx += 1 - self.add_dxil_op("SampleCmpLevelZero", next_op_idx, "SampleCmpLevelZero", "samples a texture and compares a single component against the specified comparison value", "hfwi", "ro", [ - db_dxil_param(0, "$r", "", "the value for the constant buffer variable"), - db_dxil_param(2, "res", "srv", "handle of SRV to sample"), - db_dxil_param(3, "res", "sampler", "handle of sampler to use"), - db_dxil_param(4, "f", "coord0", "coordinate"), - db_dxil_param(5, "f", "coord1", "coordinate, undef for Texture1D"), - db_dxil_param(6, "f", "coord2", "coordinate, undef for Texture1D, Texture1DArray or Texture2D"), - db_dxil_param(7, "f", "coord3", "coordinate, defined only for TextureCubeArray"), - db_dxil_param(8, "i32", "offset0", "optional offset, applicable to Texture1D, Texture1DArray, and as part of offset1"), - db_dxil_param(9, "i32", "offset1", "optional offset, applicable to Texture2D, Texture2DArray, and as part of offset2"), - db_dxil_param(10, "i32", "offset2", "optional offset, applicable to Texture3D"), - db_dxil_param(11, "f", "compareValue", "the value to compare with")], - counters=('tex_cmp',)) - next_op_idx += 1 - self.add_dxil_op("TextureLoad", next_op_idx, "TextureLoad", "reads texel data without any filtering or sampling", "hfwi", "ro", [ - db_dxil_param(0, "$r", "", "the loaded value"), - db_dxil_param(2, "res", "srv", "handle of SRV or UAV to sample"), - db_dxil_param(3, "i32", "mipLevelOrSampleCount", "sample count for Texture2DMS, mip level otherwise"), - db_dxil_param(4, "i32", "coord0", "coordinate"), - db_dxil_param(5, "i32", "coord1", "coordinate"), - db_dxil_param(6, "i32", "coord2", "coordinate"), - db_dxil_param(7, "i32", "offset0", "optional offset"), - db_dxil_param(8, "i32", "offset1", "optional offset"), - db_dxil_param(9, "i32", "offset2", "optional offset")], - counters=('tex_load',)) - next_op_idx += 1 - self.add_dxil_op("TextureStore", next_op_idx, "TextureStore", "reads texel data without any filtering or sampling", "hfwi", "", [ - db_dxil_param(0, "v", "", ""), - db_dxil_param(2, "res", "srv", "handle of UAV to store to"), - db_dxil_param(3, "i32", "coord0", "coordinate"), - db_dxil_param(4, "i32", "coord1", "coordinate"), - db_dxil_param(5, "i32", "coord2", "coordinate"), - db_dxil_param(6, "$o", "value0", "value"), - db_dxil_param(7, "$o", "value1", "value"), - db_dxil_param(8, "$o", "value2", "value"), - db_dxil_param(9, "$o", "value3", "value"), - db_dxil_param(10,"i8", "mask", "written value mask")], - counters=('tex_store',)) - next_op_idx += 1 - self.add_dxil_op("BufferLoad", next_op_idx, "BufferLoad", "reads from a TypedBuffer", "hfwi", "ro", [ - db_dxil_param(0, "$r", "", "the loaded value"), - db_dxil_param(2, "res", "srv", "handle of TypedBuffer SRV to sample"), - db_dxil_param(3, "i32", "index", "element index"), - db_dxil_param(4, "i32", "wot", "coordinate")], - counters=('tex_load',)) - next_op_idx += 1 - self.add_dxil_op("BufferStore", next_op_idx, "BufferStore", "writes to a RWTypedBuffer", "hfwi", "", [ - db_dxil_param(0, "v", "", ""), - db_dxil_param(2, "res", "uav", "handle of UAV to store to"), - db_dxil_param(3, "i32", "coord0", "coordinate in elements"), - db_dxil_param(4, "i32", "coord1", "coordinate (unused?)"), - db_dxil_param(5, "$o", "value0", "value"), - db_dxil_param(6, "$o", "value1", "value"), - db_dxil_param(7, "$o", "value2", "value"), - db_dxil_param(8, "$o", "value3", "value"), - db_dxil_param(9, "i8", "mask", "written value mask")], - counters=('tex_store',)) - next_op_idx += 1 - self.add_dxil_op("BufferUpdateCounter", next_op_idx, "BufferUpdateCounter", "atomically increments/decrements the hidden 32-bit counter stored with a Count or Append UAV", "v", "", [ - db_dxil_param(0, "i32", "", "the new value in the buffer"), - db_dxil_param(2, "res", "uav", "handle to a structured buffer UAV with the count or append flag"), - db_dxil_param(3, "i8", "inc", "1 to increase, 0 to decrease")], - counters=('atomic',)) - next_op_idx += 1 - self.add_dxil_op("CheckAccessFullyMapped", next_op_idx, "CheckAccessFullyMapped", "determines whether all values from a Sample, Gather, or Load operation accessed mapped tiles in a tiled resource", "i", "ro", [ - db_dxil_param(0, "i1", "", "nonzero if all values accessed mapped tiles in a tiled resource"), - db_dxil_param(2, "u32", "status", "status result from the Sample, Gather or Load operation")]) - next_op_idx += 1 - self.add_dxil_op("GetDimensions", next_op_idx, "GetDimensions", "gets texture size information", "v", "ro", [ - db_dxil_param(0, "dims", "", "dimension information for texture"), - db_dxil_param(2, "res", "handle", "resource handle to query"), - db_dxil_param(3, "i32", "mipLevel", "mip level to query")]) - next_op_idx += 1 - self.add_dxil_op("TextureGather", next_op_idx, "TextureGather", "gathers the four texels that would be used in a bi-linear filtering operation", "hfwi", "ro", [ - db_dxil_param(0, "$r", "", "dimension information for texture"), - db_dxil_param(2, "res", "srv", "handle of SRV to sample"), - db_dxil_param(3, "res", "sampler", "handle of sampler to use"), - db_dxil_param(4, "f", "coord0", "coordinate"), - db_dxil_param(5, "f", "coord1", "coordinate, undef for Texture1D"), - db_dxil_param(6, "f", "coord2", "coordinate, undef for Texture1D, Texture1DArray or Texture2D"), - db_dxil_param(7, "f", "coord3", "coordinate, defined only for TextureCubeArray"), - db_dxil_param(8, "i32", "offset0", "optional offset, applicable to Texture1D, Texture1DArray, and as part of offset1"), - db_dxil_param(9, "i32", "offset1", "optional offset, applicable to Texture2D, Texture2DArray, and as part of offset2"), - db_dxil_param(10, "i32", "channel", "channel to sample")], - counters=('tex_norm',)) - next_op_idx += 1 - self.add_dxil_op("TextureGatherCmp", next_op_idx, "TextureGatherCmp", "same as TextureGather, except this instrution performs comparison on texels, similar to SampleCmp", "hfwi", "ro", [ - db_dxil_param(0, "$r", "", "gathered texels"), - db_dxil_param(2, "res", "srv", "handle of SRV to sample"), - db_dxil_param(3, "res", "sampler", "handle of sampler to use"), - db_dxil_param(4, "f", "coord0", "coordinate"), - db_dxil_param(5, "f", "coord1", "coordinate, undef for Texture1D"), - db_dxil_param(6, "f", "coord2", "coordinate, undef for Texture1D, Texture1DArray or Texture2D"), - db_dxil_param(7, "f", "coord3", "coordinate, defined only for TextureCubeArray"), - db_dxil_param(8, "i32", "offset0", "optional offset, applicable to Texture1D, Texture1DArray, and as part of offset1"), - db_dxil_param(9, "i32", "offset1", "optional offset, applicable to Texture2D, Texture2DArray, and as part of offset2"), - db_dxil_param(10, "i32", "channel", "channel to sample"), - db_dxil_param(11, "f", "compareValue", "value to compare with")], - counters=('tex_cmp',)) - next_op_idx += 1 - - self.add_dxil_op("Texture2DMSGetSamplePosition", next_op_idx, "Texture2DMSGetSamplePosition", "gets the position of the specified sample", "v", "ro", [ - db_dxil_param(0, "SamplePos", "", "sample position"), - db_dxil_param(2, "res", "srv", "handle of SRV to sample"), - db_dxil_param(3, "i32", "index", "zero-based sample index")]) - next_op_idx += 1 - self.add_dxil_op("RenderTargetGetSamplePosition", next_op_idx, "RenderTargetGetSamplePosition", "gets the position of the specified sample", "v", "ro", [ - db_dxil_param(0, "SamplePos", "", "sample position"), - db_dxil_param(2, "i32", "index", "zero-based sample index")]) - next_op_idx += 1 - self.add_dxil_op("RenderTargetGetSampleCount", next_op_idx, "RenderTargetGetSampleCount", "gets the number of samples for a render target", "v", "ro", [ - db_dxil_param(0, "u32", "", "number of sampling locations for a render target")]) + self.add_dxil_op( + "CreateHandle", + next_op_idx, + "CreateHandle", + "creates the handle to a resource", + "v", + "ro", + [ + db_dxil_param(0, "res", "", "the handle to the resource"), + db_dxil_param( + 2, + "i8", + "resourceClass", + "the class of resource to create (SRV, UAV, CBuffer, Sampler)", + is_const=True, + ), # maps to DxilResourceBase::Class + db_dxil_param( + 3, "i32", "rangeId", "range identifier for resource", is_const=True + ), + db_dxil_param(4, "i32", "index", "zero-based index into range"), + db_dxil_param( + 5, + "i1", + "nonUniformIndex", + "non-uniform resource index", + is_const=True, + ), + ], + ) + next_op_idx += 1 + self.add_dxil_op( + "CBufferLoad", + next_op_idx, + "CBufferLoad", + "loads a value from a constant buffer resource", + "hfd8wil", + "ro", + [ + db_dxil_param( + 0, "$o", "", "the value for the constant buffer variable" + ), + db_dxil_param(2, "res", "handle", "cbuffer handle"), + db_dxil_param(3, "u32", "byteOffset", "linear byte offset of value"), + db_dxil_param( + 4, "u32", "alignment", "load access alignment", is_const=True + ), + ], + ) + next_op_idx += 1 + self.add_dxil_op( + "CBufferLoadLegacy", + next_op_idx, + "CBufferLoadLegacy", + "loads a value from a constant buffer resource", + "hfdwil", + "ro", + [ + db_dxil_param( + 0, "$cb", "", "the value for the constant buffer variable" + ), + db_dxil_param(2, "res", "handle", "cbuffer handle"), + db_dxil_param( + 3, "u32", "regIndex", "0-based index into cbuffer instance" + ), + ], + ) + next_op_idx += 1 + self.add_dxil_op( + "Sample", + next_op_idx, + "Sample", + "samples a texture", + "hfwi", + "ro", + [ + db_dxil_param(0, "$r", "", "the sampled value"), + db_dxil_param(2, "res", "srv", "handle of SRV to sample"), + db_dxil_param(3, "res", "sampler", "handle of sampler to use"), + db_dxil_param(4, "f", "coord0", "coordinate"), + db_dxil_param(5, "f", "coord1", "coordinate, undef for Texture1D"), + db_dxil_param( + 6, + "f", + "coord2", + "coordinate, undef for Texture1D, Texture1DArray or Texture2D", + ), + db_dxil_param( + 7, "f", "coord3", "coordinate, defined only for TextureCubeArray" + ), + db_dxil_param( + 8, + "i32", + "offset0", + "optional offset, applicable to Texture1D, Texture1DArray, and as part of offset1", + ), + db_dxil_param( + 9, + "i32", + "offset1", + "optional offset, applicable to Texture2D, Texture2DArray, and as part of offset2", + ), + db_dxil_param( + 10, "i32", "offset2", "optional offset, applicable to Texture3D" + ), + db_dxil_param(11, "f", "clamp", "clamp value"), + ], + counters=("tex_norm",), + ) + next_op_idx += 1 + self.add_dxil_op( + "SampleBias", + next_op_idx, + "SampleBias", + "samples a texture after applying the input bias to the mipmap level", + "hfwi", + "ro", + [ + db_dxil_param(0, "$r", "", "the sampled value"), + db_dxil_param(2, "res", "srv", "handle of SRV to sample"), + db_dxil_param(3, "res", "sampler", "handle of sampler to use"), + db_dxil_param(4, "f", "coord0", "coordinate"), + db_dxil_param(5, "f", "coord1", "coordinate, undef for Texture1D"), + db_dxil_param( + 6, + "f", + "coord2", + "coordinate, undef for Texture1D, Texture1DArray or Texture2D", + ), + db_dxil_param( + 7, "f", "coord3", "coordinate, defined only for TextureCubeArray" + ), + db_dxil_param( + 8, + "i32", + "offset0", + "optional offset, applicable to Texture1D, Texture1DArray, and as part of offset1", + ), + db_dxil_param( + 9, + "i32", + "offset1", + "optional offset, applicable to Texture2D, Texture2DArray, and as part of offset2", + ), + db_dxil_param( + 10, "i32", "offset2", "optional offset, applicable to Texture3D" + ), + db_dxil_param(11, "f", "bias", "bias value"), + db_dxil_param(12, "f", "clamp", "clamp value"), + ], + counters=("tex_bias",), + ) + next_op_idx += 1 + self.add_dxil_op( + "SampleLevel", + next_op_idx, + "SampleLevel", + "samples a texture using a mipmap-level offset", + "hfwi", + "ro", + [ + db_dxil_param(0, "$r", "", "the sampled value"), + db_dxil_param(2, "res", "srv", "handle of SRV to sample"), + db_dxil_param(3, "res", "sampler", "handle of sampler to use"), + db_dxil_param(4, "f", "coord0", "coordinate"), + db_dxil_param(5, "f", "coord1", "coordinate, undef for Texture1D"), + db_dxil_param( + 6, + "f", + "coord2", + "coordinate, undef for Texture1D, Texture1DArray or Texture2D", + ), + db_dxil_param( + 7, "f", "coord3", "coordinate, defined only for TextureCubeArray" + ), + db_dxil_param( + 8, + "i32", + "offset0", + "optional offset, applicable to Texture1D, Texture1DArray, and as part of offset1", + ), + db_dxil_param( + 9, + "i32", + "offset1", + "optional offset, applicable to Texture2D, Texture2DArray, and as part of offset2", + ), + db_dxil_param( + 10, "i32", "offset2", "optional offset, applicable to Texture3D" + ), + db_dxil_param( + 11, + "f", + "LOD", + "level of detail, biggest map if less than or equal to zero; fraction used to interpolate across levels", + ), + ], + counters=("tex_norm",), + ) + next_op_idx += 1 + self.add_dxil_op( + "SampleGrad", + next_op_idx, + "SampleGrad", + "samples a texture using a gradient to influence the way the sample location is calculated", + "hfwi", + "ro", + [ + db_dxil_param(0, "$r", "", "the sampled value"), + db_dxil_param(2, "res", "srv", "handle of SRV to sample"), + db_dxil_param(3, "res", "sampler", "handle of sampler to use"), + db_dxil_param(4, "f", "coord0", "coordinate"), + db_dxil_param(5, "f", "coord1", "coordinate, undef for Texture1D"), + db_dxil_param( + 6, + "f", + "coord2", + "coordinate, undef for Texture1D, Texture1DArray or Texture2D", + ), + db_dxil_param( + 7, "f", "coord3", "coordinate, defined only for TextureCubeArray" + ), + db_dxil_param( + 8, + "i32", + "offset0", + "optional offset, applicable to Texture1D, Texture1DArray, and as part of offset1", + ), + db_dxil_param( + 9, + "i32", + "offset1", + "optional offset, applicable to Texture2D, Texture2DArray, and as part of offset2", + ), + db_dxil_param( + 10, "i32", "offset2", "optional offset, applicable to Texture3D" + ), + db_dxil_param( + 11, + "f", + "ddx0", + "rate of change of the texture coordinate in the x direction", + ), + db_dxil_param( + 12, + "f", + "ddx1", + "rate of change of the texture coordinate in the x direction", + ), + db_dxil_param( + 13, + "f", + "ddx2", + "rate of change of the texture coordinate in the x direction", + ), + db_dxil_param( + 14, + "f", + "ddy0", + "rate of change of the texture coordinate in the y direction", + ), + db_dxil_param( + 15, + "f", + "ddy1", + "rate of change of the texture coordinate in the y direction", + ), + db_dxil_param( + 16, + "f", + "ddy2", + "rate of change of the texture coordinate in the y direction", + ), + db_dxil_param(17, "f", "clamp", "clamp value"), + ], + counters=("tex_grad",), + ) + next_op_idx += 1 + self.add_dxil_op( + "SampleCmp", + next_op_idx, + "SampleCmp", + "samples a texture and compares a single component against the specified comparison value", + "hf", + "ro", + [ + db_dxil_param( + 0, "$r", "", "the value for the constant buffer variable" + ), + db_dxil_param(2, "res", "srv", "handle of SRV to sample"), + db_dxil_param(3, "res", "sampler", "handle of sampler to use"), + db_dxil_param(4, "f", "coord0", "coordinate"), + db_dxil_param(5, "f", "coord1", "coordinate, undef for Texture1D"), + db_dxil_param( + 6, + "f", + "coord2", + "coordinate, undef for Texture1D, Texture1DArray or Texture2D", + ), + db_dxil_param( + 7, "f", "coord3", "coordinate, defined only for TextureCubeArray" + ), + db_dxil_param( + 8, + "i32", + "offset0", + "optional offset, applicable to Texture1D, Texture1DArray, and as part of offset1", + ), + db_dxil_param( + 9, + "i32", + "offset1", + "optional offset, applicable to Texture2D, Texture2DArray, and as part of offset2", + ), + db_dxil_param( + 10, "i32", "offset2", "optional offset, applicable to Texture3D" + ), + db_dxil_param(11, "f", "compareValue", "the value to compare with"), + db_dxil_param(12, "f", "clamp", "clamp value"), + ], + counters=("tex_cmp",), + ) + next_op_idx += 1 + self.add_dxil_op( + "SampleCmpLevelZero", + next_op_idx, + "SampleCmpLevelZero", + "samples a texture and compares a single component against the specified comparison value", + "hf", + "ro", + [ + db_dxil_param( + 0, "$r", "", "the value for the constant buffer variable" + ), + db_dxil_param(2, "res", "srv", "handle of SRV to sample"), + db_dxil_param(3, "res", "sampler", "handle of sampler to use"), + db_dxil_param(4, "f", "coord0", "coordinate"), + db_dxil_param(5, "f", "coord1", "coordinate, undef for Texture1D"), + db_dxil_param( + 6, + "f", + "coord2", + "coordinate, undef for Texture1D, Texture1DArray or Texture2D", + ), + db_dxil_param( + 7, "f", "coord3", "coordinate, defined only for TextureCubeArray" + ), + db_dxil_param( + 8, + "i32", + "offset0", + "optional offset, applicable to Texture1D, Texture1DArray, and as part of offset1", + ), + db_dxil_param( + 9, + "i32", + "offset1", + "optional offset, applicable to Texture2D, Texture2DArray, and as part of offset2", + ), + db_dxil_param( + 10, "i32", "offset2", "optional offset, applicable to Texture3D" + ), + db_dxil_param(11, "f", "compareValue", "the value to compare with"), + ], + counters=("tex_cmp",), + ) + next_op_idx += 1 + self.add_dxil_op( + "TextureLoad", + next_op_idx, + "TextureLoad", + "reads texel data without any filtering or sampling", + "hfwi", + "ro", + [ + db_dxil_param(0, "$r", "", "the loaded value"), + db_dxil_param(2, "res", "srv", "handle of SRV or UAV to sample"), + db_dxil_param( + 3, + "i32", + "mipLevelOrSampleCount", + "sample count for Texture2DMS, mip level otherwise", + ), + db_dxil_param(4, "i32", "coord0", "coordinate"), + db_dxil_param(5, "i32", "coord1", "coordinate"), + db_dxil_param(6, "i32", "coord2", "coordinate"), + db_dxil_param(7, "i32", "offset0", "optional offset"), + db_dxil_param(8, "i32", "offset1", "optional offset"), + db_dxil_param(9, "i32", "offset2", "optional offset"), + ], + counters=("tex_load",), + ) + next_op_idx += 1 + self.add_dxil_op( + "TextureStore", + next_op_idx, + "TextureStore", + "reads texel data without any filtering or sampling", + "hfwi", + "", + [ + db_dxil_param(0, "v", "", ""), + db_dxil_param(2, "res", "srv", "handle of UAV to store to"), + db_dxil_param(3, "i32", "coord0", "coordinate"), + db_dxil_param(4, "i32", "coord1", "coordinate"), + db_dxil_param(5, "i32", "coord2", "coordinate"), + db_dxil_param(6, "$o", "value0", "value"), + db_dxil_param(7, "$o", "value1", "value"), + db_dxil_param(8, "$o", "value2", "value"), + db_dxil_param(9, "$o", "value3", "value"), + db_dxil_param(10, "i8", "mask", "written value mask"), + ], + counters=("tex_store",), + ) + next_op_idx += 1 + self.add_dxil_op( + "BufferLoad", + next_op_idx, + "BufferLoad", + "reads from a TypedBuffer", + "hfwi", + "ro", + [ + db_dxil_param(0, "$r", "", "the loaded value"), + db_dxil_param(2, "res", "srv", "handle of TypedBuffer SRV to sample"), + db_dxil_param(3, "i32", "index", "element index"), + db_dxil_param(4, "i32", "wot", "coordinate"), + ], + counters=("tex_load",), + ) + next_op_idx += 1 + self.add_dxil_op( + "BufferStore", + next_op_idx, + "BufferStore", + "writes to a RWTypedBuffer", + "hfwi", + "", + [ + db_dxil_param(0, "v", "", ""), + db_dxil_param(2, "res", "uav", "handle of UAV to store to"), + db_dxil_param(3, "i32", "coord0", "coordinate in elements"), + db_dxil_param(4, "i32", "coord1", "coordinate (unused?)"), + db_dxil_param(5, "$o", "value0", "value"), + db_dxil_param(6, "$o", "value1", "value"), + db_dxil_param(7, "$o", "value2", "value"), + db_dxil_param(8, "$o", "value3", "value"), + db_dxil_param(9, "i8", "mask", "written value mask"), + ], + counters=("tex_store",), + ) + next_op_idx += 1 + self.add_dxil_op( + "BufferUpdateCounter", + next_op_idx, + "BufferUpdateCounter", + "atomically increments/decrements the hidden 32-bit counter stored with a Count or Append UAV", + "v", + "", + [ + db_dxil_param(0, "i32", "", "the new value in the buffer"), + db_dxil_param( + 2, + "res", + "uav", + "handle to a structured buffer UAV with the count or append flag", + ), + db_dxil_param(3, "i8", "inc", "1 to increase, 0 to decrease"), + ], + counters=("atomic",), + ) + next_op_idx += 1 + self.add_dxil_op( + "CheckAccessFullyMapped", + next_op_idx, + "CheckAccessFullyMapped", + "determines whether all values from a Sample, Gather, or Load operation accessed mapped tiles in a tiled resource", + "i", + "ro", + [ + db_dxil_param( + 0, + "i1", + "", + "nonzero if all values accessed mapped tiles in a tiled resource", + ), + db_dxil_param( + 2, + "u32", + "status", + "status result from the Sample, Gather or Load operation", + ), + ], + ) + next_op_idx += 1 + self.add_dxil_op( + "GetDimensions", + next_op_idx, + "GetDimensions", + "gets texture size information", + "v", + "ro", + [ + db_dxil_param(0, "dims", "", "dimension information for texture"), + db_dxil_param(2, "res", "handle", "resource handle to query"), + db_dxil_param(3, "i32", "mipLevel", "mip level to query"), + ], + ) + next_op_idx += 1 + self.add_dxil_op( + "TextureGather", + next_op_idx, + "TextureGather", + "gathers the four texels that would be used in a bi-linear filtering operation", + "hfwi", + "ro", + [ + db_dxil_param(0, "$r", "", "dimension information for texture"), + db_dxil_param(2, "res", "srv", "handle of SRV to sample"), + db_dxil_param(3, "res", "sampler", "handle of sampler to use"), + db_dxil_param(4, "f", "coord0", "coordinate"), + db_dxil_param(5, "f", "coord1", "coordinate, undef for Texture1D"), + db_dxil_param( + 6, + "f", + "coord2", + "coordinate, undef for Texture1D, Texture1DArray or Texture2D", + ), + db_dxil_param( + 7, "f", "coord3", "coordinate, defined only for TextureCubeArray" + ), + db_dxil_param( + 8, + "i32", + "offset0", + "optional offset, applicable to Texture1D, Texture1DArray, and as part of offset1", + ), + db_dxil_param( + 9, + "i32", + "offset1", + "optional offset, applicable to Texture2D, Texture2DArray, and as part of offset2", + ), + db_dxil_param(10, "i32", "channel", "channel to sample"), + ], + counters=("tex_norm",), + ) + next_op_idx += 1 + self.add_dxil_op( + "TextureGatherCmp", + next_op_idx, + "TextureGatherCmp", + "same as TextureGather, except this instrution performs comparison on texels, similar to SampleCmp", + "hfwi", + "ro", + [ + db_dxil_param(0, "$r", "", "gathered texels"), + db_dxil_param(2, "res", "srv", "handle of SRV to sample"), + db_dxil_param(3, "res", "sampler", "handle of sampler to use"), + db_dxil_param(4, "f", "coord0", "coordinate"), + db_dxil_param(5, "f", "coord1", "coordinate, undef for Texture1D"), + db_dxil_param( + 6, + "f", + "coord2", + "coordinate, undef for Texture1D, Texture1DArray or Texture2D", + ), + db_dxil_param( + 7, "f", "coord3", "coordinate, defined only for TextureCubeArray" + ), + db_dxil_param( + 8, + "i32", + "offset0", + "optional offset, applicable to Texture1D, Texture1DArray, and as part of offset1", + ), + db_dxil_param( + 9, + "i32", + "offset1", + "optional offset, applicable to Texture2D, Texture2DArray, and as part of offset2", + ), + db_dxil_param(10, "i32", "channel", "channel to sample"), + db_dxil_param(11, "f", "compareValue", "value to compare with"), + ], + counters=("tex_cmp",), + ) + next_op_idx += 1 + + self.add_dxil_op( + "Texture2DMSGetSamplePosition", + next_op_idx, + "Texture2DMSGetSamplePosition", + "gets the position of the specified sample", + "v", + "ro", + [ + db_dxil_param(0, "SamplePos", "", "sample position"), + db_dxil_param(2, "res", "srv", "handle of SRV to sample"), + db_dxil_param(3, "i32", "index", "zero-based sample index"), + ], + ) + next_op_idx += 1 + self.add_dxil_op( + "RenderTargetGetSamplePosition", + next_op_idx, + "RenderTargetGetSamplePosition", + "gets the position of the specified sample", + "v", + "ro", + [ + db_dxil_param(0, "SamplePos", "", "sample position"), + db_dxil_param(2, "i32", "index", "zero-based sample index"), + ], + ) + next_op_idx += 1 + self.add_dxil_op( + "RenderTargetGetSampleCount", + next_op_idx, + "RenderTargetGetSampleCount", + "gets the number of samples for a render target", + "v", + "ro", + [ + db_dxil_param( + 0, "u32", "", "number of sampling locations for a render target" + ) + ], + ) next_op_idx += 1 # Atomics. Note that on TGSM, atomics are performed with LLVM instructions. - self.add_dxil_op("AtomicBinOp", next_op_idx, "AtomicBinOp", "performs an atomic operation on two operands", "li", "", [ - db_dxil_param(0, "$o", "", "the original value in the location updated"), - db_dxil_param(2, "res", "handle", "typed int or uint UAV handle"), - db_dxil_param(3, "i32", "atomicOp", "atomic operation as per DXIL::AtomicBinOpCode"), - db_dxil_param(4, "i32", "offset0", "offset in elements"), - db_dxil_param(5, "i32", "offset1", "offset"), - db_dxil_param(6, "i32", "offset2", "offset"), - db_dxil_param(7, "$o", "newValue", "new value")], - counters=('atomic',)) - next_op_idx += 1 - self.add_dxil_op("AtomicCompareExchange", next_op_idx, "AtomicCompareExchange", "atomic compare and exchange to memory", "li", "", [ - db_dxil_param(0, "$o", "", "the original value in the location updated"), - db_dxil_param(2, "res", "handle", "typed int or uint UAV handle"), - db_dxil_param(3, "i32", "offset0", "offset in elements"), - db_dxil_param(4, "i32", "offset1", "offset"), - db_dxil_param(5, "i32", "offset2", "offset"), - db_dxil_param(6, "$o", "compareValue", "value to compare for exchange"), - db_dxil_param(7, "$o", "newValue", "new value")], - counters=('atomic',)) + self.add_dxil_op( + "AtomicBinOp", + next_op_idx, + "AtomicBinOp", + "performs an atomic operation on two operands", + "li", + "", + [ + db_dxil_param( + 0, "$o", "", "the original value in the location updated" + ), + db_dxil_param(2, "res", "handle", "typed int or uint UAV handle"), + db_dxil_param( + 3, + "i32", + "atomicOp", + "atomic operation as per DXIL::AtomicBinOpCode", + ), + db_dxil_param(4, "i32", "offset0", "offset in elements"), + db_dxil_param(5, "i32", "offset1", "offset"), + db_dxil_param(6, "i32", "offset2", "offset"), + db_dxil_param(7, "$o", "newValue", "new value"), + ], + counters=("atomic",), + ) + next_op_idx += 1 + self.add_dxil_op( + "AtomicCompareExchange", + next_op_idx, + "AtomicCompareExchange", + "atomic compare and exchange to memory", + "li", + "", + [ + db_dxil_param( + 0, "$o", "", "the original value in the location updated" + ), + db_dxil_param(2, "res", "handle", "typed int or uint UAV handle"), + db_dxil_param(3, "i32", "offset0", "offset in elements"), + db_dxil_param(4, "i32", "offset1", "offset"), + db_dxil_param(5, "i32", "offset2", "offset"), + db_dxil_param(6, "$o", "compareValue", "value to compare for exchange"), + db_dxil_param(7, "$o", "newValue", "new value"), + ], + counters=("atomic",), + ) next_op_idx += 1 # Synchronization. - self.add_dxil_op("Barrier", next_op_idx, "Barrier", "inserts a memory barrier in the shader", "v", "nd", [ - retvoid_param, - db_dxil_param(2, "i32", "barrierMode", "a mask of DXIL::BarrierMode values", is_const=True)], - counters=('barrier',)) + self.add_dxil_op( + "Barrier", + next_op_idx, + "Barrier", + "inserts a memory barrier in the shader", + "v", + "nd", + [ + retvoid_param, + db_dxil_param( + 2, + "i32", + "barrierMode", + "a mask of DXIL::BarrierMode values", + is_const=True, + ), + ], + counters=("barrier",), + ) next_op_idx += 1 # Pixel shader - self.add_dxil_op("CalculateLOD", next_op_idx, "CalculateLOD", "calculates the level of detail", "f", "ro", [ - db_dxil_param(0, "f", "", "level of detail"), - db_dxil_param(2, "res", "handle", "resource handle"), - db_dxil_param(3, "res", "sampler", "sampler handle"), - db_dxil_param(4, "f", "coord0", "coordinate"), - db_dxil_param(5, "f", "coord1", "coordinate"), - db_dxil_param(6, "f", "coord2", "coordinate"), - db_dxil_param(7, "i1", "clamped", "1 if clampled LOD should be calculated, 0 for unclamped")]) - next_op_idx += 1 - self.add_dxil_op("Discard", next_op_idx, "Discard", "discard the current pixel", "v", "", [ - retvoid_param, - db_dxil_param(2, "i1", "condition", "condition for conditional discard")]) - next_op_idx += 1 - self.add_dxil_op("DerivCoarseX", next_op_idx, "Unary", "computes the rate of change of components per stamp", "hf", "rn", [ - db_dxil_param(0, "$o", "", "rate of change in value with regards to RenderTarget x direction"), - db_dxil_param(2, "$o", "value", "input to rate of change")]) - next_op_idx += 1 - self.add_dxil_op("DerivCoarseY", next_op_idx, "Unary", "computes the rate of change of components per stamp", "hf", "rn", [ - db_dxil_param(0, "$o", "", "rate of change in value with regards to RenderTarget y direction"), - db_dxil_param(2, "$o", "value", "input to rate of change")]) - next_op_idx += 1 - self.add_dxil_op("DerivFineX", next_op_idx, "Unary", "computes the rate of change of components per pixel", "hf", "rn", [ - db_dxil_param(0, "$o", "", "rate of change in value with regards to RenderTarget x direction"), - db_dxil_param(2, "$o", "value", "input to rate of change")]) - next_op_idx += 1 - self.add_dxil_op("DerivFineY", next_op_idx, "Unary", "computes the rate of change of components per pixel", "hf", "rn", [ - db_dxil_param(0, "$o", "", "rate of change in value with regards to RenderTarget y direction"), - db_dxil_param(2, "$o", "value", "input to rate of change")]) - next_op_idx += 1 - self.add_dxil_op("EvalSnapped", next_op_idx, "EvalSnapped", "evaluates an input attribute at pixel center with an offset", "hf", "rn", [ - db_dxil_param(0, "$o", "", "result"), - db_dxil_param(2, "i32", "inputSigId", "input signature element ID"), - db_dxil_param(3, "i32", "inputRowIndex", "row index of an input attribute"), - db_dxil_param(4, "i8", "inputColIndex", "column index of an input attribute"), - db_dxil_param(5, "i32", "offsetX", "2D offset from the pixel center using a 16x16 grid"), - db_dxil_param(6, "i32", "offsetY", "2D offset from the pixel center using a 16x16 grid")]) - next_op_idx += 1 - self.add_dxil_op("EvalSampleIndex", next_op_idx, "EvalSampleIndex", "evaluates an input attribute at a sample location", "hf", "rn", [ - db_dxil_param(0, "$o", "", "result"), - db_dxil_param(2, "i32", "inputSigId", "input signature element ID"), - db_dxil_param(3, "i32", "inputRowIndex", "row index of an input attribute"), - db_dxil_param(4, "i8", "inputColIndex", "column index of an input attribute"), - db_dxil_param(5, "i32", "sampleIndex", "sample location")]) - next_op_idx += 1 - self.add_dxil_op("EvalCentroid", next_op_idx, "EvalCentroid", "evaluates an input attribute at pixel center", "hf", "rn", [ - db_dxil_param(0, "$o", "", "result"), - db_dxil_param(2, "i32", "inputSigId", "input signature element ID"), - db_dxil_param(3, "i32", "inputRowIndex", "row index of an input attribute"), - db_dxil_param(4, "i8", "inputColIndex", "column index of an input attribute")]) - next_op_idx += 1 - self.add_dxil_op("SampleIndex", next_op_idx, "SampleIndex", "returns the sample index in a sample-frequency pixel shader", "i", "rn", [ - db_dxil_param(0, "i32", "", "result")]) - next_op_idx += 1 - self.add_dxil_op("Coverage", next_op_idx, "Coverage", "returns the coverage mask input in a pixel shader", "i", "rn", [ - db_dxil_param(0, "i32", "", "result")]) - next_op_idx += 1 - self.add_dxil_op("InnerCoverage", next_op_idx, "InnerCoverage", "returns underestimated coverage input from conservative rasterization in a pixel shader", "i", "rn", [ - db_dxil_param(0, "i32", "", "result")]) + self.add_dxil_op( + "CalculateLOD", + next_op_idx, + "CalculateLOD", + "calculates the level of detail", + "f", + "ro", + [ + db_dxil_param(0, "f", "", "level of detail"), + db_dxil_param(2, "res", "handle", "resource handle"), + db_dxil_param(3, "res", "sampler", "sampler handle"), + db_dxil_param(4, "f", "coord0", "coordinate"), + db_dxil_param(5, "f", "coord1", "coordinate"), + db_dxil_param(6, "f", "coord2", "coordinate"), + db_dxil_param( + 7, + "i1", + "clamped", + "1 if clampled LOD should be calculated, 0 for unclamped", + ), + ], + ) + next_op_idx += 1 + self.add_dxil_op( + "Discard", + next_op_idx, + "Discard", + "discard the current pixel", + "v", + "", + [ + retvoid_param, + db_dxil_param( + 2, "i1", "condition", "condition for conditional discard" + ), + ], + ) + next_op_idx += 1 + self.add_dxil_op( + "DerivCoarseX", + next_op_idx, + "Unary", + "computes the rate of change of components per stamp", + "hf", + "rn", + [ + db_dxil_param( + 0, + "$o", + "", + "rate of change in value with regards to RenderTarget x direction", + ), + db_dxil_param(2, "$o", "value", "input to rate of change"), + ], + ) + next_op_idx += 1 + self.add_dxil_op( + "DerivCoarseY", + next_op_idx, + "Unary", + "computes the rate of change of components per stamp", + "hf", + "rn", + [ + db_dxil_param( + 0, + "$o", + "", + "rate of change in value with regards to RenderTarget y direction", + ), + db_dxil_param(2, "$o", "value", "input to rate of change"), + ], + ) + next_op_idx += 1 + self.add_dxil_op( + "DerivFineX", + next_op_idx, + "Unary", + "computes the rate of change of components per pixel", + "hf", + "rn", + [ + db_dxil_param( + 0, + "$o", + "", + "rate of change in value with regards to RenderTarget x direction", + ), + db_dxil_param(2, "$o", "value", "input to rate of change"), + ], + ) + next_op_idx += 1 + self.add_dxil_op( + "DerivFineY", + next_op_idx, + "Unary", + "computes the rate of change of components per pixel", + "hf", + "rn", + [ + db_dxil_param( + 0, + "$o", + "", + "rate of change in value with regards to RenderTarget y direction", + ), + db_dxil_param(2, "$o", "value", "input to rate of change"), + ], + ) + next_op_idx += 1 + self.add_dxil_op( + "EvalSnapped", + next_op_idx, + "EvalSnapped", + "evaluates an input attribute at pixel center with an offset", + "hf", + "rn", + [ + db_dxil_param(0, "$o", "", "result"), + db_dxil_param(2, "i32", "inputSigId", "input signature element ID"), + db_dxil_param( + 3, "i32", "inputRowIndex", "row index of an input attribute" + ), + db_dxil_param( + 4, "i8", "inputColIndex", "column index of an input attribute" + ), + db_dxil_param( + 5, + "i32", + "offsetX", + "2D offset from the pixel center using a 16x16 grid", + ), + db_dxil_param( + 6, + "i32", + "offsetY", + "2D offset from the pixel center using a 16x16 grid", + ), + ], + ) + next_op_idx += 1 + self.add_dxil_op( + "EvalSampleIndex", + next_op_idx, + "EvalSampleIndex", + "evaluates an input attribute at a sample location", + "hf", + "rn", + [ + db_dxil_param(0, "$o", "", "result"), + db_dxil_param(2, "i32", "inputSigId", "input signature element ID"), + db_dxil_param( + 3, "i32", "inputRowIndex", "row index of an input attribute" + ), + db_dxil_param( + 4, "i8", "inputColIndex", "column index of an input attribute" + ), + db_dxil_param(5, "i32", "sampleIndex", "sample location"), + ], + ) + next_op_idx += 1 + self.add_dxil_op( + "EvalCentroid", + next_op_idx, + "EvalCentroid", + "evaluates an input attribute at pixel center", + "hf", + "rn", + [ + db_dxil_param(0, "$o", "", "result"), + db_dxil_param(2, "i32", "inputSigId", "input signature element ID"), + db_dxil_param( + 3, "i32", "inputRowIndex", "row index of an input attribute" + ), + db_dxil_param( + 4, "i8", "inputColIndex", "column index of an input attribute" + ), + ], + ) + next_op_idx += 1 + self.add_dxil_op( + "SampleIndex", + next_op_idx, + "SampleIndex", + "returns the sample index in a sample-frequency pixel shader", + "i", + "rn", + [db_dxil_param(0, "i32", "", "result")], + ) + next_op_idx += 1 + self.add_dxil_op( + "Coverage", + next_op_idx, + "Coverage", + "returns the coverage mask input in a pixel shader", + "i", + "rn", + [db_dxil_param(0, "i32", "", "result")], + ) + next_op_idx += 1 + self.add_dxil_op( + "InnerCoverage", + next_op_idx, + "InnerCoverage", + "returns underestimated coverage input from conservative rasterization in a pixel shader", + "i", + "rn", + [db_dxil_param(0, "i32", "", "result")], + ) next_op_idx += 1 # Compute shader. - self.add_dxil_op("ThreadId", next_op_idx, "ThreadId", "reads the thread ID", "i", "rn", [ - db_dxil_param(0, "i32", "", "thread ID component"), - db_dxil_param(2, "i32", "component", "component to read (x,y,z)")]) - next_op_idx += 1 - self.add_dxil_op("GroupId", next_op_idx, "GroupId", "reads the group ID (SV_GroupID)", "i", "rn", [ - db_dxil_param(0, "i32", "", "group ID component"), - db_dxil_param(2, "i32", "component", "component to read")]) - next_op_idx += 1 - self.add_dxil_op("ThreadIdInGroup", next_op_idx, "ThreadIdInGroup", "reads the thread ID within the group (SV_GroupThreadID)", "i", "rn", [ - db_dxil_param(0, "i32", "", "thread ID in group component"), - db_dxil_param(2, "i32", "component", "component to read (x,y,z)")]) - next_op_idx += 1 - self.add_dxil_op("FlattenedThreadIdInGroup", next_op_idx, "FlattenedThreadIdInGroup", "provides a flattened index for a given thread within a given group (SV_GroupIndex)", "i", "rn", [ - db_dxil_param(0, "i32", "", "result")]) + self.add_dxil_op( + "ThreadId", + next_op_idx, + "ThreadId", + "reads the thread ID", + "i", + "rn", + [ + db_dxil_param(0, "i32", "", "thread ID component"), + db_dxil_param(2, "i32", "component", "component to read (x,y,z)"), + ], + ) + next_op_idx += 1 + self.add_dxil_op( + "GroupId", + next_op_idx, + "GroupId", + "reads the group ID (SV_GroupID)", + "i", + "rn", + [ + db_dxil_param(0, "i32", "", "group ID component"), + db_dxil_param(2, "i32", "component", "component to read"), + ], + ) + next_op_idx += 1 + self.add_dxil_op( + "ThreadIdInGroup", + next_op_idx, + "ThreadIdInGroup", + "reads the thread ID within the group (SV_GroupThreadID)", + "i", + "rn", + [ + db_dxil_param(0, "i32", "", "thread ID in group component"), + db_dxil_param(2, "i32", "component", "component to read (x,y,z)"), + ], + ) + next_op_idx += 1 + self.add_dxil_op( + "FlattenedThreadIdInGroup", + next_op_idx, + "FlattenedThreadIdInGroup", + "provides a flattened index for a given thread within a given group (SV_GroupIndex)", + "i", + "rn", + [db_dxil_param(0, "i32", "", "result")], + ) next_op_idx += 1 # Geometry shader - self.add_dxil_op("EmitStream", next_op_idx, "EmitStream", "emits a vertex to a given stream", "v", "", [ - retvoid_param, - db_dxil_param(2, "i8", "streamId", "target stream ID for operation")], - counters=('gs_emit',)) - next_op_idx += 1 - self.add_dxil_op("CutStream", next_op_idx, "CutStream", "completes the current primitive topology at the specified stream", "v", "", [ - retvoid_param, - db_dxil_param(2, "i8", "streamId", "target stream ID for operation")], - counters=('gs_cut',)) - next_op_idx += 1 - self.add_dxil_op("EmitThenCutStream", next_op_idx, "EmitThenCutStream", "equivalent to an EmitStream followed by a CutStream", "v", "", [ - retvoid_param, - db_dxil_param(2, "i8", "streamId", "target stream ID for operation")], - counters=('gs_emit','gs_cut')) - next_op_idx += 1 - self.add_dxil_op("GSInstanceID", next_op_idx, "GSInstanceID", "GSInstanceID", "i", "rn", [ - db_dxil_param(0, "i32", "", "result")]) + self.add_dxil_op( + "EmitStream", + next_op_idx, + "EmitStream", + "emits a vertex to a given stream", + "v", + "", + [ + retvoid_param, + db_dxil_param(2, "i8", "streamId", "target stream ID for operation"), + ], + counters=("gs_emit",), + ) + next_op_idx += 1 + self.add_dxil_op( + "CutStream", + next_op_idx, + "CutStream", + "completes the current primitive topology at the specified stream", + "v", + "", + [ + retvoid_param, + db_dxil_param(2, "i8", "streamId", "target stream ID for operation"), + ], + counters=("gs_cut",), + ) + next_op_idx += 1 + self.add_dxil_op( + "EmitThenCutStream", + next_op_idx, + "EmitThenCutStream", + "equivalent to an EmitStream followed by a CutStream", + "v", + "", + [ + retvoid_param, + db_dxil_param(2, "i8", "streamId", "target stream ID for operation"), + ], + counters=("gs_emit", "gs_cut"), + ) + next_op_idx += 1 + self.add_dxil_op( + "GSInstanceID", + next_op_idx, + "GSInstanceID", + "GSInstanceID", + "i", + "rn", + [db_dxil_param(0, "i32", "", "result")], + ) next_op_idx += 1 # Double precision - self.add_dxil_op("MakeDouble", next_op_idx, "MakeDouble", "creates a double value", "d", "rn", [ - db_dxil_param(0, "d", "", "result"), - db_dxil_param(2, "i32", "lo", "low part of double"), - db_dxil_param(3, "i32", "hi", "high part of double")]) - next_op_idx += 1 - self.add_dxil_op("SplitDouble", next_op_idx, "SplitDouble", "splits a double into low and high parts", "d", "rn", [ - db_dxil_param(0, "splitdouble", "", "result"), - db_dxil_param(2, "d", "value", "value to split")]) + self.add_dxil_op( + "MakeDouble", + next_op_idx, + "MakeDouble", + "creates a double value", + "d", + "rn", + [ + db_dxil_param(0, "d", "", "result"), + db_dxil_param(2, "i32", "lo", "low part of double"), + db_dxil_param(3, "i32", "hi", "high part of double"), + ], + ) + next_op_idx += 1 + self.add_dxil_op( + "SplitDouble", + next_op_idx, + "SplitDouble", + "splits a double into low and high parts", + "d", + "rn", + [ + db_dxil_param(0, "splitdouble", "", "result"), + db_dxil_param(2, "d", "value", "value to split"), + ], + ) next_op_idx += 1 # Domain & Hull shader. - self.add_dxil_op("LoadOutputControlPoint", next_op_idx, "LoadOutputControlPoint", "LoadOutputControlPoint", "hfwi", "rn", [ - db_dxil_param(0, "$o", "", "result"), - db_dxil_param(2, "i32", "inputSigId", "input signature element ID"), - db_dxil_param(3, "i32", "row", "row, relative to the element"), - db_dxil_param(4, "i8", "col", "column, relative to the element"), - db_dxil_param(5, "i32", "index", "vertex/point index")], - counters=('sig_ld',)) - next_op_idx += 1 - self.add_dxil_op("LoadPatchConstant", next_op_idx, "LoadPatchConstant", "LoadPatchConstant", "hfwi", "rn", [ - db_dxil_param(0, "$o", "", "result"), - db_dxil_param(2, "i32", "inputSigId", "input signature element ID"), - db_dxil_param(3, "i32", "row", "row, relative to the element"), - db_dxil_param(4, "i8", "col", "column, relative to the element")], - counters=('sig_ld',)) + self.add_dxil_op( + "LoadOutputControlPoint", + next_op_idx, + "LoadOutputControlPoint", + "LoadOutputControlPoint", + "hfwi", + "rn", + [ + db_dxil_param(0, "$o", "", "result"), + db_dxil_param(2, "i32", "inputSigId", "input signature element ID"), + db_dxil_param(3, "i32", "row", "row, relative to the element"), + db_dxil_param(4, "i8", "col", "column, relative to the element"), + db_dxil_param(5, "i32", "index", "vertex/point index"), + ], + counters=("sig_ld",), + ) + next_op_idx += 1 + self.add_dxil_op( + "LoadPatchConstant", + next_op_idx, + "LoadPatchConstant", + "LoadPatchConstant", + "hfwi", + "rn", + [ + db_dxil_param(0, "$o", "", "result"), + db_dxil_param(2, "i32", "inputSigId", "input signature element ID"), + db_dxil_param(3, "i32", "row", "row, relative to the element"), + db_dxil_param(4, "i8", "col", "column, relative to the element"), + ], + counters=("sig_ld",), + ) next_op_idx += 1 # Domain shader. - self.add_dxil_op("DomainLocation", next_op_idx, "DomainLocation", "DomainLocation", "f", "rn", [ - db_dxil_param(0, "f", "", "result"), - db_dxil_param(2, "i8", "component", "input", is_const=True)]) + self.add_dxil_op( + "DomainLocation", + next_op_idx, + "DomainLocation", + "DomainLocation", + "f", + "rn", + [ + db_dxil_param(0, "f", "", "result"), + db_dxil_param(2, "i8", "component", "input", is_const=True), + ], + ) next_op_idx += 1 # Hull shader. - self.add_dxil_op("StorePatchConstant", next_op_idx, "StorePatchConstant", "StorePatchConstant", "hfwi", "", [ - retvoid_param, - db_dxil_param(2, "i32", "outputSigID", "output signature element ID"), - db_dxil_param(3, "i32", "row", "row, relative to the element"), - db_dxil_param(4, "i8", "col", "column, relative to the element"), - db_dxil_param(5, "$o", "value", "value to store")], - counters=('sig_st',)) - next_op_idx += 1 - self.add_dxil_op("OutputControlPointID", next_op_idx, "OutputControlPointID", "OutputControlPointID", "i", "rn", [ - db_dxil_param(0, "i32", "", "result")]) - next_op_idx += 1 - self.add_dxil_op("PrimitiveID", next_op_idx, "PrimitiveID", "PrimitiveID", "i", "rn", [ - db_dxil_param(0, "i32", "", "result")]) + self.add_dxil_op( + "StorePatchConstant", + next_op_idx, + "StorePatchConstant", + "StorePatchConstant", + "hfwi", + "", + [ + retvoid_param, + db_dxil_param(2, "i32", "outputSigID", "output signature element ID"), + db_dxil_param(3, "i32", "row", "row, relative to the element"), + db_dxil_param(4, "i8", "col", "column, relative to the element"), + db_dxil_param(5, "$o", "value", "value to store"), + ], + counters=("sig_st",), + ) + next_op_idx += 1 + self.add_dxil_op( + "OutputControlPointID", + next_op_idx, + "OutputControlPointID", + "OutputControlPointID", + "i", + "rn", + [db_dxil_param(0, "i32", "", "result")], + ) + next_op_idx += 1 + self.add_dxil_op( + "PrimitiveID", + next_op_idx, + "PrimitiveID", + "PrimitiveID", + "i", + "rn", + [db_dxil_param(0, "i32", "", "result")], + ) + next_op_idx += 1 + + self.add_dxil_op( + "CycleCounterLegacy", + next_op_idx, + "CycleCounterLegacy", + "CycleCounterLegacy", + "v", + "", + [db_dxil_param(0, "twoi32", "", "result")], + ) next_op_idx += 1 - self.add_dxil_op("CycleCounterLegacy", next_op_idx, "CycleCounterLegacy", "CycleCounterLegacy", "v", "", [ - db_dxil_param(0, "twoi32", "", "result")]) - next_op_idx += 1 - # Add wave intrinsics. - self.add_dxil_op("WaveIsFirstLane", next_op_idx, "WaveIsFirstLane", "returns 1 for the first lane in the wave", "v", "", [ - db_dxil_param(0, "i1", "", "operation result")]) - next_op_idx += 1 - self.add_dxil_op("WaveGetLaneIndex", next_op_idx, "WaveGetLaneIndex", "returns the index of the current lane in the wave", "v", "rn", [ - db_dxil_param(0, "i32", "", "operation result")]) - next_op_idx += 1 - self.add_dxil_op("WaveGetLaneCount", next_op_idx, "WaveGetLaneCount", "returns the number of lanes in the wave", "v", "rn", [ - db_dxil_param(0, "i32", "", "operation result")]) - next_op_idx += 1 - self.add_dxil_op("WaveAnyTrue", next_op_idx, "WaveAnyTrue", "returns 1 if any of the lane evaluates the value to true", "v", "", [ - db_dxil_param(0, "i1", "", "operation result"), - db_dxil_param(2, "i1", "cond", "condition to test")]) - next_op_idx += 1 - self.add_dxil_op("WaveAllTrue", next_op_idx, "WaveAllTrue", "returns 1 if all the lanes evaluate the value to true", "v", "", [ - db_dxil_param(0, "i1", "", "operation result"), - db_dxil_param(2, "i1", "cond", "condition to test")]) - next_op_idx += 1 - self.add_dxil_op("WaveActiveAllEqual", next_op_idx, "WaveActiveAllEqual", "returns 1 if all the lanes have the same value", "hfd18wil", "", [ - db_dxil_param(0, "i1", "", "operation result"), - db_dxil_param(2, "$o", "value", "value to compare")]) - next_op_idx += 1 - self.add_dxil_op("WaveActiveBallot", next_op_idx, "WaveActiveBallot", "returns a struct with a bit set for each lane where the condition is true", "v", "", [ - db_dxil_param(0, "fouri32", "", "operation result"), - db_dxil_param(2, "i1", "cond", "condition to ballot on")]) - next_op_idx += 1 - self.add_dxil_op("WaveReadLaneAt", next_op_idx, "WaveReadLaneAt", "returns the value from the specified lane", "hfd18wil", "", [ - db_dxil_param(0, "$o", "", "operation result"), - db_dxil_param(2, "$o", "value", "value to read"), - db_dxil_param(3, "i32", "lane", "lane index")]) - next_op_idx += 1 - self.add_dxil_op("WaveReadLaneFirst", next_op_idx, "WaveReadLaneFirst", "returns the value from the first lane", "hfd18wil", "", [ - db_dxil_param(0, "$o", "", "operation result"), - db_dxil_param(2, "$o", "value", "value to read")]) - next_op_idx += 1 - self.add_dxil_op("WaveActiveOp", next_op_idx, "WaveActiveOp", "returns the result the operation across waves", "hfd18wil", "", [ - db_dxil_param(0, "$o", "", "operation result"), - db_dxil_param(2, "$o", "value", "input value"), - db_dxil_param(3, "i8", "op", "kind of operation to perform", enum_name="WaveOpKind", is_const=True), - db_dxil_param(4, "i8", "sop", "sign of operands", enum_name="SignedOpKind", is_const=True)]) - next_op_idx += 1 - self.add_enum_type("SignedOpKind", "Sign vs. unsigned operands for operation", [ - (0, "Signed", "signed integer or floating-point operands"), - (1, "Unsigned", "unsigned integer operands")]) - self.add_enum_type("WaveOpKind", "Kind of cross-lane operation", [ - (0, "Sum", "sum of values"), - (1, "Product", "product of values"), - (2, "Min", "minimum value"), - (3, "Max", "maximum value")]) - self.add_dxil_op("WaveActiveBit", next_op_idx, "WaveActiveBit", "returns the result of the operation across all lanes", "8wil", "", [ - db_dxil_param(0, "$o", "", "operation result"), - db_dxil_param(2, "$o", "value", "input value"), - db_dxil_param(3, "i8", "op", "kind of operation to perform", enum_name="WaveBitOpKind", is_const=True)]) - next_op_idx += 1 - self.add_enum_type("WaveBitOpKind", "Kind of bitwise cross-lane operation", [ - (0, "And", "bitwise and of values"), - (1, "Or", "bitwise or of values"), - (2, "Xor", "bitwise xor of values")]) - self.add_dxil_op("WavePrefixOp", next_op_idx, "WavePrefixOp", "returns the result of the operation on prior lanes", "hfd8wil", "", [ - db_dxil_param(0, "$o", "", "operation result"), - db_dxil_param(2, "$o", "value", "input value"), - db_dxil_param(3, "i8", "op", "0=sum,1=product", enum_name="WaveOpKind", is_const=True), - db_dxil_param(4, "i8", "sop", "sign of operands", enum_name="SignedOpKind", is_const=True)]) - next_op_idx += 1 - self.add_dxil_op("QuadReadLaneAt", next_op_idx, "QuadReadLaneAt", "reads from a lane in the quad", "hfd18wil", "", [ - db_dxil_param(0, "$o", "", "operation result"), - db_dxil_param(2, "$o", "value", "value to read"), - db_dxil_param(3, "u32", "quadLane", "lane to read from (0-4)", max_value = 3)]) - next_op_idx += 1 - self.add_enum_type("QuadOpKind", "Kind of quad-level operation", [ - (0, "ReadAcrossX", "returns the value from the other lane in the quad in the horizontal direction"), - (1, "ReadAcrossY", "returns the value from the other lane in the quad in the vertical direction"), - (2, "ReadAcrossDiagonal", "returns the value from the lane across the quad in horizontal and vertical direction")]) - self.add_dxil_op("QuadOp", next_op_idx, "QuadOp", "returns the result of a quad-level operation", "hfd8wil", "", [ - db_dxil_param(0, "$o", "", "operation result"), - db_dxil_param(2, "$o", "value", "value for operation"), - db_dxil_param(3, "i8", "op", "operation", enum_name = "QuadOpKind", is_const=True)]) + self.add_dxil_op( + "WaveIsFirstLane", + next_op_idx, + "WaveIsFirstLane", + "returns 1 for the first lane in the wave", + "v", + "", + [db_dxil_param(0, "i1", "", "operation result")], + ) + next_op_idx += 1 + self.add_dxil_op( + "WaveGetLaneIndex", + next_op_idx, + "WaveGetLaneIndex", + "returns the index of the current lane in the wave", + "v", + "rn", + [db_dxil_param(0, "i32", "", "operation result")], + ) + next_op_idx += 1 + self.add_dxil_op( + "WaveGetLaneCount", + next_op_idx, + "WaveGetLaneCount", + "returns the number of lanes in the wave", + "v", + "rn", + [db_dxil_param(0, "i32", "", "operation result")], + ) + next_op_idx += 1 + self.add_dxil_op( + "WaveAnyTrue", + next_op_idx, + "WaveAnyTrue", + "returns 1 if any of the lane evaluates the value to true", + "v", + "", + [ + db_dxil_param(0, "i1", "", "operation result"), + db_dxil_param(2, "i1", "cond", "condition to test"), + ], + ) + next_op_idx += 1 + self.add_dxil_op( + "WaveAllTrue", + next_op_idx, + "WaveAllTrue", + "returns 1 if all the lanes evaluate the value to true", + "v", + "", + [ + db_dxil_param(0, "i1", "", "operation result"), + db_dxil_param(2, "i1", "cond", "condition to test"), + ], + ) + next_op_idx += 1 + self.add_dxil_op( + "WaveActiveAllEqual", + next_op_idx, + "WaveActiveAllEqual", + "returns 1 if all the lanes have the same value", + "hfd18wil", + "", + [ + db_dxil_param(0, "i1", "", "operation result"), + db_dxil_param(2, "$o", "value", "value to compare"), + ], + ) + next_op_idx += 1 + self.add_dxil_op( + "WaveActiveBallot", + next_op_idx, + "WaveActiveBallot", + "returns a struct with a bit set for each lane where the condition is true", + "v", + "", + [ + db_dxil_param(0, "fouri32", "", "operation result"), + db_dxil_param(2, "i1", "cond", "condition to ballot on"), + ], + ) + next_op_idx += 1 + self.add_dxil_op( + "WaveReadLaneAt", + next_op_idx, + "WaveReadLaneAt", + "returns the value from the specified lane", + "hfd18wil", + "", + [ + db_dxil_param(0, "$o", "", "operation result"), + db_dxil_param(2, "$o", "value", "value to read"), + db_dxil_param(3, "i32", "lane", "lane index"), + ], + ) + next_op_idx += 1 + self.add_dxil_op( + "WaveReadLaneFirst", + next_op_idx, + "WaveReadLaneFirst", + "returns the value from the first lane", + "hfd18wil", + "", + [ + db_dxil_param(0, "$o", "", "operation result"), + db_dxil_param(2, "$o", "value", "value to read"), + ], + ) + next_op_idx += 1 + self.add_dxil_op( + "WaveActiveOp", + next_op_idx, + "WaveActiveOp", + "returns the result the operation across waves", + "hfd18wil", + "", + [ + db_dxil_param(0, "$o", "", "operation result"), + db_dxil_param(2, "$o", "value", "input value"), + db_dxil_param( + 3, + "i8", + "op", + "kind of operation to perform", + enum_name="WaveOpKind", + is_const=True, + ), + db_dxil_param( + 4, + "i8", + "sop", + "sign of operands", + enum_name="SignedOpKind", + is_const=True, + ), + ], + ) + next_op_idx += 1 + self.add_enum_type( + "SignedOpKind", + "Sign vs. unsigned operands for operation", + [ + (0, "Signed", "signed integer or floating-point operands"), + (1, "Unsigned", "unsigned integer operands"), + ], + ) + self.add_enum_type( + "WaveOpKind", + "Kind of cross-lane operation", + [ + (0, "Sum", "sum of values"), + (1, "Product", "product of values"), + (2, "Min", "minimum value"), + (3, "Max", "maximum value"), + ], + ) + self.add_dxil_op( + "WaveActiveBit", + next_op_idx, + "WaveActiveBit", + "returns the result of the operation across all lanes", + "8wil", + "", + [ + db_dxil_param(0, "$o", "", "operation result"), + db_dxil_param(2, "$o", "value", "input value"), + db_dxil_param( + 3, + "i8", + "op", + "kind of operation to perform", + enum_name="WaveBitOpKind", + is_const=True, + ), + ], + ) + next_op_idx += 1 + self.add_enum_type( + "WaveBitOpKind", + "Kind of bitwise cross-lane operation", + [ + (0, "And", "bitwise and of values"), + (1, "Or", "bitwise or of values"), + (2, "Xor", "bitwise xor of values"), + ], + ) + self.add_dxil_op( + "WavePrefixOp", + next_op_idx, + "WavePrefixOp", + "returns the result of the operation on prior lanes", + "hfd8wil", + "", + [ + db_dxil_param(0, "$o", "", "operation result"), + db_dxil_param(2, "$o", "value", "input value"), + db_dxil_param( + 3, + "i8", + "op", + "0=sum,1=product", + enum_name="WaveOpKind", + is_const=True, + ), + db_dxil_param( + 4, + "i8", + "sop", + "sign of operands", + enum_name="SignedOpKind", + is_const=True, + ), + ], + ) + next_op_idx += 1 + self.add_dxil_op( + "QuadReadLaneAt", + next_op_idx, + "QuadReadLaneAt", + "reads from a lane in the quad", + "hfd18wil", + "", + [ + db_dxil_param(0, "$o", "", "operation result"), + db_dxil_param(2, "$o", "value", "value to read"), + db_dxil_param( + 3, "u32", "quadLane", "lane to read from (0-4)", max_value=3 + ), + ], + ) + next_op_idx += 1 + self.add_enum_type( + "QuadOpKind", + "Kind of quad-level operation", + [ + ( + 0, + "ReadAcrossX", + "returns the value from the other lane in the quad in the horizontal direction", + ), + ( + 1, + "ReadAcrossY", + "returns the value from the other lane in the quad in the vertical direction", + ), + ( + 2, + "ReadAcrossDiagonal", + "returns the value from the lane across the quad in horizontal and vertical direction", + ), + ], + ) + self.add_dxil_op( + "QuadOp", + next_op_idx, + "QuadOp", + "returns the result of a quad-level operation", + "hfd8wil", + "", + [ + db_dxil_param(0, "$o", "", "operation result"), + db_dxil_param(2, "$o", "value", "value for operation"), + db_dxil_param( + 3, "i8", "op", "operation", enum_name="QuadOpKind", is_const=True + ), + ], + ) next_op_idx += 1 # Add bitcasts - self.add_dxil_op("BitcastI16toF16", next_op_idx, "BitcastI16toF16", "bitcast between different sizes", "v", "rn", [ - db_dxil_param(0, "h", "", "operation result"), - db_dxil_param(2, "i16", "value", "input value")]) - next_op_idx += 1 - self.add_dxil_op("BitcastF16toI16", next_op_idx, "BitcastF16toI16", "bitcast between different sizes", "v", "rn", [ - db_dxil_param(0, "i16", "", "operation result"), - db_dxil_param(2, "h", "value", "input value")]) - next_op_idx += 1 - self.add_dxil_op("BitcastI32toF32", next_op_idx, "BitcastI32toF32", "bitcast between different sizes", "v", "rn", [ - db_dxil_param(0, "f", "", "operation result"), - db_dxil_param(2, "i32", "value", "input value")]) - next_op_idx += 1 - self.add_dxil_op("BitcastF32toI32", next_op_idx, "BitcastF32toI32", "bitcast between different sizes", "v", "rn", [ - db_dxil_param(0, "i32", "", "operation result"), - db_dxil_param(2, "f", "value", "input value")]) - next_op_idx += 1 - self.add_dxil_op("BitcastI64toF64", next_op_idx, "BitcastI64toF64", "bitcast between different sizes", "v", "rn", [ - db_dxil_param(0, "d", "", "operation result"), - db_dxil_param(2, "i64", "value", "input value")]) - next_op_idx += 1 - self.add_dxil_op("BitcastF64toI64", next_op_idx, "BitcastF64toI64", "bitcast between different sizes", "v", "rn", [ - db_dxil_param(0, "i64", "", "operation result"), - db_dxil_param(2, "d", "value", "input value")]) - next_op_idx += 1 - - self.add_dxil_op("LegacyF32ToF16", next_op_idx, "LegacyF32ToF16", "legacy fuction to convert float (f32) to half (f16) (this is not related to min-precision)", "v", "rn", [ - db_dxil_param(0, "i32", "", "low 16 bits - half value, high 16 bits - zeroes"), - db_dxil_param(2, "f", "value", "float value to convert")]) - next_op_idx += 1 - - self.add_dxil_op("LegacyF16ToF32", next_op_idx, "LegacyF16ToF32", "legacy fuction to convert half (f16) to float (f32) (this is not related to min-precision)", "v", "rn", [ - db_dxil_param(0, "f", "", "converted float value"), - db_dxil_param(2, "i32", "value", "half value to convert")]) - next_op_idx += 1 - - self.add_dxil_op("LegacyDoubleToFloat", next_op_idx, "LegacyDoubleToFloat", "legacy fuction to convert double to float", "v", "rn", [ - db_dxil_param(0, "f", "", "float value"), - db_dxil_param(2, "d", "value", "double value to convert")]) - next_op_idx += 1 - - self.add_dxil_op("LegacyDoubleToSInt32", next_op_idx, "LegacyDoubleToSInt32", "legacy fuction to convert double to int32", "v", "rn", [ - db_dxil_param(0, "i32", "", "i32 value"), - db_dxil_param(2, "d", "value", "double value to convert")]) - next_op_idx += 1 - - self.add_dxil_op("LegacyDoubleToUInt32", next_op_idx, "LegacyDoubleToUInt32", "legacy fuction to convert double to uint32", "v", "rn", [ - db_dxil_param(0, "i32", "", "i32 value"), - db_dxil_param(2, "d", "value", "double value to convert")]) - next_op_idx += 1 - - self.add_dxil_op("WaveAllBitCount", next_op_idx, "WaveAllOp", "returns the count of bits set to 1 across the wave", "v", "", [ - db_dxil_param(0, "i32", "", "operation result"), - db_dxil_param(2, "i1", "value", "input value")]) + self.add_dxil_op( + "BitcastI16toF16", + next_op_idx, + "BitcastI16toF16", + "bitcast between different sizes", + "v", + "rn", + [ + db_dxil_param(0, "h", "", "operation result"), + db_dxil_param(2, "i16", "value", "input value"), + ], + ) + next_op_idx += 1 + self.add_dxil_op( + "BitcastF16toI16", + next_op_idx, + "BitcastF16toI16", + "bitcast between different sizes", + "v", + "rn", + [ + db_dxil_param(0, "i16", "", "operation result"), + db_dxil_param(2, "h", "value", "input value"), + ], + ) + next_op_idx += 1 + self.add_dxil_op( + "BitcastI32toF32", + next_op_idx, + "BitcastI32toF32", + "bitcast between different sizes", + "v", + "rn", + [ + db_dxil_param(0, "f", "", "operation result"), + db_dxil_param(2, "i32", "value", "input value"), + ], + ) + next_op_idx += 1 + self.add_dxil_op( + "BitcastF32toI32", + next_op_idx, + "BitcastF32toI32", + "bitcast between different sizes", + "v", + "rn", + [ + db_dxil_param(0, "i32", "", "operation result"), + db_dxil_param(2, "f", "value", "input value"), + ], + ) + next_op_idx += 1 + self.add_dxil_op( + "BitcastI64toF64", + next_op_idx, + "BitcastI64toF64", + "bitcast between different sizes", + "v", + "rn", + [ + db_dxil_param(0, "d", "", "operation result"), + db_dxil_param(2, "i64", "value", "input value"), + ], + ) + next_op_idx += 1 + self.add_dxil_op( + "BitcastF64toI64", + next_op_idx, + "BitcastF64toI64", + "bitcast between different sizes", + "v", + "rn", + [ + db_dxil_param(0, "i64", "", "operation result"), + db_dxil_param(2, "d", "value", "input value"), + ], + ) + next_op_idx += 1 + + self.add_dxil_op( + "LegacyF32ToF16", + next_op_idx, + "LegacyF32ToF16", + "legacy fuction to convert float (f32) to half (f16) (this is not related to min-precision)", + "v", + "rn", + [ + db_dxil_param( + 0, "i32", "", "low 16 bits - half value, high 16 bits - zeroes" + ), + db_dxil_param(2, "f", "value", "float value to convert"), + ], + ) + next_op_idx += 1 + + self.add_dxil_op( + "LegacyF16ToF32", + next_op_idx, + "LegacyF16ToF32", + "legacy fuction to convert half (f16) to float (f32) (this is not related to min-precision)", + "v", + "rn", + [ + db_dxil_param(0, "f", "", "converted float value"), + db_dxil_param(2, "i32", "value", "half value to convert"), + ], + ) + next_op_idx += 1 + + self.add_dxil_op( + "LegacyDoubleToFloat", + next_op_idx, + "LegacyDoubleToFloat", + "legacy fuction to convert double to float", + "v", + "rn", + [ + db_dxil_param(0, "f", "", "float value"), + db_dxil_param(2, "d", "value", "double value to convert"), + ], + ) + next_op_idx += 1 + + self.add_dxil_op( + "LegacyDoubleToSInt32", + next_op_idx, + "LegacyDoubleToSInt32", + "legacy fuction to convert double to int32", + "v", + "rn", + [ + db_dxil_param(0, "i32", "", "i32 value"), + db_dxil_param(2, "d", "value", "double value to convert"), + ], + ) + next_op_idx += 1 + + self.add_dxil_op( + "LegacyDoubleToUInt32", + next_op_idx, + "LegacyDoubleToUInt32", + "legacy fuction to convert double to uint32", + "v", + "rn", + [ + db_dxil_param(0, "i32", "", "i32 value"), + db_dxil_param(2, "d", "value", "double value to convert"), + ], + ) + next_op_idx += 1 + + self.add_dxil_op( + "WaveAllBitCount", + next_op_idx, + "WaveAllOp", + "returns the count of bits set to 1 across the wave", + "v", + "", + [ + db_dxil_param(0, "i32", "", "operation result"), + db_dxil_param(2, "i1", "value", "input value"), + ], + ) next_op_idx += 1 # WavePrefixBitCount has different signature compare to WavePrefixOp, set its opclass to WavePrefixOp is not correct. # It works now because WavePrefixOp and WavePrefixBitCount don't interfere on overload types. # Keep it unchanged for back-compat. - self.add_dxil_op("WavePrefixBitCount", next_op_idx, "WavePrefixOp", "returns the count of bits set to 1 on prior lanes", "v", "", [ - db_dxil_param(0, "i32", "", "operation result"), - db_dxil_param(2, "i1", "value", "input value")]) + self.add_dxil_op( + "WavePrefixBitCount", + next_op_idx, + "WavePrefixOp", + "returns the count of bits set to 1 on prior lanes", + "v", + "", + [ + db_dxil_param(0, "i32", "", "operation result"), + db_dxil_param(2, "i1", "value", "input value"), + ], + ) next_op_idx += 1 # End of DXIL 1.0 opcodes. self.set_op_count_for_version(1, 0, next_op_idx) - self.add_dxil_op("AttributeAtVertex", next_op_idx, "AttributeAtVertex", "returns the values of the attributes at the vertex.", "hfiw", "rn", [ - db_dxil_param(0, "$o", "", "result"), - db_dxil_param(2, "i32", "inputSigId", "input signature element ID"), - db_dxil_param(3, "i32", "inputRowIndex", "row index of an input attribute"), - db_dxil_param(4, "i8", "inputColIndex", "column index of an input attribute"), - db_dxil_param(5, "i8", "VertexID", "Vertex Index") - ]) - next_op_idx += 1 - self.add_dxil_op("ViewID", next_op_idx, "ViewID", "returns the view index", "i", "rn", [ - db_dxil_param(0, "i32", "", "result")]) + self.add_dxil_op( + "AttributeAtVertex", + next_op_idx, + "AttributeAtVertex", + "returns the values of the attributes at the vertex.", + "hfiw", + "rn", + [ + db_dxil_param(0, "$o", "", "result"), + db_dxil_param(2, "i32", "inputSigId", "input signature element ID"), + db_dxil_param( + 3, "i32", "inputRowIndex", "row index of an input attribute" + ), + db_dxil_param( + 4, "i8", "inputColIndex", "column index of an input attribute" + ), + db_dxil_param(5, "i8", "VertexID", "Vertex Index"), + ], + ) + next_op_idx += 1 + self.add_dxil_op( + "ViewID", + next_op_idx, + "ViewID", + "returns the view index", + "i", + "rn", + [db_dxil_param(0, "i32", "", "result")], + ) next_op_idx += 1 # End of DXIL 1.1 opcodes. self.set_op_count_for_version(1, 1, next_op_idx) - self.add_dxil_op("RawBufferLoad", next_op_idx, "RawBufferLoad", "reads from a raw buffer and structured buffer", "hfwidl", "ro", [ - db_dxil_param(0, "$r", "", "the loaded value"), - db_dxil_param(2, "res", "srv", "handle of TypedBuffer SRV to sample"), - db_dxil_param(3, "i32", "index", "element index for StructuredBuffer, or byte offset for ByteAddressBuffer"), - db_dxil_param(4, "i32", "elementOffset", "offset into element for StructuredBuffer, or undef for ByteAddressBuffer"), - db_dxil_param(5, "i8", "mask", "loading value mask", is_const=True), - db_dxil_param(6, "i32", "alignment", "relative load access alignment", is_const=True)], - counters=('tex_load',)) - next_op_idx += 1 - - self.add_dxil_op("RawBufferStore", next_op_idx, "RawBufferStore", "writes to a RWByteAddressBuffer or RWStructuredBuffer", "hfwidl", "", [ - db_dxil_param(0, "v", "", ""), - db_dxil_param(2, "res", "uav", "handle of UAV to store to"), - db_dxil_param(3, "i32", "index", "element index for StructuredBuffer, or byte offset for ByteAddressBuffer"), - db_dxil_param(4, "i32", "elementOffset", "offset into element for StructuredBuffer, or undef for ByteAddressBuffer"), - db_dxil_param(5, "$o", "value0", "value"), - db_dxil_param(6, "$o", "value1", "value"), - db_dxil_param(7, "$o", "value2", "value"), - db_dxil_param(8, "$o", "value3", "value"), - db_dxil_param(9, "i8", "mask", "mask of contiguous components stored starting at first component (valid: 1, 3, 7, 15)", is_const=True), - db_dxil_param(10, "i32", "alignment", "relative store access alignment", is_const=True)], - counters=('tex_store',)) + self.add_dxil_op( + "RawBufferLoad", + next_op_idx, + "RawBufferLoad", + "reads from a raw buffer and structured buffer", + "hfwidl", + "ro", + [ + db_dxil_param(0, "$r", "", "the loaded value"), + db_dxil_param(2, "res", "srv", "handle of TypedBuffer SRV to sample"), + db_dxil_param( + 3, + "i32", + "index", + "element index for StructuredBuffer, or byte offset for ByteAddressBuffer", + ), + db_dxil_param( + 4, + "i32", + "elementOffset", + "offset into element for StructuredBuffer, or undef for ByteAddressBuffer", + ), + db_dxil_param(5, "i8", "mask", "loading value mask", is_const=True), + db_dxil_param( + 6, + "i32", + "alignment", + "relative load access alignment", + is_const=True, + ), + ], + counters=("tex_load",), + ) + next_op_idx += 1 + + self.add_dxil_op( + "RawBufferStore", + next_op_idx, + "RawBufferStore", + "writes to a RWByteAddressBuffer or RWStructuredBuffer", + "hfwidl", + "", + [ + db_dxil_param(0, "v", "", ""), + db_dxil_param(2, "res", "uav", "handle of UAV to store to"), + db_dxil_param( + 3, + "i32", + "index", + "element index for StructuredBuffer, or byte offset for ByteAddressBuffer", + ), + db_dxil_param( + 4, + "i32", + "elementOffset", + "offset into element for StructuredBuffer, or undef for ByteAddressBuffer", + ), + db_dxil_param(5, "$o", "value0", "value"), + db_dxil_param(6, "$o", "value1", "value"), + db_dxil_param(7, "$o", "value2", "value"), + db_dxil_param(8, "$o", "value3", "value"), + db_dxil_param( + 9, + "i8", + "mask", + "mask of contiguous components stored starting at first component (valid: 1, 3, 7, 15)", + is_const=True, + ), + db_dxil_param( + 10, + "i32", + "alignment", + "relative store access alignment", + is_const=True, + ), + ], + counters=("tex_store",), + ) next_op_idx += 1 # End of DXIL 1.2 opcodes. self.set_op_count_for_version(1, 2, next_op_idx) - assert next_op_idx == 141, "next operation index is %d rather than 141 and thus opcodes are broken" % next_op_idx - - self.add_dxil_op("InstanceID", next_op_idx, "InstanceID", "The user-provided InstanceID on the bottom-level acceleration structure instance within the top-level structure", "i", "rn", [ - db_dxil_param(0, "i32", "", "result")]) - next_op_idx += 1 - - self.add_dxil_op("InstanceIndex", next_op_idx, "InstanceIndex", "The autogenerated index of the current instance in the top-level structure", "i", "rn", [ - db_dxil_param(0, "i32", "", "result")]) - next_op_idx += 1 - - self.add_dxil_op("HitKind", next_op_idx, "HitKind", "Returns the value passed as HitKind in ReportIntersection(). If intersection was reported by fixed-function triangle intersection, HitKind will be one of HIT_KIND_TRIANGLE_FRONT_FACE or HIT_KIND_TRIANGLE_BACK_FACE.", "i", "rn", [ - db_dxil_param(0, "i32", "", "result")]) - next_op_idx += 1 - - self.add_dxil_op("RayFlags", next_op_idx, "RayFlags", "uint containing the current ray flags.", "i", "rn", [ - db_dxil_param(0, "i32", "", "result")]) - next_op_idx += 1 - - self.add_dxil_op("DispatchRaysIndex", next_op_idx, "DispatchRaysIndex", "The current x and y location within the Width and Height", "i", "rn", [ - db_dxil_param(0, "i32", "", "result"), - db_dxil_param(2, "i8", "col", "column, relative to the element")]) - next_op_idx += 1 - - self.add_dxil_op("DispatchRaysDimensions", next_op_idx, "DispatchRaysDimensions", "The Width and Height values from the D3D12_DISPATCH_RAYS_DESC structure provided to the originating DispatchRays() call.", "i", "rn", [ - db_dxil_param(0, "i32", "", "result"), - db_dxil_param(2, "i8", "col", "column, relative to the element")]) - next_op_idx += 1 - - self.add_dxil_op("WorldRayOrigin", next_op_idx, "WorldRayOrigin", "The world-space origin for the current ray.", "f", "rn", [ - db_dxil_param(0, "f", "", "result"), - db_dxil_param(2, "i8", "col", "column, relative to the element")]) - next_op_idx += 1 - - self.add_dxil_op("WorldRayDirection", next_op_idx, "WorldRayDirection", "The world-space direction for the current ray.", "f", "rn", [ - db_dxil_param(0, "f", "", "result"), - db_dxil_param(2, "i8", "col", "column, relative to the element")]) - next_op_idx += 1 - - self.add_dxil_op("ObjectRayOrigin", next_op_idx, "ObjectRayOrigin", "Object-space origin for the current ray.", "f", "rn", [ - db_dxil_param(0, "f", "", "result"), - db_dxil_param(2, "i8", "col", "column, relative to the element")]) - next_op_idx += 1 - - self.add_dxil_op("ObjectRayDirection", next_op_idx, "ObjectRayDirection", "Object-space direction for the current ray.", "f", "rn", [ - db_dxil_param(0, "f", "", "result"), - db_dxil_param(2, "i8", "col", "column, relative to the element")]) - next_op_idx += 1 - - self.add_dxil_op("ObjectToWorld", next_op_idx, "ObjectToWorld", "Matrix for transforming from object-space to world-space.", "f", "rn", [ - db_dxil_param(0, "f", "", "result"), - db_dxil_param(2, "i32", "row", "row, relative to the element"), - db_dxil_param(3, "i8", "col", "column, relative to the element")]) - next_op_idx += 1 - - self.add_dxil_op("WorldToObject", next_op_idx, "WorldToObject", "Matrix for transforming from world-space to object-space.", "f", "rn", [ - db_dxil_param(0, "f", "", "result"), - db_dxil_param(2, "i32", "row", "row, relative to the element"), - db_dxil_param(3, "i8", "col", "column, relative to the element")]) - next_op_idx += 1 - - self.add_dxil_op("RayTMin", next_op_idx, "RayTMin", "float representing the parametric starting point for the ray.", "f", "rn", [ - db_dxil_param(0, "f", "", "result")]) - next_op_idx += 1 - - self.add_dxil_op("RayTCurrent", next_op_idx, "RayTCurrent", "float representing the current parametric ending point for the ray", "f", "ro", [ - db_dxil_param(0, "f", "", "result")]) - next_op_idx += 1 - - self.add_dxil_op("IgnoreHit", next_op_idx, "IgnoreHit", "Used in an any hit shader to reject an intersection and terminate the shader", "v", "nr", [ - db_dxil_param(0, "v", "", "")]) - next_op_idx += 1 - - self.add_dxil_op("AcceptHitAndEndSearch", next_op_idx, "AcceptHitAndEndSearch", "Used in an any hit shader to abort the ray query and the intersection shader (if any). The current hit is committed and execution passes to the closest hit shader with the closest hit recorded so far", "v", "nr", [ - db_dxil_param(0, "v", "", "")]) - next_op_idx += 1 - - self.add_dxil_op("TraceRay", next_op_idx, "TraceRay", "initiates raytrace", "u", "", [ - db_dxil_param(0, "v", "", ""), - db_dxil_param(2, "res", "AccelerationStructure", "Top-level acceleration structure to use"), - db_dxil_param(3, "i32", "RayFlags", "Valid combination of Ray_flags"), - db_dxil_param(4, "i32", "InstanceInclusionMask", "Bottom 8 bits of InstanceInclusionMask are used to include/rejectgeometry instances based on the InstanceMask in each instance: if(!((InstanceInclusionMask & InstanceMask) & 0xff)) { ignore intersection }"), - db_dxil_param(5, "i32", "RayContributionToHitGroupIndex", "Offset to add into Addressing calculations within shader tables for hit group indexing. Only the bottom 4 bits of this value are used"), - db_dxil_param(6, "i32", "MultiplierForGeometryContributionToShaderIndex", "Stride to multiply by per-geometry GeometryContributionToHitGroupIndex in Addressing calculations within shader tables for hit group indexing. Only the bottom 4 bits of this value are used"), - db_dxil_param(7, "i32", "MissShaderIndex", "Miss shader index in Addressing calculations within shader tables. Only the bottom 16 bits of this value are used"), - db_dxil_param(8, "f", "Origin_X", "Origin x of the ray"), - db_dxil_param(9, "f", "Origin_Y", "Origin y of the ray"), - db_dxil_param(10, "f", "Origin_Z", "Origin z of the ray"), - db_dxil_param(11, "f", "TMin", "Tmin of the ray"), - db_dxil_param(12, "f", "Direction_X", "Direction x of the ray"), - db_dxil_param(13, "f", "Direction_Y", "Direction y of the ray"), - db_dxil_param(14, "f", "Direction_Z", "Direction z of the ray"), - db_dxil_param(15, "f", "TMax", "Tmax of the ray"), - db_dxil_param(16, "udt", "payload", "User-defined intersection attribute structure")]) - next_op_idx += 1 - - self.add_dxil_op("ReportHit", next_op_idx, "ReportHit", "returns true if hit was accepted", "u", "", [ - db_dxil_param(0, "i1", "", "result"), - db_dxil_param(2, "f", "THit", "parametric distance of the intersection"), - db_dxil_param(3, "i32", "HitKind", "User-specified value in range of 0-127 to identify the type of hit. Read by any_hit or closes_hit shaders with HitKind()"), - db_dxil_param(4, "udt", "Attributes", "User-defined intersection attribute structure")]) - next_op_idx += 1 - - self.add_dxil_op("CallShader", next_op_idx, "CallShader", "Call a shader in the callable shader table supplied through the DispatchRays() API", "u", "", [ - db_dxil_param(0, "v", "", "result"), - db_dxil_param(2, "i32", "ShaderIndex", "Provides index into the callable shader table supplied through the DispatchRays() API"), - db_dxil_param(3, "udt", "Parameter", "User-defined parameters to pass to the callable shader,This parameter structure must match the parameter structure used in the callable shader pointed to in the shader table")]) - next_op_idx += 1 - - self.add_dxil_op("CreateHandleForLib", next_op_idx, "CreateHandleForLib", "create resource handle from resource struct for library", "o", "ro", [ - db_dxil_param(0, "res", "", "result"), - db_dxil_param(2, "obj", "Resource", "resource to create the handle")]) + assert next_op_idx == 141, ( + "next operation index is %d rather than 141 and thus opcodes are broken" + % next_op_idx + ) + + self.add_dxil_op( + "InstanceID", + next_op_idx, + "InstanceID", + "The user-provided InstanceID on the bottom-level acceleration structure instance within the top-level structure", + "i", + "rn", + [db_dxil_param(0, "i32", "", "result")], + ) + next_op_idx += 1 + + self.add_dxil_op( + "InstanceIndex", + next_op_idx, + "InstanceIndex", + "The autogenerated index of the current instance in the top-level structure", + "i", + "rn", + [db_dxil_param(0, "i32", "", "result")], + ) + next_op_idx += 1 + + self.add_dxil_op( + "HitKind", + next_op_idx, + "HitKind", + "Returns the value passed as HitKind in ReportIntersection(). If intersection was reported by fixed-function triangle intersection, HitKind will be one of HIT_KIND_TRIANGLE_FRONT_FACE or HIT_KIND_TRIANGLE_BACK_FACE.", + "i", + "rn", + [db_dxil_param(0, "i32", "", "result")], + ) + next_op_idx += 1 + + self.add_dxil_op( + "RayFlags", + next_op_idx, + "RayFlags", + "uint containing the current ray flags.", + "i", + "rn", + [db_dxil_param(0, "i32", "", "result")], + ) + next_op_idx += 1 + + self.add_dxil_op( + "DispatchRaysIndex", + next_op_idx, + "DispatchRaysIndex", + "The current x and y location within the Width and Height", + "i", + "rn", + [ + db_dxil_param(0, "i32", "", "result"), + db_dxil_param(2, "i8", "col", "column, relative to the element"), + ], + ) + next_op_idx += 1 + + self.add_dxil_op( + "DispatchRaysDimensions", + next_op_idx, + "DispatchRaysDimensions", + "The Width and Height values from the D3D12_DISPATCH_RAYS_DESC structure provided to the originating DispatchRays() call.", + "i", + "rn", + [ + db_dxil_param(0, "i32", "", "result"), + db_dxil_param(2, "i8", "col", "column, relative to the element"), + ], + ) + next_op_idx += 1 + + self.add_dxil_op( + "WorldRayOrigin", + next_op_idx, + "WorldRayOrigin", + "The world-space origin for the current ray.", + "f", + "rn", + [ + db_dxil_param(0, "f", "", "result"), + db_dxil_param(2, "i8", "col", "column, relative to the element"), + ], + ) + next_op_idx += 1 + + self.add_dxil_op( + "WorldRayDirection", + next_op_idx, + "WorldRayDirection", + "The world-space direction for the current ray.", + "f", + "rn", + [ + db_dxil_param(0, "f", "", "result"), + db_dxil_param(2, "i8", "col", "column, relative to the element"), + ], + ) + next_op_idx += 1 + + self.add_dxil_op( + "ObjectRayOrigin", + next_op_idx, + "ObjectRayOrigin", + "Object-space origin for the current ray.", + "f", + "rn", + [ + db_dxil_param(0, "f", "", "result"), + db_dxil_param(2, "i8", "col", "column, relative to the element"), + ], + ) + next_op_idx += 1 + + self.add_dxil_op( + "ObjectRayDirection", + next_op_idx, + "ObjectRayDirection", + "Object-space direction for the current ray.", + "f", + "rn", + [ + db_dxil_param(0, "f", "", "result"), + db_dxil_param(2, "i8", "col", "column, relative to the element"), + ], + ) + next_op_idx += 1 + + self.add_dxil_op( + "ObjectToWorld", + next_op_idx, + "ObjectToWorld", + "Matrix for transforming from object-space to world-space.", + "f", + "rn", + [ + db_dxil_param(0, "f", "", "result"), + db_dxil_param(2, "i32", "row", "row, relative to the element"), + db_dxil_param(3, "i8", "col", "column, relative to the element"), + ], + ) + next_op_idx += 1 + + self.add_dxil_op( + "WorldToObject", + next_op_idx, + "WorldToObject", + "Matrix for transforming from world-space to object-space.", + "f", + "rn", + [ + db_dxil_param(0, "f", "", "result"), + db_dxil_param(2, "i32", "row", "row, relative to the element"), + db_dxil_param(3, "i8", "col", "column, relative to the element"), + ], + ) + next_op_idx += 1 + + self.add_dxil_op( + "RayTMin", + next_op_idx, + "RayTMin", + "float representing the parametric starting point for the ray.", + "f", + "rn", + [db_dxil_param(0, "f", "", "result")], + ) + next_op_idx += 1 + + self.add_dxil_op( + "RayTCurrent", + next_op_idx, + "RayTCurrent", + "float representing the current parametric ending point for the ray", + "f", + "ro", + [db_dxil_param(0, "f", "", "result")], + ) + next_op_idx += 1 + + self.add_dxil_op( + "IgnoreHit", + next_op_idx, + "IgnoreHit", + "Used in an any hit shader to reject an intersection and terminate the shader", + "v", + "nr", + [db_dxil_param(0, "v", "", "")], + ) + next_op_idx += 1 + + self.add_dxil_op( + "AcceptHitAndEndSearch", + next_op_idx, + "AcceptHitAndEndSearch", + "Used in an any hit shader to abort the ray query and the intersection shader (if any). The current hit is committed and execution passes to the closest hit shader with the closest hit recorded so far", + "v", + "nr", + [db_dxil_param(0, "v", "", "")], + ) + next_op_idx += 1 + + self.add_dxil_op( + "TraceRay", + next_op_idx, + "TraceRay", + "initiates raytrace", + "u", + "", + [ + db_dxil_param(0, "v", "", ""), + db_dxil_param( + 2, + "res", + "AccelerationStructure", + "Top-level acceleration structure to use", + ), + db_dxil_param(3, "i32", "RayFlags", "Valid combination of Ray_flags"), + db_dxil_param( + 4, + "i32", + "InstanceInclusionMask", + "Bottom 8 bits of InstanceInclusionMask are used to include/rejectgeometry instances based on the InstanceMask in each instance: if(!((InstanceInclusionMask & InstanceMask) & 0xff)) { ignore intersection }", + ), + db_dxil_param( + 5, + "i32", + "RayContributionToHitGroupIndex", + "Offset to add into Addressing calculations within shader tables for hit group indexing. Only the bottom 4 bits of this value are used", + ), + db_dxil_param( + 6, + "i32", + "MultiplierForGeometryContributionToShaderIndex", + "Stride to multiply by per-geometry GeometryContributionToHitGroupIndex in Addressing calculations within shader tables for hit group indexing. Only the bottom 4 bits of this value are used", + ), + db_dxil_param( + 7, + "i32", + "MissShaderIndex", + "Miss shader index in Addressing calculations within shader tables. Only the bottom 16 bits of this value are used", + ), + db_dxil_param(8, "f", "Origin_X", "Origin x of the ray"), + db_dxil_param(9, "f", "Origin_Y", "Origin y of the ray"), + db_dxil_param(10, "f", "Origin_Z", "Origin z of the ray"), + db_dxil_param(11, "f", "TMin", "Tmin of the ray"), + db_dxil_param(12, "f", "Direction_X", "Direction x of the ray"), + db_dxil_param(13, "f", "Direction_Y", "Direction y of the ray"), + db_dxil_param(14, "f", "Direction_Z", "Direction z of the ray"), + db_dxil_param(15, "f", "TMax", "Tmax of the ray"), + db_dxil_param( + 16, + "udt", + "payload", + "User-defined intersection attribute structure", + ), + ], + ) + next_op_idx += 1 + + self.add_dxil_op( + "ReportHit", + next_op_idx, + "ReportHit", + "returns true if hit was accepted", + "u", + "", + [ + db_dxil_param(0, "i1", "", "result"), + db_dxil_param( + 2, "f", "THit", "parametric distance of the intersection" + ), + db_dxil_param( + 3, + "i32", + "HitKind", + "User-specified value in range of 0-127 to identify the type of hit. Read by any_hit or closes_hit shaders with HitKind()", + ), + db_dxil_param( + 4, + "udt", + "Attributes", + "User-defined intersection attribute structure", + ), + ], + ) + next_op_idx += 1 + + self.add_dxil_op( + "CallShader", + next_op_idx, + "CallShader", + "Call a shader in the callable shader table supplied through the DispatchRays() API", + "u", + "", + [ + db_dxil_param(0, "v", "", "result"), + db_dxil_param( + 2, + "i32", + "ShaderIndex", + "Provides index into the callable shader table supplied through the DispatchRays() API", + ), + db_dxil_param( + 3, + "udt", + "Parameter", + "User-defined parameters to pass to the callable shader,This parameter structure must match the parameter structure used in the callable shader pointed to in the shader table", + ), + ], + ) + next_op_idx += 1 + + self.add_dxil_op( + "CreateHandleForLib", + next_op_idx, + "CreateHandleForLib", + "create resource handle from resource struct for library", + "o", + "ro", + [ + db_dxil_param(0, "res", "", "result"), + db_dxil_param(2, "obj", "Resource", "resource to create the handle"), + ], + ) next_op_idx += 1 # Maps to PrimitiveIndex() intrinsics for raytracing (same meaning as PrimitiveID) - self.add_dxil_op("PrimitiveIndex", next_op_idx, "PrimitiveIndex", "PrimitiveIndex for raytracing shaders", "i", "rn", [ - db_dxil_param(0, "i32", "", "result")]) + self.add_dxil_op( + "PrimitiveIndex", + next_op_idx, + "PrimitiveIndex", + "PrimitiveIndex for raytracing shaders", + "i", + "rn", + [db_dxil_param(0, "i32", "", "result")], + ) next_op_idx += 1 # End of DXIL 1.3 opcodes. self.set_op_count_for_version(1, 3, next_op_idx) - assert next_op_idx == 162, "next operation index is %d rather than 162 and thus opcodes are broken" % next_op_idx - - self.add_dxil_op("Dot2AddHalf", next_op_idx, "Dot2AddHalf", "2D half dot product with accumulate to float", "f", "rn", [ - db_dxil_param(0, "$o", "", "accumulated result"), - db_dxil_param(2, "$o", "acc", "input accumulator"), - db_dxil_param(3, "h", "ax", "the first component of the first vector"), - db_dxil_param(4, "h", "ay", "the second component of the first vector"), - db_dxil_param(5, "h", "bx", "the first component of the second vector"), - db_dxil_param(6, "h", "by", "the second component of the second vector")], - counters=('floats',)) - next_op_idx += 1 - - self.add_dxil_op("Dot4AddI8Packed", next_op_idx, "Dot4AddPacked", "signed dot product of 4 x i8 vectors packed into i32, with accumulate to i32", "i", "rn", [ - db_dxil_param(0, "i32", "", "accumulated result"), - db_dxil_param(2, "i32", "acc", "input accumulator"), - db_dxil_param(3, "i32", "a", "first packed 4 x i8 for dot product"), - db_dxil_param(4, "i32", "b", "second packed 4 x i8 for dot product")], - counters=('ints',)) - next_op_idx += 1 - - self.add_dxil_op("Dot4AddU8Packed", next_op_idx, "Dot4AddPacked", "unsigned dot product of 4 x u8 vectors packed into i32, with accumulate to i32", "i", "rn", [ - db_dxil_param(0, "i32", "", "accumulated result"), - db_dxil_param(2, "i32", "acc", "input accumulator"), - db_dxil_param(3, "i32", "a", "first packed 4 x u8 for dot product"), - db_dxil_param(4, "i32", "b", "second packed 4 x u8 for dot product")], - counters=('uints',)) + assert next_op_idx == 162, ( + "next operation index is %d rather than 162 and thus opcodes are broken" + % next_op_idx + ) + + self.add_dxil_op( + "Dot2AddHalf", + next_op_idx, + "Dot2AddHalf", + "2D half dot product with accumulate to float", + "f", + "rn", + [ + db_dxil_param(0, "$o", "", "accumulated result"), + db_dxil_param(2, "$o", "acc", "input accumulator"), + db_dxil_param(3, "h", "ax", "the first component of the first vector"), + db_dxil_param(4, "h", "ay", "the second component of the first vector"), + db_dxil_param(5, "h", "bx", "the first component of the second vector"), + db_dxil_param( + 6, "h", "by", "the second component of the second vector" + ), + ], + counters=("floats",), + ) + next_op_idx += 1 + + self.add_dxil_op( + "Dot4AddI8Packed", + next_op_idx, + "Dot4AddPacked", + "signed dot product of 4 x i8 vectors packed into i32, with accumulate to i32", + "i", + "rn", + [ + db_dxil_param(0, "i32", "", "accumulated result"), + db_dxil_param(2, "i32", "acc", "input accumulator"), + db_dxil_param(3, "i32", "a", "first packed 4 x i8 for dot product"), + db_dxil_param(4, "i32", "b", "second packed 4 x i8 for dot product"), + ], + counters=("ints",), + ) + next_op_idx += 1 + + self.add_dxil_op( + "Dot4AddU8Packed", + next_op_idx, + "Dot4AddPacked", + "unsigned dot product of 4 x u8 vectors packed into i32, with accumulate to i32", + "i", + "rn", + [ + db_dxil_param(0, "i32", "", "accumulated result"), + db_dxil_param(2, "i32", "acc", "input accumulator"), + db_dxil_param(3, "i32", "a", "first packed 4 x u8 for dot product"), + db_dxil_param(4, "i32", "b", "second packed 4 x u8 for dot product"), + ], + counters=("uints",), + ) next_op_idx += 1 # End of DXIL 1.4 opcodes. self.set_op_count_for_version(1, 4, next_op_idx) - assert next_op_idx == 165, "next operation index is %d rather than 165 and thus opcodes are broken" % next_op_idx - - self.add_dxil_op("WaveMatch", next_op_idx, "WaveMatch", "returns the bitmask of active lanes that have the same value", "hfd8wil", "", [ - db_dxil_param(0, "fouri32", "", "operation result"), - db_dxil_param(2, "$o", "value", "input value")]) - next_op_idx += 1 - - self.add_dxil_op("WaveMultiPrefixOp", next_op_idx, "WaveMultiPrefixOp", "returns the result of the operation on groups of lanes identified by a bitmask", "hfd8wil", "", [ - db_dxil_param(0, "$o", "", "operation result"), - db_dxil_param(2, "$o", "value", "input value"), - db_dxil_param(3, "i32", "mask0", "mask 0"), - db_dxil_param(4, "i32", "mask1", "mask 1"), - db_dxil_param(5, "i32", "mask2", "mask 2"), - db_dxil_param(6, "i32", "mask3", "mask 3"), - db_dxil_param(7, "i8", "op", "operation", enum_name="WaveMultiPrefixOpKind", is_const=True), - db_dxil_param(8, "i8", "sop", "sign of operands", enum_name="SignedOpKind", is_const=True)]) - next_op_idx += 1 - self.add_enum_type("WaveMultiPrefixOpKind", "Kind of cross-lane for multi-prefix operation", [ - (0, "Sum", "sum of values"), - (1, "And", "bitwise and of values"), - (2, "Or", "bitwise or of values"), - (3, "Xor", "bitwise xor of values"), - (4, "Product", "product of values")]) - - self.add_dxil_op("WaveMultiPrefixBitCount", next_op_idx, "WaveMultiPrefixBitCount", "returns the count of bits set to 1 on groups of lanes identified by a bitmask", "v", "", [ - db_dxil_param(0, "i32", "", "operation result"), - db_dxil_param(2, "i1", "value", "input value"), - db_dxil_param(3, "i32", "mask0", "mask 0"), - db_dxil_param(4, "i32", "mask1", "mask 1"), - db_dxil_param(5, "i32", "mask2", "mask 2"), - db_dxil_param(6, "i32", "mask3", "mask 3")]) + assert next_op_idx == 165, ( + "next operation index is %d rather than 165 and thus opcodes are broken" + % next_op_idx + ) + + self.add_dxil_op( + "WaveMatch", + next_op_idx, + "WaveMatch", + "returns the bitmask of active lanes that have the same value", + "hfd8wil", + "", + [ + db_dxil_param(0, "fouri32", "", "operation result"), + db_dxil_param(2, "$o", "value", "input value"), + ], + ) + next_op_idx += 1 + + self.add_dxil_op( + "WaveMultiPrefixOp", + next_op_idx, + "WaveMultiPrefixOp", + "returns the result of the operation on groups of lanes identified by a bitmask", + "hfd8wil", + "", + [ + db_dxil_param(0, "$o", "", "operation result"), + db_dxil_param(2, "$o", "value", "input value"), + db_dxil_param(3, "i32", "mask0", "mask 0"), + db_dxil_param(4, "i32", "mask1", "mask 1"), + db_dxil_param(5, "i32", "mask2", "mask 2"), + db_dxil_param(6, "i32", "mask3", "mask 3"), + db_dxil_param( + 7, + "i8", + "op", + "operation", + enum_name="WaveMultiPrefixOpKind", + is_const=True, + ), + db_dxil_param( + 8, + "i8", + "sop", + "sign of operands", + enum_name="SignedOpKind", + is_const=True, + ), + ], + ) + next_op_idx += 1 + self.add_enum_type( + "WaveMultiPrefixOpKind", + "Kind of cross-lane for multi-prefix operation", + [ + (0, "Sum", "sum of values"), + (1, "And", "bitwise and of values"), + (2, "Or", "bitwise or of values"), + (3, "Xor", "bitwise xor of values"), + (4, "Product", "product of values"), + ], + ) + + self.add_dxil_op( + "WaveMultiPrefixBitCount", + next_op_idx, + "WaveMultiPrefixBitCount", + "returns the count of bits set to 1 on groups of lanes identified by a bitmask", + "v", + "", + [ + db_dxil_param(0, "i32", "", "operation result"), + db_dxil_param(2, "i1", "value", "input value"), + db_dxil_param(3, "i32", "mask0", "mask 0"), + db_dxil_param(4, "i32", "mask1", "mask 1"), + db_dxil_param(5, "i32", "mask2", "mask 2"), + db_dxil_param(6, "i32", "mask3", "mask 3"), + ], + ) next_op_idx += 1 # Mesh Shader - self.add_dxil_op("SetMeshOutputCounts", next_op_idx, "SetMeshOutputCounts", "Mesh shader intrinsic SetMeshOutputCounts", "v", "", [ - retvoid_param, - db_dxil_param(2, "i32", "numVertices", "number of output vertices"), - db_dxil_param(3, "i32", "numPrimitives", "number of output primitives")]) - next_op_idx += 1 - self.add_dxil_op("EmitIndices", next_op_idx, "EmitIndices", "emit a primitive's vertex indices in a mesh shader", "v", "", [ - retvoid_param, - db_dxil_param(2, "u32", "PrimitiveIndex", "a primitive's index"), - db_dxil_param(3, "u32", "VertexIndex0", "a primitive's first vertex index"), - db_dxil_param(4, "u32", "VertexIndex1", "a primitive's second vertex index"), - db_dxil_param(5, "u32", "VertexIndex2", "a primitive's third vertex index")]) - next_op_idx += 1 - self.add_dxil_op("GetMeshPayload", next_op_idx, "GetMeshPayload", "get the mesh payload which is from amplification shader", "u", "ro", [ - db_dxil_param(0, "$o", "", "mesh payload result")]) - next_op_idx += 1 - self.add_dxil_op("StoreVertexOutput", next_op_idx, "StoreVertexOutput", "stores the value to mesh shader vertex output", "hfwi", "", [ - retvoid_param, - db_dxil_param(2, "u32", "outputSigId", "vertex output signature element ID"), - db_dxil_param(3, "u32", "rowIndex", "row index relative to element"), - db_dxil_param(4, "u8", "colIndex", "column index relative to element"), - db_dxil_param(5, "$o", "value", "value to store"), - db_dxil_param(6, "u32", "vertexIndex", "vertex index")], - counters=('sig_st',)) - next_op_idx += 1 - self.add_dxil_op("StorePrimitiveOutput", next_op_idx, "StorePrimitiveOutput", "stores the value to mesh shader primitive output", "hfwi", "", [ - retvoid_param, - db_dxil_param(2, "u32", "outputSigId", "primitive output signature element ID"), - db_dxil_param(3, "u32", "rowIndex", "row index relative to element"), - db_dxil_param(4, "u8", "colIndex", "column index relative to element"), - db_dxil_param(5, "$o", "value", "value to store"), - db_dxil_param(6, "u32", "primitiveIndex", "primitive index")], - counters=('sig_st',)) + self.add_dxil_op( + "SetMeshOutputCounts", + next_op_idx, + "SetMeshOutputCounts", + "Mesh shader intrinsic SetMeshOutputCounts", + "v", + "", + [ + retvoid_param, + db_dxil_param(2, "i32", "numVertices", "number of output vertices"), + db_dxil_param(3, "i32", "numPrimitives", "number of output primitives"), + ], + ) + next_op_idx += 1 + self.add_dxil_op( + "EmitIndices", + next_op_idx, + "EmitIndices", + "emit a primitive's vertex indices in a mesh shader", + "v", + "", + [ + retvoid_param, + db_dxil_param(2, "u32", "PrimitiveIndex", "a primitive's index"), + db_dxil_param( + 3, "u32", "VertexIndex0", "a primitive's first vertex index" + ), + db_dxil_param( + 4, "u32", "VertexIndex1", "a primitive's second vertex index" + ), + db_dxil_param( + 5, "u32", "VertexIndex2", "a primitive's third vertex index" + ), + ], + ) + next_op_idx += 1 + self.add_dxil_op( + "GetMeshPayload", + next_op_idx, + "GetMeshPayload", + "get the mesh payload which is from amplification shader", + "u", + "ro", + [db_dxil_param(0, "$o", "", "mesh payload result")], + ) + next_op_idx += 1 + self.add_dxil_op( + "StoreVertexOutput", + next_op_idx, + "StoreVertexOutput", + "stores the value to mesh shader vertex output", + "hfwi", + "", + [ + retvoid_param, + db_dxil_param( + 2, "u32", "outputSigId", "vertex output signature element ID" + ), + db_dxil_param(3, "u32", "rowIndex", "row index relative to element"), + db_dxil_param(4, "u8", "colIndex", "column index relative to element"), + db_dxil_param(5, "$o", "value", "value to store"), + db_dxil_param(6, "u32", "vertexIndex", "vertex index"), + ], + counters=("sig_st",), + ) + next_op_idx += 1 + self.add_dxil_op( + "StorePrimitiveOutput", + next_op_idx, + "StorePrimitiveOutput", + "stores the value to mesh shader primitive output", + "hfwi", + "", + [ + retvoid_param, + db_dxil_param( + 2, "u32", "outputSigId", "primitive output signature element ID" + ), + db_dxil_param(3, "u32", "rowIndex", "row index relative to element"), + db_dxil_param(4, "u8", "colIndex", "column index relative to element"), + db_dxil_param(5, "$o", "value", "value to store"), + db_dxil_param(6, "u32", "primitiveIndex", "primitive index"), + ], + counters=("sig_st",), + ) next_op_idx += 1 # Amplification Shader - self.add_dxil_op("DispatchMesh", next_op_idx, "DispatchMesh", "Amplification shader intrinsic DispatchMesh", "u", "", [ - retvoid_param, - db_dxil_param(2, "i32", "threadGroupCountX", "thread group count x"), - db_dxil_param(3, "i32", "threadGroupCountY", "thread group count y"), - db_dxil_param(4, "i32", "threadGroupCountZ", "thread group count z"), - db_dxil_param(5, "$o", "payload", "payload")]) + self.add_dxil_op( + "DispatchMesh", + next_op_idx, + "DispatchMesh", + "Amplification shader intrinsic DispatchMesh", + "u", + "", + [ + retvoid_param, + db_dxil_param(2, "i32", "threadGroupCountX", "thread group count x"), + db_dxil_param(3, "i32", "threadGroupCountY", "thread group count y"), + db_dxil_param(4, "i32", "threadGroupCountZ", "thread group count z"), + db_dxil_param(5, "$o", "payload", "payload"), + ], + ) next_op_idx += 1 # Sampler feedback - self.add_dxil_op("WriteSamplerFeedback", next_op_idx, "WriteSamplerFeedback", "updates a feedback texture for a sampling operation", "v", "", [ - db_dxil_param(0, "v", "", ""), - db_dxil_param(2, "res", "feedbackTex", "handle of feedback texture UAV"), - db_dxil_param(3, "res", "sampledTex", "handled of sampled texture SRV"), - db_dxil_param(4, "res", "sampler", "handle of sampler"), - db_dxil_param(5, "f", "c0", "coordinate c0"), - db_dxil_param(6, "f", "c1", "coordinate c1"), - db_dxil_param(7, "f", "c2", "coordinate c2"), - db_dxil_param(8, "f", "c3", "coordinate c3"), - db_dxil_param(9, "f", "clamp", "clamp")], - counters=('tex_store',)) - next_op_idx += 1 - self.add_dxil_op("WriteSamplerFeedbackBias", next_op_idx, "WriteSamplerFeedbackBias", "updates a feedback texture for a sampling operation with a bias on the mipmap level", "v", "", [ - db_dxil_param(0, "v", "", ""), - db_dxil_param(2, "res", "feedbackTex", "handle of feedback texture UAV"), - db_dxil_param(3, "res", "sampledTex", "handled of sampled texture SRV"), - db_dxil_param(4, "res", "sampler", "handle of sampler"), - db_dxil_param(5, "f", "c0", "coordinate c0"), - db_dxil_param(6, "f", "c1", "coordinate c1"), - db_dxil_param(7, "f", "c2", "coordinate c2"), - db_dxil_param(8, "f", "c3", "coordinate c3"), - db_dxil_param(9, "f", "bias", "bias in [-16.f,15.99f]"), - db_dxil_param(10, "f", "clamp", "clamp")], - counters=('tex_store',)) - next_op_idx += 1 - self.add_dxil_op("WriteSamplerFeedbackLevel", next_op_idx, "WriteSamplerFeedbackLevel", "updates a feedback texture for a sampling operation with a mipmap-level offset", "v", "", [ - db_dxil_param(0, "v", "", ""), - db_dxil_param(2, "res", "feedbackTex", "handle of feedback texture UAV"), - db_dxil_param(3, "res", "sampledTex", "handled of sampled texture SRV"), - db_dxil_param(4, "res", "sampler", "handle of sampler"), - db_dxil_param(5, "f", "c0", "coordinate c0"), - db_dxil_param(6, "f", "c1", "coordinate c1"), - db_dxil_param(7, "f", "c2", "coordinate c2"), - db_dxil_param(8, "f", "c3", "coordinate c3"), - db_dxil_param(9, "f", "lod", "LOD")], - counters=('tex_store',)) - next_op_idx += 1 - self.add_dxil_op("WriteSamplerFeedbackGrad", next_op_idx, "WriteSamplerFeedbackGrad", "updates a feedback texture for a sampling operation with explicit gradients", "v", "", [ - db_dxil_param(0, "v", "", ""), - db_dxil_param(2, "res", "feedbackTex", "handle of feedback texture UAV"), - db_dxil_param(3, "res", "sampledTex", "handled of sampled texture SRV"), - db_dxil_param(4, "res", "sampler", "handle of sampler"), - db_dxil_param(5, "f", "c0", "coordinate c0"), - db_dxil_param(6, "f", "c1", "coordinate c1"), - db_dxil_param(7, "f", "c2", "coordinate c2"), - db_dxil_param(8, "f", "c3", "coordinate c3"), - db_dxil_param(9, "f", "ddx0", "rate of change of coordinate c0 in the x direction"), - db_dxil_param(10, "f", "ddx1", "rate of change of coordinate c1 in the x direction"), - db_dxil_param(11, "f", "ddx2", "rate of change of coordinate c2 in the x direction"), - db_dxil_param(12, "f", "ddy0", "rate of change of coordinate c0 in the y direction"), - db_dxil_param(13, "f", "ddy1", "rate of change of coordinate c1 in the y direction"), - db_dxil_param(14, "f", "ddy2", "rate of change of coordinate c2 in the y direction"), - db_dxil_param(15, "f", "clamp", "clamp")], - counters=('tex_store',)) + self.add_dxil_op( + "WriteSamplerFeedback", + next_op_idx, + "WriteSamplerFeedback", + "updates a feedback texture for a sampling operation", + "v", + "", + [ + db_dxil_param(0, "v", "", ""), + db_dxil_param( + 2, "res", "feedbackTex", "handle of feedback texture UAV" + ), + db_dxil_param(3, "res", "sampledTex", "handled of sampled texture SRV"), + db_dxil_param(4, "res", "sampler", "handle of sampler"), + db_dxil_param(5, "f", "c0", "coordinate c0"), + db_dxil_param(6, "f", "c1", "coordinate c1"), + db_dxil_param(7, "f", "c2", "coordinate c2"), + db_dxil_param(8, "f", "c3", "coordinate c3"), + db_dxil_param(9, "f", "clamp", "clamp"), + ], + counters=("tex_store",), + ) + next_op_idx += 1 + self.add_dxil_op( + "WriteSamplerFeedbackBias", + next_op_idx, + "WriteSamplerFeedbackBias", + "updates a feedback texture for a sampling operation with a bias on the mipmap level", + "v", + "", + [ + db_dxil_param(0, "v", "", ""), + db_dxil_param( + 2, "res", "feedbackTex", "handle of feedback texture UAV" + ), + db_dxil_param(3, "res", "sampledTex", "handled of sampled texture SRV"), + db_dxil_param(4, "res", "sampler", "handle of sampler"), + db_dxil_param(5, "f", "c0", "coordinate c0"), + db_dxil_param(6, "f", "c1", "coordinate c1"), + db_dxil_param(7, "f", "c2", "coordinate c2"), + db_dxil_param(8, "f", "c3", "coordinate c3"), + db_dxil_param(9, "f", "bias", "bias in [-16.f,15.99f]"), + db_dxil_param(10, "f", "clamp", "clamp"), + ], + counters=("tex_store",), + ) + next_op_idx += 1 + self.add_dxil_op( + "WriteSamplerFeedbackLevel", + next_op_idx, + "WriteSamplerFeedbackLevel", + "updates a feedback texture for a sampling operation with a mipmap-level offset", + "v", + "", + [ + db_dxil_param(0, "v", "", ""), + db_dxil_param( + 2, "res", "feedbackTex", "handle of feedback texture UAV" + ), + db_dxil_param(3, "res", "sampledTex", "handled of sampled texture SRV"), + db_dxil_param(4, "res", "sampler", "handle of sampler"), + db_dxil_param(5, "f", "c0", "coordinate c0"), + db_dxil_param(6, "f", "c1", "coordinate c1"), + db_dxil_param(7, "f", "c2", "coordinate c2"), + db_dxil_param(8, "f", "c3", "coordinate c3"), + db_dxil_param(9, "f", "lod", "LOD"), + ], + counters=("tex_store",), + ) + next_op_idx += 1 + self.add_dxil_op( + "WriteSamplerFeedbackGrad", + next_op_idx, + "WriteSamplerFeedbackGrad", + "updates a feedback texture for a sampling operation with explicit gradients", + "v", + "", + [ + db_dxil_param(0, "v", "", ""), + db_dxil_param( + 2, "res", "feedbackTex", "handle of feedback texture UAV" + ), + db_dxil_param(3, "res", "sampledTex", "handled of sampled texture SRV"), + db_dxil_param(4, "res", "sampler", "handle of sampler"), + db_dxil_param(5, "f", "c0", "coordinate c0"), + db_dxil_param(6, "f", "c1", "coordinate c1"), + db_dxil_param(7, "f", "c2", "coordinate c2"), + db_dxil_param(8, "f", "c3", "coordinate c3"), + db_dxil_param( + 9, "f", "ddx0", "rate of change of coordinate c0 in the x direction" + ), + db_dxil_param( + 10, + "f", + "ddx1", + "rate of change of coordinate c1 in the x direction", + ), + db_dxil_param( + 11, + "f", + "ddx2", + "rate of change of coordinate c2 in the x direction", + ), + db_dxil_param( + 12, + "f", + "ddy0", + "rate of change of coordinate c0 in the y direction", + ), + db_dxil_param( + 13, + "f", + "ddy1", + "rate of change of coordinate c1 in the y direction", + ), + db_dxil_param( + 14, + "f", + "ddy2", + "rate of change of coordinate c2 in the y direction", + ), + db_dxil_param(15, "f", "clamp", "clamp"), + ], + counters=("tex_store",), + ) next_op_idx += 1 # RayQuery - self.add_dxil_op("AllocateRayQuery", next_op_idx, "AllocateRayQuery", "allocates space for RayQuery and return handle", "v", "", [ - db_dxil_param(0, "i32", "", "handle to RayQuery state"), - db_dxil_param(2, "u32", "constRayFlags", "Valid combination of RAY_FLAGS", is_const=True)]) - next_op_idx += 1 - - self.add_dxil_op("RayQuery_TraceRayInline", next_op_idx, "RayQuery_TraceRayInline", "initializes RayQuery for raytrace", "v", "", [ - db_dxil_param(0, "v", "", ""), - db_dxil_param(2, "i32", "rayQueryHandle", "RayQuery handle"), - db_dxil_param(3, "res", "accelerationStructure", "Top-level acceleration structure to use"), - db_dxil_param(4, "i32", "rayFlags", "Valid combination of RAY_FLAGS, combined with constRayFlags provided to AllocateRayQuery"), - db_dxil_param(5, "i32", "instanceInclusionMask", "Bottom 8 bits of InstanceInclusionMask are used to include/rejectgeometry instances based on the InstanceMask in each instance: if(!((InstanceInclusionMask & InstanceMask) & 0xff)) { ignore intersection }"), - db_dxil_param(6, "f", "origin_X", "Origin x of the ray"), - db_dxil_param(7, "f", "origin_Y", "Origin y of the ray"), - db_dxil_param(8, "f", "origin_Z", "Origin z of the ray"), - db_dxil_param(9, "f", "tMin", "Tmin of the ray"), - db_dxil_param(10, "f", "direction_X", "Direction x of the ray"), - db_dxil_param(11, "f", "direction_Y", "Direction y of the ray"), - db_dxil_param(12, "f", "direction_Z", "Direction z of the ray"), - db_dxil_param(13, "f", "tMax", "Tmax of the ray")]) - next_op_idx += 1 - - self.add_dxil_op("RayQuery_Proceed", next_op_idx, "RayQuery_Proceed", "advances a ray query", "1", "", [ - db_dxil_param(0, "i1", "", "operation result"), - db_dxil_param(2, "i32", "rayQueryHandle", "RayQuery handle")]) - next_op_idx += 1 - - self.add_dxil_op("RayQuery_Abort", next_op_idx, "RayQuery_Abort", "aborts a ray query", "v", "", [ - db_dxil_param(0, "v", "", ""), - db_dxil_param(2, "i32", "rayQueryHandle", "RayQuery handle")]) - next_op_idx += 1 - - self.add_dxil_op("RayQuery_CommitNonOpaqueTriangleHit", next_op_idx, "RayQuery_CommitNonOpaqueTriangleHit", "commits a non opaque triangle hit", "v", "", [ - db_dxil_param(0, "v", "", ""), - db_dxil_param(2, "i32", "rayQueryHandle", "RayQuery handle")]) - next_op_idx += 1 - - self.add_dxil_op("RayQuery_CommitProceduralPrimitiveHit", next_op_idx, "RayQuery_CommitProceduralPrimitiveHit", "commits a procedural primitive hit", "v", "", [ - db_dxil_param(0, "v", "", ""), - db_dxil_param(2, "i32", "rayQueryHandle", "RayQuery handle"), - db_dxil_param(3, "f", "t", "Procedural primitive hit distance (t) to commit.")]) - next_op_idx += 1 - - self.add_dxil_op("RayQuery_CommittedStatus", next_op_idx, "RayQuery_StateScalar", "returns uint status (COMMITTED_STATUS) of the committed hit in a ray query", "i", "ro", [ - db_dxil_param(0, "i32", "", "operation result"), - db_dxil_param(2, "i32", "rayQueryHandle", "RayQuery handle")]) - next_op_idx += 1 - - self.add_dxil_op("RayQuery_CandidateType", next_op_idx, "RayQuery_StateScalar", "returns uint candidate type (CANDIDATE_TYPE) of the current hit candidate in a ray query, after Proceed() has returned true", "i", "ro", [ - db_dxil_param(0, "i32", "", "operation result"), - db_dxil_param(2, "i32", "rayQueryHandle", "RayQuery handle")]) - next_op_idx += 1 - - self.add_dxil_op("RayQuery_CandidateObjectToWorld3x4", next_op_idx, "RayQuery_StateMatrix", "returns matrix for transforming from object-space to world-space for a candidate hit.", "f", "ro", [ - db_dxil_param(0, "f", "", "operation result"), - db_dxil_param(2, "i32", "rayQueryHandle", "RayQuery handle"), - db_dxil_param(3, "i32", "row", "row [0..2], relative to the element"), - db_dxil_param(4, "i8", "col", "column [0..3], relative to the element")]) - next_op_idx += 1 - - self.add_dxil_op("RayQuery_CandidateWorldToObject3x4", next_op_idx, "RayQuery_StateMatrix", "returns matrix for transforming from world-space to object-space for a candidate hit.", "f", "ro", [ - db_dxil_param(0, "f", "", "operation result"), - db_dxil_param(2, "i32", "rayQueryHandle", "RayQuery handle"), - db_dxil_param(3, "i32", "row", "row [0..2], relative to the element"), - db_dxil_param(4, "i8", "col", "column [0..3], relative to the element")]) - next_op_idx += 1 - - self.add_dxil_op("RayQuery_CommittedObjectToWorld3x4", next_op_idx, "RayQuery_StateMatrix", "returns matrix for transforming from object-space to world-space for a Committed hit.", "f", "ro", [ - db_dxil_param(0, "f", "", "operation result"), - db_dxil_param(2, "i32", "rayQueryHandle", "RayQuery handle"), - db_dxil_param(3, "i32", "row", "row [0..2], relative to the element"), - db_dxil_param(4, "i8", "col", "column [0..3], relative to the element")]) - next_op_idx += 1 - - self.add_dxil_op("RayQuery_CommittedWorldToObject3x4", next_op_idx, "RayQuery_StateMatrix", "returns matrix for transforming from world-space to object-space for a Committed hit.", "f", "ro", [ - db_dxil_param(0, "f", "", "operation result"), - db_dxil_param(2, "i32", "rayQueryHandle", "RayQuery handle"), - db_dxil_param(3, "i32", "row", "row [0..2], relative to the element"), - db_dxil_param(4, "i8", "col", "column [0..3], relative to the element")]) - next_op_idx += 1 - - self.add_dxil_op("RayQuery_CandidateProceduralPrimitiveNonOpaque", next_op_idx, "RayQuery_StateScalar", "returns if current candidate procedural primitive is non opaque", "1", "ro", [ - db_dxil_param(0, "i1", "", "operation result"), - db_dxil_param(2, "i32", "rayQueryHandle", "RayQuery handle")]) - next_op_idx += 1 - - self.add_dxil_op("RayQuery_CandidateTriangleFrontFace", next_op_idx, "RayQuery_StateScalar", "returns if current candidate triangle is front facing", "1", "ro", [ - db_dxil_param(0, "i1", "", "operation result"), - db_dxil_param(2, "i32", "rayQueryHandle", "RayQuery handle")]) - next_op_idx += 1 - - self.add_dxil_op("RayQuery_CommittedTriangleFrontFace", next_op_idx, "RayQuery_StateScalar", "returns if current committed triangle is front facing", "1", "ro", [ - db_dxil_param(0, "i1", "", "operation result"), - db_dxil_param(2, "i32", "rayQueryHandle", "RayQuery handle")]) - next_op_idx += 1 - - self.add_dxil_op("RayQuery_CandidateTriangleBarycentrics", next_op_idx, "RayQuery_StateVector", "returns candidate triangle hit barycentrics", "f", "ro", [ - db_dxil_param(0, "f", "", "operation result"), - db_dxil_param(2, "i32", "rayQueryHandle", "RayQuery handle"), - db_dxil_param(3, "i8", "component", "component [0..2]",is_const=True)]) - next_op_idx += 1 - - self.add_dxil_op("RayQuery_CommittedTriangleBarycentrics", next_op_idx, "RayQuery_StateVector", "returns committed triangle hit barycentrics", "f", "ro", [ - db_dxil_param(0, "f", "", "operation result"), - db_dxil_param(2, "i32", "rayQueryHandle", "RayQuery handle"), - db_dxil_param(3, "i8", "component", "component [0..2]",is_const=True)]) - next_op_idx += 1 - - self.add_dxil_op("RayQuery_RayFlags", next_op_idx, "RayQuery_StateScalar", "returns ray flags", "i", "ro", [ - db_dxil_param(0, "i32", "", "operation result"), - db_dxil_param(2, "i32", "rayQueryHandle", "RayQuery handle")]) - next_op_idx += 1 - - self.add_dxil_op("RayQuery_WorldRayOrigin", next_op_idx, "RayQuery_StateVector", "returns world ray origin", "f", "ro", [ - db_dxil_param(0, "f", "", "operation result"), - db_dxil_param(2, "i32", "rayQueryHandle", "RayQuery handle"), - db_dxil_param(3, "i8", "component", "component [0..2]",is_const=True)]) - next_op_idx += 1 - - self.add_dxil_op("RayQuery_WorldRayDirection", next_op_idx, "RayQuery_StateVector", "returns world ray direction", "f", "ro", [ - db_dxil_param(0, "f", "", "operation result"), - db_dxil_param(2, "i32", "rayQueryHandle", "RayQuery handle"), - db_dxil_param(3, "i8", "component", "component [0..2]",is_const=True)]) - next_op_idx += 1 - - self.add_dxil_op("RayQuery_RayTMin", next_op_idx, "RayQuery_StateScalar", "returns float representing the parametric starting point for the ray.", "f", "ro", [ - db_dxil_param(0, "f", "", "operation result"), - db_dxil_param(2, "i32", "rayQueryHandle", "RayQuery handle")]) - next_op_idx += 1 - - self.add_dxil_op("RayQuery_CandidateTriangleRayT", next_op_idx, "RayQuery_StateScalar", "returns float representing the parametric point on the ray for the current candidate triangle hit.", "f", "ro", [ - db_dxil_param(0, "f", "", "operation result"), - db_dxil_param(2, "i32", "rayQueryHandle", "RayQuery handle")]) - next_op_idx += 1 - - self.add_dxil_op("RayQuery_CommittedRayT", next_op_idx, "RayQuery_StateScalar", "returns float representing the parametric point on the ray for the current committed hit.", "f", "ro", [ - db_dxil_param(0, "f", "", "operation result"), - db_dxil_param(2, "i32", "rayQueryHandle", "RayQuery handle")]) - next_op_idx += 1 - - self.add_dxil_op("RayQuery_CandidateInstanceIndex", next_op_idx, "RayQuery_StateScalar", "returns candidate hit instance index", "i", "ro", [ - db_dxil_param(0, "i32", "", "operation result"), - db_dxil_param(2, "i32", "rayQueryHandle", "RayQuery handle")]) - next_op_idx += 1 - - self.add_dxil_op("RayQuery_CandidateInstanceID", next_op_idx, "RayQuery_StateScalar", "returns candidate hit instance ID", "i", "ro", [ - db_dxil_param(0, "i32", "", "operation result"), - db_dxil_param(2, "i32", "rayQueryHandle", "RayQuery handle")]) - next_op_idx += 1 - - self.add_dxil_op("RayQuery_CandidateGeometryIndex", next_op_idx, "RayQuery_StateScalar", "returns candidate hit geometry index", "i", "ro", [ - db_dxil_param(0, "i32", "", "operation result"), - db_dxil_param(2, "i32", "rayQueryHandle", "RayQuery handle")]) - next_op_idx += 1 - - self.add_dxil_op("RayQuery_CandidatePrimitiveIndex", next_op_idx, "RayQuery_StateScalar", "returns candidate hit geometry index", "i", "ro", [ - db_dxil_param(0, "i32", "", "operation result"), - db_dxil_param(2, "i32", "rayQueryHandle", "RayQuery handle")]) - next_op_idx += 1 - - self.add_dxil_op("RayQuery_CandidateObjectRayOrigin", next_op_idx, "RayQuery_StateVector", "returns candidate hit object ray origin", "f", "ro", [ - db_dxil_param(0, "f", "", "operation result"), - db_dxil_param(2, "i32", "rayQueryHandle", "RayQuery handle"), - db_dxil_param(3, "i8", "component", "component [0..2]",is_const=True)]) - next_op_idx += 1 - - self.add_dxil_op("RayQuery_CandidateObjectRayDirection", next_op_idx, "RayQuery_StateVector", "returns candidate object ray direction", "f", "ro", [ - db_dxil_param(0, "f", "", "operation result"), - db_dxil_param(2, "i32", "rayQueryHandle", "RayQuery handle"), - db_dxil_param(3, "i8", "component", "component [0..2]",is_const=True)]) - next_op_idx += 1 - - self.add_dxil_op("RayQuery_CommittedInstanceIndex", next_op_idx, "RayQuery_StateScalar", "returns committed hit instance index", "i", "ro", [ - db_dxil_param(0, "i32", "", "operation result"), - db_dxil_param(2, "i32", "rayQueryHandle", "RayQuery handle")]) - next_op_idx += 1 - - self.add_dxil_op("RayQuery_CommittedInstanceID", next_op_idx, "RayQuery_StateScalar", "returns committed hit instance ID", "i", "ro", [ - db_dxil_param(0, "i32", "", "operation result"), - db_dxil_param(2, "i32", "rayQueryHandle", "RayQuery handle")]) - next_op_idx += 1 - - self.add_dxil_op("RayQuery_CommittedGeometryIndex", next_op_idx, "RayQuery_StateScalar", "returns committed hit geometry index", "i", "ro", [ - db_dxil_param(0, "i32", "", "operation result"), - db_dxil_param(2, "i32", "rayQueryHandle", "RayQuery handle")]) - next_op_idx += 1 - - self.add_dxil_op("RayQuery_CommittedPrimitiveIndex", next_op_idx, "RayQuery_StateScalar", "returns committed hit geometry index", "i", "ro", [ - db_dxil_param(0, "i32", "", "operation result"), - db_dxil_param(2, "i32", "rayQueryHandle", "RayQuery handle")]) - next_op_idx += 1 - - self.add_dxil_op("RayQuery_CommittedObjectRayOrigin", next_op_idx, "RayQuery_StateVector", "returns committed hit object ray origin", "f", "ro", [ - db_dxil_param(0, "f", "", "operation result"), - db_dxil_param(2, "i32", "rayQueryHandle", "RayQuery handle"), - db_dxil_param(3, "i8", "component", "component [0..2]",is_const=True)]) - next_op_idx += 1 - - self.add_dxil_op("RayQuery_CommittedObjectRayDirection", next_op_idx, "RayQuery_StateVector", "returns committed object ray direction", "f", "ro", [ - db_dxil_param(0, "f", "", "operation result"), - db_dxil_param(2, "i32", "rayQueryHandle", "RayQuery handle"), - db_dxil_param(3, "i8", "component", "component [0..2]",is_const=True)]) - next_op_idx += 1 - - self.add_dxil_op("GeometryIndex", next_op_idx, "GeometryIndex", "The autogenerated index of the current geometry in the bottom-level structure", "i", "rn", [ - db_dxil_param(0, "i32", "", "result")]) - next_op_idx += 1 - - self.add_dxil_op("RayQuery_CandidateInstanceContributionToHitGroupIndex", next_op_idx, "RayQuery_StateScalar", "returns candidate hit InstanceContributionToHitGroupIndex", "i", "ro", [ - db_dxil_param(0, "i32", "", "operation result"), - db_dxil_param(2, "i32", "rayQueryHandle", "RayQuery handle")]) - next_op_idx += 1 - - self.add_dxil_op("RayQuery_CommittedInstanceContributionToHitGroupIndex", next_op_idx, "RayQuery_StateScalar", "returns committed hit InstanceContributionToHitGroupIndex", "i", "ro", [ - db_dxil_param(0, "i32", "", "operation result"), - db_dxil_param(2, "i32", "rayQueryHandle", "RayQuery handle")]) + self.add_dxil_op( + "AllocateRayQuery", + next_op_idx, + "AllocateRayQuery", + "allocates space for RayQuery and return handle", + "v", + "", + [ + db_dxil_param(0, "i32", "", "handle to RayQuery state"), + db_dxil_param( + 2, + "u32", + "constRayFlags", + "Valid combination of RAY_FLAGS", + is_const=True, + ), + ], + ) + next_op_idx += 1 + + self.add_dxil_op( + "RayQuery_TraceRayInline", + next_op_idx, + "RayQuery_TraceRayInline", + "initializes RayQuery for raytrace", + "v", + "", + [ + db_dxil_param(0, "v", "", ""), + db_dxil_param(2, "i32", "rayQueryHandle", "RayQuery handle"), + db_dxil_param( + 3, + "res", + "accelerationStructure", + "Top-level acceleration structure to use", + ), + db_dxil_param( + 4, + "i32", + "rayFlags", + "Valid combination of RAY_FLAGS, combined with constRayFlags provided to AllocateRayQuery", + ), + db_dxil_param( + 5, + "i32", + "instanceInclusionMask", + "Bottom 8 bits of InstanceInclusionMask are used to include/rejectgeometry instances based on the InstanceMask in each instance: if(!((InstanceInclusionMask & InstanceMask) & 0xff)) { ignore intersection }", + ), + db_dxil_param(6, "f", "origin_X", "Origin x of the ray"), + db_dxil_param(7, "f", "origin_Y", "Origin y of the ray"), + db_dxil_param(8, "f", "origin_Z", "Origin z of the ray"), + db_dxil_param(9, "f", "tMin", "Tmin of the ray"), + db_dxil_param(10, "f", "direction_X", "Direction x of the ray"), + db_dxil_param(11, "f", "direction_Y", "Direction y of the ray"), + db_dxil_param(12, "f", "direction_Z", "Direction z of the ray"), + db_dxil_param(13, "f", "tMax", "Tmax of the ray"), + ], + ) + next_op_idx += 1 + + self.add_dxil_op( + "RayQuery_Proceed", + next_op_idx, + "RayQuery_Proceed", + "advances a ray query", + "1", + "", + [ + db_dxil_param(0, "i1", "", "operation result"), + db_dxil_param(2, "i32", "rayQueryHandle", "RayQuery handle"), + ], + ) + next_op_idx += 1 + + self.add_dxil_op( + "RayQuery_Abort", + next_op_idx, + "RayQuery_Abort", + "aborts a ray query", + "v", + "", + [ + db_dxil_param(0, "v", "", ""), + db_dxil_param(2, "i32", "rayQueryHandle", "RayQuery handle"), + ], + ) + next_op_idx += 1 + + self.add_dxil_op( + "RayQuery_CommitNonOpaqueTriangleHit", + next_op_idx, + "RayQuery_CommitNonOpaqueTriangleHit", + "commits a non opaque triangle hit", + "v", + "", + [ + db_dxil_param(0, "v", "", ""), + db_dxil_param(2, "i32", "rayQueryHandle", "RayQuery handle"), + ], + ) + next_op_idx += 1 + + self.add_dxil_op( + "RayQuery_CommitProceduralPrimitiveHit", + next_op_idx, + "RayQuery_CommitProceduralPrimitiveHit", + "commits a procedural primitive hit", + "v", + "", + [ + db_dxil_param(0, "v", "", ""), + db_dxil_param(2, "i32", "rayQueryHandle", "RayQuery handle"), + db_dxil_param( + 3, "f", "t", "Procedural primitive hit distance (t) to commit." + ), + ], + ) + next_op_idx += 1 + + self.add_dxil_op( + "RayQuery_CommittedStatus", + next_op_idx, + "RayQuery_StateScalar", + "returns uint status (COMMITTED_STATUS) of the committed hit in a ray query", + "i", + "ro", + [ + db_dxil_param(0, "i32", "", "operation result"), + db_dxil_param(2, "i32", "rayQueryHandle", "RayQuery handle"), + ], + ) + next_op_idx += 1 + + self.add_dxil_op( + "RayQuery_CandidateType", + next_op_idx, + "RayQuery_StateScalar", + "returns uint candidate type (CANDIDATE_TYPE) of the current hit candidate in a ray query, after Proceed() has returned true", + "i", + "ro", + [ + db_dxil_param(0, "i32", "", "operation result"), + db_dxil_param(2, "i32", "rayQueryHandle", "RayQuery handle"), + ], + ) + next_op_idx += 1 + + self.add_dxil_op( + "RayQuery_CandidateObjectToWorld3x4", + next_op_idx, + "RayQuery_StateMatrix", + "returns matrix for transforming from object-space to world-space for a candidate hit.", + "f", + "ro", + [ + db_dxil_param(0, "f", "", "operation result"), + db_dxil_param(2, "i32", "rayQueryHandle", "RayQuery handle"), + db_dxil_param(3, "i32", "row", "row [0..2], relative to the element"), + db_dxil_param(4, "i8", "col", "column [0..3], relative to the element"), + ], + ) + next_op_idx += 1 + + self.add_dxil_op( + "RayQuery_CandidateWorldToObject3x4", + next_op_idx, + "RayQuery_StateMatrix", + "returns matrix for transforming from world-space to object-space for a candidate hit.", + "f", + "ro", + [ + db_dxil_param(0, "f", "", "operation result"), + db_dxil_param(2, "i32", "rayQueryHandle", "RayQuery handle"), + db_dxil_param(3, "i32", "row", "row [0..2], relative to the element"), + db_dxil_param(4, "i8", "col", "column [0..3], relative to the element"), + ], + ) + next_op_idx += 1 + + self.add_dxil_op( + "RayQuery_CommittedObjectToWorld3x4", + next_op_idx, + "RayQuery_StateMatrix", + "returns matrix for transforming from object-space to world-space for a Committed hit.", + "f", + "ro", + [ + db_dxil_param(0, "f", "", "operation result"), + db_dxil_param(2, "i32", "rayQueryHandle", "RayQuery handle"), + db_dxil_param(3, "i32", "row", "row [0..2], relative to the element"), + db_dxil_param(4, "i8", "col", "column [0..3], relative to the element"), + ], + ) + next_op_idx += 1 + + self.add_dxil_op( + "RayQuery_CommittedWorldToObject3x4", + next_op_idx, + "RayQuery_StateMatrix", + "returns matrix for transforming from world-space to object-space for a Committed hit.", + "f", + "ro", + [ + db_dxil_param(0, "f", "", "operation result"), + db_dxil_param(2, "i32", "rayQueryHandle", "RayQuery handle"), + db_dxil_param(3, "i32", "row", "row [0..2], relative to the element"), + db_dxil_param(4, "i8", "col", "column [0..3], relative to the element"), + ], + ) + next_op_idx += 1 + + self.add_dxil_op( + "RayQuery_CandidateProceduralPrimitiveNonOpaque", + next_op_idx, + "RayQuery_StateScalar", + "returns if current candidate procedural primitive is non opaque", + "1", + "ro", + [ + db_dxil_param(0, "i1", "", "operation result"), + db_dxil_param(2, "i32", "rayQueryHandle", "RayQuery handle"), + ], + ) + next_op_idx += 1 + + self.add_dxil_op( + "RayQuery_CandidateTriangleFrontFace", + next_op_idx, + "RayQuery_StateScalar", + "returns if current candidate triangle is front facing", + "1", + "ro", + [ + db_dxil_param(0, "i1", "", "operation result"), + db_dxil_param(2, "i32", "rayQueryHandle", "RayQuery handle"), + ], + ) + next_op_idx += 1 + + self.add_dxil_op( + "RayQuery_CommittedTriangleFrontFace", + next_op_idx, + "RayQuery_StateScalar", + "returns if current committed triangle is front facing", + "1", + "ro", + [ + db_dxil_param(0, "i1", "", "operation result"), + db_dxil_param(2, "i32", "rayQueryHandle", "RayQuery handle"), + ], + ) + next_op_idx += 1 + + self.add_dxil_op( + "RayQuery_CandidateTriangleBarycentrics", + next_op_idx, + "RayQuery_StateVector", + "returns candidate triangle hit barycentrics", + "f", + "ro", + [ + db_dxil_param(0, "f", "", "operation result"), + db_dxil_param(2, "i32", "rayQueryHandle", "RayQuery handle"), + db_dxil_param(3, "i8", "component", "component [0..2]", is_const=True), + ], + ) + next_op_idx += 1 + + self.add_dxil_op( + "RayQuery_CommittedTriangleBarycentrics", + next_op_idx, + "RayQuery_StateVector", + "returns committed triangle hit barycentrics", + "f", + "ro", + [ + db_dxil_param(0, "f", "", "operation result"), + db_dxil_param(2, "i32", "rayQueryHandle", "RayQuery handle"), + db_dxil_param(3, "i8", "component", "component [0..2]", is_const=True), + ], + ) + next_op_idx += 1 + + self.add_dxil_op( + "RayQuery_RayFlags", + next_op_idx, + "RayQuery_StateScalar", + "returns ray flags", + "i", + "ro", + [ + db_dxil_param(0, "i32", "", "operation result"), + db_dxil_param(2, "i32", "rayQueryHandle", "RayQuery handle"), + ], + ) + next_op_idx += 1 + + self.add_dxil_op( + "RayQuery_WorldRayOrigin", + next_op_idx, + "RayQuery_StateVector", + "returns world ray origin", + "f", + "ro", + [ + db_dxil_param(0, "f", "", "operation result"), + db_dxil_param(2, "i32", "rayQueryHandle", "RayQuery handle"), + db_dxil_param(3, "i8", "component", "component [0..2]", is_const=True), + ], + ) + next_op_idx += 1 + + self.add_dxil_op( + "RayQuery_WorldRayDirection", + next_op_idx, + "RayQuery_StateVector", + "returns world ray direction", + "f", + "ro", + [ + db_dxil_param(0, "f", "", "operation result"), + db_dxil_param(2, "i32", "rayQueryHandle", "RayQuery handle"), + db_dxil_param(3, "i8", "component", "component [0..2]", is_const=True), + ], + ) + next_op_idx += 1 + + self.add_dxil_op( + "RayQuery_RayTMin", + next_op_idx, + "RayQuery_StateScalar", + "returns float representing the parametric starting point for the ray.", + "f", + "ro", + [ + db_dxil_param(0, "f", "", "operation result"), + db_dxil_param(2, "i32", "rayQueryHandle", "RayQuery handle"), + ], + ) + next_op_idx += 1 + + self.add_dxil_op( + "RayQuery_CandidateTriangleRayT", + next_op_idx, + "RayQuery_StateScalar", + "returns float representing the parametric point on the ray for the current candidate triangle hit.", + "f", + "ro", + [ + db_dxil_param(0, "f", "", "operation result"), + db_dxil_param(2, "i32", "rayQueryHandle", "RayQuery handle"), + ], + ) + next_op_idx += 1 + + self.add_dxil_op( + "RayQuery_CommittedRayT", + next_op_idx, + "RayQuery_StateScalar", + "returns float representing the parametric point on the ray for the current committed hit.", + "f", + "ro", + [ + db_dxil_param(0, "f", "", "operation result"), + db_dxil_param(2, "i32", "rayQueryHandle", "RayQuery handle"), + ], + ) + next_op_idx += 1 + + self.add_dxil_op( + "RayQuery_CandidateInstanceIndex", + next_op_idx, + "RayQuery_StateScalar", + "returns candidate hit instance index", + "i", + "ro", + [ + db_dxil_param(0, "i32", "", "operation result"), + db_dxil_param(2, "i32", "rayQueryHandle", "RayQuery handle"), + ], + ) + next_op_idx += 1 + + self.add_dxil_op( + "RayQuery_CandidateInstanceID", + next_op_idx, + "RayQuery_StateScalar", + "returns candidate hit instance ID", + "i", + "ro", + [ + db_dxil_param(0, "i32", "", "operation result"), + db_dxil_param(2, "i32", "rayQueryHandle", "RayQuery handle"), + ], + ) + next_op_idx += 1 + + self.add_dxil_op( + "RayQuery_CandidateGeometryIndex", + next_op_idx, + "RayQuery_StateScalar", + "returns candidate hit geometry index", + "i", + "ro", + [ + db_dxil_param(0, "i32", "", "operation result"), + db_dxil_param(2, "i32", "rayQueryHandle", "RayQuery handle"), + ], + ) + next_op_idx += 1 + + self.add_dxil_op( + "RayQuery_CandidatePrimitiveIndex", + next_op_idx, + "RayQuery_StateScalar", + "returns candidate hit geometry index", + "i", + "ro", + [ + db_dxil_param(0, "i32", "", "operation result"), + db_dxil_param(2, "i32", "rayQueryHandle", "RayQuery handle"), + ], + ) + next_op_idx += 1 + + self.add_dxil_op( + "RayQuery_CandidateObjectRayOrigin", + next_op_idx, + "RayQuery_StateVector", + "returns candidate hit object ray origin", + "f", + "ro", + [ + db_dxil_param(0, "f", "", "operation result"), + db_dxil_param(2, "i32", "rayQueryHandle", "RayQuery handle"), + db_dxil_param(3, "i8", "component", "component [0..2]", is_const=True), + ], + ) + next_op_idx += 1 + + self.add_dxil_op( + "RayQuery_CandidateObjectRayDirection", + next_op_idx, + "RayQuery_StateVector", + "returns candidate object ray direction", + "f", + "ro", + [ + db_dxil_param(0, "f", "", "operation result"), + db_dxil_param(2, "i32", "rayQueryHandle", "RayQuery handle"), + db_dxil_param(3, "i8", "component", "component [0..2]", is_const=True), + ], + ) + next_op_idx += 1 + + self.add_dxil_op( + "RayQuery_CommittedInstanceIndex", + next_op_idx, + "RayQuery_StateScalar", + "returns committed hit instance index", + "i", + "ro", + [ + db_dxil_param(0, "i32", "", "operation result"), + db_dxil_param(2, "i32", "rayQueryHandle", "RayQuery handle"), + ], + ) + next_op_idx += 1 + + self.add_dxil_op( + "RayQuery_CommittedInstanceID", + next_op_idx, + "RayQuery_StateScalar", + "returns committed hit instance ID", + "i", + "ro", + [ + db_dxil_param(0, "i32", "", "operation result"), + db_dxil_param(2, "i32", "rayQueryHandle", "RayQuery handle"), + ], + ) + next_op_idx += 1 + + self.add_dxil_op( + "RayQuery_CommittedGeometryIndex", + next_op_idx, + "RayQuery_StateScalar", + "returns committed hit geometry index", + "i", + "ro", + [ + db_dxil_param(0, "i32", "", "operation result"), + db_dxil_param(2, "i32", "rayQueryHandle", "RayQuery handle"), + ], + ) + next_op_idx += 1 + + self.add_dxil_op( + "RayQuery_CommittedPrimitiveIndex", + next_op_idx, + "RayQuery_StateScalar", + "returns committed hit geometry index", + "i", + "ro", + [ + db_dxil_param(0, "i32", "", "operation result"), + db_dxil_param(2, "i32", "rayQueryHandle", "RayQuery handle"), + ], + ) + next_op_idx += 1 + + self.add_dxil_op( + "RayQuery_CommittedObjectRayOrigin", + next_op_idx, + "RayQuery_StateVector", + "returns committed hit object ray origin", + "f", + "ro", + [ + db_dxil_param(0, "f", "", "operation result"), + db_dxil_param(2, "i32", "rayQueryHandle", "RayQuery handle"), + db_dxil_param(3, "i8", "component", "component [0..2]", is_const=True), + ], + ) + next_op_idx += 1 + + self.add_dxil_op( + "RayQuery_CommittedObjectRayDirection", + next_op_idx, + "RayQuery_StateVector", + "returns committed object ray direction", + "f", + "ro", + [ + db_dxil_param(0, "f", "", "operation result"), + db_dxil_param(2, "i32", "rayQueryHandle", "RayQuery handle"), + db_dxil_param(3, "i8", "component", "component [0..2]", is_const=True), + ], + ) + next_op_idx += 1 + + self.add_dxil_op( + "GeometryIndex", + next_op_idx, + "GeometryIndex", + "The autogenerated index of the current geometry in the bottom-level structure", + "i", + "rn", + [db_dxil_param(0, "i32", "", "result")], + ) + next_op_idx += 1 + + self.add_dxil_op( + "RayQuery_CandidateInstanceContributionToHitGroupIndex", + next_op_idx, + "RayQuery_StateScalar", + "returns candidate hit InstanceContributionToHitGroupIndex", + "i", + "ro", + [ + db_dxil_param(0, "i32", "", "operation result"), + db_dxil_param(2, "i32", "rayQueryHandle", "RayQuery handle"), + ], + ) + next_op_idx += 1 + + self.add_dxil_op( + "RayQuery_CommittedInstanceContributionToHitGroupIndex", + next_op_idx, + "RayQuery_StateScalar", + "returns committed hit InstanceContributionToHitGroupIndex", + "i", + "ro", + [ + db_dxil_param(0, "i32", "", "operation result"), + db_dxil_param(2, "i32", "rayQueryHandle", "RayQuery handle"), + ], + ) next_op_idx += 1 # End of DXIL 1.5 opcodes. self.set_op_count_for_version(1, 5, next_op_idx) - assert next_op_idx == 216, "216 is expected next operation index but encountered %d and thus opcodes are broken" % next_op_idx - - self.add_dxil_op("AnnotateHandle", next_op_idx, "AnnotateHandle", "annotate handle with resource properties", "v", "rn", [ - db_dxil_param(0, "res", "", "annotated handle"), - db_dxil_param(2, "res", "res", "input handle"), - db_dxil_param(3, "resproperty", "props", "details like component type, strutrure stride...", is_const=True)]) - next_op_idx += 1 - - self.add_dxil_op("CreateHandleFromBinding", next_op_idx, "CreateHandleFromBinding", "create resource handle from binding", "v", "rn", [ - db_dxil_param(0, "res", "", "result"), - db_dxil_param(2, "resbind", "bind", "resource binding", is_const=True), #{ rangeLowerBound, rangeUpperBound, spaceID, resourceClass } - db_dxil_param(3, "i32", "index", "index"), - db_dxil_param(4, "i1", "nonUniformIndex", "non-uniform resource index", is_const=True)]) - next_op_idx += 1 - - self.add_dxil_op("CreateHandleFromHeap", next_op_idx, "CreateHandleFromHeap", "create resource handle from heap", "v", "rn", [ - db_dxil_param(0, "res", "", "result"), - db_dxil_param(2, "i32", "index", "heap index"), - db_dxil_param(3, "i1", "samplerHeap", "If samplerHeap is 1, the heap indexed is the sampler descriptor heap, otherwise it is the CBV_SRV_UAV (resource) descriptor heap", is_const=True), - db_dxil_param(4, "i1", "nonUniformIndex", "non-uniform resource index", is_const=True)]) - next_op_idx += 1 - - self.add_dxil_op("Unpack4x8", next_op_idx, "Unpack4x8", "unpacks 4 8-bit signed or unsigned values into int32 or int16 vector", "iw", "rn", [ - db_dxil_param(0, "$vec4", "", "result"), - db_dxil_param(2, "i8", "unpackMode", "signed/unsigned"), - db_dxil_param(3, "i32", "pk", "packed 4 x i8")]) - next_op_idx += 1 - - self.add_dxil_op("Pack4x8", next_op_idx, "Pack4x8", "packs vector of 4 signed or unsigned values into a packed datatype, drops or clamps unused bits", "iw", "rn", [ - db_dxil_param(0, "i32", "", "result packed 4 x i8"), - db_dxil_param(2, "i8", "packMode", "trunc/unsigned clamp/signed clamp"), - db_dxil_param(3, "$o", "x", "the first component of the vector"), - db_dxil_param(4, "$o", "y", "the second component of the vector"), - db_dxil_param(5, "$o", "z", "the third component of the vector"), - db_dxil_param(6, "$o", "w", "the fourth component of the vector")]) - next_op_idx += 1 - - self.add_dxil_op("IsHelperLane", next_op_idx, "IsHelperLane", "returns true on helper lanes in pixel shaders", "1", "ro", [ - db_dxil_param(0, "i1", "", "result")]) + assert next_op_idx == 216, ( + "216 is expected next operation index but encountered %d and thus opcodes are broken" + % next_op_idx + ) + + self.add_dxil_op( + "AnnotateHandle", + next_op_idx, + "AnnotateHandle", + "annotate handle with resource properties", + "v", + "rn", + [ + db_dxil_param(0, "res", "", "annotated handle"), + db_dxil_param(2, "res", "res", "input handle"), + db_dxil_param( + 3, + "resproperty", + "props", + "details like component type, strutrure stride...", + is_const=True, + ), + ], + ) + next_op_idx += 1 + + self.add_dxil_op( + "CreateHandleFromBinding", + next_op_idx, + "CreateHandleFromBinding", + "create resource handle from binding", + "v", + "rn", + [ + db_dxil_param(0, "res", "", "result"), + db_dxil_param( + 2, "resbind", "bind", "resource binding", is_const=True + ), # { rangeLowerBound, rangeUpperBound, spaceID, resourceClass } + db_dxil_param(3, "i32", "index", "index"), + db_dxil_param( + 4, + "i1", + "nonUniformIndex", + "non-uniform resource index", + is_const=True, + ), + ], + ) + next_op_idx += 1 + + self.add_dxil_op( + "CreateHandleFromHeap", + next_op_idx, + "CreateHandleFromHeap", + "create resource handle from heap", + "v", + "rn", + [ + db_dxil_param(0, "res", "", "result"), + db_dxil_param(2, "i32", "index", "heap index"), + db_dxil_param( + 3, + "i1", + "samplerHeap", + "If samplerHeap is 1, the heap indexed is the sampler descriptor heap, otherwise it is the CBV_SRV_UAV (resource) descriptor heap", + is_const=True, + ), + db_dxil_param( + 4, + "i1", + "nonUniformIndex", + "non-uniform resource index", + is_const=True, + ), + ], + ) + next_op_idx += 1 + + self.add_dxil_op( + "Unpack4x8", + next_op_idx, + "Unpack4x8", + "unpacks 4 8-bit signed or unsigned values into int32 or int16 vector", + "iw", + "rn", + [ + db_dxil_param(0, "$vec4", "", "result"), + db_dxil_param(2, "i8", "unpackMode", "signed/unsigned"), + db_dxil_param(3, "i32", "pk", "packed 4 x i8"), + ], + ) + next_op_idx += 1 + + self.add_dxil_op( + "Pack4x8", + next_op_idx, + "Pack4x8", + "packs vector of 4 signed or unsigned values into a packed datatype, drops or clamps unused bits", + "iw", + "rn", + [ + db_dxil_param(0, "i32", "", "result packed 4 x i8"), + db_dxil_param(2, "i8", "packMode", "trunc/unsigned clamp/signed clamp"), + db_dxil_param(3, "$o", "x", "the first component of the vector"), + db_dxil_param(4, "$o", "y", "the second component of the vector"), + db_dxil_param(5, "$o", "z", "the third component of the vector"), + db_dxil_param(6, "$o", "w", "the fourth component of the vector"), + ], + ) + next_op_idx += 1 + + self.add_dxil_op( + "IsHelperLane", + next_op_idx, + "IsHelperLane", + "returns true on helper lanes in pixel shaders", + "1", + "ro", + [db_dxil_param(0, "i1", "", "result")], + ) next_op_idx += 1 # End of DXIL 1.6 opcodes. self.set_op_count_for_version(1, 6, next_op_idx) - assert next_op_idx == 222, "222 is expected next operation index but encountered %d and thus opcodes are broken" % next_op_idx - - self.add_enum_type("QuadVoteOpKind", "Kind of cross-quad vote operation", [ - (0, "Any", "true if any condition is true in this quad"), - (1, "All", "true if all conditions are true in this quad")]) - self.add_dxil_op("QuadVote", next_op_idx, "QuadVote", "compares boolean accross a quad", "1", "", [ - db_dxil_param(0, "i1", "", "result - uniform across quad"), - db_dxil_param(2, "i1", "cond", "condition"), - db_dxil_param(3, "i8", "op", "QuadVoteOpKind: 0=Any, 1=All", enum_name="QuadVoteOpKind", is_const=True)]) - next_op_idx += 1 - - self.add_dxil_op("TextureGatherRaw", next_op_idx, "TextureGatherRaw", "Gather raw elements from 4 texels with no type conversions (SRV type is constrained)", "wil", "ro", [ - db_dxil_param(0, "$r", "", "four raw texture elements gathered"), - db_dxil_param(2, "res", "srv", "handle of type-matched SRV to gather from"), - db_dxil_param(3, "res", "sampler", "handle of sampler to use"), - db_dxil_param(4, "f", "coord0", "coordinate"), - db_dxil_param(5, "f", "coord1", "coordinate, undef for Texture1D"), - db_dxil_param(6, "f", "coord2", "coordinate, undef for Texture1D, Texture1DArray or Texture2D"), - db_dxil_param(7, "f", "coord3", "coordinate, defined only for TextureCubeArray"), - db_dxil_param(8, "i32", "offset0", "optional offset, applicable to Texture1D, Texture1DArray, and as part of offset1"), - db_dxil_param(9, "i32", "offset1", "optional offset, applicable to Texture2D, Texture2DArray")], - counters=('tex_norm',)) - next_op_idx += 1 - - self.add_dxil_op("SampleCmpLevel", next_op_idx, "SampleCmpLevel", "samples a texture and compares a single component against the specified comparison value", "hf", "ro", [ - db_dxil_param(0, "$r", "", "the result of the filtered comparisons"), - db_dxil_param(2, "res", "srv", "handle of SRV to sample"), - db_dxil_param(3, "res", "sampler", "handle of sampler to use"), - db_dxil_param(4, "f", "coord0", "coordinate"), - db_dxil_param(5, "f", "coord1", "coordinate, undef for Texture1D"), - db_dxil_param(6, "f", "coord2", "coordinate, undef for Texture1D, Texture1DArray or Texture2D"), - db_dxil_param(7, "f", "coord3", "coordinate, defined only for TextureCubeArray"), - db_dxil_param(8, "i32", "offset0", "optional offset, applicable to Texture1D, Texture1DArray, and as part of offset1"), - db_dxil_param(9, "i32", "offset1", "optional offset, applicable to Texture2D, Texture2DArray, and as part of offset2"), - db_dxil_param(10, "i32", "offset2", "optional offset, applicable to Texture3D"), - db_dxil_param(11, "f", "compareValue", "the value to compare with"), - db_dxil_param(12, "f", "lod", "level of detail, biggest map if less than or equal to zero; fraction used to interpolate across levels")], - counters=('tex_cmp',)) - next_op_idx += 1 - - self.add_dxil_op("TextureStoreSample", next_op_idx, "TextureStoreSample", "stores texel data at specified sample index", "hfwi", "", [ - db_dxil_param(0, "v", "", ""), - db_dxil_param(2, "res", "srv", "handle of Texture2DMS[Array] UAV to store to"), - db_dxil_param(3, "i32", "coord0", "coordinate"), - db_dxil_param(4, "i32", "coord1", "coordinate"), - db_dxil_param(5, "i32", "coord2", "coordinate"), - db_dxil_param(6, "$o", "value0", "value"), - db_dxil_param(7, "$o", "value1", "value"), - db_dxil_param(8, "$o", "value2", "value"), - db_dxil_param(9, "$o", "value3", "value"), - db_dxil_param(10,"i8", "mask", "written value mask", is_const=True), - db_dxil_param(11, "i32", "sampleIdx", "sample index")], - counters=('tex_store',)) + assert next_op_idx == 222, ( + "222 is expected next operation index but encountered %d and thus opcodes are broken" + % next_op_idx + ) + + self.add_enum_type( + "QuadVoteOpKind", + "Kind of cross-quad vote operation", + [ + (0, "Any", "true if any condition is true in this quad"), + (1, "All", "true if all conditions are true in this quad"), + ], + ) + self.add_dxil_op( + "QuadVote", + next_op_idx, + "QuadVote", + "compares boolean accross a quad", + "1", + "", + [ + db_dxil_param(0, "i1", "", "result - uniform across quad"), + db_dxil_param(2, "i1", "cond", "condition"), + db_dxil_param( + 3, + "i8", + "op", + "QuadVoteOpKind: 0=Any, 1=All", + enum_name="QuadVoteOpKind", + is_const=True, + ), + ], + ) + next_op_idx += 1 + + self.add_dxil_op( + "TextureGatherRaw", + next_op_idx, + "TextureGatherRaw", + "Gather raw elements from 4 texels with no type conversions (SRV type is constrained)", + "wil", + "ro", + [ + db_dxil_param(0, "$r", "", "four raw texture elements gathered"), + db_dxil_param( + 2, "res", "srv", "handle of type-matched SRV to gather from" + ), + db_dxil_param(3, "res", "sampler", "handle of sampler to use"), + db_dxil_param(4, "f", "coord0", "coordinate"), + db_dxil_param(5, "f", "coord1", "coordinate, undef for Texture1D"), + db_dxil_param( + 6, + "f", + "coord2", + "coordinate, undef for Texture1D, Texture1DArray or Texture2D", + ), + db_dxil_param( + 7, "f", "coord3", "coordinate, defined only for TextureCubeArray" + ), + db_dxil_param( + 8, + "i32", + "offset0", + "optional offset, applicable to Texture1D, Texture1DArray, and as part of offset1", + ), + db_dxil_param( + 9, + "i32", + "offset1", + "optional offset, applicable to Texture2D, Texture2DArray", + ), + ], + counters=("tex_norm",), + ) + next_op_idx += 1 + + self.add_dxil_op( + "SampleCmpLevel", + next_op_idx, + "SampleCmpLevel", + "samples a texture and compares a single component against the specified comparison value", + "hf", + "ro", + [ + db_dxil_param(0, "$r", "", "the result of the filtered comparisons"), + db_dxil_param(2, "res", "srv", "handle of SRV to sample"), + db_dxil_param(3, "res", "sampler", "handle of sampler to use"), + db_dxil_param(4, "f", "coord0", "coordinate"), + db_dxil_param(5, "f", "coord1", "coordinate, undef for Texture1D"), + db_dxil_param( + 6, + "f", + "coord2", + "coordinate, undef for Texture1D, Texture1DArray or Texture2D", + ), + db_dxil_param( + 7, "f", "coord3", "coordinate, defined only for TextureCubeArray" + ), + db_dxil_param( + 8, + "i32", + "offset0", + "optional offset, applicable to Texture1D, Texture1DArray, and as part of offset1", + ), + db_dxil_param( + 9, + "i32", + "offset1", + "optional offset, applicable to Texture2D, Texture2DArray, and as part of offset2", + ), + db_dxil_param( + 10, "i32", "offset2", "optional offset, applicable to Texture3D" + ), + db_dxil_param(11, "f", "compareValue", "the value to compare with"), + db_dxil_param( + 12, + "f", + "lod", + "level of detail, biggest map if less than or equal to zero; fraction used to interpolate across levels", + ), + ], + counters=("tex_cmp",), + ) + next_op_idx += 1 + + self.add_dxil_op( + "TextureStoreSample", + next_op_idx, + "TextureStoreSample", + "stores texel data at specified sample index", + "hfwi", + "", + [ + db_dxil_param(0, "v", "", ""), + db_dxil_param( + 2, "res", "srv", "handle of Texture2DMS[Array] UAV to store to" + ), + db_dxil_param(3, "i32", "coord0", "coordinate"), + db_dxil_param(4, "i32", "coord1", "coordinate"), + db_dxil_param(5, "i32", "coord2", "coordinate"), + db_dxil_param(6, "$o", "value0", "value"), + db_dxil_param(7, "$o", "value1", "value"), + db_dxil_param(8, "$o", "value2", "value"), + db_dxil_param(9, "$o", "value3", "value"), + db_dxil_param(10, "i8", "mask", "written value mask", is_const=True), + db_dxil_param(11, "i32", "sampleIdx", "sample index"), + ], + counters=("tex_store",), + ) next_op_idx += 1 # End of DXIL 1.7 opcodes. self.set_op_count_for_version(1, 7, next_op_idx) - assert next_op_idx == 226, "226 is expected next operation index but encountered %d and thus opcodes are broken" % next_op_idx + assert next_op_idx == 226, ( + "226 is expected next operation index but encountered %d and thus opcodes are broken" + % next_op_idx + ) # Set interesting properties. self.build_indices() - for i in "CalculateLOD,DerivCoarseX,DerivCoarseY,DerivFineX,DerivFineY,Sample,SampleBias,SampleCmp".split(","): + for ( + i + ) in "CalculateLOD,DerivCoarseX,DerivCoarseY,DerivFineX,DerivFineY,Sample,SampleBias,SampleCmp".split( + "," + ): self.name_idx[i].is_gradient = True for i in "DerivCoarseX,DerivCoarseY,DerivFineX,DerivFineY".split(","): - assert self.name_idx[i].is_gradient == True, "all derivatives are marked as requiring gradients" + assert ( + self.name_idx[i].is_gradient == True + ), "all derivatives are marked as requiring gradients" self.name_idx[i].is_deriv = True # TODO - some arguments are required to be immediate constants in DXIL, eg resource kinds; add this information # consider - report instructions that are overloaded on a single type, then turn them into non-overloaded version of that type - self.verify_dense(self.get_dxil_insts(), lambda x : x.dxil_opid, lambda x : x.name) + self.verify_dense( + self.get_dxil_insts(), lambda x: x.dxil_opid, lambda x: x.name + ) for i in self.instr: - self.verify_dense(i.ops, lambda x : x.pos, lambda x : i.name) + self.verify_dense(i.ops, lambda x: x.pos, lambda x: i.name) for i in self.instr: if i.is_dxil_op: - assert i.oload_types != "", "overload for DXIL operation %s should not be empty - use void if n/a" % (i.name) - assert i.oload_types == "v" or i.oload_types.find("v") < 0, "void overload should be exclusive to other types (%s)" % i.name - assert type(i.oload_types) is str, "overload for %s should be a string - use empty if n/a" % (i.name) + assert i.oload_types != "", ( + "overload for DXIL operation %s should not be empty - use void if n/a" + % (i.name) + ) + assert i.oload_types == "v" or i.oload_types.find("v") < 0, ( + "void overload should be exclusive to other types (%s)" % i.name + ) + assert ( + type(i.oload_types) is str + ), "overload for %s should be a string - use empty if n/a" % (i.name) # Verify that all operations in each class have the same signature. import itertools + class_sort_func = lambda x, y: x < y - class_key_func = lambda x : x.dxil_class - instr_ordered_by_class = sorted([i for i in self.instr if i.is_dxil_op], key=class_key_func) - instr_grouped_by_class = itertools.groupby(instr_ordered_by_class, key=class_key_func) + class_key_func = lambda x: x.dxil_class + instr_ordered_by_class = sorted( + [i for i in self.instr if i.is_dxil_op], key=class_key_func + ) + instr_grouped_by_class = itertools.groupby( + instr_ordered_by_class, key=class_key_func + ) + def calc_oload_sig(inst): result = "" for o in inst.ops: result += o.llvm_type return result + for k, g in instr_grouped_by_class: group = list(g) if len(group) > 1: @@ -1967,7 +4976,7 @@ def calc_oload_sig(inst): for other in group[1:]: other_group = calc_oload_sig(other) # TODO: uncomment assert when opcodes are fixed - #assert first_group == other_group, "overload signature %s for instruction %s differs from %s in %s" % (first.name, first_group, other.name, other_group) + # assert first_group == other_group, "overload signature %s for instruction %s differs from %s in %s" % (first.name, first_group, other.name, other_group) def populate_extended_docs(self): "Update the documentation with text from external files." @@ -1981,13 +4990,18 @@ def populate_extended_docs(self): inst_remarks = "" is_block = False for idx, line in enumerate(ops_file): - if line.startswith("#"): continue + if line.startswith("#"): + continue if line.startswith(block_starter): - assert is_block == False, "unexpected block begin at line %i" % (idx+1) + assert is_block == False, "unexpected block begin at line %i" % ( + idx + 1 + ) is_block = True continue if line.startswith(block_end): - assert is_block == True, "unexpected block end at line %i" % (idx+1) + assert is_block == True, "unexpected block end at line %i" % ( + idx + 1 + ) is_block = False continue if line.startswith(inst_starter): @@ -1996,28 +5010,39 @@ def populate_extended_docs(self): self.name_idx[inst_name].doc = inst_doc self.name_idx[inst_name].remarks = inst_remarks.strip() inst_remarks = "" - line = line[len(inst_starter):] + line = line[len(inst_starter) :] sep_idx = line.find("-") inst_name = line[:sep_idx].strip() - inst_doc = line[sep_idx+1:].strip() + inst_doc = line[sep_idx + 1 :].strip() else: inst_remarks += line if is_block else "\n" + line.strip() if inst_name: self.name_idx[inst_name].remarks = inst_remarks.strip() - def populate_metadata(self): # For now, simply describe the allowed named metadata. m = self.metadata - m.append(db_dxil_metadata("dx.controlflow.hints", "Provides control flow hints to an instruction.")) + m.append( + db_dxil_metadata( + "dx.controlflow.hints", "Provides control flow hints to an instruction." + ) + ) m.append(db_dxil_metadata("dx.entryPoints", "Entry point functions.")) m.append(db_dxil_metadata("dx.precise", "Marks an instruction as precise.")) - m.append(db_dxil_metadata("dx.resources", "Resources used by the entry point shaders.")) + m.append( + db_dxil_metadata( + "dx.resources", "Resources used by the entry point shaders." + ) + ) m.append(db_dxil_metadata("dx.shaderModel", "Shader model for the module.")) - m.append(db_dxil_metadata("dx.typeAnnotations", "Provides annotations for types.")) + m.append( + db_dxil_metadata("dx.typeAnnotations", "Provides annotations for types.") + ) m.append(db_dxil_metadata("dx.typevar.*", ".")) m.append(db_dxil_metadata("dx.valver", "Optional validator version.")) - m.append(db_dxil_metadata("dx.version", "Optional DXIL version for the module.")) + m.append( + db_dxil_metadata("dx.version", "Optional DXIL version for the module.") + ) # dx.typevar.* is not the name of metadata, but the prefix for global variables # that will be referenced by structure type annotations. @@ -2025,279 +5050,968 @@ def populate_passes(self): # Populate passes and their options. p = self.passes category_lib = "set this before add_pass" + def add_pass(name, type_name, doc, opts): - apass = db_dxil_pass(name, type_name=type_name, doc=doc, category_lib=category_lib) + apass = db_dxil_pass( + name, type_name=type_name, doc=doc, category_lib=category_lib + ) for o in opts: - assert 'n' in o, "option in %s has no 'n' member" % name - apass.args.append(db_dxil_pass_arg(o['n'], ident=o.get('i'), type_name=o.get('t'), is_ctor_param=o.get('c'), doc=o.get('d'))) + assert "n" in o, "option in %s has no 'n' member" % name + apass.args.append( + db_dxil_pass_arg( + o["n"], + ident=o.get("i"), + type_name=o.get("t"), + is_ctor_param=o.get("c"), + doc=o.get("d"), + ) + ) p.append(apass) category_lib = "llvm" # Add discriminators is a DWARF 4 thing, useful for the profiler. # Consider removing lib\Transforms\Utils\AddDiscriminators.cpp altogether - add_pass("add-discriminators", "AddDiscriminators", "Add DWARF path discriminators", - [{'n':"no-discriminators", 'i':"NoDiscriminators", 't':"bool"}]) + add_pass( + "add-discriminators", + "AddDiscriminators", + "Add DWARF path discriminators", + [{"n": "no-discriminators", "i": "NoDiscriminators", "t": "bool"}], + ) # Sample profile is part of the sample profiling infrastructure. # Consider removing lib\Transforms\Scalar\SampleProfile.cpp - add_pass("sample-profile", "SampleProfileLoader", "Sample Profile loader", [ - {'n':"sample-profile-file", 'i':"SampleProfileFile", 't':"string"}, - {'n':"sample-profile-max-propagate-iterations", 'i':"SampleProfileMaxPropagateIterations", 't':"unsigned"}]) + add_pass( + "sample-profile", + "SampleProfileLoader", + "Sample Profile loader", + [ + {"n": "sample-profile-file", "i": "SampleProfileFile", "t": "string"}, + { + "n": "sample-profile-max-propagate-iterations", + "i": "SampleProfileMaxPropagateIterations", + "t": "unsigned", + }, + ], + ) # inline and always-inline share a base class - those are the arguments we document for each of them. inliner_args = [ - {'n':'InsertLifetime', 't':'bool', 'c':1, 'd':'Insert @llvm.lifetime intrinsics'}, - {'n':'InlineThreshold', 't':'unsigned', 'c':1, 'd':'Insert @llvm.lifetime intrinsics'}] - add_pass("inline", "SimpleInliner", "Function Integration/Inlining", inliner_args) -# {'n':"OptLevel", 't':"unsigned", 'c':1}, -# {'n':"SizeOptLevel", 't':'unsigned', 'c':1} - add_pass('always-inline', 'AlwaysInliner', 'Inliner for always_inline functions', inliner_args) -# {'n':'InsertLifetime', 't':'bool', 'c':1, 'd':'Insert @llvm.lifetime intrinsics'} + { + "n": "InsertLifetime", + "t": "bool", + "c": 1, + "d": "Insert @llvm.lifetime intrinsics", + }, + { + "n": "InlineThreshold", + "t": "unsigned", + "c": 1, + "d": "Insert @llvm.lifetime intrinsics", + }, + ] + add_pass( + "inline", "SimpleInliner", "Function Integration/Inlining", inliner_args + ) + # {'n':"OptLevel", 't':"unsigned", 'c':1}, + # {'n':"SizeOptLevel", 't':'unsigned', 'c':1} + add_pass( + "always-inline", + "AlwaysInliner", + "Inliner for always_inline functions", + inliner_args, + ) + # {'n':'InsertLifetime', 't':'bool', 'c':1, 'd':'Insert @llvm.lifetime intrinsics'} # Consider a review of the target-specific wrapper. - add_pass("tti", "TargetTransformInfoWrapperPass", "Target Transform Information", [ - {'n':'TIRA', 't':'TargetIRAnalysis', 'c':1}]) - add_pass("verify", "VerifierLegacyPass", "Module Verifier", [ - {'n':'FatalErrors', 't':'bool', 'c':1}, - {'n':'verify-debug-info', 'i':'VerifyDebugInfo', 't':'bool'}]) - add_pass("targetlibinfo", "TargetLibraryInfoWrapperPass", "Target Library Information", [ - {'n':'TLIImpl', 't':'TargetLibraryInfoImpl', 'c':1}, - {'n':'vector-library', 'i':'ClVectorLibrary', 't':'TargetLibraryInfoImpl::VectorLibrary'}]) + add_pass( + "tti", + "TargetTransformInfoWrapperPass", + "Target Transform Information", + [{"n": "TIRA", "t": "TargetIRAnalysis", "c": 1}], + ) + add_pass( + "verify", + "VerifierLegacyPass", + "Module Verifier", + [ + {"n": "FatalErrors", "t": "bool", "c": 1}, + {"n": "verify-debug-info", "i": "VerifyDebugInfo", "t": "bool"}, + ], + ) + add_pass( + "targetlibinfo", + "TargetLibraryInfoWrapperPass", + "Target Library Information", + [ + {"n": "TLIImpl", "t": "TargetLibraryInfoImpl", "c": 1}, + { + "n": "vector-library", + "i": "ClVectorLibrary", + "t": "TargetLibraryInfoImpl::VectorLibrary", + }, + ], + ) add_pass("cfl-aa", "CFLAliasAnalysis", "CFL-Based AA implementation", []) - add_pass("tbaa", "TypeBasedAliasAnalysis", "Type-Based Alias Analysis", [ - {'n':"enable-tbaa", 'i':'EnableTBAA', 't':'bool', 'd':'Use to disable TBAA functionality'}]) - add_pass("scoped-noalias", "ScopedNoAliasAA", "Scoped NoAlias Alias Analysis", [ - {'n':"enable-scoped-noalias", 'i':'EnableScopedNoAlias', 't':'bool', 'd':'Use to disable scoped no-alias'}]) - add_pass("basicaa", "BasicAliasAnalysis", "Basic Alias Analysis (stateless AA impl)", []) - add_pass("simplifycfg", "CFGSimplifyPass", "Simplify the CFG", [ - {'n':'Threshold', 't':'int', 'c':1}, - {'n':'Ftor', 't':'std::function', 'c':1}, - {'n':'bonus-inst-threshold', 'i':'UserBonusInstThreshold', 't':'unsigned', 'd':'Control the number of bonus instructions (default = 1)'}]) + add_pass( + "tbaa", + "TypeBasedAliasAnalysis", + "Type-Based Alias Analysis", + [ + { + "n": "enable-tbaa", + "i": "EnableTBAA", + "t": "bool", + "d": "Use to disable TBAA functionality", + } + ], + ) + add_pass( + "scoped-noalias", + "ScopedNoAliasAA", + "Scoped NoAlias Alias Analysis", + [ + { + "n": "enable-scoped-noalias", + "i": "EnableScopedNoAlias", + "t": "bool", + "d": "Use to disable scoped no-alias", + } + ], + ) + add_pass( + "basicaa", + "BasicAliasAnalysis", + "Basic Alias Analysis (stateless AA impl)", + [], + ) + add_pass( + "simplifycfg", + "CFGSimplifyPass", + "Simplify the CFG", + [ + {"n": "Threshold", "t": "int", "c": 1}, + {"n": "Ftor", "t": "std::function", "c": 1}, + { + "n": "bonus-inst-threshold", + "i": "UserBonusInstThreshold", + "t": "unsigned", + "d": "Control the number of bonus instructions (default = 1)", + }, + ], + ) # UseNewSROA is used by PassManagerBuilder::populateFunctionPassManager, not a pass per se. - add_pass("sroa", "SROA", "Scalar Replacement Of Aggregates", [ - {'n':'RequiresDomTree', 't':'bool', 'c':1}, - {'n':'SkipHLSLMat', 't':'bool', 'c':1}, - {'n':'force-ssa-updater', 'i':'ForceSSAUpdater', 't':'bool', 'd':'Force the pass to not use DomTree and mem2reg, insteadforming SSA values through the SSAUpdater infrastructure.'}, - {'n':'sroa-random-shuffle-slices', 'i':'SROARandomShuffleSlices', 't':'bool', 'd':'Enable randomly shuffling the slices to help uncover instability in their order.'}, - {'n':'sroa-strict-inbounds', 'i':'SROAStrictInbounds', 't':'bool', 'd':'Experiment with completely strict handling of inbounds GEPs.'}]) - add_pass("dxil-cond-mem2reg", "DxilConditionalMem2Reg", "Dxil Conditional Mem2Reg", [ - {'n':'NoOpt', 't':'bool', 'c':1}, - ]) - add_pass('scalarrepl', 'SROA_DT', 'Scalar Replacement of Aggregates (DT)', [ - {'n':'Threshold', 't':'int', 'c':1}, - {'n':'StructMemberThreshold', 't':'int', 'c':1}, - {'n':'ArrayElementThreshold', 't':'int', 'c':1}, - {'n':'ScalarLoadThreshold', 't':'int', 'c':1}]) - add_pass('scalarrepl-ssa', 'SROA_SSAUp', 'Scalar Replacement of Aggregates (SSAUp)', [ - {'n':'Threshold', 't':'int', 'c':1}, - {'n':'StructMemberThreshold', 't':'int', 'c':1}, - {'n':'ArrayElementThreshold', 't':'int', 'c':1}, - {'n':'ScalarLoadThreshold', 't':'int', 'c':1}]) - add_pass('early-cse', 'EarlyCSELegacyPass', 'Early CSE', []) + add_pass( + "sroa", + "SROA", + "Scalar Replacement Of Aggregates", + [ + {"n": "RequiresDomTree", "t": "bool", "c": 1}, + {"n": "SkipHLSLMat", "t": "bool", "c": 1}, + { + "n": "force-ssa-updater", + "i": "ForceSSAUpdater", + "t": "bool", + "d": "Force the pass to not use DomTree and mem2reg, insteadforming SSA values through the SSAUpdater infrastructure.", + }, + { + "n": "sroa-random-shuffle-slices", + "i": "SROARandomShuffleSlices", + "t": "bool", + "d": "Enable randomly shuffling the slices to help uncover instability in their order.", + }, + { + "n": "sroa-strict-inbounds", + "i": "SROAStrictInbounds", + "t": "bool", + "d": "Experiment with completely strict handling of inbounds GEPs.", + }, + ], + ) + add_pass( + "dxil-cond-mem2reg", + "DxilConditionalMem2Reg", + "Dxil Conditional Mem2Reg", + [ + {"n": "NoOpt", "t": "bool", "c": 1}, + ], + ) + add_pass( + "scalarrepl", + "SROA_DT", + "Scalar Replacement of Aggregates (DT)", + [ + {"n": "Threshold", "t": "int", "c": 1}, + {"n": "StructMemberThreshold", "t": "int", "c": 1}, + {"n": "ArrayElementThreshold", "t": "int", "c": 1}, + {"n": "ScalarLoadThreshold", "t": "int", "c": 1}, + ], + ) + add_pass( + "scalarrepl-ssa", + "SROA_SSAUp", + "Scalar Replacement of Aggregates (SSAUp)", + [ + {"n": "Threshold", "t": "int", "c": 1}, + {"n": "StructMemberThreshold", "t": "int", "c": 1}, + {"n": "ArrayElementThreshold", "t": "int", "c": 1}, + {"n": "ScalarLoadThreshold", "t": "int", "c": 1}, + ], + ) + add_pass("early-cse", "EarlyCSELegacyPass", "Early CSE", []) # More branch weight support. - add_pass('lower-expect', 'LowerExpectIntrinsic', "Lower 'expect' Intrinsics", [ - {'n':'likely-branch-weight', 'i':'LikelyBranchWeight', 't':'uint32_t', 'd':'Weight of the branch likely to be taken (default = 64)'}, - {'n':'unlikely-branch-weight', 'i':'UnlikelyBranchWeight', 't':'uint32_t', 'd':'Weight of the branch unlikely to be taken (default = 4)'}]) + add_pass( + "lower-expect", + "LowerExpectIntrinsic", + "Lower 'expect' Intrinsics", + [ + { + "n": "likely-branch-weight", + "i": "LikelyBranchWeight", + "t": "uint32_t", + "d": "Weight of the branch likely to be taken (default = 64)", + }, + { + "n": "unlikely-branch-weight", + "i": "UnlikelyBranchWeight", + "t": "uint32_t", + "d": "Weight of the branch unlikely to be taken (default = 4)", + }, + ], + ) # Consider removing lib\Transforms\Utils\SymbolRewriter.cpp - add_pass('rewrite-symbols', 'RewriteSymbols', 'Rewrite Symbols', [ - {'n':'DL', 't':'SymbolRewriter::RewriteDescriptorList', 'c':1}, - {'n':'rewrite-map-file', 'i':'RewriteMapFiles', 't':'string'}]) - add_pass('mergefunc', 'MergeFunctions', 'Merge Functions', [ - {'n':'mergefunc-sanity', 'i':'NumFunctionsForSanityCheck', 't':'unsigned', 'd':"How many functions in module could be used for MergeFunctions pass sanity check. '0' disables this check. Works only with '-debug' key."}]) + add_pass( + "rewrite-symbols", + "RewriteSymbols", + "Rewrite Symbols", + [ + {"n": "DL", "t": "SymbolRewriter::RewriteDescriptorList", "c": 1}, + {"n": "rewrite-map-file", "i": "RewriteMapFiles", "t": "string"}, + ], + ) + add_pass( + "mergefunc", + "MergeFunctions", + "Merge Functions", + [ + { + "n": "mergefunc-sanity", + "i": "NumFunctionsForSanityCheck", + "t": "unsigned", + "d": "How many functions in module could be used for MergeFunctions pass sanity check. '0' disables this check. Works only with '-debug' key.", + } + ], + ) # Consider removing GlobalExtensions globals altogether. - add_pass('barrier', 'BarrierNoop', 'A No-Op Barrier Pass', []) - add_pass('dce', 'DCE', 'Dead Code Elimination', []) - add_pass('die', 'DeadInstElimination', 'Dead Instruction Elimination', []) - add_pass('globaldce', 'GlobalDCE', 'Dead Global Elimination', []) - add_pass('mem2reg', 'PromotePass', 'Promote Memory to Register', []) - add_pass('scalarizer', 'Scalarizer', 'Scalarize vector operations', []) - - category_lib="pix" - add_pass('hlsl-dxil-add-pixel-hit-instrmentation', 'DxilAddPixelHitInstrumentation', 'DXIL Count completed PS invocations and costs', [ - {'n':'force-early-z','t':'int','c':1}, - {'n':'add-pixel-cost','t':'int','c':1}, - {'n':'rt-width','t':'int','c':1}, - {'n':'sv-position-index','t':'int','c':1}, - {'n':'num-pixels','t':'int','c':1}]) - add_pass('hlsl-dxil-constantColor', 'DxilOutputColorBecomesConstant', 'DXIL Constant Color Mod', [ - {'n':'mod-mode','t':'int','c':1}, - {'n':'constant-red','t':'float','c':1}, - {'n':'constant-green','t':'float','c':1}, - {'n':'constant-blue','t':'float','c':1}, - {'n':'constant-alpha','t':'float','c':1}]) - add_pass('hlsl-dxil-remove-discards', 'DxilRemoveDiscards', 'HLSL DXIL Remove all discard instructions', []) - add_pass('hlsl-dxil-force-early-z', 'DxilForceEarlyZ', 'HLSL DXIL Force the early Z global flag, if shader has no discard calls', []) - add_pass('hlsl-dxil-pix-meshshader-output-instrumentation', 'DxilPIXMeshShaderOutputInstrumentation', 'DXIL mesh shader output instrumentation for PIX', [ - {'n':'expand-payload','t':'int','c':1}, - {'n':'UAVSize','t':'int','c':1}]) - add_pass('hlsl-dxil-pix-shader-access-instrumentation', 'DxilShaderAccessTracking', 'HLSL DXIL shader access tracking for PIX', [ - {'n':'config','t':'int','c':1}, - {'n':'checkForDynamicIndexing','t':'bool','c':1}]) - add_pass('hlsl-dxil-debug-instrumentation', 'DxilDebugInstrumentation', 'HLSL DXIL debug instrumentation for PIX', [ - {'n':'UAVSize','t':'int','c':1}, - {'n':'FirstInstruction','t':'int','c':1}, - {'n':'LastInstruction','t':'int','c':1}, - {'n':'parameter0','t':'int','c':1}, - {'n':'parameter1','t':'int','c':1}, - {'n':'parameter2','t':'int','c':1}]) - add_pass('dxil-annotate-with-virtual-regs', 'DxilAnnotateWithVirtualRegister', 'Annotates each instruction in the DXIL module with a virtual register number', [ - {'n':'startInstruction','t':'int','c':1}]) - add_pass('dxil-dbg-value-to-dbg-declare', 'DxilDbgValueToDbgDeclare', 'Converts llvm.dbg.value uses to llvm.dbg.declare.', []) - add_pass('hlsl-dxil-reduce-msaa-to-single', 'DxilReduceMSAAToSingleSample', 'HLSL DXIL Reduce all MSAA reads to single-sample reads', []) - add_pass('hlsl-dxil-PIX-add-tid-to-as-payload', 'DxilPIXAddTidToAmplificationShaderPayload', 'HLSL DXIL Add flat thread id to payload from AS to MS', [ - {'n':'dispatchArgY','t':'int','c':1}, - {'n':'dispatchArgZ','t':'int','c':1}]) - add_pass('hlsl-dxil-pix-dxr-invocations-log', 'DxilPIXDXRInvocationsLog', 'HLSL DXIL Logs all non-RayGen DXR 1.0 invocations into a UAV', [ - {'n':'maxNumEntriesInLog','t':'int','c':1}]) - - category_lib="dxil_gen" - - add_pass('hlsl-hlemit', 'HLEmitMetadata', 'HLSL High-Level Metadata Emit.', []) - add_pass("hl-expand-store-intrinsics", "HLExpandStoreIntrinsics", "Expand HLSL store intrinsics", []) - add_pass('scalarrepl-param-hlsl', 'SROA_Parameter_HLSL', 'Scalar Replacement of Aggregates HLSL (parameters)', []) - add_pass('static-global-to-alloca', 'LowerStaticGlobalIntoAlloca', 'Lower static global into Alloca', []) - add_pass('hlmatrixlower', 'HLMatrixLowerPass', 'HLSL High-Level Matrix Lower', []) - add_pass('matrixbitcastlower', 'MatrixBitcastLowerPass', 'Matrix Bitcast lower', []) - add_pass("reg2mem_hlsl", "RegToMemHlsl", "Demote values with phi-node usage to stack slots", []) - add_pass('dynamic-vector-to-array', 'DynamicIndexingVectorToArray', 'Replace dynamic indexing vector with array', [ - {'n':'ReplaceAllVectors','t':'bool','c':1}]) - add_pass('hlsl-dxil-promote-local-resources', 'DxilPromoteLocalResources', 'DXIL promote local resource use', []) - add_pass('hlsl-dxil-promote-static-resources', 'DxilPromoteStaticResources', 'DXIL promote static resource use', []) - add_pass('hlsl-dxil-legalize-resources', 'DxilLegalizeResources', 'DXIL legalize resource use', []) - add_pass('hlsl-dxil-legalize-eval-operations', 'DxilLegalizeEvalOperations', 'DXIL legalize eval operations', []) - add_pass('dxilgen', 'DxilGenerationPass', 'HLSL DXIL Generation', [ - {'n':'NotOptimized','t':'bool','c':1}]) - add_pass('invalidate-undef-resource', 'InvalidateUndefResources', 'Invalidate undef resources', []) - add_pass('simplify-inst', 'SimplifyInst', 'Simplify Instructions', []) - add_pass('hlsl-dxil-precise', 'DxilPrecisePropagatePass', 'DXIL precise attribute propagate', []) - add_pass('dxil-legalize-sample-offset', 'DxilLegalizeSampleOffsetPass', 'DXIL legalize sample offset', []) - add_pass('dxil-gvn-hoist', 'DxilSimpleGVNHoist', 'DXIL simple gvn hoist', []) - add_pass('dxil-gvn-eliminate-region', 'DxilSimpleGVNEliminateRegion', 'DXIL simple eliminate region', []) - add_pass('hlsl-hlensure', 'HLEnsureMetadata', 'HLSL High-Level Metadata Ensure', []) - add_pass('multi-dim-one-dim', 'MultiDimArrayToOneDimArray', 'Flatten multi-dim array into one-dim array', []) - add_pass('resource-handle', 'ResourceToHandle', 'Lower resource into handle', []) - add_pass('hlsl-passes-nopause', 'NoPausePasses', 'Clears metadata used for pause and resume', []) - add_pass('hlsl-passes-pause', 'PausePasses', 'Prepare to pause passes', []) - add_pass('hlsl-passes-resume', 'ResumePasses', 'Prepare to resume passes', []) - add_pass('hlsl-dxil-lower-handle-for-lib', 'DxilLowerCreateHandleForLib', 'DXIL Lower createHandleForLib', []) - add_pass('hlsl-dxil-cleanup-dynamic-resource-handle', 'DxilCleanupDynamicResourceHandle', 'DXIL Cleanup dynamic resource handle calls', []) - add_pass('hlsl-dxil-allocate-resources-for-lib', 'DxilAllocateResourcesForLib', 'DXIL Allocate Resources For Library', []) - add_pass('hlsl-dxil-convergent-mark', 'DxilConvergentMark', 'Mark convergent', []) - add_pass('hlsl-dxil-convergent-clear', 'DxilConvergentClear', 'Clear convergent before dxil emit', []) - add_pass('hlsl-dxil-eliminate-output-dynamic', 'DxilEliminateOutputDynamicIndexing', 'DXIL eliminate ouptut dynamic indexing', []) - add_pass('dxil-delete-redundant-debug-values', 'DxilDeleteRedundantDebugValues', 'Dxil Delete Redundant Debug Values', []) - add_pass('hlsl-dxilfinalize', 'DxilFinalizeModule', 'HLSL DXIL Finalize Module', []) - add_pass('hlsl-dxilemit', 'DxilEmitMetadata', 'HLSL DXIL Metadata Emit', []) - add_pass('hlsl-dxilload', 'DxilLoadMetadata', 'HLSL DXIL Metadata Load', []) - add_pass('dxil-dfe', 'DxilDeadFunctionElimination', 'Remove all unused function except entry from DxilModule', []) - add_pass('hl-dfe', 'HLDeadFunctionElimination', 'Remove all unused function except entry from HLModule', []) - add_pass('hl-preprocess', 'HLPreprocess', 'Preprocess HLModule after inline', []) - add_pass('hlsl-dxil-expand-trig', 'DxilExpandTrigIntrinsics', 'DXIL expand trig intrinsics', []) - add_pass('hlsl-hca', 'HoistConstantArray', 'HLSL constant array hoisting', []) - add_pass('hlsl-dxil-preserve-all-outputs', 'DxilPreserveAllOutputs', 'DXIL write to all outputs in signature', []) - add_pass('red', 'ReducibilityAnalysis', 'Reducibility Analysis', []) - add_pass('viewid-state', 'ComputeViewIdState', 'Compute information related to ViewID', []) - add_pass('hlsl-translate-dxil-opcode-version', 'DxilTranslateRawBuffer', 'Translates one version of dxil to another', []) - add_pass('hlsl-dxil-cleanup-addrspacecast', 'DxilCleanupAddrSpaceCast', 'HLSL DXIL Cleanup Address Space Cast (part of hlsl-dxilfinalize)', []) - add_pass('dxil-fix-array-init', 'DxilFixConstArrayInitializer', 'Dxil Fix Array Initializer', []) - add_pass('hlsl-validate-wave-sensitivity', 'DxilValidateWaveSensitivity', 'HLSL DXIL wave sensitiveity validation', []) - add_pass('dxil-elim-vector', 'DxilEliminateVector', 'Dxil Eliminate Vectors', []) - add_pass('dxil-rewrite-output-arg-debug-info', 'DxilRewriteOutputArgDebugInfo', 'Dxil Rewrite Output Arg Debug Info', []) - add_pass('dxil-finalize-preserves', 'DxilFinalizePreserves', 'Dxil Finalize Preserves', []) - add_pass('dxil-reinsert-nops', 'DxilReinsertNops', 'Dxil Reinsert Nops', []) - add_pass('dxil-insert-preserves', 'DxilInsertPreserves', 'Dxil Insert Noops', [ - {'n':'AllowPreserves', 't':'bool', 'c':1}, - ]) - add_pass('dxil-preserves-to-select', 'DxilPreserveToSelect', 'Dxil Preserves To Select', []) - add_pass('dxil-delete-loop', 'DxilLoopDeletion', 'Dxil Loop Deletion', []) - add_pass('dxil-value-cache', 'DxilValueCache', 'Dxil Value Cache',[]) - add_pass('hlsl-cleanup-dxbreak', 'CleanupDxBreak', 'HLSL Remove unnecessary dx.break conditions', []) - add_pass('dxil-rename-resources', 'DxilRenameResources', 'Rename resources to prevent merge by name during linking', [ - {'n':'prefix', 'i':'Prefix', 't':'string', 'd':'Prefix to add to resource names'}, - {'n':'from-binding', 'i':'FromBinding', 't':'bool', 'c':1, 'd':'Append binding to name when bound'}, - {'n':'keep-name', 'i':'KeepName', 't':'bool', 'c':1, 'd':'Keep name when appending binding'}, - ]) - add_pass('hlsl-dxil-resources-to-handle', 'DxilMutateResourceToHandle', 'Mutate resource to handle',[]) - - category_lib="llvm" - add_pass('ipsccp', 'IPSCCP', 'Interprocedural Sparse Conditional Constant Propagation', []) - add_pass('globalopt', 'GlobalOpt', 'Global Variable Optimizer', []) - add_pass('deadargelim', 'DAE', 'Dead Argument Elimination', []) + add_pass("barrier", "BarrierNoop", "A No-Op Barrier Pass", []) + add_pass("dce", "DCE", "Dead Code Elimination", []) + add_pass("die", "DeadInstElimination", "Dead Instruction Elimination", []) + add_pass("globaldce", "GlobalDCE", "Dead Global Elimination", []) + add_pass("mem2reg", "PromotePass", "Promote Memory to Register", []) + add_pass("scalarizer", "Scalarizer", "Scalarize vector operations", []) + + category_lib = "pix" + add_pass( + "hlsl-dxil-add-pixel-hit-instrmentation", + "DxilAddPixelHitInstrumentation", + "DXIL Count completed PS invocations and costs", + [ + {"n": "force-early-z", "t": "int", "c": 1}, + {"n": "add-pixel-cost", "t": "int", "c": 1}, + {"n": "rt-width", "t": "int", "c": 1}, + {"n": "sv-position-index", "t": "int", "c": 1}, + {"n": "num-pixels", "t": "int", "c": 1}, + ], + ) + add_pass( + "hlsl-dxil-constantColor", + "DxilOutputColorBecomesConstant", + "DXIL Constant Color Mod", + [ + {"n": "mod-mode", "t": "int", "c": 1}, + {"n": "constant-red", "t": "float", "c": 1}, + {"n": "constant-green", "t": "float", "c": 1}, + {"n": "constant-blue", "t": "float", "c": 1}, + {"n": "constant-alpha", "t": "float", "c": 1}, + ], + ) + add_pass( + "hlsl-dxil-remove-discards", + "DxilRemoveDiscards", + "HLSL DXIL Remove all discard instructions", + [], + ) + add_pass( + "hlsl-dxil-force-early-z", + "DxilForceEarlyZ", + "HLSL DXIL Force the early Z global flag, if shader has no discard calls", + [], + ) + add_pass( + "hlsl-dxil-pix-meshshader-output-instrumentation", + "DxilPIXMeshShaderOutputInstrumentation", + "DXIL mesh shader output instrumentation for PIX", + [ + {"n": "expand-payload", "t": "int", "c": 1}, + {"n": "UAVSize", "t": "int", "c": 1}, + ], + ) + add_pass( + "hlsl-dxil-pix-shader-access-instrumentation", + "DxilShaderAccessTracking", + "HLSL DXIL shader access tracking for PIX", + [ + {"n": "config", "t": "int", "c": 1}, + {"n": "checkForDynamicIndexing", "t": "bool", "c": 1}, + ], + ) + add_pass( + "hlsl-dxil-debug-instrumentation", + "DxilDebugInstrumentation", + "HLSL DXIL debug instrumentation for PIX", + [ + {"n": "UAVSize", "t": "int", "c": 1}, + {"n": "FirstInstruction", "t": "int", "c": 1}, + {"n": "LastInstruction", "t": "int", "c": 1}, + {"n": "parameter0", "t": "int", "c": 1}, + {"n": "parameter1", "t": "int", "c": 1}, + {"n": "parameter2", "t": "int", "c": 1}, + ], + ) + add_pass( + "dxil-annotate-with-virtual-regs", + "DxilAnnotateWithVirtualRegister", + "Annotates each instruction in the DXIL module with a virtual register number", + [{"n": "startInstruction", "t": "int", "c": 1}], + ) + add_pass( + "dxil-dbg-value-to-dbg-declare", + "DxilDbgValueToDbgDeclare", + "Converts llvm.dbg.value uses to llvm.dbg.declare.", + [], + ) + add_pass( + "hlsl-dxil-reduce-msaa-to-single", + "DxilReduceMSAAToSingleSample", + "HLSL DXIL Reduce all MSAA reads to single-sample reads", + [], + ) + add_pass( + "hlsl-dxil-PIX-add-tid-to-as-payload", + "DxilPIXAddTidToAmplificationShaderPayload", + "HLSL DXIL Add flat thread id to payload from AS to MS", + [ + {"n": "dispatchArgY", "t": "int", "c": 1}, + {"n": "dispatchArgZ", "t": "int", "c": 1}, + ], + ) + add_pass( + "hlsl-dxil-pix-dxr-invocations-log", + "DxilPIXDXRInvocationsLog", + "HLSL DXIL Logs all non-RayGen DXR 1.0 invocations into a UAV", + [{"n": "maxNumEntriesInLog", "t": "int", "c": 1}], + ) + + category_lib = "dxil_gen" + + add_pass("hlsl-hlemit", "HLEmitMetadata", "HLSL High-Level Metadata Emit.", []) + add_pass( + "hl-expand-store-intrinsics", + "HLExpandStoreIntrinsics", + "Expand HLSL store intrinsics", + [], + ) + add_pass( + "scalarrepl-param-hlsl", + "SROA_Parameter_HLSL", + "Scalar Replacement of Aggregates HLSL (parameters)", + [], + ) + add_pass( + "static-global-to-alloca", + "LowerStaticGlobalIntoAlloca", + "Lower static global into Alloca", + [], + ) + add_pass( + "hlmatrixlower", "HLMatrixLowerPass", "HLSL High-Level Matrix Lower", [] + ) + add_pass( + "matrixbitcastlower", "MatrixBitcastLowerPass", "Matrix Bitcast lower", [] + ) + add_pass( + "reg2mem_hlsl", + "RegToMemHlsl", + "Demote values with phi-node usage to stack slots", + [], + ) + add_pass( + "dynamic-vector-to-array", + "DynamicIndexingVectorToArray", + "Replace dynamic indexing vector with array", + [{"n": "ReplaceAllVectors", "t": "bool", "c": 1}], + ) + add_pass( + "hlsl-dxil-promote-local-resources", + "DxilPromoteLocalResources", + "DXIL promote local resource use", + [], + ) + add_pass( + "hlsl-dxil-promote-static-resources", + "DxilPromoteStaticResources", + "DXIL promote static resource use", + [], + ) + add_pass( + "hlsl-dxil-legalize-resources", + "DxilLegalizeResources", + "DXIL legalize resource use", + [], + ) + add_pass( + "hlsl-dxil-legalize-eval-operations", + "DxilLegalizeEvalOperations", + "DXIL legalize eval operations", + [], + ) + add_pass( + "dxilgen", + "DxilGenerationPass", + "HLSL DXIL Generation", + [{"n": "NotOptimized", "t": "bool", "c": 1}], + ) + add_pass( + "invalidate-undef-resource", + "InvalidateUndefResources", + "Invalidate undef resources", + [], + ) + add_pass("simplify-inst", "SimplifyInst", "Simplify Instructions", []) + add_pass( + "hlsl-dxil-precise", + "DxilPrecisePropagatePass", + "DXIL precise attribute propagate", + [], + ) + add_pass( + "dxil-legalize-sample-offset", + "DxilLegalizeSampleOffsetPass", + "DXIL legalize sample offset", + [], + ) + add_pass("dxil-gvn-hoist", "DxilSimpleGVNHoist", "DXIL simple gvn hoist", []) + add_pass( + "dxil-gvn-eliminate-region", + "DxilSimpleGVNEliminateRegion", + "DXIL simple eliminate region", + [], + ) + add_pass( + "hlsl-hlensure", "HLEnsureMetadata", "HLSL High-Level Metadata Ensure", [] + ) + add_pass( + "multi-dim-one-dim", + "MultiDimArrayToOneDimArray", + "Flatten multi-dim array into one-dim array", + [], + ) + add_pass( + "resource-handle", "ResourceToHandle", "Lower resource into handle", [] + ) + add_pass( + "hlsl-passes-nopause", + "NoPausePasses", + "Clears metadata used for pause and resume", + [], + ) + add_pass("hlsl-passes-pause", "PausePasses", "Prepare to pause passes", []) + add_pass("hlsl-passes-resume", "ResumePasses", "Prepare to resume passes", []) + add_pass( + "hlsl-dxil-lower-handle-for-lib", + "DxilLowerCreateHandleForLib", + "DXIL Lower createHandleForLib", + [], + ) + add_pass( + "hlsl-dxil-cleanup-dynamic-resource-handle", + "DxilCleanupDynamicResourceHandle", + "DXIL Cleanup dynamic resource handle calls", + [], + ) + add_pass( + "hlsl-dxil-allocate-resources-for-lib", + "DxilAllocateResourcesForLib", + "DXIL Allocate Resources For Library", + [], + ) + add_pass( + "hlsl-dxil-convergent-mark", "DxilConvergentMark", "Mark convergent", [] + ) + add_pass( + "hlsl-dxil-convergent-clear", + "DxilConvergentClear", + "Clear convergent before dxil emit", + [], + ) + add_pass( + "hlsl-dxil-eliminate-output-dynamic", + "DxilEliminateOutputDynamicIndexing", + "DXIL eliminate ouptut dynamic indexing", + [], + ) + add_pass( + "dxil-delete-redundant-debug-values", + "DxilDeleteRedundantDebugValues", + "Dxil Delete Redundant Debug Values", + [], + ) + add_pass( + "hlsl-dxilfinalize", "DxilFinalizeModule", "HLSL DXIL Finalize Module", [] + ) + add_pass("hlsl-dxilemit", "DxilEmitMetadata", "HLSL DXIL Metadata Emit", []) + add_pass("hlsl-dxilload", "DxilLoadMetadata", "HLSL DXIL Metadata Load", []) + add_pass( + "dxil-dfe", + "DxilDeadFunctionElimination", + "Remove all unused function except entry from DxilModule", + [], + ) + add_pass( + "hl-dfe", + "HLDeadFunctionElimination", + "Remove all unused function except entry from HLModule", + [], + ) + add_pass( + "hl-preprocess", "HLPreprocess", "Preprocess HLModule after inline", [] + ) + add_pass( + "hlsl-dxil-expand-trig", + "DxilExpandTrigIntrinsics", + "DXIL expand trig intrinsics", + [], + ) + add_pass("hlsl-hca", "HoistConstantArray", "HLSL constant array hoisting", []) + add_pass( + "hlsl-dxil-preserve-all-outputs", + "DxilPreserveAllOutputs", + "DXIL write to all outputs in signature", + [], + ) + add_pass("red", "ReducibilityAnalysis", "Reducibility Analysis", []) + add_pass( + "viewid-state", + "ComputeViewIdState", + "Compute information related to ViewID", + [], + ) + add_pass( + "hlsl-translate-dxil-opcode-version", + "DxilTranslateRawBuffer", + "Translates one version of dxil to another", + [], + ) + add_pass( + "hlsl-dxil-cleanup-addrspacecast", + "DxilCleanupAddrSpaceCast", + "HLSL DXIL Cleanup Address Space Cast (part of hlsl-dxilfinalize)", + [], + ) + add_pass( + "dxil-fix-array-init", + "DxilFixConstArrayInitializer", + "Dxil Fix Array Initializer", + [], + ) + add_pass( + "hlsl-validate-wave-sensitivity", + "DxilValidateWaveSensitivity", + "HLSL DXIL wave sensitiveity validation", + [], + ) + add_pass( + "dxil-elim-vector", "DxilEliminateVector", "Dxil Eliminate Vectors", [] + ) + add_pass( + "dxil-rewrite-output-arg-debug-info", + "DxilRewriteOutputArgDebugInfo", + "Dxil Rewrite Output Arg Debug Info", + [], + ) + add_pass( + "dxil-finalize-preserves", + "DxilFinalizePreserves", + "Dxil Finalize Preserves", + [], + ) + add_pass("dxil-reinsert-nops", "DxilReinsertNops", "Dxil Reinsert Nops", []) + add_pass( + "dxil-insert-preserves", + "DxilInsertPreserves", + "Dxil Insert Noops", + [ + {"n": "AllowPreserves", "t": "bool", "c": 1}, + ], + ) + add_pass( + "dxil-preserves-to-select", + "DxilPreserveToSelect", + "Dxil Preserves To Select", + [], + ) + add_pass("dxil-delete-loop", "DxilLoopDeletion", "Dxil Loop Deletion", []) + add_pass("dxil-value-cache", "DxilValueCache", "Dxil Value Cache", []) + add_pass( + "hlsl-cleanup-dxbreak", + "CleanupDxBreak", + "HLSL Remove unnecessary dx.break conditions", + [], + ) + add_pass( + "dxil-rename-resources", + "DxilRenameResources", + "Rename resources to prevent merge by name during linking", + [ + { + "n": "prefix", + "i": "Prefix", + "t": "string", + "d": "Prefix to add to resource names", + }, + { + "n": "from-binding", + "i": "FromBinding", + "t": "bool", + "c": 1, + "d": "Append binding to name when bound", + }, + { + "n": "keep-name", + "i": "KeepName", + "t": "bool", + "c": 1, + "d": "Keep name when appending binding", + }, + ], + ) + add_pass( + "hlsl-dxil-resources-to-handle", + "DxilMutateResourceToHandle", + "Mutate resource to handle", + [], + ) + + category_lib = "llvm" + add_pass( + "ipsccp", + "IPSCCP", + "Interprocedural Sparse Conditional Constant Propagation", + [], + ) + add_pass("globalopt", "GlobalOpt", "Global Variable Optimizer", []) + add_pass("deadargelim", "DAE", "Dead Argument Elimination", []) # Should we get rid of this, or invest in bugpoint support? - add_pass('deadarghaX0r', 'DAH', 'Dead Argument Hacking (BUGPOINT USE ONLY; DO NOT USE)', []) - add_pass('instcombine', 'InstructionCombiningPass', 'Combine redundant instructions', [ - {'n':'NoSink', 't':'bool', 'c':1}, - ]) - add_pass('prune-eh', 'PruneEH', 'Remove unused exception handling info', []) - add_pass('functionattrs', 'FunctionAttrs', 'Deduce function attributes', []) + add_pass( + "deadarghaX0r", + "DAH", + "Dead Argument Hacking (BUGPOINT USE ONLY; DO NOT USE)", + [], + ) + add_pass( + "instcombine", + "InstructionCombiningPass", + "Combine redundant instructions", + [ + {"n": "NoSink", "t": "bool", "c": 1}, + ], + ) + add_pass("prune-eh", "PruneEH", "Remove unused exception handling info", []) + add_pass("functionattrs", "FunctionAttrs", "Deduce function attributes", []) # add_pass('argpromotion', 'ArgPromotion', "Promote 'by reference' arguments to scalars", [ # {'n':'maxElements', 't':'unsigned', 'c':1}]) - add_pass('jump-threading', 'JumpThreading', 'Jump Threading', [ - {'n':'Threshold', 't':'int', 'c':1}, - {'n':'jump-threading-threshold', 'i':'BBDuplicateThreshold', 't':'unsigned', 'd':'Max block size to duplicate for jump threading'}]) - add_pass('correlated-propagation', 'CorrelatedValuePropagation', 'Value Propagation', []) + add_pass( + "jump-threading", + "JumpThreading", + "Jump Threading", + [ + {"n": "Threshold", "t": "int", "c": 1}, + { + "n": "jump-threading-threshold", + "i": "BBDuplicateThreshold", + "t": "unsigned", + "d": "Max block size to duplicate for jump threading", + }, + ], + ) + add_pass( + "correlated-propagation", + "CorrelatedValuePropagation", + "Value Propagation", + [], + ) # createTailCallEliminationPass is removed - but is this checked before? - add_pass('reassociate', 'Reassociate', 'Reassociate expressions', []) - add_pass('loop-rotate', 'LoopRotate', 'Rotate Loops', [ - {'n':'MaxHeaderSize', 't':'int', 'c':1}, - {'n':'rotation-max-header-size', 'i':'DefaultRotationThreshold', 't':'unsigned', 'd':'The default maximum header size for automatic loop rotation'}]) - add_pass('licm', 'LICM', 'Loop Invariant Code Motion', [ - {'n':'disable-licm-promotion', 'i':'DisablePromotion', 't':'bool', 'd':'Disable memory promotion in LICM pass'}]) - add_pass('loop-unswitch', 'LoopUnswitch', 'Unswitch loops', [ - {'n':'Os', 't':'bool', 'c':1, 'd':'Optimize for size'}, - {'n':'loop-unswitch-threshold', 'i':'Threshold', 't':'unsigned', 'd':'Max loop size to unswitch'}]) + add_pass("reassociate", "Reassociate", "Reassociate expressions", []) + add_pass( + "loop-rotate", + "LoopRotate", + "Rotate Loops", + [ + {"n": "MaxHeaderSize", "t": "int", "c": 1}, + { + "n": "rotation-max-header-size", + "i": "DefaultRotationThreshold", + "t": "unsigned", + "d": "The default maximum header size for automatic loop rotation", + }, + ], + ) + add_pass( + "licm", + "LICM", + "Loop Invariant Code Motion", + [ + { + "n": "disable-licm-promotion", + "i": "DisablePromotion", + "t": "bool", + "d": "Disable memory promotion in LICM pass", + } + ], + ) + add_pass( + "loop-unswitch", + "LoopUnswitch", + "Unswitch loops", + [ + {"n": "Os", "t": "bool", "c": 1, "d": "Optimize for size"}, + { + "n": "loop-unswitch-threshold", + "i": "Threshold", + "t": "unsigned", + "d": "Max loop size to unswitch", + }, + ], + ) # C:\nobackup\work\HLSLonLLVM\lib\Transforms\IPO\PassManagerBuilder.cpp:353 - add_pass('indvars', 'IndVarSimplify', "Induction Variable Simplification", []) - add_pass('loop-idiom', 'LoopIdiomRecognize', "Recognize loop idioms", []) - add_pass('dxil-loop-unroll', 'DxilLoopUnroll', 'DxilLoopUnroll', [ - {'n':'MaxIterationAttempt', 't':'unsigned', 'c':1, 'd':'Maximum number of iterations to attempt when iteratively unrolling.'}, - {'n':'OnlyWarnOnFail', 't':'bool', 'c':1, 'd':'Whether to just warn when unrolling fails.'}, - {'n':'StructurizeLoopExits', 't':'bool', 'c':1, 'd':'Whether the unroller should try to structurize loop exits first.'} - ]) - add_pass('dxil-erase-dead-region', 'DxilEraseDeadRegion', 'DxilEraseDeadRegion', []) - add_pass('dxil-remove-dead-blocks', 'DxilRemoveDeadBlocks', 'DxilRemoveDeadBlocks', []) - add_pass('dxil-o0-legalize', 'DxilNoOptLegalize', 'DXIL No-Opt Legalize', []) - add_pass('dxil-o0-simplify-inst', 'DxilNoOptSimplifyInstructions', 'DXIL No-Opt Simplify Inst', []) - add_pass('dxil-loop-deletion', 'DxilLoopDeletion', "Dxil Delete dead loops", [ - {'n':'NoSink', 't':'bool', 'c':1}, - ]) - add_pass('loop-deletion', 'LoopDeletion', "Delete dead loops", []) - add_pass('loop-interchange', 'LoopInterchange', 'Interchanges loops for cache reuse', []) - add_pass('loop-unroll', 'LoopUnroll', 'Unroll loops', [ - {'n':'Threshold', 't':'int', 'c':1}, - {'n':'Count', 't':'int', 'c':1}, - {'n':'AllowPartial', 't':'int', 'c':1}, - {'n':'Runtime', 't':'int', 'c':1}, - {'n':'unroll-threshold', 'i':'UnrollThreshold', 't':'unsigned', 'd':'The baseline cost threshold for loop unrolling'}, - {'n':'unroll-percent-dynamic-cost-saved-threshold', 'i':'UnrollPercentDynamicCostSavedThreshold', 't':'unsigned', 'd':'The percentage of estimated dynamic cost which must be saved by unrolling to allow unrolling up to the max threshold.'}, - {'n':'unroll-dynamic-cost-savings-discount', 'i':'UnrollDynamicCostSavingsDiscount', 't':'unsigned', 'd':"This is the amount discounted from the total unroll cost when the unrolled form has a high dynamic cost savings (triggered by the '-unroll-perecent-dynamic-cost-saved-threshold' flag)."}, - {'n':'unroll-max-iteration-count-to-analyze', 'i':'UnrollMaxIterationsCountToAnalyze', 't':'unsigned', 'd':"Don't allow loop unrolling to simulate more than this number of iterations when checking full unroll profitability"}, - {'n':'unroll-count', 'i':'UnrollCount', 't':'unsigned', 'd':'Use this unroll count for all loops including those with unroll_count pragma values, for testing purposes'}, - {'n':'unroll-allow-partial', 'i':'UnrollAllowPartial', 't':'bool', 'd':'Allows loops to be partially unrolled until -unroll-threshold loop size is reached.'}, - {'n':'unroll-runtime', 'i':'UnrollRuntime', 't':'bool', 'd':'Unroll loops with run-time trip counts'}, - {'n':'pragma-unroll-threshold', 'i':'PragmaUnrollThreshold', 't':'unsigned', 'd':'Unrolled size limit for loops with an unroll(full) or unroll_count pragma.'}]) - add_pass('mldst-motion', 'MergedLoadStoreMotion', 'MergedLoadStoreMotion', []) - add_pass('gvn', 'GVN', 'Global Value Numbering', [ - {'n':'noloads', 't':'bool', 'c':1}, - {'n':'enable-pre', 'i':'EnablePRE', 't':'bool'}, - {'n':'enable-load-pre', 'i':'EnableLoadPRE', 't':'bool'}, - {'n':'max-recurse-depth', 'i':'MaxRecurseDepth', 't':'uint32_t', 'd':'Max recurse depth'}]) - add_pass('sccp', 'SCCP', 'Sparse Conditional Constant Propagation', []) - add_pass('bdce', 'BDCE', 'Bit-Tracking Dead Code Elimination', []) - add_pass('dse', 'DSE', 'Dead Store Elimination', []) - add_pass('loop-reroll', 'LoopReroll', 'Reroll loops', [ - {'n':'max-reroll-increment', 'i':'MaxInc', 't':'unsigned', 'd':'The maximum increment for loop rerolling'}, - {'n':'reroll-num-tolerated-failed-matches', 'i':'NumToleratedFailedMatches', 't':'unsigned', 'd':'The maximum number of failures to tolerate during fuzzy matching.'}]) - add_pass('load-combine', 'LoadCombine', 'Combine Adjacent Loads', []) - add_pass('adce', 'ADCE', 'Aggressive Dead Code Elimination', []) - add_pass('float2int', 'Float2Int', 'Float to int', [ - {'n':'float2int-max-integer-bw', 'i':'MaxIntegerBW', 't':'unsigned', 'd':'Max integer bitwidth to consider in float2int'}]) - add_pass('loop-distribute', 'LoopDistribute', 'Loop Distribition', [ - {'n':'loop-distribute-verify', 'i':'LDistVerify', 't':'bool', 'd':'Turn on DominatorTree and LoopInfo verification after Loop Distribution'}, - {'n':'loop-distribute-non-if-convertible', 'i':'DistributeNonIfConvertible', 't':'bool', 'd':'Whether to distribute into a loop that may not be if-convertible by the loop vectorizer'}]) - add_pass('alignment-from-assumptions', 'AlignmentFromAssumptions', 'Alignment from assumptions', []) - add_pass('strip-dead-prototypes', 'StripDeadPrototypesPass', 'Strip Unused Function Prototypes', []) - add_pass('elim-avail-extern', 'EliminateAvailableExternally', 'Eliminate Available Externally Globals', []) - add_pass('constmerge', 'ConstantMerge', 'Merge Duplicate Global Constants', []) - add_pass('lowerbitsets', 'LowerBitSets', 'Lower bitset metadata', [ - {'n':'lowerbitsets-avoid-reuse', 'i':'AvoidReuse', 't':'bool', 'd':'Try to avoid reuse of byte array addresses using aliases'}]) + add_pass("indvars", "IndVarSimplify", "Induction Variable Simplification", []) + add_pass("loop-idiom", "LoopIdiomRecognize", "Recognize loop idioms", []) + add_pass( + "dxil-loop-unroll", + "DxilLoopUnroll", + "DxilLoopUnroll", + [ + { + "n": "MaxIterationAttempt", + "t": "unsigned", + "c": 1, + "d": "Maximum number of iterations to attempt when iteratively unrolling.", + }, + { + "n": "OnlyWarnOnFail", + "t": "bool", + "c": 1, + "d": "Whether to just warn when unrolling fails.", + }, + { + "n": "StructurizeLoopExits", + "t": "bool", + "c": 1, + "d": "Whether the unroller should try to structurize loop exits first.", + }, + ], + ) + add_pass( + "dxil-erase-dead-region", "DxilEraseDeadRegion", "DxilEraseDeadRegion", [] + ) + add_pass( + "dxil-remove-dead-blocks", + "DxilRemoveDeadBlocks", + "DxilRemoveDeadBlocks", + [], + ) + add_pass("dxil-o0-legalize", "DxilNoOptLegalize", "DXIL No-Opt Legalize", []) + add_pass( + "dxil-o0-simplify-inst", + "DxilNoOptSimplifyInstructions", + "DXIL No-Opt Simplify Inst", + [], + ) + add_pass( + "dxil-loop-deletion", + "DxilLoopDeletion", + "Dxil Delete dead loops", + [ + {"n": "NoSink", "t": "bool", "c": 1}, + ], + ) + add_pass("loop-deletion", "LoopDeletion", "Delete dead loops", []) + add_pass( + "loop-interchange", + "LoopInterchange", + "Interchanges loops for cache reuse", + [], + ) + add_pass( + "loop-unroll", + "LoopUnroll", + "Unroll loops", + [ + {"n": "Threshold", "t": "int", "c": 1}, + {"n": "Count", "t": "int", "c": 1}, + {"n": "AllowPartial", "t": "int", "c": 1}, + {"n": "Runtime", "t": "int", "c": 1}, + { + "n": "unroll-threshold", + "i": "UnrollThreshold", + "t": "unsigned", + "d": "The baseline cost threshold for loop unrolling", + }, + { + "n": "unroll-percent-dynamic-cost-saved-threshold", + "i": "UnrollPercentDynamicCostSavedThreshold", + "t": "unsigned", + "d": "The percentage of estimated dynamic cost which must be saved by unrolling to allow unrolling up to the max threshold.", + }, + { + "n": "unroll-dynamic-cost-savings-discount", + "i": "UnrollDynamicCostSavingsDiscount", + "t": "unsigned", + "d": "This is the amount discounted from the total unroll cost when the unrolled form has a high dynamic cost savings (triggered by the '-unroll-perecent-dynamic-cost-saved-threshold' flag).", + }, + { + "n": "unroll-max-iteration-count-to-analyze", + "i": "UnrollMaxIterationsCountToAnalyze", + "t": "unsigned", + "d": "Don't allow loop unrolling to simulate more than this number of iterations when checking full unroll profitability", + }, + { + "n": "unroll-count", + "i": "UnrollCount", + "t": "unsigned", + "d": "Use this unroll count for all loops including those with unroll_count pragma values, for testing purposes", + }, + { + "n": "unroll-allow-partial", + "i": "UnrollAllowPartial", + "t": "bool", + "d": "Allows loops to be partially unrolled until -unroll-threshold loop size is reached.", + }, + { + "n": "unroll-runtime", + "i": "UnrollRuntime", + "t": "bool", + "d": "Unroll loops with run-time trip counts", + }, + { + "n": "pragma-unroll-threshold", + "i": "PragmaUnrollThreshold", + "t": "unsigned", + "d": "Unrolled size limit for loops with an unroll(full) or unroll_count pragma.", + }, + ], + ) + add_pass("mldst-motion", "MergedLoadStoreMotion", "MergedLoadStoreMotion", []) + add_pass( + "gvn", + "GVN", + "Global Value Numbering", + [ + {"n": "noloads", "t": "bool", "c": 1}, + {"n": "enable-pre", "i": "EnablePRE", "t": "bool"}, + {"n": "enable-load-pre", "i": "EnableLoadPRE", "t": "bool"}, + { + "n": "max-recurse-depth", + "i": "MaxRecurseDepth", + "t": "uint32_t", + "d": "Max recurse depth", + }, + ], + ) + add_pass("sccp", "SCCP", "Sparse Conditional Constant Propagation", []) + add_pass("bdce", "BDCE", "Bit-Tracking Dead Code Elimination", []) + add_pass("dse", "DSE", "Dead Store Elimination", []) + add_pass( + "loop-reroll", + "LoopReroll", + "Reroll loops", + [ + { + "n": "max-reroll-increment", + "i": "MaxInc", + "t": "unsigned", + "d": "The maximum increment for loop rerolling", + }, + { + "n": "reroll-num-tolerated-failed-matches", + "i": "NumToleratedFailedMatches", + "t": "unsigned", + "d": "The maximum number of failures to tolerate during fuzzy matching.", + }, + ], + ) + add_pass("load-combine", "LoadCombine", "Combine Adjacent Loads", []) + add_pass("adce", "ADCE", "Aggressive Dead Code Elimination", []) + add_pass( + "float2int", + "Float2Int", + "Float to int", + [ + { + "n": "float2int-max-integer-bw", + "i": "MaxIntegerBW", + "t": "unsigned", + "d": "Max integer bitwidth to consider in float2int", + } + ], + ) + add_pass( + "loop-distribute", + "LoopDistribute", + "Loop Distribition", + [ + { + "n": "loop-distribute-verify", + "i": "LDistVerify", + "t": "bool", + "d": "Turn on DominatorTree and LoopInfo verification after Loop Distribution", + }, + { + "n": "loop-distribute-non-if-convertible", + "i": "DistributeNonIfConvertible", + "t": "bool", + "d": "Whether to distribute into a loop that may not be if-convertible by the loop vectorizer", + }, + ], + ) + add_pass( + "alignment-from-assumptions", + "AlignmentFromAssumptions", + "Alignment from assumptions", + [], + ) + add_pass( + "strip-dead-prototypes", + "StripDeadPrototypesPass", + "Strip Unused Function Prototypes", + [], + ) + add_pass( + "elim-avail-extern", + "EliminateAvailableExternally", + "Eliminate Available Externally Globals", + [], + ) + add_pass("constmerge", "ConstantMerge", "Merge Duplicate Global Constants", []) + add_pass( + "lowerbitsets", + "LowerBitSets", + "Lower bitset metadata", + [ + { + "n": "lowerbitsets-avoid-reuse", + "i": "AvoidReuse", + "t": "bool", + "d": "Try to avoid reuse of byte array addresses using aliases", + } + ], + ) # TODO: turn STATISTICS macros into ETW events # assert no duplicate names self.pass_idx_args = set() @@ -2307,93 +6021,133 @@ def add_pass(name, type_name, doc, opts): assert ap.name not in p_names p_names.add(ap.name) for anarg in ap.args: - assert anarg.is_ctor_param or anarg.name not in p_ids, "argument %s in %s is not ctor and is duplicate" % (anarg.name, ap.name) + assert ( + anarg.is_ctor_param or anarg.name not in p_ids + ), "argument %s in %s is not ctor and is duplicate" % ( + anarg.name, + ap.name, + ) if not anarg.is_ctor_param: p_ids.add(anarg.name) self.pass_idx_args.add(anarg.name) def build_semantics(self): - SemanticKind = db_dxil_enum("SemanticKind", "Semantic kind; Arbitrary or specific system value.", [ - (0, "Arbitrary", ""), - (1, "VertexID", ""), - (2, "InstanceID", ""), - (3, "Position", ""), - (4, "RenderTargetArrayIndex", ""), - (5, "ViewPortArrayIndex", ""), - (6, "ClipDistance", ""), - (7, "CullDistance", ""), - (8, "OutputControlPointID", ""), - (9, "DomainLocation", ""), - (10, "PrimitiveID", ""), - (11, "GSInstanceID", ""), - (12, "SampleIndex", ""), - (13, "IsFrontFace", ""), - (14, "Coverage", ""), - (15, "InnerCoverage", ""), - (16, "Target", ""), - (17, "Depth", ""), - (18, "DepthLessEqual", ""), - (19, "DepthGreaterEqual", ""), - (20, "StencilRef", ""), - (21, "DispatchThreadID", ""), - (22, "GroupID", ""), - (23, "GroupIndex", ""), - (24, "GroupThreadID", ""), - (25, "TessFactor", ""), - (26, "InsideTessFactor", ""), - (27, "ViewID", ""), - (28, "Barycentrics", ""), - (29, "ShadingRate", ""), - (30, "CullPrimitive", ""), - (31, "Invalid", ""), - ]) + SemanticKind = db_dxil_enum( + "SemanticKind", + "Semantic kind; Arbitrary or specific system value.", + [ + (0, "Arbitrary", ""), + (1, "VertexID", ""), + (2, "InstanceID", ""), + (3, "Position", ""), + (4, "RenderTargetArrayIndex", ""), + (5, "ViewPortArrayIndex", ""), + (6, "ClipDistance", ""), + (7, "CullDistance", ""), + (8, "OutputControlPointID", ""), + (9, "DomainLocation", ""), + (10, "PrimitiveID", ""), + (11, "GSInstanceID", ""), + (12, "SampleIndex", ""), + (13, "IsFrontFace", ""), + (14, "Coverage", ""), + (15, "InnerCoverage", ""), + (16, "Target", ""), + (17, "Depth", ""), + (18, "DepthLessEqual", ""), + (19, "DepthGreaterEqual", ""), + (20, "StencilRef", ""), + (21, "DispatchThreadID", ""), + (22, "GroupID", ""), + (23, "GroupIndex", ""), + (24, "GroupThreadID", ""), + (25, "TessFactor", ""), + (26, "InsideTessFactor", ""), + (27, "ViewID", ""), + (28, "Barycentrics", ""), + (29, "ShadingRate", ""), + (30, "CullPrimitive", ""), + (31, "Invalid", ""), + ], + ) self.enums.append(SemanticKind) - SigPointKind = db_dxil_enum("SigPointKind", "Signature Point is more specific than shader stage or signature as it is unique in both stage and item dimensionality or frequency.", [ - (0, "VSIn", "Ordinary Vertex Shader input from Input Assembler"), - (1, "VSOut", "Ordinary Vertex Shader output that may feed Rasterizer"), - (2, "PCIn", "Patch Constant function non-patch inputs"), - (3, "HSIn", "Hull Shader function non-patch inputs"), - (4, "HSCPIn", "Hull Shader patch inputs - Control Points"), - (5, "HSCPOut", "Hull Shader function output - Control Point"), - (6, "PCOut", "Patch Constant function output - Patch Constant data passed to Domain Shader"), - (7, "DSIn", "Domain Shader regular input - Patch Constant data plus system values"), - (8, "DSCPIn", "Domain Shader patch input - Control Points"), - (9, "DSOut", "Domain Shader output - vertex data that may feed Rasterizer"), - (10, "GSVIn", "Geometry Shader vertex input - qualified with primitive type"), - (11, "GSIn", "Geometry Shader non-vertex inputs (system values)"), - (12, "GSOut", "Geometry Shader output - vertex data that may feed Rasterizer"), - (13, "PSIn", "Pixel Shader input"), - (14, "PSOut", "Pixel Shader output"), - (15, "CSIn", "Compute Shader input"), - (16, "MSIn", "Mesh Shader input"), - (17, "MSOut", "Mesh Shader vertices output"), - (18, "MSPOut", "Mesh Shader primitives output"), - (19, "ASIn", "Amplification Shader input"), - (21, "Invalid", ""), - ]) + SigPointKind = db_dxil_enum( + "SigPointKind", + "Signature Point is more specific than shader stage or signature as it is unique in both stage and item dimensionality or frequency.", + [ + (0, "VSIn", "Ordinary Vertex Shader input from Input Assembler"), + (1, "VSOut", "Ordinary Vertex Shader output that may feed Rasterizer"), + (2, "PCIn", "Patch Constant function non-patch inputs"), + (3, "HSIn", "Hull Shader function non-patch inputs"), + (4, "HSCPIn", "Hull Shader patch inputs - Control Points"), + (5, "HSCPOut", "Hull Shader function output - Control Point"), + ( + 6, + "PCOut", + "Patch Constant function output - Patch Constant data passed to Domain Shader", + ), + ( + 7, + "DSIn", + "Domain Shader regular input - Patch Constant data plus system values", + ), + (8, "DSCPIn", "Domain Shader patch input - Control Points"), + ( + 9, + "DSOut", + "Domain Shader output - vertex data that may feed Rasterizer", + ), + ( + 10, + "GSVIn", + "Geometry Shader vertex input - qualified with primitive type", + ), + (11, "GSIn", "Geometry Shader non-vertex inputs (system values)"), + ( + 12, + "GSOut", + "Geometry Shader output - vertex data that may feed Rasterizer", + ), + (13, "PSIn", "Pixel Shader input"), + (14, "PSOut", "Pixel Shader output"), + (15, "CSIn", "Compute Shader input"), + (16, "MSIn", "Mesh Shader input"), + (17, "MSOut", "Mesh Shader vertices output"), + (18, "MSPOut", "Mesh Shader primitives output"), + (19, "ASIn", "Amplification Shader input"), + (21, "Invalid", ""), + ], + ) self.enums.append(SigPointKind) - PackingKind = db_dxil_enum("PackingKind", "Kind of signature point", [ - (0, "None", "No packing should be performed"), - (1, "InputAssembler", "Vertex Shader input from Input Assembler"), - (2, "Vertex", "Vertex that may feed the Rasterizer"), - (3, "PatchConstant", "Patch constant signature"), - (4, "Target", "Render Target (Pixel Shader Output)"), - (5, "Invalid", ""), - ]) - - Float32DenormMode = db_dxil_enum("Float32DenormMode", "float32 denorm behavior", [ - (0, "Any", "Undefined behavior for denormal numbers"), - (1, "Preserve", "Preserve both input and output"), - (2, "FTZ", "Preserve denormal inputs. Flush denorm outputs"), - (3, "Reserve3", "Reserved Value. Not used for now"), - (4, "Reserve4", "Reserved Value. Not used for now"), - (5, "Reserve5", "Reserved Value. Not used for now"), - (6, "Reserve6", "Reserved Value. Not used for now"), - (7, "Reserve7", "Reserved Value. Not used for now"), - ]) + PackingKind = db_dxil_enum( + "PackingKind", + "Kind of signature point", + [ + (0, "None", "No packing should be performed"), + (1, "InputAssembler", "Vertex Shader input from Input Assembler"), + (2, "Vertex", "Vertex that may feed the Rasterizer"), + (3, "PatchConstant", "Patch constant signature"), + (4, "Target", "Render Target (Pixel Shader Output)"), + (5, "Invalid", ""), + ], + ) + + Float32DenormMode = db_dxil_enum( + "Float32DenormMode", + "float32 denorm behavior", + [ + (0, "Any", "Undefined behavior for denormal numbers"), + (1, "Preserve", "Preserve both input and output"), + (2, "FTZ", "Preserve denormal inputs. Flush denorm outputs"), + (3, "Reserve3", "Reserved Value. Not used for now"), + (4, "Reserve4", "Reserved Value. Not used for now"), + (5, "Reserve5", "Reserved Value. Not used for now"), + (6, "Reserve6", "Reserved Value. Not used for now"), + (7, "Reserve7", "Reserved Value. Not used for now"), + ], + ) self.enums.append(Float32DenormMode) - SigPointCSV = """ SigPoint, Related, ShaderKind, PackingKind, SignatureKind VSIn, Invalid, Vertex, InputAssembler, Input @@ -2418,27 +6172,48 @@ def build_semantics(self): ASIn, Invalid, Amplification, None, Invalid Invalid, Invalid, Invalid, Invalid, Invalid """ - table = [list(map(str.strip, line.split(','))) for line in SigPointCSV.splitlines() if line.strip()] - for row in table[1:]: assert(len(row) == len(table[0])) # Ensure table is rectangular + table = [ + list(map(str.strip, line.split(","))) + for line in SigPointCSV.splitlines() + if line.strip() + ] + for row in table[1:]: + assert len(row) == len(table[0]) # Ensure table is rectangular # Make sure labels match enums, otherwise the table isn't aligned or in-sync if not ([row[0] for row in table[1:]] == SigPointKind.value_names()): - assert(False and 'SigPointKind does not align with SigPointCSV row labels') + assert False and "SigPointKind does not align with SigPointCSV row labels" self.sigpoint_table = table self.enums.append(PackingKind) - SemanticInterpretationKind = db_dxil_enum("SemanticInterpretationKind", "Defines how a semantic is interpreted at a particular SignaturePoint", [ - (0, "NA", "Not Available"), - (1, "SV", "Normal System Value"), - (2, "SGV", "System Generated Value (sorted last)"), - (3, "Arb", "Treated as Arbitrary"), - (4, "NotInSig", "Not included in signature (intrinsic access)"), - (5, "NotPacked", "Included in signature, but does not contribute to packing"), - (6, "Target", "Special handling for SV_Target"), - (7, "TessFactor", "Special handling for tessellation factors"), - (8, "Shadow", "Shadow element must be added to a signature for compatibility"), - (8, "ClipCull", "Special packing rules for SV_ClipDistance or SV_CullDistance"), - (9, "Invalid", ""), - ]) + SemanticInterpretationKind = db_dxil_enum( + "SemanticInterpretationKind", + "Defines how a semantic is interpreted at a particular SignaturePoint", + [ + (0, "NA", "Not Available"), + (1, "SV", "Normal System Value"), + (2, "SGV", "System Generated Value (sorted last)"), + (3, "Arb", "Treated as Arbitrary"), + (4, "NotInSig", "Not included in signature (intrinsic access)"), + ( + 5, + "NotPacked", + "Included in signature, but does not contribute to packing", + ), + (6, "Target", "Special handling for SV_Target"), + (7, "TessFactor", "Special handling for tessellation factors"), + ( + 8, + "Shadow", + "Shadow element must be added to a signature for compatibility", + ), + ( + 8, + "ClipCull", + "Special packing rules for SV_ClipDistance or SV_CullDistance", + ), + (9, "Invalid", ""), + ], + ) self.enums.append(SemanticInterpretationKind) # The following has SampleIndex, Coverage, and InnerCoverage as loaded with instructions rather than from the signature @@ -2476,87 +6251,295 @@ def build_semantics(self): ShadingRate,NA,SV _64,NA,NA,SV _64,SV _64,NA,NA,SV _64,SV _64,SV _64,NA,SV _64,SV _64,NA,NA,NA,NA,SV,NA CullPrimitive,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NotInSig,NA,NA,NA,NA,NotPacked,NA """ - table = [list(map(str.strip, line.split(','))) for line in SemanticInterpretationCSV.splitlines() if line.strip()] - for row in table[1:]: assert(len(row) == len(table[0])) # Ensure table is rectangular + table = [ + list(map(str.strip, line.split(","))) + for line in SemanticInterpretationCSV.splitlines() + if line.strip() + ] + for row in table[1:]: + assert len(row) == len(table[0]) # Ensure table is rectangular # Make sure labels match enums, otherwise the table isn't aligned or in-sync - assert(table[0][1:] == SigPointKind.value_names()[:-1]) # exclude Invalid - if not ([row[0] for row in table[1:]] == SemanticKind.value_names()[:-1]): # exclude Invalid - assert(False and 'SemanticKind does not align with SemanticInterpretationCSV row labels') + assert table[0][1:] == SigPointKind.value_names()[:-1] # exclude Invalid + if not ( + [row[0] for row in table[1:]] == SemanticKind.value_names()[:-1] + ): # exclude Invalid + assert ( + False + and "SemanticKind does not align with SemanticInterpretationCSV row labels" + ) self.interpretation_table = table def build_valrules(self): - self.add_valrule_msg("Bitcode.Valid", "Module must be bitcode-valid", "Module bitcode is invalid.") - - self.add_valrule_msg("Container.PartMatches", "DXIL Container Parts must match Module", "Container part '%0' does not match expected for module.") - self.add_valrule_msg("Container.PartRepeated", "DXIL Container must have only one of each part type", "More than one container part '%0'.") - self.add_valrule_msg("Container.PartMissing", "DXIL Container requires certain parts, corresponding to module", "Missing part '%0' required by module.") - self.add_valrule_msg("Container.PartInvalid", "DXIL Container must not contain unknown parts", "Unknown part '%0' found in DXIL container.") - self.add_valrule_msg("Container.RootSignatureIncompatible", "Root Signature in DXIL Container must be compatible with shader", "Root Signature in DXIL container is not compatible with shader.") + self.add_valrule_msg( + "Bitcode.Valid", + "Module must be bitcode-valid", + "Module bitcode is invalid.", + ) + + self.add_valrule_msg( + "Container.PartMatches", + "DXIL Container Parts must match Module", + "Container part '%0' does not match expected for module.", + ) + self.add_valrule_msg( + "Container.PartRepeated", + "DXIL Container must have only one of each part type", + "More than one container part '%0'.", + ) + self.add_valrule_msg( + "Container.PartMissing", + "DXIL Container requires certain parts, corresponding to module", + "Missing part '%0' required by module.", + ) + self.add_valrule_msg( + "Container.PartInvalid", + "DXIL Container must not contain unknown parts", + "Unknown part '%0' found in DXIL container.", + ) + self.add_valrule_msg( + "Container.RootSignatureIncompatible", + "Root Signature in DXIL Container must be compatible with shader", + "Root Signature in DXIL container is not compatible with shader.", + ) self.add_valrule("Meta.Required", "Required metadata missing.") - self.add_valrule_msg("Meta.Known", "Named metadata should be known", "Named metadata '%0' is unknown.") + self.add_valrule_msg( + "Meta.Known", + "Named metadata should be known", + "Named metadata '%0' is unknown.", + ) self.add_valrule("Meta.Used", "All metadata must be used by dxil.") - self.add_valrule_msg("Meta.Target", "Target triple must be 'dxil-ms-dx'", "Unknown target triple '%0'.") - self.add_valrule("Meta.WellFormed", "Metadata must be well-formed in operand count and types.") # TODO: add string arg for what metadata is malformed (this is emitted from a lot of places and provides no context whatsoever) - self.add_valrule_msg("Meta.VersionSupported", "Version in metadata must be supported.", "%0 version in metadata (%1.%2) is not supported; maximum: (%3.%4).") - 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_msg("Meta.SemaKindMatchesName", "Semantic name must match system value, when defined.", "Semantic name %0 does not match System Value kind %1.") - self.add_valrule_msg("Meta.DuplicateSysValue", "System value may only appear once in signature", "System value %0 appears more than once in the same signature.") - self.add_valrule_msg("Meta.SemanticIndexMax", "System value semantics have a maximum valid semantic index", "%0 semantic index exceeds maximum (%1).") - self.add_valrule_msg("Meta.SystemValueRows", "System value may only have 1 row", "rows for system value semantic %0 must be 1.") - self.add_valrule_msg("Meta.SemanticShouldBeAllocated", "Semantic should have a valid packing location", "%0 Semantic '%1' should have a valid packing location.") - self.add_valrule_msg("Meta.SemanticShouldNotBeAllocated", "Semantic should have a packing location of -1", "%0 Semantic '%1' should have a packing location of -1.") + self.add_valrule_msg( + "Meta.Target", + "Target triple must be 'dxil-ms-dx'", + "Unknown target triple '%0'.", + ) + self.add_valrule( + "Meta.WellFormed", + "Metadata must be well-formed in operand count and types.", + ) # TODO: add string arg for what metadata is malformed (this is emitted from a lot of places and provides no context whatsoever) + self.add_valrule_msg( + "Meta.VersionSupported", + "Version in metadata must be supported.", + "%0 version in metadata (%1.%2) is not supported; maximum: (%3.%4).", + ) + 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_msg( + "Meta.SemaKindMatchesName", + "Semantic name must match system value, when defined.", + "Semantic name %0 does not match System Value kind %1.", + ) + self.add_valrule_msg( + "Meta.DuplicateSysValue", + "System value may only appear once in signature", + "System value %0 appears more than once in the same signature.", + ) + self.add_valrule_msg( + "Meta.SemanticIndexMax", + "System value semantics have a maximum valid semantic index", + "%0 semantic index exceeds maximum (%1).", + ) + self.add_valrule_msg( + "Meta.SystemValueRows", + "System value may only have 1 row", + "rows for system value semantic %0 must be 1.", + ) + self.add_valrule_msg( + "Meta.SemanticShouldBeAllocated", + "Semantic should have a valid packing location", + "%0 Semantic '%1' should have a valid packing location.", + ) + self.add_valrule_msg( + "Meta.SemanticShouldNotBeAllocated", + "Semantic should have a packing location of -1", + "%0 Semantic '%1' should have a packing location of -1.", + ) 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.") - self.add_valrule_msg("Meta.SignatureOverlap", "Signature elements may not overlap in packing location.", "signature element %0 at location (%1,%2) size (%3,%4) overlaps another signature element.") - self.add_valrule_msg("Meta.SignatureOutOfRange", "Signature elements must fit within maximum signature size", "signature element %0 at location (%1,%2) size (%3,%4) is out of range.") - self.add_valrule_msg("Meta.SignatureIndexConflict", "Only elements with compatible indexing rules may be packed together", "signature element %0 at location (%1,%2) size (%3,%4) has an indexing conflict with another signature element packed into the same row.") - self.add_valrule_msg("Meta.SignatureIllegalComponentOrder", "Component ordering for packed elements must be: arbitrary < system value < system generated value", "signature element %0 at location (%1,%2) size (%3,%4) violates component ordering rule (arb < sv < sgv).") - self.add_valrule_msg("Meta.SignatureDataWidth", "Data width must be identical for all elements packed into the same row.", "signature element %0 at location (%1, %2) size (%3, %4) has data width that differs from another element packed into the same row.") - self.add_valrule_msg("Meta.IntegerInterpMode", "Interpolation mode on integer must be Constant", "signature element %0 specifies invalid interpolation mode for integer component type.") - self.add_valrule_msg("Meta.InterpModeInOneRow", "Interpolation mode must be identical for all elements packed into the same row.", "signature element %0 at location (%1,%2) size (%3,%4) has interpolation mode that differs from another element packed into the same row.") + self.add_valrule( + "Meta.DenseResIDs", "Resource identifiers must be zero-based and dense." + ) + self.add_valrule_msg( + "Meta.SignatureOverlap", + "Signature elements may not overlap in packing location.", + "signature element %0 at location (%1,%2) size (%3,%4) overlaps another signature element.", + ) + self.add_valrule_msg( + "Meta.SignatureOutOfRange", + "Signature elements must fit within maximum signature size", + "signature element %0 at location (%1,%2) size (%3,%4) is out of range.", + ) + self.add_valrule_msg( + "Meta.SignatureIndexConflict", + "Only elements with compatible indexing rules may be packed together", + "signature element %0 at location (%1,%2) size (%3,%4) has an indexing conflict with another signature element packed into the same row.", + ) + self.add_valrule_msg( + "Meta.SignatureIllegalComponentOrder", + "Component ordering for packed elements must be: arbitrary < system value < system generated value", + "signature element %0 at location (%1,%2) size (%3,%4) violates component ordering rule (arb < sv < sgv).", + ) + self.add_valrule_msg( + "Meta.SignatureDataWidth", + "Data width must be identical for all elements packed into the same row.", + "signature element %0 at location (%1, %2) size (%3, %4) has data width that differs from another element packed into the same row.", + ) + self.add_valrule_msg( + "Meta.IntegerInterpMode", + "Interpolation mode on integer must be Constant", + "signature element %0 specifies invalid interpolation mode for integer component type.", + ) + self.add_valrule_msg( + "Meta.InterpModeInOneRow", + "Interpolation mode must be identical for all elements packed into the same row.", + "signature element %0 at location (%1,%2) size (%3,%4) has interpolation mode that differs from another element packed into the same row.", + ) self.add_valrule("Meta.SemanticCompType", "%0 must be %1.") - self.add_valrule_msg("Meta.ClipCullMaxRows", "Combined elements of SV_ClipDistance and SV_CullDistance must fit in two rows.", "ClipDistance and CullDistance occupy more than the maximum of 2 rows combined.") - self.add_valrule_msg("Meta.ClipCullMaxComponents", "Combined elements of SV_ClipDistance and SV_CullDistance must fit in 8 components", "ClipDistance and CullDistance use more than the maximum of 8 components combined.") - self.add_valrule("Meta.SignatureCompType", "signature %0 specifies unrecognized or invalid component type.") - self.add_valrule("Meta.TessellatorPartition", "Invalid Tessellator Partitioning specified. Must be integer, pow2, fractional_odd or fractional_even.") - self.add_valrule("Meta.TessellatorOutputPrimitive", "Invalid Tessellator Output Primitive specified. Must be point, line, triangleCW or triangleCCW.") - self.add_valrule("Meta.MaxTessFactor", "Hull Shader MaxTessFactor must be [%0..%1]. %2 specified.") + self.add_valrule_msg( + "Meta.ClipCullMaxRows", + "Combined elements of SV_ClipDistance and SV_CullDistance must fit in two rows.", + "ClipDistance and CullDistance occupy more than the maximum of 2 rows combined.", + ) + self.add_valrule_msg( + "Meta.ClipCullMaxComponents", + "Combined elements of SV_ClipDistance and SV_CullDistance must fit in 8 components", + "ClipDistance and CullDistance use more than the maximum of 8 components combined.", + ) + self.add_valrule( + "Meta.SignatureCompType", + "signature %0 specifies unrecognized or invalid component type.", + ) + self.add_valrule( + "Meta.TessellatorPartition", + "Invalid Tessellator Partitioning specified. Must be integer, pow2, fractional_odd or fractional_even.", + ) + self.add_valrule( + "Meta.TessellatorOutputPrimitive", + "Invalid Tessellator Output Primitive specified. Must be point, line, triangleCW or triangleCCW.", + ) + self.add_valrule( + "Meta.MaxTessFactor", + "Hull Shader MaxTessFactor must be [%0..%1]. %2 specified.", + ) self.add_valrule("Meta.ValidSamplerMode", "Invalid sampler mode on sampler .") - self.add_valrule("Meta.GlcNotOnAppendConsume", "globallycoherent cannot be used with append/consume buffers: '%0'.") - 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.GlcNotOnAppendConsume", + "globallycoherent cannot be used with append/consume buffers: '%0'.", + ) + 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("Meta.ControlFlowHintNotOnControlFlow", "Control flow hint only works on control flow inst.") - self.add_valrule("Meta.TextureType", "elements of typed buffers and textures must fit in four 32-bit quantities.") - self.add_valrule("Meta.BarycentricsInterpolation", "SV_Barycentrics cannot be used with 'nointerpolation' type.") - self.add_valrule("Meta.BarycentricsFloat3", "only 'float3' type is allowed for SV_Barycentrics.") - self.add_valrule("Meta.BarycentricsTwoPerspectives", "There can only be up to two input attributes of SV_Barycentrics with different perspective interpolation mode.") - self.add_valrule("Meta.NoEntryPropsForEntry", "Entry point %0 must have entry properties.") + 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( + "Meta.ControlFlowHintNotOnControlFlow", + "Control flow hint only works on control flow inst.", + ) + self.add_valrule( + "Meta.TextureType", + "elements of typed buffers and textures must fit in four 32-bit quantities.", + ) + self.add_valrule( + "Meta.BarycentricsInterpolation", + "SV_Barycentrics cannot be used with 'nointerpolation' type.", + ) + self.add_valrule( + "Meta.BarycentricsFloat3", + "only 'float3' type is allowed for SV_Barycentrics.", + ) + self.add_valrule( + "Meta.BarycentricsTwoPerspectives", + "There can only be up to two input attributes of SV_Barycentrics with different perspective interpolation mode.", + ) + self.add_valrule( + "Meta.NoEntryPropsForEntry", "Entry point %0 must have entry properties." + ) 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.PtrBitCast", "Pointer type bitcast must be have same size.") - self.add_valrule("Instr.MinPrecisonBitCast", "Bitcast on minprecison types is not allowed.") - self.add_valrule("Instr.StructBitCast", "Bitcast on struct types is not allowed.") - self.add_valrule("Instr.Status", "Resource status should only be used by CheckAccessFullyMapped.") - self.add_valrule("Instr.CheckAccessFullyMapped", "CheckAccessFullyMapped should only be used on resource status.") - self.add_valrule_msg("Instr.OpConst", "DXIL intrinsic requires an immediate constant operand", "%0 of %1 must be an immediate constant.") + 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.PtrBitCast", "Pointer type bitcast must be have same size." + ) + self.add_valrule( + "Instr.MinPrecisonBitCast", "Bitcast on minprecison types is not allowed." + ) + self.add_valrule( + "Instr.StructBitCast", "Bitcast on struct types is not allowed." + ) + self.add_valrule( + "Instr.Status", + "Resource status should only be used by CheckAccessFullyMapped.", + ) + self.add_valrule( + "Instr.CheckAccessFullyMapped", + "CheckAccessFullyMapped should only be used on resource status.", + ) + 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_msg("Instr.OperandRange", "DXIL intrinsic operand must be within defined range", "expect %0 between %1, got %2.") - self.add_valrule("Instr.NoReadingUninitialized", "Instructions should not read uninitialized value.") - self.add_valrule("Instr.NoGenericPtrAddrSpaceCast", "Address space cast between pointer types must have one part to be generic address space.") - self.add_valrule("Instr.InBoundsAccess", "Access to out-of-bounds memory is disallowed.") - self.add_valrule("Instr.OpConstRange", "Constant values must be in-range for operation.") - self.add_valrule("Instr.ImmBiasForSampleB", "bias amount for sample_b must be in the range [%0,%1], but %2 was specified as an immediate.") + self.add_valrule( + "Instr.OpCodeReserved", "Instructions must not reference reserved opcodes." + ) + self.add_valrule_msg( + "Instr.OperandRange", + "DXIL intrinsic operand must be within defined range", + "expect %0 between %1, got %2.", + ) + self.add_valrule( + "Instr.NoReadingUninitialized", + "Instructions should not read uninitialized value.", + ) + self.add_valrule( + "Instr.NoGenericPtrAddrSpaceCast", + "Address space cast between pointer types must have one part to be generic address space.", + ) + self.add_valrule( + "Instr.InBoundsAccess", "Access to out-of-bounds memory is disallowed." + ) + self.add_valrule( + "Instr.OpConstRange", "Constant values must be in-range for operation." + ) + self.add_valrule( + "Instr.ImmBiasForSampleB", + "bias amount for sample_b must be in the range [%0,%1], but %2 was specified as an immediate.", + ) # If streams have not been declared, you must use cut instead of cut_stream in GS - is there an equivalent rule here? # Need to clean up all error messages and actually implement. @@ -2566,77 +6549,241 @@ def build_valrules(self): self.add_valrule("Instr.NoIndefiniteAcos", "No indefinite arccosine.") self.add_valrule("Instr.NoIDivByZero", "No signed integer division by zero.") self.add_valrule("Instr.NoUDivByZero", "No unsigned integer division by zero.") - self.add_valrule("Instr.NoIndefiniteDsxy", "No indefinite derivative calculation.") - self.add_valrule("Instr.MinPrecisionNotPrecise", "Instructions marked precise may not refer to minprecision values.") + self.add_valrule( + "Instr.NoIndefiniteDsxy", "No indefinite derivative calculation." + ) + self.add_valrule( + "Instr.MinPrecisionNotPrecise", + "Instructions marked precise may not refer to minprecision values.", + ) # Backend - self.add_valrule("Instr.OnlyOneAllocConsume", "RWStructuredBuffers may increment or decrement their counters, but not both.") + self.add_valrule( + "Instr.OnlyOneAllocConsume", + "RWStructuredBuffers may increment or decrement their counters, but not both.", + ) # CCompiler - self.add_valrule("Instr.TextureOffset", "offset texture instructions must take offset which can resolve to integer literal in the range -8 to 7.") + self.add_valrule( + "Instr.TextureOffset", + "offset texture instructions must take offset which can resolve to integer literal in the range -8 to 7.", + ) # D3D12 - 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_GUARANTEED_RACE_CONDITION_UAV", "TODO - race condition writing to shared resource detected, consider making this write conditional.") warning on fxc. - #self.add_valrule("Instr.ERR_GUARANTEED_RACE_CONDITION_GSM", "TODO - race condition writing to shared memory detected, consider making this write conditional.") warning on fxc. - #self.add_valrule("Instr.ERR_INFINITE_LOOP", "TODO - ERR_INFINITE_LOOP") fxc will report error if it can prove the loop is infinite. - self.add_valrule("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.") + 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_GUARANTEED_RACE_CONDITION_UAV", "TODO - race condition writing to shared resource detected, consider making this write conditional.") warning on fxc. + # self.add_valrule("Instr.ERR_GUARANTEED_RACE_CONDITION_GSM", "TODO - race condition writing to shared memory detected, consider making this write conditional.") warning on fxc. + # self.add_valrule("Instr.ERR_INFINITE_LOOP", "TODO - ERR_INFINITE_LOOP") fxc will report error if it can prove the loop is infinite. + self.add_valrule( + "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.", + ) self.add_valrule("Instr.ResourceCoordinateMiss", "coord uninitialized.") - self.add_valrule("Instr.ResourceCoordinateTooMany", "out of bound coord must be undef.") + self.add_valrule( + "Instr.ResourceCoordinateTooMany", "out of bound coord must be undef." + ) self.add_valrule("Instr.ResourceOffsetMiss", "offset uninitialized.") - self.add_valrule("Instr.ResourceOffsetTooMany", "out of bound offset must be undef.") - self.add_valrule("Instr.UndefResultForGetDimension", "GetDimensions used undef dimension %0 on %1.") - self.add_valrule("Instr.SamplerModeForLOD", "lod instruction requires sampler declared in default mode.") - self.add_valrule("Instr.SamplerModeForSample", "sample/_l/_d/_cl_s/gather instruction requires sampler declared in default mode.") - self.add_valrule("Instr.SamplerModeForSampleC", "sample_c_*/gather_c instructions require sampler declared in comparison mode.") - self.add_valrule("Instr.SampleCompType", "sample_* instructions require resource to be declared to return UNORM, SNORM or FLOAT.") - self.add_valrule("Instr.BarrierModeUselessUGroup", "sync can't specify both _ugroup and _uglobal. If both are needed, just specify _uglobal.") - self.add_valrule("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.") - self.add_valrule("Instr.BarrierModeForNonCS", "sync in a non-Compute/Amplification/Mesh Shader must only sync UAV (sync_uglobal).") - self.add_valrule("Instr.WriteMaskForTypedUAVStore", "store on typed uav must write to all four components of the UAV.") - self.add_valrule("Instr.WriteMaskGapForUAV", "UAV write mask must be contiguous, starting at x: .x, .xy, .xyz, or .xyzw.") - self.add_valrule("Instr.ResourceKindForCalcLOD","lod requires resource declared as texture1D/2D/3D/Cube/CubeArray/1DArray/2DArray.") - self.add_valrule("Instr.ResourceKindForSample", "sample/_l/_d requires resource declared as texture1D/2D/3D/Cube/1DArray/2DArray/CubeArray.") - self.add_valrule("Instr.ResourceKindForSampleC", "samplec requires resource declared as texture1D/2D/Cube/1DArray/2DArray/CubeArray.") - self.add_valrule("Instr.ResourceKindForGather", "gather requires resource declared as texture/2D/Cube/2DArray/CubeArray.") - self.add_valrule("Instr.WriteMaskMatchValueForUAVStore", "uav store write mask must match store value mask, write mask is %0 and store value mask is %1.") - self.add_valrule("Instr.UndefinedValueForUAVStore", "Assignment of undefined values to UAV.") - self.add_valrule("Instr.ResourceKindForBufferLoadStore", "buffer load/store only works on Raw/Typed/StructuredBuffer.") - self.add_valrule("Instr.ResourceKindForTextureStore", "texture store only works on Texture1D/1DArray/2D/2DArray/3D.") - self.add_valrule("Instr.ResourceKindForGetDim", "Invalid resource kind on GetDimensions.") - self.add_valrule("Instr.ResourceKindForTextureLoad", "texture load only works on Texture1D/1DArray/2D/2DArray/3D/MS2D/MS2DArray.") - self.add_valrule("Instr.ResourceClassForSamplerGather", "sample, lod and gather should be on srv resource.") - self.add_valrule("Instr.ResourceClassForUAVStore", "store should be 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 be used by Load/GEP/Call.") - self.add_valrule("Instr.ResourceKindForTraceRay", "TraceRay should only use RTAccelerationStructure.") + self.add_valrule( + "Instr.ResourceOffsetTooMany", "out of bound offset must be undef." + ) + self.add_valrule( + "Instr.UndefResultForGetDimension", + "GetDimensions used undef dimension %0 on %1.", + ) + self.add_valrule( + "Instr.SamplerModeForLOD", + "lod instruction requires sampler declared in default mode.", + ) + self.add_valrule( + "Instr.SamplerModeForSample", + "sample/_l/_d/_cl_s/gather instruction requires sampler declared in default mode.", + ) + self.add_valrule( + "Instr.SamplerModeForSampleC", + "sample_c_*/gather_c instructions require sampler declared in comparison mode.", + ) + self.add_valrule( + "Instr.SampleCompType", + "sample_* instructions require resource to be declared to return UNORM, SNORM or FLOAT.", + ) + self.add_valrule( + "Instr.BarrierModeUselessUGroup", + "sync can't specify both _ugroup and _uglobal. If both are needed, just specify _uglobal.", + ) + self.add_valrule( + "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.", + ) + self.add_valrule( + "Instr.BarrierModeForNonCS", + "sync in a non-Compute/Amplification/Mesh Shader must only sync UAV (sync_uglobal).", + ) + self.add_valrule( + "Instr.WriteMaskForTypedUAVStore", + "store on typed uav must write to all four components of the UAV.", + ) + self.add_valrule( + "Instr.WriteMaskGapForUAV", + "UAV write mask must be contiguous, starting at x: .x, .xy, .xyz, or .xyzw.", + ) + self.add_valrule( + "Instr.ResourceKindForCalcLOD", + "lod requires resource declared as texture1D/2D/3D/Cube/CubeArray/1DArray/2DArray.", + ) + self.add_valrule( + "Instr.ResourceKindForSample", + "sample/_l/_d requires resource declared as texture1D/2D/3D/Cube/1DArray/2DArray/CubeArray.", + ) + self.add_valrule( + "Instr.ResourceKindForSampleC", + "samplec requires resource declared as texture1D/2D/Cube/1DArray/2DArray/CubeArray.", + ) + self.add_valrule( + "Instr.ResourceKindForGather", + "gather requires resource declared as texture/2D/Cube/2DArray/CubeArray.", + ) + self.add_valrule( + "Instr.WriteMaskMatchValueForUAVStore", + "uav store write mask must match store value mask, write mask is %0 and store value mask is %1.", + ) + self.add_valrule( + "Instr.UndefinedValueForUAVStore", "Assignment of undefined values to UAV." + ) + self.add_valrule( + "Instr.ResourceKindForBufferLoadStore", + "buffer load/store only works on Raw/Typed/StructuredBuffer.", + ) + self.add_valrule( + "Instr.ResourceKindForTextureStore", + "texture store only works on Texture1D/1DArray/2D/2DArray/3D.", + ) + self.add_valrule( + "Instr.ResourceKindForGetDim", "Invalid resource kind on GetDimensions." + ) + self.add_valrule( + "Instr.ResourceKindForTextureLoad", + "texture load only works on Texture1D/1DArray/2D/2DArray/3D/MS2D/MS2DArray.", + ) + self.add_valrule( + "Instr.ResourceClassForSamplerGather", + "sample, lod and gather should be on srv resource.", + ) + self.add_valrule( + "Instr.ResourceClassForUAVStore", "store should be 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 be 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.") - self.add_valrule("Instr.CoordinateCountForRawTypedBuf", "raw/typed buffer don't need 2 coordinates.") - self.add_valrule("Instr.CoordinateCountForStructBuf", "structured buffer require 2 coordinates.") - self.add_valrule("Instr.MipLevelForGetDimension", "Use mip level on buffer when GetDimensions.") - self.add_valrule("Instr.DxilStructUser", "Dxil struct types should only be used by ExtractValue.") - 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.MipOnUAVLoad", "uav load don't support mipLevel/sampleIndex." + ) + self.add_valrule( + "Instr.SampleIndexForLoad2DMS", + "load on Texture2DMS/2DMSArray require sampleIndex.", + ) + self.add_valrule( + "Instr.CoordinateCountForRawTypedBuf", + "raw/typed buffer don't need 2 coordinates.", + ) + self.add_valrule( + "Instr.CoordinateCountForStructBuf", + "structured buffer require 2 coordinates.", + ) + self.add_valrule( + "Instr.MipLevelForGetDimension", + "Use mip level on buffer when GetDimensions.", + ) + self.add_valrule( + "Instr.DxilStructUser", + "Dxil struct types should only be used by ExtractValue.", + ) + 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.") - self.add_valrule("Instr.ExtractValue", "ExtractValue should only be used on dxil struct types and cmpxchg.") - self.add_valrule("Instr.TGSMRaceCond", "Race condition writing to shared memory detected, consider making this write conditional.") - self.add_valrule("Instr.AttributeAtVertexNoInterpolation", "Attribute %0 must have nointerpolation mode in order to use GetAttributeAtVertex function.") - self.add_valrule("Instr.CreateHandleImmRangeID", "Local resource must map to global resource.") - self.add_valrule("Instr.SignatureOperationNotInEntry", "Dxil operation for input output signature must be in entryPoints.") - self.add_valrule("Instr.MultipleSetMeshOutputCounts", "SetMeshOUtputCounts cannot be called multiple times.") - self.add_valrule("Instr.MissingSetMeshOutputCounts", "Missing SetMeshOutputCounts call.") - self.add_valrule("Instr.NonDominatingSetMeshOutputCounts", "Non-Dominating SetMeshOutputCounts call.") - self.add_valrule("Instr.MultipleGetMeshPayload", "GetMeshPayload cannot be called multiple times.") - self.add_valrule("Instr.NotOnceDispatchMesh", "DispatchMesh must be called exactly once in an Amplification shader.") - self.add_valrule("Instr.NonDominatingDispatchMesh", "Non-Dominating DispatchMesh call.") - self.add_valrule("Instr.AtomicOpNonGroupshared", "Non-groupshared destination to atomic operation.") - self.add_valrule("Instr.AtomicIntrinNonUAV", "Non-UAV destination to atomic intrinsic.") + 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.", + ) + self.add_valrule( + "Instr.ExtractValue", + "ExtractValue should only be used on dxil struct types and cmpxchg.", + ) + self.add_valrule( + "Instr.TGSMRaceCond", + "Race condition writing to shared memory detected, consider making this write conditional.", + ) + self.add_valrule( + "Instr.AttributeAtVertexNoInterpolation", + "Attribute %0 must have nointerpolation mode in order to use GetAttributeAtVertex function.", + ) + self.add_valrule( + "Instr.CreateHandleImmRangeID", + "Local resource must map to global resource.", + ) + self.add_valrule( + "Instr.SignatureOperationNotInEntry", + "Dxil operation for input output signature must be in entryPoints.", + ) + self.add_valrule( + "Instr.MultipleSetMeshOutputCounts", + "SetMeshOUtputCounts cannot be called multiple times.", + ) + self.add_valrule( + "Instr.MissingSetMeshOutputCounts", "Missing SetMeshOutputCounts call." + ) + self.add_valrule( + "Instr.NonDominatingSetMeshOutputCounts", + "Non-Dominating SetMeshOutputCounts call.", + ) + self.add_valrule( + "Instr.MultipleGetMeshPayload", + "GetMeshPayload cannot be called multiple times.", + ) + self.add_valrule( + "Instr.NotOnceDispatchMesh", + "DispatchMesh must be called exactly once in an Amplification shader.", + ) + self.add_valrule( + "Instr.NonDominatingDispatchMesh", "Non-Dominating DispatchMesh call." + ) + self.add_valrule( + "Instr.AtomicOpNonGroupshared", + "Non-groupshared destination to atomic operation.", + ) + self.add_valrule( + "Instr.AtomicIntrinNonUAV", "Non-UAV destination to atomic intrinsic." + ) self.add_valrule("Instr.AtomicConst", "Constant destination to atomic.") # Some legacy rules: @@ -2645,116 +6792,421 @@ def build_valrules(self): # - multiple rules regarding library functions, which isn't a supported feature for DXIL (at this time) # - multiple rules regarding interfaces, which isn't a supported feature for DXIL # - rules for DX9-style intrinsics, which aren't supported for DXIL - - self.add_valrule_msg("Types.NoVector", "Vector types must not be present", "Vector type '%0' is not allowed.") - self.add_valrule_msg("Types.Defined", "Type must be defined based on DXIL primitives", "Type '%0' is not defined on DXIL primitives.") - self.add_valrule_msg("Types.IntWidth", "Int type must be of valid width", "Int type '%0' has an invalid width.") - self.add_valrule("Types.NoMultiDim", "Only one dimension allowed for array type.") - self.add_valrule("Types.NoPtrToPtr", "Pointers to pointers, or pointers in structures are not allowed.") - self.add_valrule("Types.I8", "I8 can only be used as immediate value for intrinsic or as i8* via bitcast by lifetime intrinsics.") - - self.add_valrule_msg("Sm.Name", "Target shader model name must be known", "Unknown shader model '%0'.") - self.add_valrule_msg("Sm.DxilVersion", "Target shader model requires specific Dxil Version", "Shader model requires Dxil Version %0.%1.") - self.add_valrule_msg("Sm.Opcode", "Opcode must be defined in target shader model", "Opcode %0 not valid in shader model %1.") - self.add_valrule("Sm.Operand", "Operand must be defined in target shader model.") - self.add_valrule_msg("Sm.Semantic", "Semantic must be defined in target shader model", "Semantic '%0' is invalid as %1 %2.") - self.add_valrule_msg("Sm.NoInterpMode", "Interpolation mode must be undefined for VS input/PS output/patch constant.", "Interpolation mode for '%0' is set but should be undefined.") - self.add_valrule_msg("Sm.ConstantInterpMode", "Interpolation mode must be constant for MS primitive output.", "Interpolation mode for '%0' should be constant.") - self.add_valrule("Sm.NoPSOutputIdx", "Pixel shader output registers are not indexable.")# TODO restrict to PS - self.add_valrule("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).") - self.add_valrule("Sm.ThreadGroupChannelRange", "Declared Thread Group %0 size %1 outside valid range [%2..%3].") - self.add_valrule("Sm.MaxTheadGroup", "Declared Thread Group Count %0 (X*Y*Z) is beyond the valid maximum of %1.") - self.add_valrule("Sm.MaxTGSMSize", "Total Thread Group Shared Memory storage is %0, exceeded %1.") - self.add_valrule("Sm.TGSMUnsupported", "Thread Group Shared Memory not supported %0.") - self.add_valrule("Sm.WaveSizeValue", "Declared WaveSize %0 outside valid range [%1..%2], or not a power of 2.") - self.add_valrule("Sm.WaveSizeNeedsDxil16Plus", "WaveSize is valid only for DXIL version 1.6 and higher.") - self.add_valrule("Sm.ROVOnlyInPS", "RasterizerOrdered objects are only allowed in 5.0+ pixel shaders.") - self.add_valrule("Sm.TessFactorForDomain", "Required TessFactor for domain not found declared anywhere in Patch Constant data.") - self.add_valrule("Sm.TessFactorSizeMatchDomain", "TessFactor rows, columns (%0, %1) invalid for domain %2. Expected %3 rows and 1 column.") - self.add_valrule("Sm.InsideTessFactorSizeMatchDomain", "InsideTessFactor rows, columns (%0, %1) invalid for domain %2. Expected %3 rows and 1 column.") - self.add_valrule("Sm.DomainLocationIdxOOB", "DomainLocation component index out of bounds for the domain.") - self.add_valrule("Sm.HullPassThruControlPointCountMatch", "For pass thru hull shader, input control point count must match output control point count"); - self.add_valrule("Sm.OutputControlPointsTotalScalars", "Total number of scalars across all HS output control points must not exceed .") - self.add_valrule("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.") - self.add_valrule("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.") - self.add_valrule("Sm.ValidDomain", "Invalid Tessellator Domain specified. Must be isoline, tri or quad.") - self.add_valrule("Sm.PatchConstantOnlyForHSDS", "patch constant signature only valid in HS and DS.") - self.add_valrule("Sm.StreamIndexRange", "Stream index (%0) must between 0 and %1.") - self.add_valrule("Sm.PSOutputSemantic", "Pixel Shader allows output semantics to be SV_Target, SV_Depth, SV_DepthGreaterEqual, SV_DepthLessEqual, SV_Coverage or SV_StencilRef, %0 found.") - self.add_valrule("Sm.PSMultipleDepthSemantic", "Pixel Shader only allows one type of depth semantic to be declared.") - self.add_valrule("Sm.PSTargetIndexMatchesRow", "SV_Target semantic index must match packed row location.") - self.add_valrule("Sm.PSTargetCol0", "SV_Target packed location must start at column 0.") - self.add_valrule("Sm.PSCoverageAndInnerCoverage", "InnerCoverage and Coverage are mutually exclusive.") - self.add_valrule("Sm.GSOutputVertexCountRange", "GS output vertex count must be [0..%0]. %1 specified.") - self.add_valrule("Sm.GSInstanceCountRange", "GS instance count must be [1..%0]. %1 specified.") - self.add_valrule("Sm.DSInputControlPointCountRange", "DS input control point count must be [0..%0]. %1 specified.") - self.add_valrule("Sm.HSInputControlPointCountRange", "HS input control point count must be [0..%0]. %1 specified.") - self.add_valrule("Sm.ZeroHSInputControlPointWithInput", "When HS input control point count is 0, no input signature should exist.") - self.add_valrule("Sm.OutputControlPointCountRange", "output control point count must be [0..%0]. %1 specified.") + + self.add_valrule_msg( + "Types.NoVector", + "Vector types must not be present", + "Vector type '%0' is not allowed.", + ) + self.add_valrule_msg( + "Types.Defined", + "Type must be defined based on DXIL primitives", + "Type '%0' is not defined on DXIL primitives.", + ) + self.add_valrule_msg( + "Types.IntWidth", + "Int type must be of valid width", + "Int type '%0' has an invalid width.", + ) + self.add_valrule( + "Types.NoMultiDim", "Only one dimension allowed for array type." + ) + self.add_valrule( + "Types.NoPtrToPtr", + "Pointers to pointers, or pointers in structures are not allowed.", + ) + self.add_valrule( + "Types.I8", + "I8 can only be used as immediate value for intrinsic or as i8* via bitcast by lifetime intrinsics.", + ) + + self.add_valrule_msg( + "Sm.Name", + "Target shader model name must be known", + "Unknown shader model '%0'.", + ) + self.add_valrule_msg( + "Sm.DxilVersion", + "Target shader model requires specific Dxil Version", + "Shader model requires Dxil Version %0.%1.", + ) + self.add_valrule_msg( + "Sm.Opcode", + "Opcode must be defined in target shader model", + "Opcode %0 not valid in shader model %1.", + ) + self.add_valrule( + "Sm.Operand", "Operand must be defined in target shader model." + ) + self.add_valrule_msg( + "Sm.Semantic", + "Semantic must be defined in target shader model", + "Semantic '%0' is invalid as %1 %2.", + ) + self.add_valrule_msg( + "Sm.NoInterpMode", + "Interpolation mode must be undefined for VS input/PS output/patch constant.", + "Interpolation mode for '%0' is set but should be undefined.", + ) + self.add_valrule_msg( + "Sm.ConstantInterpMode", + "Interpolation mode must be constant for MS primitive output.", + "Interpolation mode for '%0' should be constant.", + ) + self.add_valrule( + "Sm.NoPSOutputIdx", "Pixel shader output registers are not indexable." + ) # TODO restrict to PS + self.add_valrule( + "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).", + ) + self.add_valrule( + "Sm.ThreadGroupChannelRange", + "Declared Thread Group %0 size %1 outside valid range [%2..%3].", + ) + self.add_valrule( + "Sm.MaxTheadGroup", + "Declared Thread Group Count %0 (X*Y*Z) is beyond the valid maximum of %1.", + ) + self.add_valrule( + "Sm.MaxTGSMSize", + "Total Thread Group Shared Memory storage is %0, exceeded %1.", + ) + self.add_valrule( + "Sm.TGSMUnsupported", "Thread Group Shared Memory not supported %0." + ) + self.add_valrule( + "Sm.WaveSizeValue", + "Declared WaveSize %0 outside valid range [%1..%2], or not a power of 2.", + ) + self.add_valrule( + "Sm.WaveSizeNeedsDxil16Plus", + "WaveSize is valid only for DXIL version 1.6 and higher.", + ) + self.add_valrule( + "Sm.ROVOnlyInPS", + "RasterizerOrdered objects are only allowed in 5.0+ pixel shaders.", + ) + self.add_valrule( + "Sm.TessFactorForDomain", + "Required TessFactor for domain not found declared anywhere in Patch Constant data.", + ) + self.add_valrule( + "Sm.TessFactorSizeMatchDomain", + "TessFactor rows, columns (%0, %1) invalid for domain %2. Expected %3 rows and 1 column.", + ) + self.add_valrule( + "Sm.InsideTessFactorSizeMatchDomain", + "InsideTessFactor rows, columns (%0, %1) invalid for domain %2. Expected %3 rows and 1 column.", + ) + self.add_valrule( + "Sm.DomainLocationIdxOOB", + "DomainLocation component index out of bounds for the domain.", + ) + self.add_valrule( + "Sm.HullPassThruControlPointCountMatch", + "For pass thru hull shader, input control point count must match output control point count", + ) + self.add_valrule( + "Sm.OutputControlPointsTotalScalars", + "Total number of scalars across all HS output control points must not exceed .", + ) + self.add_valrule( + "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.", + ) + self.add_valrule( + "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.", + ) + self.add_valrule( + "Sm.ValidDomain", + "Invalid Tessellator Domain specified. Must be isoline, tri or quad.", + ) + self.add_valrule( + "Sm.PatchConstantOnlyForHSDS", + "patch constant signature only valid in HS and DS.", + ) + self.add_valrule( + "Sm.StreamIndexRange", "Stream index (%0) must between 0 and %1." + ) + self.add_valrule( + "Sm.PSOutputSemantic", + "Pixel Shader allows output semantics to be SV_Target, SV_Depth, SV_DepthGreaterEqual, SV_DepthLessEqual, SV_Coverage or SV_StencilRef, %0 found.", + ) + self.add_valrule( + "Sm.PSMultipleDepthSemantic", + "Pixel Shader only allows one type of depth semantic to be declared.", + ) + self.add_valrule( + "Sm.PSTargetIndexMatchesRow", + "SV_Target semantic index must match packed row location.", + ) + self.add_valrule( + "Sm.PSTargetCol0", "SV_Target packed location must start at column 0." + ) + self.add_valrule( + "Sm.PSCoverageAndInnerCoverage", + "InnerCoverage and Coverage are mutually exclusive.", + ) + self.add_valrule( + "Sm.GSOutputVertexCountRange", + "GS output vertex count must be [0..%0]. %1 specified.", + ) + self.add_valrule( + "Sm.GSInstanceCountRange", + "GS instance count must be [1..%0]. %1 specified.", + ) + self.add_valrule( + "Sm.DSInputControlPointCountRange", + "DS input control point count must be [0..%0]. %1 specified.", + ) + self.add_valrule( + "Sm.HSInputControlPointCountRange", + "HS input control point count must be [0..%0]. %1 specified.", + ) + self.add_valrule( + "Sm.ZeroHSInputControlPointWithInput", + "When HS input control point count is 0, no input signature should exist.", + ) + self.add_valrule( + "Sm.OutputControlPointCountRange", + "output control point count must be [0..%0]. %1 specified.", + ) self.add_valrule("Sm.GSValidInputPrimitive", "GS input primitive unrecognized.") - self.add_valrule("Sm.GSValidOutputPrimitiveTopology", "GS output primitive topology unrecognized.") - self.add_valrule("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.") - self.add_valrule("Sm.InvalidTextureKindOnUAV", "TextureCube[Array] resources are not supported with UAVs.") + self.add_valrule( + "Sm.GSValidOutputPrimitiveTopology", + "GS output primitive topology unrecognized.", + ) + self.add_valrule( + "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.", + ) + self.add_valrule( + "Sm.InvalidTextureKindOnUAV", + "TextureCube[Array] resources are not supported with UAVs.", + ) self.add_valrule("Sm.InvalidResourceKind", "Invalid resources kind.") - self.add_valrule("Sm.InvalidResourceCompType","Invalid resource return type.") - self.add_valrule("Sm.InvalidSamplerFeedbackType","Invalid sampler feedback 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.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.") - 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.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.CBufferSize", "CBuffer size must not exceed 65536 bytes", "CBuffer size is %0 bytes, exceeding maximum of 65536 bytes.") - 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.CBufferArrayOffsetAlignment", "CBuffer array offset must be aligned to 16-bytes", "CBuffer %0 has unaligned array offset at %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.") - self.add_valrule("Sm.MeshShaderMaxVertexCount", "MS max vertex output count must be [0..%0]. %1 specified.") - self.add_valrule("Sm.MeshShaderMaxPrimitiveCount", "MS max primitive output count must be [0..%0]. %1 specified.") - self.add_valrule("Sm.MeshShaderPayloadSize", "For mesh shader with entry '%0', payload size %1 is greater than maximum size of %2 bytes.") - self.add_valrule("Sm.MeshShaderPayloadSizeDeclared", "For mesh shader with entry '%0', payload size %1 is greater than declared size of %2 bytes.") - self.add_valrule("Sm.MeshShaderOutputSize", "For shader '%0', vertex plus primitive output size is greater than %1.") - self.add_valrule("Sm.MeshShaderInOutSize", "For shader '%0', payload plus output size is greater than %1.") - self.add_valrule("Sm.MeshVSigRowCount", "For shader '%0', vertex output signatures are taking up more than %1 rows.") - self.add_valrule("Sm.MeshPSigRowCount", "For shader '%0', primitive output signatures are taking up more than %1 rows.") - self.add_valrule("Sm.MeshTotalSigRowCount", "For shader '%0', vertex and primitive output signatures are taking up more than %1 rows.") - self.add_valrule("Sm.MaxMSSMSize", "Total Thread Group Shared Memory storage is %0, exceeded %1.") - self.add_valrule("Sm.AmplificationShaderPayloadSize", "For amplification shader with entry '%0', payload size %1 is greater than maximum size of %2 bytes.") - self.add_valrule("Sm.AmplificationShaderPayloadSizeDeclared", "For amplification shader with entry '%0', payload size %1 is greater than declared size of %2 bytes.") + self.add_valrule("Sm.InvalidResourceCompType", "Invalid resource return type.") + self.add_valrule( + "Sm.InvalidSamplerFeedbackType", "Invalid sampler feedback 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.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.", + ) + 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.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.CBufferSize", + "CBuffer size must not exceed 65536 bytes", + "CBuffer size is %0 bytes, exceeding maximum of 65536 bytes.", + ) + 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.CBufferArrayOffsetAlignment", + "CBuffer array offset must be aligned to 16-bytes", + "CBuffer %0 has unaligned array offset at %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.", + ) + self.add_valrule( + "Sm.MeshShaderMaxVertexCount", + "MS max vertex output count must be [0..%0]. %1 specified.", + ) + self.add_valrule( + "Sm.MeshShaderMaxPrimitiveCount", + "MS max primitive output count must be [0..%0]. %1 specified.", + ) + self.add_valrule( + "Sm.MeshShaderPayloadSize", + "For mesh shader with entry '%0', payload size %1 is greater than maximum size of %2 bytes.", + ) + self.add_valrule( + "Sm.MeshShaderPayloadSizeDeclared", + "For mesh shader with entry '%0', payload size %1 is greater than declared size of %2 bytes.", + ) + self.add_valrule( + "Sm.MeshShaderOutputSize", + "For shader '%0', vertex plus primitive output size is greater than %1.", + ) + self.add_valrule( + "Sm.MeshShaderInOutSize", + "For shader '%0', payload plus output size is greater than %1.", + ) + self.add_valrule( + "Sm.MeshVSigRowCount", + "For shader '%0', vertex output signatures are taking up more than %1 rows.", + ) + self.add_valrule( + "Sm.MeshPSigRowCount", + "For shader '%0', primitive output signatures are taking up more than %1 rows.", + ) + self.add_valrule( + "Sm.MeshTotalSigRowCount", + "For shader '%0', vertex and primitive output signatures are taking up more than %1 rows.", + ) + self.add_valrule( + "Sm.MaxMSSMSize", + "Total Thread Group Shared Memory storage is %0, exceeded %1.", + ) + self.add_valrule( + "Sm.AmplificationShaderPayloadSize", + "For amplification shader with entry '%0', payload size %1 is greater than maximum size of %2 bytes.", + ) + self.add_valrule( + "Sm.AmplificationShaderPayloadSizeDeclared", + "For amplification shader with entry '%0', payload size %1 is greater than declared size of %2 bytes.", + ) # fxc relaxed check of gradient check. - #self.add_valrule("Uni.NoUniInDiv", "TODO - No instruction requiring uniform execution can be present in divergent block") - #self.add_valrule("Uni.GradientFlow", "TODO - No divergent gradient operations inside flow control") # a bit more specific than the prior rule - #self.add_valrule("Uni.ThreadSync", "TODO - Thread sync operation must be in non-varying flow control due to a potential race condition, adding a sync after reading any values controlling shader execution at this point") - #self.add_valrule("Uni.NoWaveSensitiveGradient", "Gradient operations are not affected by wave-sensitive data or control flow.") - + # self.add_valrule("Uni.NoUniInDiv", "TODO - No instruction requiring uniform execution can be present in divergent block") + # self.add_valrule("Uni.GradientFlow", "TODO - No divergent gradient operations inside flow control") # a bit more specific than the prior rule + # self.add_valrule("Uni.ThreadSync", "TODO - Thread sync operation must be in non-varying flow control due to a potential race condition, adding a sync after reading any values controlling shader execution at this point") + # self.add_valrule("Uni.NoWaveSensitiveGradient", "Gradient operations are not affected by wave-sensitive data or control flow.") + self.add_valrule("Flow.Reducible", "Execution flow must be reducible.") self.add_valrule("Flow.NoRecusion", "Recursion is not permitted.") self.add_valrule("Flow.DeadLoop", "Loop must have break.") - self.add_valrule_msg("Flow.FunctionCall", "Function with parameter is not permitted", "Function %0 with parameter is not permitted, it should be inlined.") - - self.add_valrule_msg("Decl.DxilNsReserved", "The DXIL reserved prefixes must only be used by built-in functions and types", "Declaration '%0' uses a reserved prefix.") - self.add_valrule_msg("Decl.DxilFnExtern", "External function must be a DXIL function", "External function '%0' is not a DXIL function.") - self.add_valrule_msg("Decl.UsedInternal", "Internal declaration must be used", "Internal declaration '%0' is unused.") - self.add_valrule_msg("Decl.NotUsedExternal", "External declaration should not be used", "External declaration '%0' is unused.") - self.add_valrule_msg("Decl.UsedExternalFunction", "External function must be used", "External function '%0' is unused.") - 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.") + self.add_valrule_msg( + "Flow.FunctionCall", + "Function with parameter is not permitted", + "Function %0 with parameter is not permitted, it should be inlined.", + ) + + self.add_valrule_msg( + "Decl.DxilNsReserved", + "The DXIL reserved prefixes must only be used by built-in functions and types", + "Declaration '%0' uses a reserved prefix.", + ) + self.add_valrule_msg( + "Decl.DxilFnExtern", + "External function must be a DXIL function", + "External function '%0' is not a DXIL function.", + ) + self.add_valrule_msg( + "Decl.UsedInternal", + "Internal declaration must be used", + "Internal declaration '%0' is unused.", + ) + self.add_valrule_msg( + "Decl.NotUsedExternal", + "External declaration should not be used", + "External declaration '%0' is unused.", + ) + self.add_valrule_msg( + "Decl.UsedExternalFunction", + "External function must be used", + "External function '%0' is unused.", + ) + 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 = { @@ -2766,8 +7218,8 @@ def build_valrules(self): "TYPES": "Type system", "SM": "Shader model", "UNI": "Uniform analysis", - "DECL": "Declaration" - } + "DECL": "Declaration", + } valrule_enum = db_dxil_enum("ValidationRule", "Known validation rules") valrule_enum.is_internal = True for vr in self.val_rules: @@ -2782,7 +7234,7 @@ def populate_counters(self): self.llvm_op_counters = set() self.dxil_op_counters = set() for i in self.instr: - counters = getattr(i, 'props', {}).get('counters', ()) + counters = getattr(i, "props", {}).get("counters", ()) if i.dxil_opid: self.dxil_op_counters.update(counters) else: @@ -2793,37 +7245,70 @@ def populate_counters(self): self.counters = list(sorted(counter_set)) def add_valrule(self, name, desc): - self.val_rules.append(db_dxil_valrule(name, len(self.val_rules), err_msg=desc, doc=desc)) + self.val_rules.append( + db_dxil_valrule(name, len(self.val_rules), err_msg=desc, doc=desc) + ) def add_valrule_msg(self, name, desc, err_msg): - self.val_rules.append(db_dxil_valrule(name, len(self.val_rules), err_msg=err_msg, doc=desc)) - - def add_llvm_instr(self, kind, llvm_id, name, llvm_name, doc, oload_types, op_params, **props): - i = db_dxil_inst(name, llvm_id=llvm_id, llvm_name=llvm_name, doc=doc, ops=op_params, oload_types=oload_types) + self.val_rules.append( + db_dxil_valrule(name, len(self.val_rules), err_msg=err_msg, doc=desc) + ) + + def add_llvm_instr( + self, kind, llvm_id, name, llvm_name, doc, oload_types, op_params, **props + ): + i = db_dxil_inst( + name, + llvm_id=llvm_id, + llvm_name=llvm_name, + doc=doc, + ops=op_params, + oload_types=oload_types, + ) i.props = props self.instr.append(i) - def add_dxil_op(self, name, code_id, code_class, doc, oload_types, fn_attr, op_params, **props): + def add_dxil_op( + self, name, code_id, code_class, doc, oload_types, fn_attr, op_params, **props + ): # The return value is parameter 0, insert the opcode as 1. op_params.insert(1, self.opcode_param) - i = db_dxil_inst(name, - llvm_id=self.call_instr.llvm_id, llvm_name=self.call_instr.llvm_name, - dxil_op=name, dxil_opid=code_id, doc=doc, ops=op_params, dxil_class=code_class, - oload_types=oload_types, fn_attr=fn_attr) + i = db_dxil_inst( + name, + llvm_id=self.call_instr.llvm_id, + llvm_name=self.call_instr.llvm_name, + dxil_op=name, + dxil_opid=code_id, + doc=doc, + ops=op_params, + dxil_class=code_class, + oload_types=oload_types, + fn_attr=fn_attr, + ) i.props = props self.instr.append(i) + def add_dxil_op_reserved(self, name, code_id): # The return value is parameter 0, insert the opcode as 1. op_params = [db_dxil_param(0, "v", "", "reserved"), self.opcode_param] - i = db_dxil_inst(name, - llvm_id=self.call_instr.llvm_id, llvm_name=self.call_instr.llvm_name, - dxil_op=name, dxil_opid=code_id, doc="reserved", ops=op_params, dxil_class="Reserved", - oload_types="v", fn_attr="") + i = db_dxil_inst( + name, + llvm_id=self.call_instr.llvm_id, + llvm_name=self.call_instr.llvm_name, + dxil_op=name, + dxil_opid=code_id, + doc="reserved", + ops=op_params, + dxil_class="Reserved", + oload_types="v", + fn_attr="", + ) self.instr.append(i) def get_instr_by_llvm_name(self, llvm_name): "Return the instruction with the given LLVM name" return next(i for i in self.instr if i.llvm_name == llvm_name) + def get_dxil_insts(self): for i in self.instr: if i.dxil_op != "": @@ -2831,33 +7316,59 @@ def get_dxil_insts(self): def print_stats(self): "Print some basic statistics on the instruction database." - print ("Instruction count: %d" % len(self.instr)) - print ("Max parameter count in instruction: %d" % max(len(i.ops) - 1 for i in self.instr)) - print ("Parameter count: %d" % sum(len(i.ops) - 1 for i in self.instr)) + print("Instruction count: %d" % len(self.instr)) + print( + "Max parameter count in instruction: %d" + % max(len(i.ops) - 1 for i in self.instr) + ) + print( + "Parameter count: %d" + % sum(len(i.ops) - 1 for i in self.instr) + ) + ############################################################################### # HLSL-specific information. # ############################################################################### + class db_hlsl_attribute(object): "An HLSL attribute declaration" + def __init__(self, title_name, scope, args, doc): self.name = title_name.lower() # lowercase attribute name - self.title_name = title_name # title-case attribute name - self.scope = scope # one of l (loop), c (condition), s (switch), f (function) - self.args = args # list of arguments - self.doc = doc # documentation + self.title_name = title_name # title-case attribute name + self.scope = scope # one of l (loop), c (condition), s (switch), f (function) + self.args = args # list of arguments + self.doc = doc # documentation + class db_hlsl_intrinsic(object): "An HLSL intrinsic declaration" - def __init__(self, name, idx, opname, params, ns, ns_idx, doc, ro, rn, wv, unsigned_op, overload_idx, hidden): - self.name = name # Function name - self.idx = idx # Unique number within namespace - self.opname = opname # D3D-style name - self.params = params # List of parameters - self.ns = ns # Function namespace - self.ns_idx = ns_idx # Namespace index - self.doc = doc # Documentation + + def __init__( + self, + name, + idx, + opname, + params, + ns, + ns_idx, + doc, + ro, + rn, + wv, + unsigned_op, + overload_idx, + hidden, + ): + self.name = name # Function name + self.idx = idx # Unique number within namespace + self.opname = opname # D3D-style name + self.params = params # List of parameters + self.ns = ns # Function namespace + self.ns_idx = ns_idx # Namespace index + self.doc = doc # Documentation id_prefix = "IOP" if ns == "Intrinsics" else "MOP" # SPIR-V Change Starts if ns == "VkIntrinsics": @@ -2865,42 +7376,74 @@ def __init__(self, name, idx, opname, params, ns, ns_idx, doc, ro, rn, wv, unsig self.name = "Vk" + self.name id_prefix = "IOP" # SPIR-V Change Ends - self.enum_name = "%s_%s" % (id_prefix, name) # enum name - self.readonly = ro # Only read memory - self.readnone = rn # Not read memory - self.wave = wv # Is wave-sensitive - self.unsigned_op = unsigned_op # Unsigned opcode if exist + self.enum_name = "%s_%s" % (id_prefix, name) # enum name + self.readonly = ro # Only read memory + self.readnone = rn # Not read memory + self.wave = wv # Is wave-sensitive + self.unsigned_op = unsigned_op # Unsigned opcode if exist if unsigned_op != "": self.unsigned_op = "%s_%s" % (id_prefix, unsigned_op) - self.overload_param_index = overload_idx # Parameter determines the overload type, -1 means ret type - self.hidden = hidden # Internal high-level op, not exposed to HLSL - self.key = ("%3d" % ns_idx) + "!" + name + "!" + ("%2d" % len(params)) + "!" + ("%3d" % idx) # Unique key - self.vulkanSpecific = ns.startswith("Vk") # Vulkan specific intrinsic - SPIRV change + self.overload_param_index = ( + overload_idx # Parameter determines the overload type, -1 means ret type + ) + self.hidden = hidden # Internal high-level op, not exposed to HLSL + self.key = ( + ("%3d" % ns_idx) + + "!" + + name + + "!" + + ("%2d" % len(params)) + + "!" + + ("%3d" % idx) + ) # Unique key + self.vulkanSpecific = ns.startswith( + "Vk" + ) # Vulkan specific intrinsic - SPIRV change + class db_hlsl_namespace(object): "A grouping of HLSL intrinsics" + def __init__(self, name): self.name = name self.intrinsics = [] + class db_hlsl_intrisic_param(object): "An HLSL parameter declaration for an intrinsic" - def __init__(self, name, param_qual, template_id, template_list, component_id, component_list, rows, cols, type_name, idx, template_id_idx, component_id_idx): - self.name = name # Parameter name - self.param_qual = param_qual # Parameter qualifier expressions - self.template_id = template_id # Template ID (possibly identifier) - self.template_list = template_list # Template list (possibly identifier) - self.component_id = component_id # Component ID (possibly identifier) - self.component_list = component_list # Component list (possibly identifier) - self.rows = rows # Row count for parameter, possibly identifier - self.cols = cols # Row count for parameter, possibly identifier - self.type_name = type_name # Type name - self.idx = idx # Argument index - self.template_id_idx = template_id_idx # Template ID numeric value - self.component_id_idx = component_id_idx # Component ID numeric value + + def __init__( + self, + name, + param_qual, + template_id, + template_list, + component_id, + component_list, + rows, + cols, + type_name, + idx, + template_id_idx, + component_id_idx, + ): + self.name = name # Parameter name + self.param_qual = param_qual # Parameter qualifier expressions + self.template_id = template_id # Template ID (possibly identifier) + self.template_list = template_list # Template list (possibly identifier) + self.component_id = component_id # Component ID (possibly identifier) + self.component_list = component_list # Component list (possibly identifier) + self.rows = rows # Row count for parameter, possibly identifier + self.cols = cols # Row count for parameter, possibly identifier + self.type_name = type_name # Type name + self.idx = idx # Argument index + self.template_id_idx = template_id_idx # Template ID numeric value + self.component_id_idx = component_id_idx # Component ID numeric value + class db_hlsl(object): "A database of HLSL language data" + def __init__(self, intrinsic_defs): self.base_types = { "bool": "LICOMPTYPE_BOOL", @@ -2937,32 +7480,29 @@ def __init__(self, intrinsic_defs): "sampler_cmp": "LICOMPTYPE_SAMPLERCMP", "sampler": "LICOMPTYPE_SAMPLER", "resource": "LICOMPTYPE_RESOURCE", - "ray_desc" : "LICOMPTYPE_RAYDESC", - "acceleration_struct" : "LICOMPTYPE_ACCELERATION_STRUCT", - "udt" : "LICOMPTYPE_USER_DEFINED_TYPE", + "ray_desc": "LICOMPTYPE_RAYDESC", + "acceleration_struct": "LICOMPTYPE_ACCELERATION_STRUCT", + "udt": "LICOMPTYPE_USER_DEFINED_TYPE", "void": "LICOMPTYPE_VOID", "string": "LICOMPTYPE_STRING", "Texture2D": "LICOMPTYPE_TEXTURE2D", "Texture2DArray": "LICOMPTYPE_TEXTURE2DARRAY", "wave": "LICOMPTYPE_WAVE", - "p32i8" : "LICOMPTYPE_INT8_4PACKED", - "p32u8" : "LICOMPTYPE_UINT8_4PACKED", + "p32i8": "LICOMPTYPE_INT8_4PACKED", + "p32u8": "LICOMPTYPE_UINT8_4PACKED", "any_int16or32": "LICOMPTYPE_ANY_INT16_OR_32", "sint16or32_only": "LICOMPTYPE_SINT16_OR_32_ONLY", "any_sampler": "LICOMPTYPE_ANY_SAMPLER", - } - self.trans_rowcol = { - "r": "IA_R", - "c": "IA_C", - "r2": "IA_R2", - "c2": "IA_C2"} + } + self.trans_rowcol = {"r": "IA_R", "c": "IA_C", "r2": "IA_R2", "c2": "IA_C2"} self.param_qual = { "in": "AR_QUAL_IN", "inout": "AR_QUAL_IN | AR_QUAL_OUT", - "ref" : "AR_QUAL_REF", + "ref": "AR_QUAL_REF", "out": "AR_QUAL_OUT", "col_major": "AR_QUAL_COLMAJOR", - "row_major": "AR_QUAL_ROWMAJOR"} + "row_major": "AR_QUAL_ROWMAJOR", + } self.intrinsics = [] self.load_intrinsics(intrinsic_defs) self.create_namespaces() @@ -2980,13 +7520,18 @@ def create_namespaces(self): def load_intrinsics(self, intrinsic_defs): import re + blank_re = re.compile(r"^\s*$") comment_re = re.compile(r"^\s*//") namespace_beg_re = re.compile(r"^namespace\s+(\w+)\s*{\s*$") namespace_end_re = re.compile(r"^}\s*namespace\s*$") - intrinsic_re = re.compile(r"^\s*([^(]+)\s+\[\[(\S*)\]\]\s+(\w+)\s*\(\s*([^)]*)\s*\)\s*(:\s*\w+\s*)?;$") + intrinsic_re = re.compile( + r"^\s*([^(]+)\s+\[\[(\S*)\]\]\s+(\w+)\s*\(\s*([^)]*)\s*\)\s*(:\s*\w+\s*)?;$" + ) operand_re = re.compile(r"^:\s*(\w+)\s*$") - bracket_cleanup_re = re.compile(r"<\s*(\S+)\s*,\s*(\S+)\s*>") # change to to help split params and parse + bracket_cleanup_re = re.compile( + r"<\s*(\S+)\s*,\s*(\S+)\s*>" + ) # change to to help split params and parse params_split_re = re.compile(r"\s*,\s*") ws_split_re = re.compile(r"\s+") typeref_re = re.compile(r"\$type(\d+)$") @@ -3020,8 +7565,8 @@ def process_arg(desc, idx, done_args, intrinsic_name): else: opt_list = ws_split_re.split(desc) assert len(opt_list) > 0, "malformed parameter desc %s" % (desc) - param_name = opt_list.pop() # last token is name - type_name = opt_list.pop() # next-to-last is type specifier + param_name = opt_list.pop() # last token is name + type_name = opt_list.pop() # next-to-last is type specifier param_qual = "0" template_id = str(idx) @@ -3054,7 +7599,9 @@ def process_arg(desc, idx, done_args, intrinsic_name): assert idx != 1, "Can't use $type on the first argument" assert template_id != "0", "Can't match an input to the return type" done_idx = int(template_id) - 1 - assert done_idx <= len(args) + 1, "$type must refer to a processed arg" + assert ( + done_idx <= len(args) + 1 + ), "$type must refer to a processed arg" done_arg = done_args[done_idx] type_name = done_arg.type_name # Determine matrix/vector/any/scalar type names. @@ -3079,11 +7626,22 @@ def process_arg(desc, idx, done_args, intrinsic_name): template_list = "LITEMPLATE_ANY" else: base_type = type_name - if base_type.startswith("sampler") or base_type.startswith("string") or base_type.startswith("Texture") or base_type.startswith("wave") or base_type.startswith("acceleration_struct") or base_type.startswith("ray_desc") or base_type.startswith("any_sampler"): + if ( + base_type.startswith("sampler") + or base_type.startswith("string") + or base_type.startswith("Texture") + or base_type.startswith("wave") + or base_type.startswith("acceleration_struct") + or base_type.startswith("ray_desc") + or base_type.startswith("any_sampler") + ): template_list = "LITEMPLATE_OBJECT" else: template_list = "LITEMPLATE_SCALAR" - assert base_type in self.base_types, "Unknown base type '%s' in '%s'" % (base_type, desc) + assert base_type in self.base_types, "Unknown base type '%s' in '%s'" % ( + base_type, + desc, + ) component_list = self.base_types[base_type] rows = translate_rowcol(rows) cols = translate_rowcol(cols) @@ -3092,7 +7650,9 @@ def process_arg(desc, idx, done_args, intrinsic_name): param_qual = add_flag(param_qual, self.param_qual[opt]) else: opt_param_match_match = opt_param_match_re.match(opt) - assert opt_param_match_match, "Unknown parameter qualifier '%s'" % (opt) + assert opt_param_match_match, "Unknown parameter qualifier '%s'" % ( + opt + ) template_id = opt_param_match_match.group(1) component_id = opt_param_match_match.group(2) if component_list == "LICOMPTYPE_VOID": @@ -3106,8 +7666,12 @@ def process_arg(desc, idx, done_args, intrinsic_name): template_id_idx = int(template_id) component_id_idx = int(component_id) # Verify that references don't point to the right (except for the return value). - assert idx == 0 or template_id_idx <= int(idx), "Argument '%s' has a forward reference" % (param_name) - assert idx == 0 or component_id_idx <= int(idx), "Argument '%s' has a forward reference" % (param_name) + assert idx == 0 or template_id_idx <= int( + idx + ), "Argument '%s' has a forward reference" % (param_name) + assert idx == 0 or component_id_idx <= int( + idx + ), "Argument '%s' has a forward reference" % (param_name) if template_id == "-1": template_id = "INTRIN_TEMPLATE_FROM_TYPE" elif template_id == "-2": @@ -3116,62 +7680,91 @@ def process_arg(desc, idx, done_args, intrinsic_name): template_id = "INTRIN_TEMPLATE_FROM_FUNCTION" if component_id == "-1": component_id = "INTRIN_COMPTYPE_FROM_TYPE_ELT0" - return db_hlsl_intrisic_param(param_name, param_qual, template_id, template_list, component_id, component_list, rows, cols, type_name, idx, template_id_idx, component_id_idx) + return db_hlsl_intrisic_param( + param_name, + param_qual, + template_id, + template_list, + component_id, + component_list, + rows, + cols, + type_name, + idx, + template_id_idx, + component_id_idx, + ) def process_attr(attr): - attrs = attr.split(',') - readonly = False # Only read memory - readnone = False # Not read memory - is_wave = False; # Is wave-sensitive - unsigned_op = "" # Unsigned opcode if exist - overload_param_index = -1 # Parameter determines the overload type, -1 means ret type. + attrs = attr.split(",") + readonly = False # Only read memory + readnone = False # Not read memory + is_wave = False + # Is wave-sensitive + unsigned_op = "" # Unsigned opcode if exist + overload_param_index = ( + -1 + ) # Parameter determines the overload type, -1 means ret type. hidden = False for a in attrs: - if (a == ""): + if a == "": continue - if (a == "ro"): + if a == "ro": readonly = True continue - if (a == "rn"): + if a == "rn": readnone = True continue - if (a == "wv"): + if a == "wv": is_wave = True continue - if (a == "hidden"): + if a == "hidden": hidden = True continue - assign = a.split('=') + assign = a.split("=") - if (len(assign) != 2): + if len(assign) != 2: assert False, "invalid attr %s" % (a) continue d = assign[0] v = assign[1] - if (d == "unsigned_op"): + if d == "unsigned_op": unsigned_op = v continue - if (d == "overload"): + if d == "overload": overload_param_index = int(v) continue assert False, "invalid attr %s" % (a) - return readonly, readnone, is_wave, unsigned_op, overload_param_index, hidden + return ( + readonly, + readnone, + is_wave, + unsigned_op, + overload_param_index, + hidden, + ) current_namespace = None for line in intrinsic_defs: - if blank_re.match(line): continue - if comment_re.match(line): continue + if blank_re.match(line): + continue + if comment_re.match(line): + continue match_obj = namespace_beg_re.match(line) if match_obj: - assert not current_namespace, "cannot open namespace without closing prior one" + assert ( + not current_namespace + ), "cannot open namespace without closing prior one" current_namespace = match_obj.group(1) num_entries = 0 ns_idx += 1 continue if namespace_end_re.match(line): - assert current_namespace, "cannot close namespace without previously opening it" + assert ( + current_namespace + ), "cannot close namespace without previously opening it" current_namespace = None continue match_obj = intrinsic_re.match(line) @@ -3190,7 +7783,14 @@ def process_attr(attr): op = operand_match.group(1) if not op: op = name - readonly, readnone, is_wave, unsigned_op, overload_param_index, hidden = process_attr(attr) + ( + readonly, + readnone, + is_wave, + unsigned_op, + overload_param_index, + hidden, + ) = process_attr(attr) # Add an entry for this intrinsic. if bracket_cleanup_re.search(opts): opts = bracket_cleanup_re.sub(r"<\1@\2>", opts) @@ -3212,9 +7812,23 @@ def process_attr(attr): # It needs to be the first entry, so prepend it. args.insert(0, process_arg(ret_desc, 0, args, name)) # TODO: verify a single level of indirection - self.intrinsics.append(db_hlsl_intrinsic( - name, num_entries, op, args, current_namespace, ns_idx, "pending doc for " + name, - readonly, readnone, is_wave, unsigned_op, overload_param_index, hidden)) + self.intrinsics.append( + db_hlsl_intrinsic( + name, + num_entries, + op, + args, + current_namespace, + ns_idx, + "pending doc for " + name, + readonly, + readnone, + is_wave, + unsigned_op, + overload_param_index, + hidden, + ) + ) num_entries += 1 continue assert False, "cannot parse line %s" % (line) @@ -3222,30 +7836,125 @@ def process_attr(attr): def populate_attributes(self): "Populate basic definitions for attributes." attributes = [] + def add_attr(title_name, scope, doc): attributes.append(db_hlsl_attribute(title_name, scope, [], doc)) + def add_attr_arg(title_name, scope, args, doc): attributes.append(db_hlsl_attribute(title_name, scope, args, doc)) - add_attr("Allow_UAV_Condition", "l", "Allows a compute shader loop termination condition to be based off of a UAV read. The loop must not contain synchronization intrinsics") - add_attr("Branch", "c", "Evaluate only one side of the if statement depending on the given condition") - add_attr("Call", "s", "The bodies of the individual cases in the switch will be moved into hardware subroutines and the switch will be a series of subroutine calls") - add_attr("EarlyDepthStencil", "f", "Forces depth-stencil testing before a shader executes") - add_attr("FastOpt", "l", "Reduces the compile time but produces less aggressive optimizations") - add_attr("Flatten", "c", "Evaluate both sides of the if statement and choose between the two resulting values") + + add_attr( + "Allow_UAV_Condition", + "l", + "Allows a compute shader loop termination condition to be based off of a UAV read. The loop must not contain synchronization intrinsics", + ) + add_attr( + "Branch", + "c", + "Evaluate only one side of the if statement depending on the given condition", + ) + add_attr( + "Call", + "s", + "The bodies of the individual cases in the switch will be moved into hardware subroutines and the switch will be a series of subroutine calls", + ) + add_attr( + "EarlyDepthStencil", + "f", + "Forces depth-stencil testing before a shader executes", + ) + add_attr( + "FastOpt", + "l", + "Reduces the compile time but produces less aggressive optimizations", + ) + add_attr( + "Flatten", + "c", + "Evaluate both sides of the if statement and choose between the two resulting values", + ) add_attr("ForceCase", "s", "Force a switch statement in the hardware") - add_attr("Loop", "l", "Generate code that uses flow control to execute each iteration of the loop") - add_attr_arg("ClipPlanes", "f", "Optional list of clip planes", [{"name":"ClipPlane", "type":"int", "count":6}]) - add_attr_arg("Domain", "f", "Defines the patch type used in the HS", [{"name":"DomainType", type:"string"}]) - add_attr_arg("Instance", "f", "Use this attribute to instance a geometry shader", [{"name":"Count", "type":"int"}]) - add_attr_arg("MaxTessFactor", "f", "Indicates the maximum value that the hull shader would return for any tessellation factor.", [{"name":"Count", "type":"int"}]) - add_attr_arg("MaxVertexCount", "f", "maxvertexcount doc", [{"name":"Count", "type":"int"}]) - add_attr_arg("NumThreads", "f", "Defines the number of threads to be executed in a single thread group.", [{"name":"x", "type":"int"},{"name":"z", "type":"int"},{"name":"y", "type":"int"}]) - add_attr_arg("OutputControlPoints", "f", "Defines the number of output control points per thread that will be created in the hull shader", [{"name":"Count", "type":"int"}]) - add_attr_arg("OutputTopology", "f", "Defines the output primitive type for the tessellator", [{"name":"Topology", "type":"string"}]) - add_attr_arg("Partitioning", "f", "Defines the tesselation scheme to be used in the hull shader", [{"name":"Scheme", "type":"scheme"}]) - add_attr_arg("PatchConstantFunc", "f", "Defines the function for computing patch constant data", [{"name":"FunctionName", "type":"string"}]) - add_attr_arg("RootSignature", "f", "RootSignature doc", [{"name":"SignatureName", "type":"string"}]) - add_attr_arg("Unroll", "l", "Unroll the loop until it stops executing or a max count", [{"name":"Count", "type":"int"}]) + add_attr( + "Loop", + "l", + "Generate code that uses flow control to execute each iteration of the loop", + ) + add_attr_arg( + "ClipPlanes", + "f", + "Optional list of clip planes", + [{"name": "ClipPlane", "type": "int", "count": 6}], + ) + add_attr_arg( + "Domain", + "f", + "Defines the patch type used in the HS", + [{"name": "DomainType", type: "string"}], + ) + add_attr_arg( + "Instance", + "f", + "Use this attribute to instance a geometry shader", + [{"name": "Count", "type": "int"}], + ) + add_attr_arg( + "MaxTessFactor", + "f", + "Indicates the maximum value that the hull shader would return for any tessellation factor.", + [{"name": "Count", "type": "int"}], + ) + add_attr_arg( + "MaxVertexCount", + "f", + "maxvertexcount doc", + [{"name": "Count", "type": "int"}], + ) + add_attr_arg( + "NumThreads", + "f", + "Defines the number of threads to be executed in a single thread group.", + [ + {"name": "x", "type": "int"}, + {"name": "z", "type": "int"}, + {"name": "y", "type": "int"}, + ], + ) + add_attr_arg( + "OutputControlPoints", + "f", + "Defines the number of output control points per thread that will be created in the hull shader", + [{"name": "Count", "type": "int"}], + ) + add_attr_arg( + "OutputTopology", + "f", + "Defines the output primitive type for the tessellator", + [{"name": "Topology", "type": "string"}], + ) + add_attr_arg( + "Partitioning", + "f", + "Defines the tesselation scheme to be used in the hull shader", + [{"name": "Scheme", "type": "scheme"}], + ) + add_attr_arg( + "PatchConstantFunc", + "f", + "Defines the function for computing patch constant data", + [{"name": "FunctionName", "type": "string"}], + ) + add_attr_arg( + "RootSignature", + "f", + "RootSignature doc", + [{"name": "SignatureName", "type": "string"}], + ) + add_attr_arg( + "Unroll", + "l", + "Unroll the loop until it stops executing or a max count", + [{"name": "Count", "type": "int"}], + ) self.attributes = attributes diff --git a/utils/hct/hctdb_instrhelp.py b/utils/hct/hctdb_instrhelp.py index 30969025aa..212c11d024 100644 --- a/utils/hct/hctdb_instrhelp.py +++ b/utils/hct/hctdb_instrhelp.py @@ -7,20 +7,27 @@ # get db singletons g_db_dxil = None + + def get_db_dxil(): global g_db_dxil if g_db_dxil is None: g_db_dxil = db_dxil() return g_db_dxil + + g_db_hlsl = None + + def get_db_hlsl(): global g_db_hlsl if g_db_hlsl is None: - thisdir = os.path.dirname(os.path.realpath(__file__)) - with open(os.path.join(thisdir, "gen_intrin_main.txt"), "r") as f: - g_db_hlsl = db_hlsl(f) + thisdir = os.path.dirname(os.path.realpath(__file__)) + with open(os.path.join(thisdir, "gen_intrin_main.txt"), "r") as f: + g_db_hlsl = db_hlsl(f) return g_db_hlsl + def format_comment(prefix, val): "Formats a value with a line-comment prefix." result = "" @@ -36,10 +43,11 @@ def format_comment(prefix, val): split_idx = val.rfind(" ", 0, content_width) result += prefix + val[:split_idx].strip() result += "\n" - val = val[split_idx+1:] + val = val[split_idx + 1 :] l = len(val) return result + def format_rst_table(list_of_tuples): "Produces a reStructuredText simple table from the specified list of tuples." # Calculate widths. @@ -71,6 +79,7 @@ def format_rst_table(list_of_tuples): result += banner return result + def build_range_tuples(i): "Produces a list of tuples with contiguous ranges in the input list." i = sorted(i) @@ -81,7 +90,7 @@ def build_range_tuples(i): low_bound = val high_bound = val else: - assert(not high_bound is None) + assert not high_bound is None if val == high_bound + 1: high_bound = val else: @@ -91,6 +100,7 @@ def build_range_tuples(i): if not low_bound is None: yield (low_bound, high_bound) + def build_range_code(var, i): "Produces a fragment of code that tests whether the variable name matches values in the given range." ranges = build_range_tuples(i) @@ -106,14 +116,22 @@ def build_range_code(var, i): result = result + " || " + cond return result + class db_docsref_gen: "A generator of reference documentation." + def __init__(self, db): self.db = db instrs = [i for i in self.db.instr if i.is_dxil_op] - instrs = sorted(instrs, key=lambda v : ("" if v.category == None else v.category) + "." + v.name) + instrs = sorted( + instrs, + key=lambda v: ("" if v.category == None else v.category) + "." + v.name, + ) self.instrs = instrs - val_rules = sorted(db.val_rules, key=lambda v : ("" if v.category == None else v.category) + "." + v.name) + val_rules = sorted( + db.val_rules, + key=lambda v: ("" if v.category == None else v.category) + "." + v.name, + ) self.val_rules = val_rules def print_content(self): @@ -147,8 +165,25 @@ def print_instruction_details(self): if o.pos == 0: print("
  • result: %s - %s
  • " % (o.llvm_type, o.doc)) else: - enum_desc = "" if o.enum_name == "" else " one of %s: %s" % (o.enum_name, ",".join(db.enum_idx[o.enum_name].value_names())) - print("
  • %d - %s: %s%s%s
  • " % (o.pos - 1, o.name, o.llvm_type, "" if o.doc == "" else " - " + o.doc, enum_desc)) + enum_desc = ( + "" + if o.enum_name == "" + else " one of %s: %s" + % ( + o.enum_name, + ",".join(db.enum_idx[o.enum_name].value_names()), + ) + ) + print( + "
  • %d - %s: %s%s%s
  • " + % ( + o.pos - 1, + o.name, + o.llvm_type, + "" if o.doc == "" else " - " + o.doc, + enum_desc, + ) + ) print("") print("") @@ -177,6 +212,7 @@ def print_footer(self): class db_instrhelp_gen: "A generator of instruction helper classes." + def __init__(self, db): self.db = db TypeInfo = collections.namedtuple("TypeInfo", "name bits") @@ -185,8 +221,8 @@ def __init__(self, db): "i8": TypeInfo("int8_t", 8), "u8": TypeInfo("uint8_t", 8), "i32": TypeInfo("int32_t", 32), - "u32": TypeInfo("uint32_t", 32) - } + "u32": TypeInfo("uint32_t", 32), + } self.IsDxilOpFuncCallInst = "hlsl::OP::IsDxilOpFuncCallInst" def print_content(self): @@ -195,16 +231,36 @@ def print_content(self): self.print_footer() def print_header(self): - print("///////////////////////////////////////////////////////////////////////////////") - print("// //") - print("// Copyright (C) Microsoft Corporation. All rights reserved. //") - print("// DxilInstructions.h //") - print("// //") - print("// This file provides a library of instruction helper classes. //") - print("// //") - print("// MUCH WORK YET TO BE DONE - EXPECT THIS WILL CHANGE - GENERATED FILE //") - print("// //") - print("///////////////////////////////////////////////////////////////////////////////") + print( + "///////////////////////////////////////////////////////////////////////////////" + ) + print( + "// //" + ) + print( + "// Copyright (C) Microsoft Corporation. All rights reserved. //" + ) + print( + "// DxilInstructions.h //" + ) + print( + "// //" + ) + print( + "// This file provides a library of instruction helper classes. //" + ) + print( + "// //" + ) + print( + "// MUCH WORK YET TO BE DONE - EXPECT THIS WILL CHANGE - GENERATED FILE //" + ) + print( + "// //" + ) + print( + "///////////////////////////////////////////////////////////////////////////////" + ) print("") print("// TODO: add correct include directives") print("// TODO: add accessors with values") @@ -213,26 +269,39 @@ def print_header(self): print("namespace hlsl {") def bool_lit(self, val): - return "true" if val else "false"; + return "true" if val else "false" def op_type(self, o): if o.llvm_type in self.llvm_type_map: return self.llvm_type_map[o.llvm_type].name - raise ValueError("Don't know how to describe type %s for operand %s." % (o.llvm_type, o.name)) + raise ValueError( + "Don't know how to describe type %s for operand %s." % (o.llvm_type, o.name) + ) + def op_size(self, o): if o.llvm_type in self.llvm_type_map: return self.llvm_type_map[o.llvm_type].bits - raise ValueError("Don't know how to describe type %s for operand %s." % (o.llvm_type, o.name)) + raise ValueError( + "Don't know how to describe type %s for operand %s." % (o.llvm_type, o.name) + ) def op_const_expr(self, o): - return "(%s)(llvm::dyn_cast(Instr->getOperand(%d))->getZExtValue())" % (self.op_type(o), o.pos - 1) + return ( + "(%s)(llvm::dyn_cast(Instr->getOperand(%d))->getZExtValue())" + % (self.op_type(o), o.pos - 1) + ) + def op_set_const_expr(self, o): type_size = self.op_size(o) - return "llvm::Constant::getIntegerValue(llvm::IntegerType::get(Instr->getContext(), %d), llvm::APInt(%d, (uint64_t)val))" % (type_size, type_size) + return ( + "llvm::Constant::getIntegerValue(llvm::IntegerType::get(Instr->getContext(), %d), llvm::APInt(%d, (uint64_t)val))" + % (type_size, type_size) + ) def print_body(self): for i in self.db.instr: - if i.is_reserved: continue + if i.is_reserved: + continue if i.inst_helper_prefix: struct_name = "%s_%s" % (i.inst_helper_prefix, i.name) elif i.is_dxil_op: @@ -248,23 +317,35 @@ def print_body(self): print(" operator bool() const {") if i.is_dxil_op: op_name = i.fully_qualified_name() - print(" return %s(Instr, %s);" % (self.IsDxilOpFuncCallInst, op_name)) + print( + " return %s(Instr, %s);" % (self.IsDxilOpFuncCallInst, op_name) + ) else: - print(" return Instr->getOpcode() == llvm::Instruction::%s;" % i.name) + print( + " return Instr->getOpcode() == llvm::Instruction::%s;" % i.name + ) print(" }") print(" // Validation support") - print(" bool isAllowed() const { return %s; }" % self.bool_lit(i.is_allowed)) + print( + " bool isAllowed() const { return %s; }" % self.bool_lit(i.is_allowed) + ) if i.is_dxil_op: print(" bool isArgumentListValid() const {") - print(" if (%d != llvm::dyn_cast(Instr)->getNumArgOperands()) return false;" % (len(i.ops) - 1)) + print( + " if (%d != llvm::dyn_cast(Instr)->getNumArgOperands()) return false;" + % (len(i.ops) - 1) + ) print(" return true;") # TODO - check operand types print(" }") print(" // Metadata") - print(" bool requiresUniformInputs() const { return %s; }" % self.bool_lit(i.requires_uniform_inputs)) + print( + " bool requiresUniformInputs() const { return %s; }" + % self.bool_lit(i.requires_uniform_inputs) + ) EnumWritten = False for o in i.ops: - if o.pos > 1: # 0 is return type, 1 is DXIL OP id + if o.pos > 1: # 0 is return type, 1 is DXIL OP id if not EnumWritten: print(" // Operand indexes") print(" enum OperandIdx {") @@ -274,31 +355,47 @@ def print_body(self): print(" };") AccessorsWritten = False for o in i.ops: - if o.pos > 1: # 0 is return type, 1 is DXIL OP id + if o.pos > 1: # 0 is return type, 1 is DXIL OP id if not AccessorsWritten: print(" // Accessors") AccessorsWritten = True - print(" llvm::Value *get_%s() const { return Instr->getOperand(%d); }" % (o.name, o.pos - 1)) - print(" void set_%s(llvm::Value *val) { Instr->setOperand(%d, val); }" % (o.name, o.pos - 1)) + print( + " llvm::Value *get_%s() const { return Instr->getOperand(%d); }" + % (o.name, o.pos - 1) + ) + print( + " void set_%s(llvm::Value *val) { Instr->setOperand(%d, val); }" + % (o.name, o.pos - 1) + ) if o.is_const: if o.llvm_type in self.llvm_type_map: - print(" %s get_%s_val() const { return %s; }" % (self.op_type(o), o.name, self.op_const_expr(o))) - print(" void set_%s_val(%s val) { Instr->setOperand(%d, %s); }" % (o.name, self.op_type(o), o.pos - 1, self.op_set_const_expr(o))) + print( + " %s get_%s_val() const { return %s; }" + % (self.op_type(o), o.name, self.op_const_expr(o)) + ) + print( + " void set_%s_val(%s val) { Instr->setOperand(%d, %s); }" + % ( + o.name, + self.op_type(o), + o.pos - 1, + self.op_set_const_expr(o), + ) + ) print("};") print("") def print_footer(self): print("} // namespace hlsl") + class db_enumhelp_gen: "A generator of enumeration declarations." + def __init__(self, db): self.db = db # Some enums should get a last enum marker. - self.lastEnumNames = { - "OpCode": "NumOpCodes", - "OpCodeClass": "NumOpClasses" - } + self.lastEnumNames = {"OpCode": "NumOpCodes", "OpCodeClass": "NumOpClasses"} def print_enum(self, e, **kwargs): print("// %s" % e.doc) @@ -306,7 +403,10 @@ def print_enum(self, e, **kwargs): hide_val = kwargs.get("hide_val", False) sorted_values = e.values if kwargs.get("sort_val", True): - sorted_values = sorted(e.values, key=lambda v : ("" if v.category == None else v.category) + "." + v.name) + sorted_values = sorted( + e.values, + key=lambda v: ("" if v.category == None else v.category) + "." + v.name, + ) last_category = None for v in sorted_values: if v.category != last_category: @@ -324,39 +424,53 @@ def print_enum(self, e, **kwargs): print(line_format.format(name=v.name, value=v.value, doc=v.doc)) if e.name in self.lastEnumNames: lastName = self.lastEnumNames[e.name] - versioned = ["%s_Dxil_%d_%d = %d," % (lastName, major, minor, info[lastName]) - for (major, minor), info in sorted(self.db.dxil_version_info.items()) - if lastName in info] + versioned = [ + "%s_Dxil_%d_%d = %d," % (lastName, major, minor, info[lastName]) + for (major, minor), info in sorted(self.db.dxil_version_info.items()) + if lastName in info + ] if versioned: print("") for val in versioned: print(" " + val) print("") - print(" " + lastName + " = " + str(len(sorted_values)) + " // exclusive last value of enumeration") + print( + " " + + lastName + + " = " + + str(len(sorted_values)) + + " // exclusive last value of enumeration" + ) print("};") def print_rdat_enum(self, e, **kwargs): nodef = kwargs.get("nodef", False) for v in e.values: - line_format = "RDAT_ENUM_VALUE_NODEF({name})" if nodef else "RDAT_ENUM_VALUE({value}, {name})" + line_format = ( + "RDAT_ENUM_VALUE_NODEF({name})" + if nodef + else "RDAT_ENUM_VALUE({value}, {name})" + ) if v.doc: line_format += " // {doc}" print(line_format.format(name=v.name, value=v.value, doc=v.doc)) def print_content(self): - for e in sorted(self.db.enums, key=lambda e : e.name): + for e in sorted(self.db.enums, key=lambda e: e.name): self.print_enum(e) + class db_oload_gen: "A generator of overload tables." + def __init__(self, db): self.db = db instrs = [i for i in self.db.instr if i.is_dxil_op] - self.instrs = sorted(instrs, key=lambda i : i.dxil_opid) + self.instrs = sorted(instrs, key=lambda i: i.dxil_opid) # Allow these to be overridden by external scripts. - self.OP = "OP" - self.OC = "OC" + self.OP = "OP" + self.OC = "OC" self.OCC = "OCC" def print_content(self): @@ -365,8 +479,14 @@ def print_content(self): self.print_opfunc_table() def print_opfunc_props(self): - print("const {OP}::OpCodeProperty {OP}::m_OpCodeProps[(unsigned){OP}::OpCode::NumOpCodes] = {{".format(OP=self.OP)) - print("// OpCode OpCode name, OpCodeClass OpCodeClass name, void, h, f, d, i1, i8, i16, i32, i64, udt, obj, function attribute") + print( + "const {OP}::OpCodeProperty {OP}::m_OpCodeProps[(unsigned){OP}::OpCode::NumOpCodes] = {{".format( + OP=self.OP + ) + ) + print( + "// OpCode OpCode name, OpCodeClass OpCodeClass name, void, h, f, d, i1, i8, i16, i32, i64, udt, obj, function attribute" + ) # Example formatted string: # { OC::TempRegLoad, "TempRegLoad", OCC::TempRegLoad, "tempRegLoad", false, true, true, false, true, false, true, true, false, Attribute::ReadOnly, }, # 012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 @@ -374,21 +494,58 @@ def print_opfunc_props(self): last_category = None # overload types are a string of (v)oid, (h)alf, (f)loat, (d)ouble, (1)-bit, (8)-bit, (w)ord, (i)nt, (l)ong, u(dt) - f = lambda i,c : "true" if i.oload_types.find(c) >= 0 else "false" - lower_exceptions = { "CBufferLoad" : "cbufferLoad", "CBufferLoadLegacy" : "cbufferLoadLegacy", "GSInstanceID" : "gsInstanceID" } - lower_fn = lambda t: lower_exceptions[t] if t in lower_exceptions else t[:1].lower() + t[1:] - attr_dict = { "": "None", "ro": "ReadOnly", "rn": "ReadNone", "nd": "NoDuplicate", "nr": "NoReturn", "wv" : "None" } - attr_fn = lambda i : "Attribute::" + attr_dict[i.fn_attr] + "," + f = lambda i, c: "true" if i.oload_types.find(c) >= 0 else "false" + lower_exceptions = { + "CBufferLoad": "cbufferLoad", + "CBufferLoadLegacy": "cbufferLoadLegacy", + "GSInstanceID": "gsInstanceID", + } + lower_fn = ( + lambda t: lower_exceptions[t] + if t in lower_exceptions + else t[:1].lower() + t[1:] + ) + attr_dict = { + "": "None", + "ro": "ReadOnly", + "rn": "ReadNone", + "nd": "NoDuplicate", + "nr": "NoReturn", + "wv": "None", + } + attr_fn = lambda i: "Attribute::" + attr_dict[i.fn_attr] + "," for i in self.instrs: if last_category != i.category: if last_category != None: print("") - print(" // {category:118} void, h, f, d, i1, i8, i16, i32, i64, udt, obj , function attribute".format(category=i.category)) + print( + " // {category:118} void, h, f, d, i1, i8, i16, i32, i64, udt, obj , function attribute".format( + category=i.category + ) + ) last_category = i.category - print(" {{ {OC}::{name:24} {quotName:27} {OCC}::{className:25} {classNameQuot:28} {{{v:>6},{h:>6},{f:>6},{d:>6},{b:>6},{e:>6},{w:>6},{i:>6},{l:>6},{u:>6},{o:>6}}}, {attr:20} }},".format( - name=i.name+",", quotName='"'+i.name+'",', className=i.dxil_class+",", classNameQuot='"'+lower_fn(i.dxil_class)+'",', - v=f(i,"v"), h=f(i,"h"), f=f(i,"f"), d=f(i,"d"), b=f(i,"1"), e=f(i,"8"), w=f(i,"w"), i=f(i,"i"), l=f(i,"l"), u=f(i,"u"), o=f(i,"o"), attr=attr_fn(i), - OC=self.OC, OCC=self.OCC)) + print( + " {{ {OC}::{name:24} {quotName:27} {OCC}::{className:25} {classNameQuot:28} {{{v:>6},{h:>6},{f:>6},{d:>6},{b:>6},{e:>6},{w:>6},{i:>6},{l:>6},{u:>6},{o:>6}}}, {attr:20} }},".format( + name=i.name + ",", + quotName='"' + i.name + '",', + className=i.dxil_class + ",", + classNameQuot='"' + lower_fn(i.dxil_class) + '",', + v=f(i, "v"), + h=f(i, "h"), + f=f(i, "f"), + d=f(i, "d"), + b=f(i, "1"), + e=f(i, "8"), + w=f(i, "w"), + i=f(i, "i"), + l=f(i, "l"), + u=f(i, "u"), + o=f(i, "o"), + attr=attr_fn(i), + OC=self.OC, + OCC=self.OCC, + ) + ) print("};") def print_opfunc_table(self): @@ -425,7 +582,7 @@ def print_opfunc_table(self): "u64": "A(pI64);", "u8": "A(pI8);", "v": "A(pV);", - "$vec4" : "VEC4(pETy);", + "$vec4": "VEC4(pETy);", "w": "A(pWav);", "SamplePos": "A(pPos);", "udt": "A(udt);", @@ -440,9 +597,11 @@ def print_opfunc_table(self): print("") print(" // %s" % i.category) last_category = i.category - line = " case OpCode::{name:24}".format(name = i.name + ":") + line = " case OpCode::{name:24}".format(name=i.name + ":") for index, o in enumerate(i.ops): - assert o.llvm_type in op_type_texts, "llvm type %s in instruction %s is unknown" % (o.llvm_type, i.name) + assert ( + o.llvm_type in op_type_texts + ), "llvm type %s in instruction %s is unknown" % (o.llvm_type, i.name) op_type_text = op_type_texts[o.llvm_type] if index == 0: line = line + "{val:13}".format(val=op_type_text) @@ -468,7 +627,7 @@ def print_opfunc_oload_type(self): for instr in self.instrs: ret_ty = instr.ops[0].llvm_type # Skip case return type is overload type - if (ret_ty == elt_ty): + if ret_ty == elt_ty: continue if ret_ty == res_ret_ty: @@ -480,21 +639,21 @@ def print_opfunc_oload_type(self): continue if ret_ty.startswith(vec_ty): - struct_list.append(instr.name); + struct_list.append(instr.name) continue in_param_ty = False # Try to find elt_ty in parameter types. for index, op in enumerate(instr.ops): # Skip return type. - if (op.pos == 0): + if op.pos == 0: continue # Skip dxil opcode. - if (op.pos == 1): + if op.pos == 1: continue op_type = op.llvm_type - if (op_type == elt_ty): + if op_type == elt_ty: # Skip return op index = index - 1 if index not in index_dict: @@ -503,7 +662,7 @@ def print_opfunc_oload_type(self): index_dict[index].append(instr.name) in_param_ty = True break - if (op_type == udt_ty or op_type == obj_ty): + if op_type == udt_ty or op_type == obj_ty: # Skip return op index = index - 1 if index not in index_dict: @@ -512,25 +671,24 @@ def print_opfunc_oload_type(self): index_dict[index].append(instr.name) in_param_ty = True - if in_param_ty: continue # No overload, just return the single oload_type. - assert len(instr.oload_types)==1, "overload no elt_ty %s" % (instr.name) + assert len(instr.oload_types) == 1, "overload no elt_ty %s" % (instr.name) ty = instr.oload_types[0] type_code_texts = { - "d": "Type::getDoubleTy(Ctx)", - "f": "Type::getFloatTy(Ctx)", - "h": "Type::getHalfTy", - "1": "IntegerType::get(Ctx, 1)", - "8": "IntegerType::get(Ctx, 8)", - "w": "IntegerType::get(Ctx, 16)", - "i": "IntegerType::get(Ctx, 32)", - "l": "IntegerType::get(Ctx, 64)", - "v": "Type::getVoidTy(Ctx)", - "u": "Type::getInt32PtrTy(Ctx)", - "o": "Type::getInt32PtrTy(Ctx)", + "d": "Type::getDoubleTy(Ctx)", + "f": "Type::getFloatTy(Ctx)", + "h": "Type::getHalfTy", + "1": "IntegerType::get(Ctx, 1)", + "8": "IntegerType::get(Ctx, 8)", + "w": "IntegerType::get(Ctx, 16)", + "i": "IntegerType::get(Ctx, 32)", + "l": "IntegerType::get(Ctx, 64)", + "v": "Type::getVoidTy(Ctx)", + "u": "Type::getInt32PtrTy(Ctx)", + "o": "Type::getInt32PtrTy(Ctx)", } assert ty in type_code_texts, "llvm type %s is unknown" % (ty) ty_code = type_code_texts[ty] @@ -543,7 +701,7 @@ def print_opfunc_oload_type(self): for index, opcodes in index_dict.items(): line = "" for opcode in opcodes: - line = line + "case OpCode::{name}".format(name = opcode + ":\n") + line = line + "case OpCode::{name}".format(name=opcode + ":\n") line = line + " DXASSERT_NOMSG(FT->getNumParams() > " + str(index) + ");\n" line = line + " return FT->getParamType(" + str(index) + ");" @@ -552,13 +710,13 @@ def print_opfunc_oload_type(self): for code, opcodes in single_dict.items(): line = "" for opcode in opcodes: - line = line + "case OpCode::{name}".format(name = opcode + ":\n") + line = line + "case OpCode::{name}".format(name=opcode + ":\n") line = line + " return " + code + ";" print(line) line = "" for opcode in struct_list: - line = line + "case OpCode::{name}".format(name = opcode + ":\n") + line = line + "case OpCode::{name}".format(name=opcode + ":\n") line = line + "{\n" line = line + " StructType *ST = cast(Ty);\n" line = line + " return ST->getElementType(0);\n" @@ -568,6 +726,7 @@ def print_opfunc_oload_type(self): class db_valfns_gen: "A generator of validation functions." + def __init__(self, db): self.db = db @@ -576,28 +735,43 @@ def print_content(self): self.print_body() def print_header(self): - print("///////////////////////////////////////////////////////////////////////////////") - print("// Instruction validation functions. //") + print( + "///////////////////////////////////////////////////////////////////////////////" + ) + print( + "// Instruction validation functions. //" + ) def bool_lit(self, val): - return "true" if val else "false"; + return "true" if val else "false" def op_type(self, o): if o.llvm_type == "i8": return "int8_t" if o.llvm_type == "u8": return "uint8_t" - raise ValueError("Don't know how to describe type %s for operand %s." % (o.llvm_type, o.name)) + raise ValueError( + "Don't know how to describe type %s for operand %s." % (o.llvm_type, o.name) + ) def op_const_expr(self, o): if o.llvm_type == "i8" or o.llvm_type == "u8": - return "(%s)(llvm::dyn_cast(Instr->getOperand(%d))->getZExtValue())" % (self.op_type(o), o.pos - 1) - raise ValueError("Don't know how to describe type %s for operand %s." % (o.llvm_type, o.name)) + return ( + "(%s)(llvm::dyn_cast(Instr->getOperand(%d))->getZExtValue())" + % (self.op_type(o), o.pos - 1) + ) + raise ValueError( + "Don't know how to describe type %s for operand %s." % (o.llvm_type, o.name) + ) def print_body(self): llvm_instrs = [i for i in self.db.instr if i.is_allowed and not i.is_dxil_op] print("static bool IsLLVMInstructionAllowed(llvm::Instruction &I) {") - self.print_comment(" // ", "Allow: %s" % ", ".join([i.name + "=" + str(i.llvm_id) for i in llvm_instrs])) + self.print_comment( + " // ", + "Allow: %s" + % ", ".join([i.name + "=" + str(i.llvm_id) for i in llvm_instrs]), + ) print(" unsigned op = I.getOpcode();") print(" return %s;" % build_range_code("op", [i.llvm_id for i in llvm_instrs])) print("}") @@ -606,18 +780,22 @@ def print_body(self): def print_comment(self, prefix, val): print(format_comment(prefix, val)) + class macro_table_gen: "A generator for macro tables." - def format_row(self, row, widths, sep=', '): - frow = [str(item) + sep + (' ' * (width - len(item))) - for item, width in list(zip(row, widths))[:-1]] + [str(row[-1])] - return ''.join(frow) + def format_row(self, row, widths, sep=", "): + frow = [ + str(item) + sep + (" " * (width - len(item))) + for item, width in list(zip(row, widths))[:-1] + ] + [str(row[-1])] + return "".join(frow) def format_table(self, table, *args, **kwargs): - widths = [ functools.reduce(max, [ len(row[i]) - for row in table], 1) - for i in range(len(table[0]))] + widths = [ + functools.reduce(max, [len(row[i]) for row in table], 1) + for i in range(len(table[0])) + ] formatted = [] for row in table: formatted.append(self.format_row(row, widths, *args, **kwargs)) @@ -625,35 +803,44 @@ def format_table(self, table, *args, **kwargs): def print_table(self, table, macro_name): formatted = self.format_table(table) - print( '// %s\n' % formatted[0] + - '#define %s(ROW) \\\n' % macro_name + - ' \\\n'.join([' ROW(%s)' % frow for frow in formatted[1:]])) + print( + "// %s\n" % formatted[0] + + "#define %s(ROW) \\\n" % macro_name + + " \\\n".join([" ROW(%s)" % frow for frow in formatted[1:]]) + ) + class db_sigpoint_gen(macro_table_gen): "A generator for SigPoint tables." + def __init__(self, db): self.db = db def print_sigpoint_table(self): - self.print_table(self.db.sigpoint_table, 'DO_SIGPOINTS') + self.print_table(self.db.sigpoint_table, "DO_SIGPOINTS") def print_interpretation_table(self): - self.print_table(self.db.interpretation_table, 'DO_INTERPRETATION_TABLE') + self.print_table(self.db.interpretation_table, "DO_INTERPRETATION_TABLE") def print_content(self): self.print_sigpoint_table() self.print_interpretation_table() + class string_output: def __init__(self): self.val = "" + def write(self, text): self.val = self.val + str(text) + def __str__(self): return self.val + def run_with_stdout(fn): import sys + _stdout_saved = sys.stdout so = string_output() try: @@ -663,6 +850,7 @@ def run_with_stdout(fn): sys.stdout = _stdout_saved return str(so) + def get_hlsl_intrinsic_stats(): db = get_db_hlsl() longest_fn = db.intrinsics[0] @@ -673,7 +861,9 @@ def get_hlsl_intrinsic_stats(): if len(i.name) > len(longest_fn.name): longest_fn = i for p_idx, p in enumerate(i.params): - if p_idx > 0 and (longest_param is None or len(p.name) > len(longest_param.name)): + if p_idx > 0 and ( + longest_param is None or len(p.name) > len(longest_param.name) + ): longest_param = p if len(i.params) > len(longest_arglist_fn.params): longest_arglist_fn = i @@ -682,8 +872,8 @@ def get_hlsl_intrinsic_stats(): v = db.namespaces[k] result += "static const UINT g_u%sCount = %d;\n" % (k, len(v.intrinsics)) result += "\n" - #NOTE:The min limits are needed to support allowing intrinsics in the extension mechanism that use longer values than the builtin hlsl intrisics. - #TODO: remove code which dependent on g_MaxIntrinsic*. + # NOTE:The min limits are needed to support allowing intrinsics in the extension mechanism that use longer values than the builtin hlsl intrisics. + # TODO: remove code which dependent on g_MaxIntrinsic*. MIN_FUNCTION_NAME_LENTH = 44 MIN_PARAM_NAME_LENTH = 48 MIN_PARAM_COUNT = 29 @@ -707,11 +897,21 @@ def get_hlsl_intrinsic_stats(): max_param_count = MIN_PARAM_COUNT max_param_count_name = "MIN_PARAM_COUNT" - result += "static const int g_MaxIntrinsicName = %d; // Count of characters for longest intrinsic name - '%s'\n" % (max_fn_name_len, max_fn_name) - result += "static const int g_MaxIntrinsicParamName = %d; // Count of characters for longest intrinsic parameter name - '%s'\n" % (max_param_name_len, max_param_name) - result += "static const int g_MaxIntrinsicParamCount = %d; // Count of parameters (without return) for longest intrinsic argument list - '%s'\n" % (max_param_count, max_param_count_name) + result += ( + "static const int g_MaxIntrinsicName = %d; // Count of characters for longest intrinsic name - '%s'\n" + % (max_fn_name_len, max_fn_name) + ) + result += ( + "static const int g_MaxIntrinsicParamName = %d; // Count of characters for longest intrinsic parameter name - '%s'\n" + % (max_param_name_len, max_param_name) + ) + result += ( + "static const int g_MaxIntrinsicParamCount = %d; // Count of parameters (without return) for longest intrinsic argument list - '%s'\n" + % (max_param_count, max_param_count_name) + ) return result + def get_hlsl_intrinsics(): db = get_db_hlsl() result = "" @@ -724,8 +924,10 @@ def get_hlsl_intrinsics(): for i in sorted(db.intrinsics, key=lambda x: x.key): if last_ns != i.ns: last_ns = i.ns - id_prefix = "IOP" if last_ns == "Intrinsics" or last_ns == "VkIntrinsics" else "MOP" # SPIRV Change - if (len(ns_table)): + id_prefix = ( + "IOP" if last_ns == "Intrinsics" or last_ns == "VkIntrinsics" else "MOP" + ) # SPIRV Change + if len(ns_table): result += ns_table + "};\n" # SPIRV Change Starts if is_vk_table: @@ -736,41 +938,70 @@ def get_hlsl_intrinsics(): # This used to be qualified as __declspec(selectany), but that's no longer necessary. ns_table = "static const HLSL_INTRINSIC g_%s[] =\n{\n" % (last_ns) # SPIRV Change Starts - if (i.vulkanSpecific): + if i.vulkanSpecific: is_vk_table = True result += "#ifdef ENABLE_SPIRV_CODEGEN\n\n" # SPIRV Change Ends arg_idx = 0 - ns_table += " {(UINT)%s::%s_%s, %s, %s, %s, %d, %d, g_%s_Args%s},\n" % (opcode_namespace, id_prefix, i.name, str(i.readonly).lower(), str(i.readnone).lower(), str(i.wave).lower(), i.overload_param_index,len(i.params), last_ns, arg_idx) - result += "static const HLSL_INTRINSIC_ARGUMENT g_%s_Args%s[] =\n{\n" % (last_ns, arg_idx) + ns_table += " {(UINT)%s::%s_%s, %s, %s, %s, %d, %d, g_%s_Args%s},\n" % ( + opcode_namespace, + id_prefix, + i.name, + str(i.readonly).lower(), + str(i.readnone).lower(), + str(i.wave).lower(), + i.overload_param_index, + len(i.params), + last_ns, + arg_idx, + ) + result += "static const HLSL_INTRINSIC_ARGUMENT g_%s_Args%s[] =\n{\n" % ( + last_ns, + arg_idx, + ) for p in i.params: name = p.name if name == i.name and i.hidden: # First parameter defines intrinsic name for parsing in HLSL. # Prepend '$hidden$' for hidden intrinsic so it can't be used in HLSL. name = "$hidden$" + name - result += " {\"%s\", %s, %s, %s, %s, %s, %s, %s},\n" % ( - name, p.param_qual, p.template_id, p.template_list, - p.component_id, p.component_list, p.rows, p.cols) + result += ' {"%s", %s, %s, %s, %s, %s, %s, %s},\n' % ( + name, + p.param_qual, + p.template_id, + p.template_list, + p.component_id, + p.component_list, + p.rows, + p.cols, + ) result += "};\n\n" arg_idx += 1 result += ns_table + "};\n" - result += "\n#endif // ENABLE_SPIRV_CODEGEN\n" if is_vk_table else "" # SPIRV Change + result += ( + "\n#endif // ENABLE_SPIRV_CODEGEN\n" if is_vk_table else "" + ) # SPIRV Change return result + # SPIRV Change Starts def wrap_with_ifdef_if_vulkan_specific(intrinsic, text): if intrinsic.vulkanSpecific: - return "#ifdef ENABLE_SPIRV_CODEGEN\n" + text + "#endif // ENABLE_SPIRV_CODEGEN\n" + return ( + "#ifdef ENABLE_SPIRV_CODEGEN\n" + text + "#endif // ENABLE_SPIRV_CODEGEN\n" + ) return text + + # SPIRV Change Ends + def enum_hlsl_intrinsics(): db = get_db_hlsl() result = "" enumed = [] for i in sorted(db.intrinsics, key=lambda x: x.key): - if (i.enum_name not in enumed): + if i.enum_name not in enumed: enumerant = " %s,\n" % (i.enum_name) result += wrap_with_ifdef_if_vulkan_specific(i, enumerant) # SPIRV Change enumed.append(i.enum_name) @@ -778,80 +1009,95 @@ def enum_hlsl_intrinsics(): result += " // unsigned\n" for i in sorted(db.intrinsics, key=lambda x: x.key): - if (i.unsigned_op != ""): - if (i.unsigned_op not in enumed): - result += " %s,\n" % (i.unsigned_op) - enumed.append(i.unsigned_op) + if i.unsigned_op != "": + if i.unsigned_op not in enumed: + result += " %s,\n" % (i.unsigned_op) + enumed.append(i.unsigned_op) result += " Num_Intrinsics,\n" return result + def has_unsigned_hlsl_intrinsics(): db = get_db_hlsl() result = "" enumed = [] # unsigned for i in sorted(db.intrinsics, key=lambda x: x.key): - if (i.unsigned_op != ""): - if (i.enum_name not in enumed): - result += " case IntrinsicOp::%s:\n" % (i.enum_name) - enumed.append(i.enum_name) + if i.unsigned_op != "": + if i.enum_name not in enumed: + result += " case IntrinsicOp::%s:\n" % (i.enum_name) + enumed.append(i.enum_name) return result + def get_unsigned_hlsl_intrinsics(): db = get_db_hlsl() result = "" enumed = [] # unsigned for i in sorted(db.intrinsics, key=lambda x: x.key): - if (i.unsigned_op != ""): - if (i.enum_name not in enumed): - enumed.append(i.enum_name) - result += " case IntrinsicOp::%s:\n" % (i.enum_name) - result += " return static_cast(IntrinsicOp::%s);\n" % (i.unsigned_op) + if i.unsigned_op != "": + if i.enum_name not in enumed: + enumed.append(i.enum_name) + result += " case IntrinsicOp::%s:\n" % (i.enum_name) + result += " return static_cast(IntrinsicOp::%s);\n" % ( + i.unsigned_op + ) return result + def get_oloads_props(): db = get_db_dxil() gen = db_oload_gen(db) return run_with_stdout(lambda: gen.print_opfunc_props()) + def get_oloads_funcs(): db = get_db_dxil() gen = db_oload_gen(db) return run_with_stdout(lambda: gen.print_opfunc_table()) + def get_funcs_oload_type(): db = get_db_dxil() gen = db_oload_gen(db) return run_with_stdout(lambda: gen.print_opfunc_oload_type()) + def get_enum_decl(name, **kwargs): db = get_db_dxil() gen = db_enumhelp_gen(db) return run_with_stdout(lambda: gen.print_enum(db.enum_idx[name], **kwargs)) + def get_rdat_enum_decl(name, **kwargs): db = get_db_dxil() gen = db_enumhelp_gen(db) return run_with_stdout(lambda: gen.print_rdat_enum(db.enum_idx[name], **kwargs)) + def get_valrule_enum(): return get_enum_decl("ValidationRule", hide_val=True) + def get_valrule_text(): db = get_db_dxil() result = "switch(value) {\n" for v in db.enum_idx["ValidationRule"].values: - result += " case hlsl::ValidationRule::" + v.name + ": return \"" + v.err_msg + "\";\n" + result += ( + " case hlsl::ValidationRule::" + v.name + ': return "' + v.err_msg + '";\n' + ) result += "}\n" return result + def get_instrhelper(): db = get_db_dxil() gen = db_instrhelp_gen(db) return run_with_stdout(lambda: gen.print_body()) + def get_instrs_pred(varname, pred, attr_name="dxil_opid"): db = get_db_dxil() if type(pred) == str: @@ -859,31 +1105,50 @@ def get_instrs_pred(varname, pred, attr_name="dxil_opid"): else: pred_fn = pred llvm_instrs = [i for i in db.instr if pred_fn(i)] - result = format_comment("// ", "Instructions: %s" % ", ".join([i.name + "=" + str(getattr(i, attr_name)) for i in llvm_instrs])) - result += "return %s;" % build_range_code(varname, [getattr(i, attr_name) for i in llvm_instrs]) + result = format_comment( + "// ", + "Instructions: %s" + % ", ".join([i.name + "=" + str(getattr(i, attr_name)) for i in llvm_instrs]), + ) + result += "return %s;" % build_range_code( + varname, [getattr(i, attr_name) for i in llvm_instrs] + ) result += "\n" return result + def counter_pred(name, dxil_op=True): def pred(i): - return (dxil_op == i.is_dxil_op) and getattr(i, 'props') and 'counters' in i.props and name in i.props['counters'] + return ( + (dxil_op == i.is_dxil_op) + and getattr(i, "props") + and "counters" in i.props + and name in i.props["counters"] + ) + return pred + def get_counters(): db = get_db_dxil() return db.counters + + def get_llvm_op_counters(): db = get_db_dxil() return [c for c in db.counters if c in db.llvm_op_counters] + + def get_dxil_op_counters(): db = get_db_dxil() return [c for c in db.counters if c in db.dxil_op_counters] + def get_instrs_rst(): "Create an rst table of allowed LLVM instructions." db = get_db_dxil() instrs = [i for i in db.instr if i.is_allowed and not i.is_dxil_op] - instrs = sorted(instrs, key=lambda v : v.llvm_id) + instrs = sorted(instrs, key=lambda v: v.llvm_id) rows = [] rows.append(["Instruction", "Action", "Operand overloads"]) for i in instrs: @@ -895,107 +1160,122 @@ def get_instrs_rst(): result += i.name + "\n" + ("~" * len(i.name)) + "\n\n" + i.remarks + "\n\n" return result + "\n" + def get_init_passes(category_libs): "Create a series of statements to initialize passes in a registry." db = get_db_dxil() result = "" - for p in sorted(db.passes, key=lambda p : p.type_name): + for p in sorted(db.passes, key=lambda p: p.type_name): # Skip if not in target category. - if (p.category_lib not in category_libs): + if p.category_lib not in category_libs: continue result += "initialize%sPass(Registry);\n" % p.type_name return result + def get_pass_arg_names(): "Return an ArrayRef of argument names based on passName" db = get_db_dxil() decl_result = "" check_result = "" - for p in sorted(db.passes, key=lambda p : p.type_name): + for p in sorted(db.passes, key=lambda p: p.type_name): if len(p.args): decl_result += "static const LPCSTR %sArgs[] = { " % p.type_name - check_result += "if (strcmp(passName, \"%s\") == 0) return ArrayRef(%sArgs, _countof(%sArgs));\n" % (p.name, p.type_name, p.type_name) + check_result += ( + 'if (strcmp(passName, "%s") == 0) return ArrayRef(%sArgs, _countof(%sArgs));\n' + % (p.name, p.type_name, p.type_name) + ) sep = "" for a in p.args: - decl_result += sep + "\"%s\"" % a.name + decl_result += sep + '"%s"' % a.name sep = ", " decl_result += " };\n" return decl_result + check_result + def get_pass_arg_descs(): "Return an ArrayRef of argument descriptions based on passName" db = get_db_dxil() decl_result = "" check_result = "" - for p in sorted(db.passes, key=lambda p : p.type_name): + for p in sorted(db.passes, key=lambda p: p.type_name): if len(p.args): decl_result += "static const LPCSTR %sArgs[] = { " % p.type_name - check_result += "if (strcmp(passName, \"%s\") == 0) return ArrayRef(%sArgs, _countof(%sArgs));\n" % (p.name, p.type_name, p.type_name) + check_result += ( + 'if (strcmp(passName, "%s") == 0) return ArrayRef(%sArgs, _countof(%sArgs));\n' + % (p.name, p.type_name, p.type_name) + ) sep = "" for a in p.args: - decl_result += sep + "\"%s\"" % a.doc + decl_result += sep + '"%s"' % a.doc sep = ", " decl_result += " };\n" return decl_result + check_result + def get_is_pass_option_name(): "Create a return expression to check whether a value 'S' is a pass option name." db = get_db_dxil() prefix = "" result = "return " for k in sorted(db.pass_idx_args): - result += prefix + "S.equals(\"%s\")" % k + result += prefix + 'S.equals("%s")' % k prefix = "\n || " return result + ";" + def get_opcodes_rst(): "Create an rst table of opcodes" db = get_db_dxil() instrs = [i for i in db.instr if i.is_allowed and i.is_dxil_op] - instrs = sorted(instrs, key=lambda v : v.dxil_opid) + instrs = sorted(instrs, key=lambda v: v.dxil_opid) rows = [] rows.append(["ID", "Name", "Description"]) for i in instrs: op_name = i.dxil_op if i.remarks: - op_name = op_name + "_" # append _ to enable internal hyperlink on rst files + op_name = ( + op_name + "_" + ) # append _ to enable internal hyperlink on rst files rows.append([i.dxil_opid, op_name, i.doc]) result = "\n\n" + format_rst_table(rows) + "\n\n" # Add detailed instruction information where available. - instrs = sorted(instrs, key=lambda v : v.name) + instrs = sorted(instrs, key=lambda v: v.name) for i in instrs: if i.remarks: result += i.name + "\n" + ("~" * len(i.name)) + "\n\n" + i.remarks + "\n\n" return result + "\n" + def get_valrules_rst(): "Create an rst table of validation rules instructions." db = get_db_dxil() rules = [i for i in db.val_rules if not i.is_disabled] - rules = sorted(rules, key=lambda v : v.name) + rules = sorted(rules, key=lambda v: v.name) rows = [] rows.append(["Rule Code", "Description"]) for i in rules: rows.append([i.name, i.doc]) return "\n\n" + format_rst_table(rows) + "\n\n" + def get_opsigs(): # Create a list of DXIL operation signatures, sorted by ID. db = get_db_dxil() instrs = [i for i in db.instr if i.is_dxil_op] - instrs = sorted(instrs, key=lambda v : v.dxil_opid) + instrs = sorted(instrs, key=lambda v: v.dxil_opid) # db_dxil already asserts that the numbering is dense. # Create the code to write out. code = "static const char *OpCodeSignatures[] = {\n" - for inst_idx,i in enumerate(instrs): - code += " \"(" + for inst_idx, i in enumerate(instrs): + code += ' "(' for operand in i.ops: - if operand.pos > 1: # skip 0 (the return value) and 1 (the opcode itself) + if operand.pos > 1: # skip 0 (the return value) and 1 (the opcode itself) code += operand.name if operand.pos < len(i.ops) - 1: code += "," - code += ")\"" + code += ')"' if inst_idx < len(instrs) - 1: code += "," code += " // " + i.name @@ -1003,61 +1283,88 @@ def get_opsigs(): code += "};\n" return code + shader_stage_to_ShaderKind = { - 'vertex': 'Vertex', - 'pixel': 'Pixel', - 'geometry': 'Geometry', - 'compute': 'Compute', - 'hull': 'Hull', - 'domain': 'Domain', - 'library': 'Library', - 'raygeneration': 'RayGeneration', - 'intersection': 'Intersection', - 'anyhit': 'AnyHit', - 'closesthit': 'ClosestHit', - 'miss': 'Miss', - 'callable': 'Callable', - 'mesh' : 'Mesh', - 'amplification' : 'Amplification', + "vertex": "Vertex", + "pixel": "Pixel", + "geometry": "Geometry", + "compute": "Compute", + "hull": "Hull", + "domain": "Domain", + "library": "Library", + "raygeneration": "RayGeneration", + "intersection": "Intersection", + "anyhit": "AnyHit", + "closesthit": "ClosestHit", + "miss": "Miss", + "callable": "Callable", + "mesh": "Mesh", + "amplification": "Amplification", } + def get_min_sm_and_mask_text(): db = get_db_dxil() instrs = [i for i in db.instr if i.is_dxil_op] - instrs = sorted(instrs, key=lambda v : (v.shader_model, v.shader_model_translated, v.shader_stages, v.dxil_opid)) + instrs = sorted( + instrs, + key=lambda v: ( + v.shader_model, + v.shader_model_translated, + v.shader_stages, + v.dxil_opid, + ), + ) last_model = None last_model_translated = None last_stage = None grouped_instrs = [] code = "" + def flush_instrs(grouped_instrs, last_model, last_model_translated, last_stage): if len(grouped_instrs) == 0: return "" - result = format_comment("// ", "Instructions: %s" % ", ".join([i.name + "=" + str(i.dxil_opid) for i in grouped_instrs])) - result += "if (" + build_range_code("op", [i.dxil_opid for i in grouped_instrs]) + ") {\n" + result = format_comment( + "// ", + "Instructions: %s" + % ", ".join([i.name + "=" + str(i.dxil_opid) for i in grouped_instrs]), + ) + result += ( + "if (" + + build_range_code("op", [i.dxil_opid for i in grouped_instrs]) + + ") {\n" + ) default = True - if last_model != (6,0): + if last_model != (6, 0): default = False if last_model_translated: result += " if (bWithTranslation) {\n" - result += " major = %d; minor = %d;\n } else {\n " % last_model_translated + result += ( + " major = %d; minor = %d;\n } else {\n " + % last_model_translated + ) result += " major = %d; minor = %d;\n" % last_model if last_model_translated: result += " }\n" if last_stage: default = False - result += " mask = %s;\n" % ' | '.join([ 'SFLAG(%s)' % shader_stage_to_ShaderKind[c] - for c in last_stage - ]) + result += " mask = %s;\n" % " | ".join( + ["SFLAG(%s)" % shader_stage_to_ShaderKind[c] for c in last_stage] + ) if default: # don't write these out, instead fall through return "" return result + " return;\n}\n" for i in instrs: - if ((i.shader_model, i.shader_model_translated, i.shader_stages) != - (last_model, last_model_translated, last_stage)): - code += flush_instrs(grouped_instrs, last_model, last_model_translated, last_stage) + if (i.shader_model, i.shader_model_translated, i.shader_stages) != ( + last_model, + last_model_translated, + last_stage, + ): + code += flush_instrs( + grouped_instrs, last_model, last_model_translated, last_stage + ) grouped_instrs = [] last_model = i.shader_model last_model_translated = i.shader_model_translated @@ -1066,48 +1373,67 @@ def flush_instrs(grouped_instrs, last_model, last_model_translated, last_stage): code += flush_instrs(grouped_instrs, last_model, last_model_translated, last_stage) return code + check_pSM_for_shader_stage = { - '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', - 'mesh': 'SK == DXIL::ShaderKind::Mesh', - 'amplification': 'SK == DXIL::ShaderKind::Amplification', + "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", + "mesh": "SK == DXIL::ShaderKind::Mesh", + "amplification": "SK == DXIL::ShaderKind::Amplification", } + def get_valopcode_sm_text(): db = get_db_dxil() instrs = [i for i in db.instr if i.is_dxil_op] - instrs = sorted(instrs, key=lambda v : (v.shader_model, v.shader_stages, v.dxil_opid)) + instrs = sorted( + instrs, key=lambda v: (v.shader_model, v.shader_stages, v.dxil_opid) + ) last_model = None last_stage = None grouped_instrs = [] code = "" + def flush_instrs(grouped_instrs, last_model, last_stage): if len(grouped_instrs) == 0: return "" - result = format_comment("// ", "Instructions: %s" % ", ".join([i.name + "=" + str(i.dxil_opid) for i in grouped_instrs])) - result += "if (" + build_range_code("op", [i.dxil_opid for i in grouped_instrs]) + ")\n" + result = format_comment( + "// ", + "Instructions: %s" + % ", ".join([i.name + "=" + str(i.dxil_opid) for i in grouped_instrs]), + ) + result += ( + "if (" + + build_range_code("op", [i.dxil_opid for i in grouped_instrs]) + + ")\n" + ) result += " return " model_cond = stage_cond = None - if last_model != (6,0): + if last_model != (6, 0): model_cond = "major > %d || (major == %d && minor >= %d)" % ( - last_model[0], last_model[0], last_model[1]) + 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]) + stage_cond = " || ".join( + [check_pSM_for_shader_stage[c] for c in last_stage] + ) if model_cond or stage_cond: - result += '\n && '.join( - ["(%s)" % expr for expr in (model_cond, stage_cond) if expr] ) + result += "\n && ".join( + ["(%s)" % expr for expr in (model_cond, stage_cond) if expr] + ) return result + ";\n" else: # don't write these out, instead fall through @@ -1124,97 +1450,144 @@ def flush_instrs(grouped_instrs, last_model, last_stage): code += "return true;\n" return code + def get_sigpoint_table(): db = get_db_dxil() gen = db_sigpoint_gen(db) return run_with_stdout(lambda: gen.print_sigpoint_table()) + def get_sigpoint_rst(): "Create an rst table for SigPointKind." db = get_db_dxil() - rows = [row[:] for row in db.sigpoint_table[:-1]] # Copy table - e = dict([(v.name, v) for v in db.enum_idx['SigPointKind'].values]) - rows[0] = ['ID'] + rows[0] + ['Description'] + rows = [row[:] for row in db.sigpoint_table[:-1]] # Copy table + e = dict([(v.name, v) for v in db.enum_idx["SigPointKind"].values]) + rows[0] = ["ID"] + rows[0] + ["Description"] for i in range(1, len(rows)): row = rows[i] v = e[row[0]] rows[i] = [v.value] + row + [v.doc] return "\n\n" + format_rst_table(rows) + "\n\n" + def get_sem_interpretation_enum_rst(): db = get_db_dxil() - rows = ([['ID', 'Name', 'Description']] + - [[v.value, v.name, v.doc] - for v in db.enum_idx['SemanticInterpretationKind'].values[:-1]]) + rows = [["ID", "Name", "Description"]] + [ + [v.value, v.name, v.doc] + for v in db.enum_idx["SemanticInterpretationKind"].values[:-1] + ] return "\n\n" + format_rst_table(rows) + "\n\n" + def get_sem_interpretation_table_rst(): db = get_db_dxil() return "\n\n" + format_rst_table(db.interpretation_table) + "\n\n" + def get_interpretation_table(): db = get_db_dxil() gen = db_sigpoint_gen(db) return run_with_stdout(lambda: gen.print_interpretation_table()) + highest_major = 6 highest_minor = 7 -highest_shader_models = {4:1, 5:1, 6:highest_minor} +highest_shader_models = {4: 1, 5: 1, 6: highest_minor} + def getShaderModels(): shader_models = [] for major, minor in highest_shader_models.items(): - for i in range(0, minor+1): + for i in range(0, minor + 1): shader_models.append(str(major) + "_" + str(i)) - return shader_models; + return shader_models + def get_highest_shader_model(): result = """static const unsigned kHighestMajor = %d; -static const unsigned kHighestMinor = %d;"""%(highest_major, highest_minor) +static const unsigned kHighestMinor = %d;""" % ( + highest_major, + highest_minor, + ) return result + def get_dxil_version_minor(): - return "const unsigned kDxilMinor = %d;"%highest_minor + return "const unsigned kDxilMinor = %d;" % highest_minor + def get_dxil_version_minor_int(): return highest_minor + def get_is_shader_model_plus(): result = "" - for i in range(0, highest_minor+1): - result += "bool IsSM%d%dPlus() const { return IsSMAtLeast(%d, %d); }\n"%(highest_major, i,highest_major, i) + for i in range(0, highest_minor + 1): + result += "bool IsSM%d%dPlus() const { return IsSMAtLeast(%d, %d); }\n" % ( + highest_major, + i, + highest_major, + i, + ) return result -profile_to_kind = {"ps":"Kind::Pixel", "vs":"Kind::Vertex", "gs":"Kind::Geometry", "hs":"5_0", "ds":"5_0", "cs":"4_0", "lib":"6_1", "ms":"6_5", "as":"6_5"} + +profile_to_kind = { + "ps": "Kind::Pixel", + "vs": "Kind::Vertex", + "gs": "Kind::Geometry", + "hs": "5_0", + "ds": "5_0", + "cs": "4_0", + "lib": "6_1", + "ms": "6_5", + "as": "6_5", +} + class shader_profile(object): "The profile description for a DXIL instruction" + def __init__(self, kind, kind_name, enum_name, start_sm, input_size, output_size): - self.kind = kind # position in parameter list + self.kind = kind # position in parameter list self.kind_name = kind_name self.enum_name = enum_name self.start_sm = start_sm self.input_size = input_size self.output_size = output_size + # kind is from DXIL::ShaderKind. -shader_profiles = [ shader_profile(0, "ps", "Kind::Pixel", "4_0", 32, 8), - shader_profile(1, "vs", "Kind::Vertex", "4_0", 32, 32), - shader_profile(2, "gs", "Kind::Geometry", "4_0", 32, 32), - shader_profile(3, "hs", "Kind::Hull", "5_0", 32, 32), - shader_profile(4, "ds", "Kind::Domain", "5_0", 32, 32), - shader_profile(5, "cs", "Kind::Compute", "4_0", 0,0), - shader_profile(6, "lib", "Kind::Library", "6_1", 32,32), - shader_profile(13, "ms", "Kind::Mesh", "6_5", 0,0), - shader_profile(14, "as", "Kind::Amplification", "6_5", 0,0), - ] +shader_profiles = [ + shader_profile(0, "ps", "Kind::Pixel", "4_0", 32, 8), + shader_profile(1, "vs", "Kind::Vertex", "4_0", 32, 32), + shader_profile(2, "gs", "Kind::Geometry", "4_0", 32, 32), + shader_profile(3, "hs", "Kind::Hull", "5_0", 32, 32), + shader_profile(4, "ds", "Kind::Domain", "5_0", 32, 32), + shader_profile(5, "cs", "Kind::Compute", "4_0", 0, 0), + shader_profile(6, "lib", "Kind::Library", "6_1", 32, 32), + shader_profile(13, "ms", "Kind::Mesh", "6_5", 0, 0), + shader_profile(14, "as", "Kind::Amplification", "6_5", 0, 0), +] + def getShaderProfiles(): # order match DXIL::ShaderKind. - profiles = (("ps", "4_0"), ("vs", "4_0"), ("gs", "4_0"), ("hs", "5_0"), ("ds", "5_0"), ("cs", "4_0"), ("lib", "6_1"), ("ms", "6_5"), ("as", "6_5")) - return profiles; + profiles = ( + ("ps", "4_0"), + ("vs", "4_0"), + ("gs", "4_0"), + ("hs", "5_0"), + ("ds", "5_0"), + ("cs", "4_0"), + ("lib", "6_1"), + ("ms", "6_5"), + ("as", "6_5"), + ) + return profiles + def get_shader_models(): result = "" @@ -1227,7 +1600,6 @@ def get_shader_models(): enum_name = profile.enum_name for major, minor in highest_shader_models.items(): - UAV_info = "true, true, UINT_MAX" if major > 5: pass @@ -1239,9 +1611,9 @@ def get_shader_models(): elif major == 5: UAV_info = "true, true, 64" - for i in range(0, minor+1): - sm = "%d_%d"%(major, i) - if (min_sm > sm): + for i in range(0, minor + 1): + sm = "%d_%d" % (major, i) + if min_sm > sm: continue input_size = profile.input_size @@ -1255,17 +1627,30 @@ def get_shader_models(): input_size = 16 output_size = 16 - sm_name = "%s_%s"%(kind_name,sm) - result += "SM(%s, %d, %d, \"%s\", %d, %d, %s),\n" % (enum_name, major, i, sm_name, input_size, output_size, UAV_info) + sm_name = "%s_%s" % (kind_name, sm) + result += 'SM(%s, %d, %d, "%s", %d, %d, %s),\n' % ( + enum_name, + major, + i, + sm_name, + input_size, + output_size, + UAV_info, + ) if kind_name == "lib": - result += "// lib_6_x is for offline linking only, and relaxes restrictions\n" - result += "SM(Kind::Library, 6, kOfflineMinor, \"lib_6_x\", 32, 32, true, true, UINT_MAX),\n" - - result += "// Values before Invalid must remain sorted by Kind, then Major, then Minor.\n" - result += "SM(Kind::Invalid, 0, 0, \"invalid\", 0, 0, false, false, 0),\n" + result += ( + "// lib_6_x is for offline linking only, and relaxes restrictions\n" + ) + result += 'SM(Kind::Library, 6, kOfflineMinor, "lib_6_x", 32, 32, true, true, UINT_MAX),\n' + + result += ( + "// Values before Invalid must remain sorted by Kind, then Major, then Minor.\n" + ) + result += 'SM(Kind::Invalid, 0, 0, "invalid", 0, 0, false, false, 0),\n' return result + def get_num_shader_models(): count = 0 for profile in shader_profiles: @@ -1277,10 +1662,9 @@ def get_num_shader_models(): enum_name = profile.enum_name for major, minor in highest_shader_models.items(): - - for i in range(0, minor+1): - sm = "%d_%d"%(major, i) - if (min_sm > sm): + for i in range(0, minor + 1): + sm = "%d_%d" % (major, i) + if min_sm > sm: continue count += 1 @@ -1289,10 +1673,11 @@ def get_num_shader_models(): count += 1 # for invalid shader_model. count += 1 - return "static const unsigned kNumShaderModels = %d;"%count + return "static const unsigned kNumShaderModels = %d;" % count + def build_shader_model_hash_idx_map(): - #must match get_shader_models. + # must match get_shader_models. result = "const static std::pair hashToIdxMap[] = {\n" count = 0 for profile in shader_profiles: @@ -1301,30 +1686,33 @@ def build_shader_model_hash_idx_map(): kind_name = profile.kind_name for major, minor in highest_shader_models.items(): - - for i in range(0, minor+1): - sm = "%d_%d"%(major, i) - if (min_sm > sm): + for i in range(0, minor + 1): + sm = "%d_%d" % (major, i) + if min_sm > sm: continue - sm_name = "%s_%s"%(kind_name,sm) - hash_v = kind << 16 | major << 8 | i; + sm_name = "%s_%s" % (kind_name, sm) + hash_v = kind << 16 | major << 8 | i result += "{%d,%d}, //%s\n" % (hash_v, count, sm_name) count += 1 if kind_name == "lib": - result += "// lib_6_x is for offline linking only, and relaxes restrictions\n" + result += ( + "// lib_6_x is for offline linking only, and relaxes restrictions\n" + ) major = 6 - #static const unsigned kOfflineMinor = 0xF; + # static const unsigned kOfflineMinor = 0xF; i = 15 - hash_v = kind << 16 | major << 8 | i; + hash_v = kind << 16 | major << 8 | i result += "{%d,%d},//%s\n" % (hash_v, count, "lib_6_x") count += 1 result += "};\n" return result + def get_validation_version(): - result = """// 1.0 is the first validator. + result = ( + """// 1.0 is the first validator. // 1.1 adds: // - ILDN container part support // 1.2 adds: @@ -1343,48 +1731,54 @@ def get_validation_version(): // - DXR 1.1 & RayQuery support *pMajor = 1; *pMinor = %d; -""" % highest_minor +""" + % highest_minor + ) return result + def get_target_profiles(): - result = "HelpText<\"Set target profile. \\n" + result = 'HelpText<"Set target profile. \\n' result += "\\t: " profiles = getShaderProfiles() shader_models = getShaderModels() - base_sm = "%d_0"%highest_major + base_sm = "%d_0" % highest_major for profile, min_sm in profiles: for shader_model in shader_models: - if (base_sm > shader_model): + if base_sm > shader_model: continue - if (min_sm > shader_model): + if min_sm > shader_model: continue - result += "%s_%s, "%(profile,shader_model) + result += "%s_%s, " % (profile, shader_model) result += "\\n\\t\\t " - result += "\">;" + result += '">;' return result + def get_min_validator_version(): result = "" - for i in range(0, highest_minor+1): - result += "case %d:\n"%i - result += " ValMinor = %d;\n"%i + for i in range(0, highest_minor + 1): + result += "case %d:\n" % i + result += " ValMinor = %d;\n" % i result += " break;\n" return result + def get_dxil_version(): result = "" - for i in range(0, highest_minor+1): - result += "case %d:\n"%i - result += " DxilMinor = %d;\n"%i + for i in range(0, highest_minor + 1): + result += "case %d:\n" % i + result += " DxilMinor = %d;\n" % i result += " break;\n" result += "case kOfflineMinor: // Always update this to highest dxil version\n" - result += " DxilMinor = %d;\n"%highest_minor + result += " DxilMinor = %d;\n" % highest_minor result += " break;\n" return result + def get_shader_model_get(): # const static std::pair hashToIdxMap[] = {}; result = build_shader_model_hash_idx_map() @@ -1396,52 +1790,63 @@ def get_shader_model_get(): result += "return &ms_ShaderModels[it->second];" return result + def get_shader_model_by_name(): result = "" - for i in range(2, highest_minor+1): - result += "case '%d':\n"%i - result += " if (Major == %d) {\n"%highest_major - result += " Minor = %d;\n"%i + for i in range(2, highest_minor + 1): + result += "case '%d':\n" % i + result += " if (Major == %d) {\n" % highest_major + result += " Minor = %d;\n" % i result += " break;\n" result += " }\n" result += "else return GetInvalid();\n" return result + def get_is_valid_for_dxil(): result = "" - for i in range(0, highest_minor+1): - result += "case %d:\n"%i + for i in range(0, highest_minor + 1): + result += "case %d:\n" % i return result + def RunCodeTagUpdate(file_path): import os import CodeTags + print(" ... updating " + file_path) args = [file_path, file_path + ".tmp"] result = CodeTags.main(args) if result != 0: print(" ... error: %d" % result) else: - with open(file_path, 'rt') as f: + with open(file_path, "rt") as f: before = f.read() - with open(file_path + ".tmp", 'rt') as f: + with open(file_path + ".tmp", "rt") as f: after = f.read() if before == after: print(" --- no changes found") else: print(" +++ changes found, updating file") - with open(file_path, 'wt') as f: + with open(file_path, "wt") as f: f.write(after) os.remove(file_path + ".tmp") + if __name__ == "__main__": - parser = argparse.ArgumentParser(description="Generate code to handle instructions.") - parser.add_argument("-gen", choices=["docs-ref", "docs-spec", "inst-header", "enums", "oloads", "valfns"], help="Output type to generate.") + parser = argparse.ArgumentParser( + description="Generate code to handle instructions." + ) + parser.add_argument( + "-gen", + choices=["docs-ref", "docs-spec", "inst-header", "enums", "oloads", "valfns"], + help="Output type to generate.", + ) parser.add_argument("-update-files", action="store_const", const=True) args = parser.parse_args() - db = get_db_dxil() # used by all generators, also handy to have it run validation + db = get_db_dxil() # used by all generators, also handy to have it run validation if args.gen == "docs-ref": gen = db_docsref_gen(db) @@ -1449,7 +1854,10 @@ def RunCodeTagUpdate(file_path): if args.gen == "docs-spec": import os, docutils.core - assert "HLSL_SRC_DIR" in os.environ, "Environment variable HLSL_SRC_DIR is not defined" + + assert ( + "HLSL_SRC_DIR" in os.environ + ), "Environment variable HLSL_SRC_DIR is not defined" hlsl_src_dir = os.environ["HLSL_SRC_DIR"] spec_file = os.path.abspath(os.path.join(hlsl_src_dir, "docs/DXIL.rst")) with open(spec_file) as f: @@ -1476,29 +1884,31 @@ def RunCodeTagUpdate(file_path): import CodeTags import os - assert "HLSL_SRC_DIR" in os.environ, "Environment variable HLSL_SRC_DIR is not defined" + assert ( + "HLSL_SRC_DIR" in os.environ + ), "Environment variable HLSL_SRC_DIR is not defined" hlsl_src_dir = os.environ["HLSL_SRC_DIR"] pj = lambda *parts: os.path.abspath(os.path.join(*parts)) files = [ - 'docs/DXIL.rst', - 'lib/DXIL/DxilOperations.cpp', - 'lib/DXIL/DxilShaderModel.cpp', - 'include/dxc/DXIL/DxilConstants.h', - 'include/dxc/DXIL/DxilShaderModel.h', - 'include/dxc/HLSL/DxilValidation.h', - 'include/dxc/Support/HLSLOptions.td', - 'include/dxc/DXIL/DxilInstructions.h', - 'lib/HLSL/DxcOptimizer.cpp', - 'lib/DxilPIXPasses/DxilPIXPasses.cpp', - 'lib/HLSL/DxilValidation.cpp', - 'tools/clang/lib/Sema/gen_intrin_main_tables_15.h', - 'include/dxc/HlslIntrinsicOp.h', - 'tools/clang/tools/dxcompiler/dxcdisassembler.cpp', - 'include/dxc/DXIL/DxilSigPoint.inl', - 'include/dxc/DXIL/DxilCounters.h', - 'lib/DXIL/DxilCounters.cpp', - 'lib/DXIL/DxilMetadataHelper.cpp', - 'include/dxc/DxilContainer/RDAT_LibraryTypes.inl', - ] + "docs/DXIL.rst", + "lib/DXIL/DxilOperations.cpp", + "lib/DXIL/DxilShaderModel.cpp", + "include/dxc/DXIL/DxilConstants.h", + "include/dxc/DXIL/DxilShaderModel.h", + "include/dxc/HLSL/DxilValidation.h", + "include/dxc/Support/HLSLOptions.td", + "include/dxc/DXIL/DxilInstructions.h", + "lib/HLSL/DxcOptimizer.cpp", + "lib/DxilPIXPasses/DxilPIXPasses.cpp", + "lib/HLSL/DxilValidation.cpp", + "tools/clang/lib/Sema/gen_intrin_main_tables_15.h", + "include/dxc/HlslIntrinsicOp.h", + "tools/clang/tools/dxcompiler/dxcdisassembler.cpp", + "include/dxc/DXIL/DxilSigPoint.inl", + "include/dxc/DXIL/DxilCounters.h", + "lib/DXIL/DxilCounters.cpp", + "lib/DXIL/DxilMetadataHelper.cpp", + "include/dxc/DxilContainer/RDAT_LibraryTypes.inl", + ] for relative_file_path in files: RunCodeTagUpdate(pj(hlsl_src_dir, relative_file_path)) diff --git a/utils/hct/hctdb_test.py b/utils/hct/hctdb_test.py index b2e9fef91d..a221b2ed87 100644 --- a/utils/hct/hctdb_test.py +++ b/utils/hct/hctdb_test.py @@ -7,17 +7,21 @@ import xml.etree.ElementTree as ET import argparse -parser = argparse.ArgumentParser(description="contains information about dxil op test cases.") -parser.add_argument('mode', help="'gen-xml' or 'info'") +parser = argparse.ArgumentParser( + description="contains information about dxil op test cases." +) +parser.add_argument("mode", help="'gen-xml' or 'info'") g_db_dxil = None + def get_db_dxil(): global g_db_dxil if g_db_dxil is None: g_db_dxil = db_dxil() return g_db_dxil + """ This class represents a test case for instructions for driver testings @@ -37,9 +41,20 @@ def get_db_dxil(): shader_text: hlsl file that is used for testing dxil op """ + class test_case(object): - def __init__(self, test_name, insts, validation_type, validation_tolerance, - input_lists, output_lists, shader_target, shader_text, **kwargs): + def __init__( + self, + test_name, + insts, + validation_type, + validation_tolerance, + input_lists, + output_lists, + shader_target, + shader_text, + **kwargs + ): self.test_name = test_name self.validation_type = validation_type self.validation_tolerance = validation_tolerance @@ -47,51 +62,122 @@ def __init__(self, test_name, insts, validation_type, validation_tolerance, self.output_lists = output_lists self.shader_target = shader_target self.shader_text = shader_text - self.insts = insts # list of instructions each test case cover - self.warp_version = -1 # known warp version that works + self.insts = insts # list of instructions each test case cover + self.warp_version = -1 # known warp version that works self.shader_arguments = "" - for k,v in kwargs.items(): + for k, v in kwargs.items(): setattr(self, k, v) + # Wrapper for each DXIL instruction class inst_node(object): def __init__(self, inst): self.inst = inst self.test_cases = [] # list of test_case -def add_test_case(test_name, inst_names, validation_type, validation_tolerance, - input_lists, output_lists, shader_target, shader_text, **kwargs): + +def add_test_case( + test_name, + inst_names, + validation_type, + validation_tolerance, + input_lists, + output_lists, + shader_target, + shader_text, + **kwargs +): insts = [] for inst_name in inst_names: - assert (inst_name in g_instruction_nodes) + assert inst_name in g_instruction_nodes insts += [g_instruction_nodes[inst_name].inst] - case = test_case(test_name, insts, validation_type, - validation_tolerance, input_lists, output_lists, - shader_target, shader_text, **kwargs) + case = test_case( + test_name, + insts, + validation_type, + validation_tolerance, + input_lists, + output_lists, + shader_target, + shader_text, + **kwargs + ) g_test_cases[test_name] = case # update instruction nodes for inst_name in inst_names: g_instruction_nodes[inst_name].test_cases += [case] -def add_test_case_int(test_name, inst_names, validation_type, validation_tolerance, - input_lists, output_lists, shader_key, shader_op_name, **kwargs): - add_test_case(test_name, inst_names, validation_type, validation_tolerance, - input_lists, output_lists, "cs_6_0", get_shader_text(shader_key, shader_op_name), **kwargs) + +def add_test_case_int( + test_name, + inst_names, + validation_type, + validation_tolerance, + input_lists, + output_lists, + shader_key, + shader_op_name, + **kwargs +): + add_test_case( + test_name, + inst_names, + validation_type, + validation_tolerance, + input_lists, + output_lists, + "cs_6_0", + get_shader_text(shader_key, shader_op_name), + **kwargs + ) input_lists_16, output_lists_16 = input_lists, output_lists if "input_16" in kwargs: input_lists_16 = kwargs["input_16"] if "output_16" in kwargs: output_lists_16 = kwargs["output_16"] - add_test_case(test_name + "Bit16", inst_names, validation_type, validation_tolerance, - input_lists_16, output_lists_16, "cs_6_2", get_shader_text(shader_key.replace("int","int16_t"), shader_op_name), - shader_arguments="-enable-16bit-types", **kwargs) - -def add_test_case_float_half(test_name, inst_names, validation_type, validation_tolerance, - float_input_lists, float_output_lists, shader_key, shader_op_name, **kwargs): - add_test_case(test_name, inst_names, validation_type, validation_tolerance, - float_input_lists, float_output_lists, "cs_6_0", get_shader_text(shader_key, shader_op_name), **kwargs) + add_test_case( + test_name + "Bit16", + inst_names, + validation_type, + validation_tolerance, + input_lists_16, + output_lists_16, + "cs_6_2", + get_shader_text(shader_key.replace("int", "int16_t"), shader_op_name), + shader_arguments="-enable-16bit-types", + **kwargs + ) + + +def add_test_case_float_half( + test_name, + inst_names, + validation_type, + validation_tolerance, + float_input_lists, + float_output_lists, + shader_key, + shader_op_name, + **kwargs +): + add_test_case( + test_name, + inst_names, + validation_type, + validation_tolerance, + float_input_lists, + float_output_lists, + "cs_6_0", + get_shader_text(shader_key, shader_op_name), + **kwargs + ) # if half test cases are different from float input lists, use those lists instead for half testings - half_input_lists, half_output_lists, half_validation_type, half_validation_tolerance = float_input_lists, float_output_lists, validation_type, validation_tolerance + ( + half_input_lists, + half_output_lists, + half_validation_type, + half_validation_tolerance, + ) = (float_input_lists, float_output_lists, validation_type, validation_tolerance) if "half_inputs" in kwargs: half_input_lists = kwargs["half_inputs"] if "half_outputs" in kwargs: @@ -102,23 +188,70 @@ def add_test_case_float_half(test_name, inst_names, validation_type, validation_ half_validation_tolerance = kwargs["half_validation_tolerance"] # skip relative error test check for half for now if validation_type != "Relative": - add_test_case(test_name + "Half", inst_names, half_validation_type, half_validation_tolerance, - half_input_lists, half_output_lists, "cs_6_2", - get_shader_text(shader_key.replace("float","half"), shader_op_name), shader_arguments="-enable-16bit-types", **kwargs) - -def add_test_case_denorm(test_name, inst_names, validation_type, validation_tolerance, input_lists, - output_lists_ftz, output_lists_preserve, shader_target, shader_text, **kwargs): - add_test_case(test_name + "FTZ", inst_names, validation_type, validation_tolerance, input_lists, - output_lists_ftz, shader_target, shader_text, shader_arguments="-denorm ftz") - add_test_case(test_name + "Preserve", inst_names, validation_type, validation_tolerance, input_lists, - output_lists_preserve, shader_target, shader_text, shader_arguments="-denorm preserve") + add_test_case( + test_name + "Half", + inst_names, + half_validation_type, + half_validation_tolerance, + half_input_lists, + half_output_lists, + "cs_6_2", + get_shader_text(shader_key.replace("float", "half"), shader_op_name), + shader_arguments="-enable-16bit-types", + **kwargs + ) + + +def add_test_case_denorm( + test_name, + inst_names, + validation_type, + validation_tolerance, + input_lists, + output_lists_ftz, + output_lists_preserve, + shader_target, + shader_text, + **kwargs +): + add_test_case( + test_name + "FTZ", + inst_names, + validation_type, + validation_tolerance, + input_lists, + output_lists_ftz, + shader_target, + shader_text, + shader_arguments="-denorm ftz", + ) + add_test_case( + test_name + "Preserve", + inst_names, + validation_type, + validation_tolerance, + input_lists, + output_lists_preserve, + shader_target, + shader_text, + shader_arguments="-denorm preserve", + ) # we can expect the same output for "any" and "preserve" mode. We should make sure that for validation zero are accepted outputs for denormal outputs. - add_test_case(test_name + "Any", inst_names, validation_type, validation_tolerance, input_lists, - output_lists_preserve + output_lists_ftz, shader_target, shader_text, shader_arguments="-denorm any") + add_test_case( + test_name + "Any", + inst_names, + validation_type, + validation_tolerance, + input_lists, + output_lists_preserve + output_lists_ftz, + shader_target, + shader_text, + shader_arguments="-denorm any", + ) g_shader_texts = { - "unary int": ''' struct SUnaryIntOp { + "unary int": """ struct SUnaryIntOp { int input; int output; }; @@ -128,9 +261,8 @@ def add_test_case_denorm(test_name, inst_names, validation_type, validation_tole SUnaryIntOp l = g_buf[GI]; l.output = %s(l.input); g_buf[GI] = l; - };''', - - "unary int16_t": ''' struct SUnaryInt16Op { + };""", + "unary int16_t": """ struct SUnaryInt16Op { int16_t input; int16_t output; }; @@ -140,9 +272,8 @@ def add_test_case_denorm(test_name, inst_names, validation_type, validation_tole SUnaryInt16Op l = g_buf[GI]; l.output = %s(l.input); g_buf[GI] = l; - };''', - - "unary uint": ''' struct SUnaryUintOp { + };""", + "unary uint": """ struct SUnaryUintOp { uint input; uint output; }; @@ -152,9 +283,8 @@ def add_test_case_denorm(test_name, inst_names, validation_type, validation_tole SUnaryUintOp l = g_buf[GI]; l.output = %s(l.input); g_buf[GI] = l; - };''', - - "unary uint16_t": ''' struct SUnaryUint16Op { + };""", + "unary uint16_t": """ struct SUnaryUint16Op { uint16_t input; uint16_t output; }; @@ -164,9 +294,8 @@ def add_test_case_denorm(test_name, inst_names, validation_type, validation_tole SUnaryUint16Op l = g_buf[GI]; l.output = %s(l.input); g_buf[GI] = l; - };''', - - "unary float": ''' struct SUnaryFPOp { + };""", + "unary float": """ struct SUnaryFPOp { float input; float output; }; @@ -176,9 +305,8 @@ def add_test_case_denorm(test_name, inst_names, validation_type, validation_tole SUnaryFPOp l = g_buf[GI]; l.output = %s(l.input); g_buf[GI] = l; - };''', - - "unary float bool": ''' struct SUnaryFPOp { + };""", + "unary float bool": """ struct SUnaryFPOp { float input; float output; }; @@ -191,9 +319,8 @@ def add_test_case_denorm(test_name, inst_names, validation_type, validation_tole else l.output = 0; g_buf[GI] = l; - };''', - - "unary half": ''' struct SUnaryFPOp { + };""", + "unary half": """ struct SUnaryFPOp { float16_t input; float16_t output; }; @@ -203,9 +330,8 @@ def add_test_case_denorm(test_name, inst_names, validation_type, validation_tole SUnaryFPOp l = g_buf[GI]; l.output = %s(l.input); g_buf[GI] = l; - };''', - - "unary half bool": ''' struct SUnaryFPOp { + };""", + "unary half bool": """ struct SUnaryFPOp { float16_t input; float16_t output; }; @@ -218,9 +344,8 @@ def add_test_case_denorm(test_name, inst_names, validation_type, validation_tole else l.output = 0; g_buf[GI] = l; - };''', - - "binary int": ''' struct SBinaryIntOp { + };""", + "binary int": """ struct SBinaryIntOp { int input1; int input2; int output1; @@ -232,9 +357,8 @@ def add_test_case_denorm(test_name, inst_names, validation_type, validation_tole SBinaryIntOp l = g_buf[GI]; l.output1 = l.input1 %s l.input2; g_buf[GI] = l; - };''', - - "binary int16_t": ''' struct SBinaryInt16Op { + };""", + "binary int16_t": """ struct SBinaryInt16Op { int16_t input1; int16_t input2; int16_t output1; @@ -246,9 +370,8 @@ def add_test_case_denorm(test_name, inst_names, validation_type, validation_tole SBinaryInt16Op l = g_buf[GI]; l.output1 = l.input1 %s l.input2; g_buf[GI] = l; - };''', - - "binary int call": ''' struct SBinaryIntOp { + };""", + "binary int call": """ struct SBinaryIntOp { int input1; int input2; int output1; @@ -260,9 +383,8 @@ def add_test_case_denorm(test_name, inst_names, validation_type, validation_tole SBinaryIntOp l = g_buf[GI]; l.output1 = %s(l.input1,l.input2); g_buf[GI] = l; - };''', - - "binary int16_t call": ''' struct SBinaryInt16Op { + };""", + "binary int16_t call": """ struct SBinaryInt16Op { int16_t input1; int16_t input2; int16_t output1; @@ -274,9 +396,8 @@ def add_test_case_denorm(test_name, inst_names, validation_type, validation_tole SBinaryInt16Op l = g_buf[GI]; l.output1 = %s(l.input1,l.input2); g_buf[GI] = l; - };''', - - "binary uint": ''' struct SBinaryUintOp { + };""", + "binary uint": """ struct SBinaryUintOp { uint input1; uint input2; uint output1; @@ -288,9 +409,8 @@ def add_test_case_denorm(test_name, inst_names, validation_type, validation_tole SBinaryUintOp l = g_buf[GI]; l.output1 = l.input1 %s l.input2; g_buf[GI] = l; - };''', - - "binary uint16_t": ''' struct SBinaryUint16Op { + };""", + "binary uint16_t": """ struct SBinaryUint16Op { uint16_t input1; uint16_t input2; uint16_t output1; @@ -302,9 +422,8 @@ def add_test_case_denorm(test_name, inst_names, validation_type, validation_tole SBinaryUint16Op l = g_buf[GI]; l.output1 = l.input1 %s l.input2; g_buf[GI] = l; - };''', - - "binary uint call": ''' struct SBinaryUintOp { + };""", + "binary uint call": """ struct SBinaryUintOp { uint input1; uint input2; uint output1; @@ -316,9 +435,8 @@ def add_test_case_denorm(test_name, inst_names, validation_type, validation_tole SBinaryUintOp l = g_buf[GI]; l.output1 = %s(l.input1,l.input2); g_buf[GI] = l; - };''', - - "binary uint16_t call": ''' struct SBinaryUint16Op { + };""", + "binary uint16_t call": """ struct SBinaryUint16Op { uint16_t input1; uint16_t input2; uint16_t output1; @@ -330,9 +448,8 @@ def add_test_case_denorm(test_name, inst_names, validation_type, validation_tole SBinaryUint16Op l = g_buf[GI]; l.output1 = %s(l.input1,l.input2); g_buf[GI] = l; - };''', - - "binary float": ''' struct SBinaryFPOp { + };""", + "binary float": """ struct SBinaryFPOp { float input1; float input2; float output1; @@ -344,9 +461,8 @@ def add_test_case_denorm(test_name, inst_names, validation_type, validation_tole SBinaryFPOp l = g_buf[GI]; l.output1 = l.input1 %s l.input2; g_buf[GI] = l; - };''', - - "binary float call": ''' struct SBinaryFPOp { + };""", + "binary float call": """ struct SBinaryFPOp { float input1; float input2; float output1; @@ -358,9 +474,8 @@ def add_test_case_denorm(test_name, inst_names, validation_type, validation_tole SBinaryFPOp l = g_buf[GI]; l.output1 = %s(l.input1,l.input2); g_buf[GI] = l; - };''', - - "binary half": ''' struct SBinaryFPOp { + };""", + "binary half": """ struct SBinaryFPOp { half input1; half input2; half output1; @@ -372,9 +487,8 @@ def add_test_case_denorm(test_name, inst_names, validation_type, validation_tole SBinaryFPOp l = g_buf[GI]; l.output1 = l.input1 %s l.input2; g_buf[GI] = l; - };''', - - "binary half call": ''' struct SBinaryFPOp { + };""", + "binary half call": """ struct SBinaryFPOp { half input1; half input2; half output1; @@ -386,9 +500,8 @@ def add_test_case_denorm(test_name, inst_names, validation_type, validation_tole SBinaryFPOp l = g_buf[GI]; l.output1 = %s(l.input1,l.input2); g_buf[GI] = l; - };''', - - "tertiary int": ''' struct STertiaryIntOp { + };""", + "tertiary int": """ struct STertiaryIntOp { int input1; int input2; int input3; @@ -400,9 +513,8 @@ def add_test_case_denorm(test_name, inst_names, validation_type, validation_tole STertiaryIntOp l = g_buf[GI]; l.output = %s(l.input1, l.input2, l.input3); g_buf[GI] = l; - };''', - - "tertiary int16_t": ''' struct STertiaryInt16Op { + };""", + "tertiary int16_t": """ struct STertiaryInt16Op { int16_t input1; int16_t input2; int16_t input3; @@ -414,9 +526,8 @@ def add_test_case_denorm(test_name, inst_names, validation_type, validation_tole STertiaryInt16Op l = g_buf[GI]; l.output = %s(l.input1, l.input2, l.input3); g_buf[GI] = l; - };''', - - "tertiary uint": ''' struct STertiaryUintOp { + };""", + "tertiary uint": """ struct STertiaryUintOp { uint input1; uint input2; uint input3; @@ -428,9 +539,8 @@ def add_test_case_denorm(test_name, inst_names, validation_type, validation_tole STertiaryUintOp l = g_buf[GI]; l.output = %s(l.input1, l.input2, l.input3); g_buf[GI] = l; - };''', - - "tertiary uint16_t": ''' struct STertiaryUint16Op { + };""", + "tertiary uint16_t": """ struct STertiaryUint16Op { uint16_t input1; uint16_t input2; uint16_t input3; @@ -442,9 +552,8 @@ def add_test_case_denorm(test_name, inst_names, validation_type, validation_tole STertiaryUint16Op l = g_buf[GI]; l.output = %s(l.input1, l.input2, l.input3); g_buf[GI] = l; - };''', - - "tertiary float": ''' struct STertiaryFloatOp { + };""", + "tertiary float": """ struct STertiaryFloatOp { float input1; float input2; float input3; @@ -456,8 +565,8 @@ def add_test_case_denorm(test_name, inst_names, validation_type, validation_tole STertiaryFloatOp l = g_buf[GI]; l.output = %s(l.input1, l.input2, l.input3); g_buf[GI] = l; - };''', - 'tertiary half': ''' struct STertiaryHalfOp { + };""", + "tertiary half": """ struct STertiaryHalfOp { half input1; half input2; half input3; @@ -469,8 +578,8 @@ def add_test_case_denorm(test_name, inst_names, validation_type, validation_tole STertiaryHalfOp l = g_buf[GI]; l.output = %s(l.input1, l.input2, l.input3); g_buf[GI] = l; - };''', - "wave op int" :''' struct PerThreadData { + };""", + "wave op int": """ struct PerThreadData { uint firstLaneId; uint laneIndex; int mask; @@ -490,8 +599,8 @@ def add_test_case_denorm(test_name, inst_names, validation_type, validation_tole pts.output = %s(pts.input); } g_sb[GI] = pts; - };''', - "wave op uint" :''' struct PerThreadData { + };""", + "wave op uint": """ struct PerThreadData { uint firstLaneId; uint laneIndex; int mask; @@ -511,8 +620,8 @@ def add_test_case_denorm(test_name, inst_names, validation_type, validation_tole pts.output = %s(pts.input); } g_sb[GI] = pts; - };''', - "wave op int count": ''' struct PerThreadData { + };""", + "wave op int count": """ struct PerThreadData { uint firstLaneId; uint laneIndex; int mask; @@ -532,8 +641,8 @@ def add_test_case_denorm(test_name, inst_names, validation_type, validation_tole pts.output = %s(pts.input > 3); } g_sb[GI] = pts; - };''', - "wave op multi prefix int": ''' struct ThreadData { + };""", + "wave op multi prefix int": """ struct ThreadData { uint key; uint firstLaneId; uint laneId; @@ -555,8 +664,8 @@ def add_test_case_denorm(test_name, inst_names, validation_type, validation_tole data.result = %s(data.value, mask); } g_buffer[id] = data; - }''', - "wave op multi prefix uint": ''' struct ThreadData { + }""", + "wave op multi prefix uint": """ struct ThreadData { uint key; uint firstLaneId; uint laneId; @@ -578,23 +687,45 @@ def add_test_case_denorm(test_name, inst_names, validation_type, validation_tole data.result = %s(data.value, mask); } g_buffer[id] = data; - }''' + }""", } + def get_shader_text(op_type, op_call): - assert(op_type in g_shader_texts) + assert op_type in g_shader_texts if op_type.startswith("wave op"): return g_shader_texts[op_type] % (op_call, op_call) return g_shader_texts[op_type] % (op_call) -g_denorm_tests = ["FAddDenormAny", "FAddDenormFTZ", "FAddDenormPreserve", - "FSubDenormAny", "FSubDenormFTZ", "FSubDenormPreserve", - "FMulDenormAny", "FMulDenormFTZ", "FMulDenormPreserve", - "FDivDenormAny", "FDivDenormFTZ", "FDivDenormPreserve", - "FMadDenormAny", "FMadDenormFTZ", "FMadDenormPreserve", - "FAbsDenormAny", "FAbsDenormFTZ", "FAbsDenormPreserve", - "FMinDenormAny", "FMinDenormFTZ", "FMinDenormPreserve", - "FMaxDenormAny", "FMaxDenormFTZ", "FMaxDenormPreserve"] + +g_denorm_tests = [ + "FAddDenormAny", + "FAddDenormFTZ", + "FAddDenormPreserve", + "FSubDenormAny", + "FSubDenormFTZ", + "FSubDenormPreserve", + "FMulDenormAny", + "FMulDenormFTZ", + "FMulDenormPreserve", + "FDivDenormAny", + "FDivDenormFTZ", + "FDivDenormPreserve", + "FMadDenormAny", + "FMadDenormFTZ", + "FMadDenormPreserve", + "FAbsDenormAny", + "FAbsDenormFTZ", + "FAbsDenormPreserve", + "FMinDenormAny", + "FMinDenormFTZ", + "FMinDenormPreserve", + "FMaxDenormAny", + "FMaxDenormFTZ", + "FMaxDenormPreserve", +] + + # This is a collection of test case for driver tests per instruction # Warning: For test cases, when you want to pass in signed 32-bit integer, # make sure to pass in negative numbers with decimal values instead of hexadecimal representation. @@ -602,202 +733,973 @@ def get_shader_text(op_type, op_call): # For half values, hex is preferable since the test framework will read string as float values # and convert them to float16, possibly losing precision. The test will read hex values as it is. def add_test_cases(): - nan = float('nan') - p_inf = float('inf') - n_inf = float('-inf') - p_denorm = float('1e-38') - n_denorm = float('-1e-38') + nan = float("nan") + p_inf = float("inf") + n_inf = float("-inf") + p_denorm = float("1e-38") + n_denorm = float("-1e-38") # Unary Float - add_test_case_float_half('Sin', ['Sin'], 'Epsilon', 0.0008, [[ - 'NaN', '-Inf', '-denorm', '-0', '0', 'denorm', 'Inf', '-314.16', - '314.16' - ]], [[ - 'NaN', 'NaN', '-0', '-0', '0', '0', 'NaN', '-0.0007346401', - '0.0007346401' - ]], "unary float", "sin", half_validation_tolerance=0.003, half_inputs=[[ - 'NaN', '-Inf', '-denorm', '-0', '0', 'denorm', 'Inf', - '0.6279297', '1.255859', '1.884766', '2.511719', '3.140625', - '3.769531', '4.398438', '5.023438', '5.652344', '6.281250' - ]], half_outputs=[[ - 'NaN', 'NaN', '-0', '-0', '0', '0', 'NaN', - '0.58747065', '0.95081574', '0.95111507', '0.58904284', '0.00096773', - '-0.58747751', '-0.95112079', '-0.95201313', '-0.58982444', '-0.00193545' - ]]) - add_test_case_float_half('Cos', ['Cos'], 'Epsilon', 0.0008, [[ - 'NaN', '-Inf', '-denorm', '-0', '0', 'denorm', 'Inf', '-314.16', - '314.16' - ]], [[ - 'NaN', 'NaN', '1.0', '1.0', '1.0', '1.0', 'NaN', '0.99999973015', - '0.99999973015' - ]], "unary float", "cos", half_validation_tolerance=0.003, half_inputs=[[ - 'NaN', '-Inf', '-denorm', '-0', '0', 'denorm', 'Inf', - '0.6279297', '1.255859', '1.884766', '2.511719', '3.140625', - '3.769531', '4.398438', '5.023438', '5.652344', '6.281250' - ]], half_outputs=[[ - 'NaN', 'NaN', '1.0', '1.0', '1.0', '1.0', 'NaN', - '0.80924553', '0.30975693', '-0.30883664', '-0.80810183', '-0.99999952', - '-0.80924052', '-0.30881903', '0.30605716', '0.80753154', '0.99999809' - ]]) - add_test_case_float_half('Tan', ['Tan'], 'Epsilon', 0.0008, [[ - 'NaN', '-Inf', '-denorm', '-0', '0', 'denorm', 'Inf', '-314.16', - '314.16' - ]], [[ - 'NaN', 'NaN', '-0.0', '-0.0', '0.0', '0.0', 'NaN', '-0.000735', - '0.000735' - ]], "unary float", "tan", half_validation_tolerance=0.016, half_inputs=[[ - 'NaN', '-Inf', '-denorm', '-0', '0', 'denorm', 'Inf', - '0.6279297', '1.255859', '1.884766', '2.511719', '3.140625', - '3.769531', '4.398438', '5.652344', '6.281250' - ]], half_outputs=[[ - 'NaN', 'NaN', '-0', '-0', '0', '0', 'NaN', - '0.72594857', '3.06955433', '-3.07967043', '-0.72892153', '-0.00096773', - '0.72596157', '3.07986474', '-0.7304042', '-0.00193546' - ]]) - add_test_case_float_half('Hcos', ['Hcos'], 'Epsilon', 0.0008, - [['NaN', '-Inf', '-denorm', '-0', '0', 'denorm', 'Inf', '1', '-1']], [[ - 'NaN', 'Inf', '1.0', '1.0', '1.0', '1.0', 'Inf', '1.543081', - '1.543081' - ]], "unary float", "cosh", half_validation_type='ulp', half_validation_tolerance=2) - add_test_case_float_half('Hsin', ['Hsin'], 'Epsilon', 0.0008, - [['NaN', '-Inf', '-denorm', '-0', '0', 'denorm', 'Inf', '1', '-1']], [[ - 'NaN', '-Inf', '0.0', '0.0', '0.0', '0.0', 'Inf', '1.175201', - '-1.175201' - ]], "unary float", "sinh") - add_test_case_float_half('Htan', ['Htan'], 'Epsilon', 0.0008, - [['NaN', '-Inf', '-denorm', '-0', '0', 'denorm', 'Inf', '1', '-1']], [[ - 'NaN', '-1', '-0.0', '-0.0', '0.0', '0.0', '1', '0.761594', - '-0.761594' - ]], "unary float", "tanh", warp_version=16202) - add_test_case_float_half('Acos', ['Acos'], 'Epsilon', 0.0008, [[ - 'NaN', '-Inf', '-denorm', '-0', '0', 'denorm', 'Inf', '1', '-1', '1.5', - '-1.5' - ]], [[ - 'NaN', 'NaN', '1.570796', '1.570796', '1.570796', '1.570796', 'NaN', - '0', '3.1415926', 'NaN', 'NaN' - ]], "unary float", "acos") - add_test_case_float_half('Asin', ['Asin'], 'Epsilon', 0.0008, [[ - 'NaN', '-Inf', '-denorm', '-0', '0', 'denorm', 'Inf', '1', '-1', '1.5', - '-1.5' - ]], [[ - 'NaN', 'NaN', '0.0', '0.0', '0.0', '0.0', 'NaN', '1.570796', - '-1.570796', 'NaN', 'NaN' - ]], "unary float", "asin") - add_test_case_float_half('Atan', ['Atan'], 'Epsilon', 0.0008, - [['NaN', '-Inf', '-denorm', '-0', '0', 'denorm', 'Inf', '1', '-1']], [[ - 'NaN', '-1.570796', '0.0', '0.0', '0.0', '0.0', '1.570796', - '0.785398163', '-0.785398163' - ]], "unary float", "atan", warp_version=16202) - add_test_case_float_half('Exp', ['Exp'], 'Relative', 21, - [['NaN', '-Inf', '-denorm', '-0', '0', 'denorm', 'Inf', '-1', '10']], - [['NaN', '0', '1', '1', '1', '1', 'Inf', '0.367879441', '22026.46579'] - ], "unary float", "exp") - add_test_case_float_half('Frc', ['Frc'], 'Epsilon', 0.0008, [[ - 'NaN', '-Inf', '-denorm', '-0', '0', 'denorm', 'Inf', '-1', '2.718280', - '1000.599976', '-7.389' - ]], [[ - 'NaN', 'NaN', '0', '0', '0', '0', 'NaN', '0', '0.718280', '0.599976', - '0.611' - ]], "unary float", "frac", - half_inputs=[['NaN', '-Inf', '0x03FF', '-0', '0', 'Inf', '-1', '2.719', - '1000.5', '0xC764']], - half_outputs=[[ - 'NaN', 'NaN', '0x03FF', '0', '0', 'NaN', '0', '0.719', '0.5', - '0x38E1']]) - add_test_case_float_half('Log', ['Log'], 'Relative', 21, [[ - 'NaN', '-Inf', '-denorm', '-0', '0', 'denorm', 'Inf', '-1', - '2.718281828', '7.389056', '100' - ]], [[ - 'NaN', 'NaN', '-Inf', '-Inf', '-Inf', '-Inf', 'Inf', 'NaN', '1.0', - '1.99999998', '4.6051701' - ]],"unary float", "log", half_inputs=[[ - 'NaN', '-Inf', '-denorm', '-0', '0', 'denorm', 'Inf', '-1', - '2.719', '7.39', '100' - ]], half_outputs=[[ - 'NaN', 'NaN', '-Inf', '-Inf', '-Inf', '-Inf', 'Inf', 'NaN', '1.0', - '2', '4.605' - ]]) - add_test_case_float_half('Sqrt', ['Sqrt'], 'ulp', 1, [[ - 'NaN', '-Inf', '-denorm', '-0', '0', 'denorm', 'Inf', '-1', '2', - '16.0', '256.0' - ]], [[ - 'NaN', 'NaN', '-0', '-0', '0', '0', 'Inf', 'NaN', '1.41421356237', - '4.0', '16.0' - ]], "unary float", "sqrt", - half_inputs=[['NaN', '-Inf', '-denorm', '-0', '0', '0x03FF', 'Inf', '-1', '2', '16.0', '256.0']], - half_outputs=[['NaN', 'NaN', 'NaN', '-0', '0', '0x1FFF', 'Inf', 'NaN', '1.41421', '4.0', '16.0']]) - add_test_case_float_half('Rsqrt', ['Rsqrt'], 'ulp', 1, [[ - 'NaN', '-Inf', '-denorm', '-0', '0', 'denorm', 'Inf', '-1', '16.0', - '256.0', '65536.0' - ]], [[ - 'NaN', 'NaN', '-Inf', '-Inf', 'Inf', 'Inf', '0', 'NaN', '0.25', - '0.0625', '0.00390625' - ]], "unary float", "rsqrt", half_inputs=[[ - 'NaN', '-Inf', '-denorm', '-0', '0', '0x03FF', 'Inf', '-1', '16.0', - '256.0', '0x7bff' - ]], half_outputs=[[ - 'NaN', 'NaN', 'NaN', '-Inf', 'Inf', '0x5801', '0', 'NaN', '0.25', - '0.0625', '0x1C00' - ]]) - add_test_case_float_half('Round_ne', ['Round_ne'], 'Epsilon', 0, [[ - 'NaN', '-Inf', '-denorm', '-0', '0', 'denorm', 'Inf', '10.0', '10.4', - '10.5', '10.6', '11.5', '-10.0', '-10.4', '-10.5', '-10.6' - ]], [[ - 'NaN', '-Inf', '-0', '-0', '0', '0', 'Inf', '10.0', '10.0', '10.0', - '11.0', '12.0', '-10.0', '-10.0', '-10.0', '-11.0' - ]], "unary float", "round") - add_test_case_float_half('Round_ni', ['Round_ni'], 'Epsilon', 0, [[ - 'NaN', '-Inf', '-denorm', '-0', '0', 'denorm', 'Inf', '10.0', '10.4', - '10.5', '10.6', '-10.0', '-10.4', '-10.5', '-10.6' - ]], [[ - 'NaN', '-Inf', '-0', '-0', '0', '0', 'Inf', '10.0', '10.0', '10.0', - '10.0', '-10.0', '-11.0', '-11.0', '-11.0' - ]], "unary float", "floor", half_inputs=[[ - 'NaN', '-Inf', '-denorm', '-0', '0', 'denorm', 'Inf', '10.0', '10.4', - '10.5', '10.6', '-10.0', '-10.4', '-10.5', '-10.6' - ]], half_outputs=[[ - 'NaN', '-Inf', '-1', '-0', '0', '0', 'Inf', '10.0', '10.0', '10.0', - '10.0', '-10.0', '-11.0', '-11.0', '-11.0' - ]]) - add_test_case_float_half('Round_pi', ['Round_pi'], 'Epsilon', 0, - [['NaN', '-Inf', '-denorm', '-0', '0', 'denorm', 'Inf', '10.0', '10.4', - '10.5', '10.6', '-10.0', '-10.4', '-10.5', '-10.6']], - [['NaN', '-Inf', '-0', '-0', '0', '0', 'Inf', '10.0', '11.0', '11.0', - '11.0', '-10.0', '-10.0', '-10.0', '-10.0']], "unary float", "ceil", - half_inputs=[['NaN', '-Inf', '-denorm', '-0', '0', 'denorm', 'Inf', '10.0', '10.4', - '10.5', '10.6', '-10.0', '-10.4', '-10.5', '-10.6']], - half_outputs=[['NaN', '-Inf', '-0', '-0', '0', '1', 'Inf', '10.0', '11.0', '11.0', - '11.0', '-10.0', '-10.0', '-10.0', '-10.0']]) - add_test_case_float_half('Round_z', ['Round_z'], 'Epsilon', 0, - [['NaN', '-Inf', '-denorm', '-0', '0', 'denorm', 'Inf', '10.0', '10.4', - '10.5', '10.6', '-10.0', '-10.4', '-10.5', '-10.6']], - [['NaN', '-Inf', '-0', '-0', '0', '0', 'Inf', '10.0', '10.0', '10.0', - '10.0', '-10.0', '-10.0', '-10.0', '-10.0']], "unary float", "trunc") - add_test_case_float_half('IsNaN', ['IsNaN'], 'Epsilon', 0, - [['NaN', '-Inf', '-denorm', '-0', '0', 'denorm', 'Inf', '1.0', '-1.0'] - ], [['1', '0', '0', '0', '0', '0', '0', '0', '0']], "unary float bool", "isnan") - add_test_case_float_half('IsInf', ['IsInf'], 'Epsilon', 0, - [['NaN', '-Inf', '-denorm', '-0', '0', 'denorm', 'Inf', '1.0', '-1.0'] - ], [['0', '1', '0', '0', '0', '0', '1', '0', '0']], "unary float bool", "isinf") - add_test_case_float_half('IsFinite', ['IsFinite'], 'Epsilon', 0, - [['NaN', '-Inf', '-denorm', '-0', '0', 'denorm', 'Inf', '1.0', '-1.0'] - ], [['0', '0', '1', '1', '1', '1', '0', '1', '1']], "unary float bool", "isfinite", warp_version=16202) - add_test_case_float_half('FAbs', ['FAbs'], 'Epsilon', 0, - [['NaN', '-Inf', '-denorm', '-0', '0', 'denorm', 'Inf', '1.0', '-1.0'] - ], [['NaN', 'Inf', 'denorm', '0', '0', 'denorm', 'Inf', '1', '1']], "unary float", "abs") + add_test_case_float_half( + "Sin", + ["Sin"], + "Epsilon", + 0.0008, + [["NaN", "-Inf", "-denorm", "-0", "0", "denorm", "Inf", "-314.16", "314.16"]], + [["NaN", "NaN", "-0", "-0", "0", "0", "NaN", "-0.0007346401", "0.0007346401"]], + "unary float", + "sin", + half_validation_tolerance=0.003, + half_inputs=[ + [ + "NaN", + "-Inf", + "-denorm", + "-0", + "0", + "denorm", + "Inf", + "0.6279297", + "1.255859", + "1.884766", + "2.511719", + "3.140625", + "3.769531", + "4.398438", + "5.023438", + "5.652344", + "6.281250", + ] + ], + half_outputs=[ + [ + "NaN", + "NaN", + "-0", + "-0", + "0", + "0", + "NaN", + "0.58747065", + "0.95081574", + "0.95111507", + "0.58904284", + "0.00096773", + "-0.58747751", + "-0.95112079", + "-0.95201313", + "-0.58982444", + "-0.00193545", + ] + ], + ) + add_test_case_float_half( + "Cos", + ["Cos"], + "Epsilon", + 0.0008, + [["NaN", "-Inf", "-denorm", "-0", "0", "denorm", "Inf", "-314.16", "314.16"]], + [ + [ + "NaN", + "NaN", + "1.0", + "1.0", + "1.0", + "1.0", + "NaN", + "0.99999973015", + "0.99999973015", + ] + ], + "unary float", + "cos", + half_validation_tolerance=0.003, + half_inputs=[ + [ + "NaN", + "-Inf", + "-denorm", + "-0", + "0", + "denorm", + "Inf", + "0.6279297", + "1.255859", + "1.884766", + "2.511719", + "3.140625", + "3.769531", + "4.398438", + "5.023438", + "5.652344", + "6.281250", + ] + ], + half_outputs=[ + [ + "NaN", + "NaN", + "1.0", + "1.0", + "1.0", + "1.0", + "NaN", + "0.80924553", + "0.30975693", + "-0.30883664", + "-0.80810183", + "-0.99999952", + "-0.80924052", + "-0.30881903", + "0.30605716", + "0.80753154", + "0.99999809", + ] + ], + ) + add_test_case_float_half( + "Tan", + ["Tan"], + "Epsilon", + 0.0008, + [["NaN", "-Inf", "-denorm", "-0", "0", "denorm", "Inf", "-314.16", "314.16"]], + [["NaN", "NaN", "-0.0", "-0.0", "0.0", "0.0", "NaN", "-0.000735", "0.000735"]], + "unary float", + "tan", + half_validation_tolerance=0.016, + half_inputs=[ + [ + "NaN", + "-Inf", + "-denorm", + "-0", + "0", + "denorm", + "Inf", + "0.6279297", + "1.255859", + "1.884766", + "2.511719", + "3.140625", + "3.769531", + "4.398438", + "5.652344", + "6.281250", + ] + ], + half_outputs=[ + [ + "NaN", + "NaN", + "-0", + "-0", + "0", + "0", + "NaN", + "0.72594857", + "3.06955433", + "-3.07967043", + "-0.72892153", + "-0.00096773", + "0.72596157", + "3.07986474", + "-0.7304042", + "-0.00193546", + ] + ], + ) + add_test_case_float_half( + "Hcos", + ["Hcos"], + "Epsilon", + 0.0008, + [["NaN", "-Inf", "-denorm", "-0", "0", "denorm", "Inf", "1", "-1"]], + [["NaN", "Inf", "1.0", "1.0", "1.0", "1.0", "Inf", "1.543081", "1.543081"]], + "unary float", + "cosh", + half_validation_type="ulp", + half_validation_tolerance=2, + ) + add_test_case_float_half( + "Hsin", + ["Hsin"], + "Epsilon", + 0.0008, + [["NaN", "-Inf", "-denorm", "-0", "0", "denorm", "Inf", "1", "-1"]], + [["NaN", "-Inf", "0.0", "0.0", "0.0", "0.0", "Inf", "1.175201", "-1.175201"]], + "unary float", + "sinh", + ) + add_test_case_float_half( + "Htan", + ["Htan"], + "Epsilon", + 0.0008, + [["NaN", "-Inf", "-denorm", "-0", "0", "denorm", "Inf", "1", "-1"]], + [["NaN", "-1", "-0.0", "-0.0", "0.0", "0.0", "1", "0.761594", "-0.761594"]], + "unary float", + "tanh", + warp_version=16202, + ) + add_test_case_float_half( + "Acos", + ["Acos"], + "Epsilon", + 0.0008, + [ + [ + "NaN", + "-Inf", + "-denorm", + "-0", + "0", + "denorm", + "Inf", + "1", + "-1", + "1.5", + "-1.5", + ] + ], + [ + [ + "NaN", + "NaN", + "1.570796", + "1.570796", + "1.570796", + "1.570796", + "NaN", + "0", + "3.1415926", + "NaN", + "NaN", + ] + ], + "unary float", + "acos", + ) + add_test_case_float_half( + "Asin", + ["Asin"], + "Epsilon", + 0.0008, + [ + [ + "NaN", + "-Inf", + "-denorm", + "-0", + "0", + "denorm", + "Inf", + "1", + "-1", + "1.5", + "-1.5", + ] + ], + [ + [ + "NaN", + "NaN", + "0.0", + "0.0", + "0.0", + "0.0", + "NaN", + "1.570796", + "-1.570796", + "NaN", + "NaN", + ] + ], + "unary float", + "asin", + ) + add_test_case_float_half( + "Atan", + ["Atan"], + "Epsilon", + 0.0008, + [["NaN", "-Inf", "-denorm", "-0", "0", "denorm", "Inf", "1", "-1"]], + [ + [ + "NaN", + "-1.570796", + "0.0", + "0.0", + "0.0", + "0.0", + "1.570796", + "0.785398163", + "-0.785398163", + ] + ], + "unary float", + "atan", + warp_version=16202, + ) + add_test_case_float_half( + "Exp", + ["Exp"], + "Relative", + 21, + [["NaN", "-Inf", "-denorm", "-0", "0", "denorm", "Inf", "-1", "10"]], + [["NaN", "0", "1", "1", "1", "1", "Inf", "0.367879441", "22026.46579"]], + "unary float", + "exp", + ) + add_test_case_float_half( + "Frc", + ["Frc"], + "Epsilon", + 0.0008, + [ + [ + "NaN", + "-Inf", + "-denorm", + "-0", + "0", + "denorm", + "Inf", + "-1", + "2.718280", + "1000.599976", + "-7.389", + ] + ], + [ + [ + "NaN", + "NaN", + "0", + "0", + "0", + "0", + "NaN", + "0", + "0.718280", + "0.599976", + "0.611", + ] + ], + "unary float", + "frac", + half_inputs=[ + [ + "NaN", + "-Inf", + "0x03FF", + "-0", + "0", + "Inf", + "-1", + "2.719", + "1000.5", + "0xC764", + ] + ], + half_outputs=[ + ["NaN", "NaN", "0x03FF", "0", "0", "NaN", "0", "0.719", "0.5", "0x38E1"] + ], + ) + add_test_case_float_half( + "Log", + ["Log"], + "Relative", + 21, + [ + [ + "NaN", + "-Inf", + "-denorm", + "-0", + "0", + "denorm", + "Inf", + "-1", + "2.718281828", + "7.389056", + "100", + ] + ], + [ + [ + "NaN", + "NaN", + "-Inf", + "-Inf", + "-Inf", + "-Inf", + "Inf", + "NaN", + "1.0", + "1.99999998", + "4.6051701", + ] + ], + "unary float", + "log", + half_inputs=[ + [ + "NaN", + "-Inf", + "-denorm", + "-0", + "0", + "denorm", + "Inf", + "-1", + "2.719", + "7.39", + "100", + ] + ], + half_outputs=[ + [ + "NaN", + "NaN", + "-Inf", + "-Inf", + "-Inf", + "-Inf", + "Inf", + "NaN", + "1.0", + "2", + "4.605", + ] + ], + ) + add_test_case_float_half( + "Sqrt", + ["Sqrt"], + "ulp", + 1, + [ + [ + "NaN", + "-Inf", + "-denorm", + "-0", + "0", + "denorm", + "Inf", + "-1", + "2", + "16.0", + "256.0", + ] + ], + [ + [ + "NaN", + "NaN", + "-0", + "-0", + "0", + "0", + "Inf", + "NaN", + "1.41421356237", + "4.0", + "16.0", + ] + ], + "unary float", + "sqrt", + half_inputs=[ + [ + "NaN", + "-Inf", + "-denorm", + "-0", + "0", + "0x03FF", + "Inf", + "-1", + "2", + "16.0", + "256.0", + ] + ], + half_outputs=[ + [ + "NaN", + "NaN", + "NaN", + "-0", + "0", + "0x1FFF", + "Inf", + "NaN", + "1.41421", + "4.0", + "16.0", + ] + ], + ) + add_test_case_float_half( + "Rsqrt", + ["Rsqrt"], + "ulp", + 1, + [ + [ + "NaN", + "-Inf", + "-denorm", + "-0", + "0", + "denorm", + "Inf", + "-1", + "16.0", + "256.0", + "65536.0", + ] + ], + [ + [ + "NaN", + "NaN", + "-Inf", + "-Inf", + "Inf", + "Inf", + "0", + "NaN", + "0.25", + "0.0625", + "0.00390625", + ] + ], + "unary float", + "rsqrt", + half_inputs=[ + [ + "NaN", + "-Inf", + "-denorm", + "-0", + "0", + "0x03FF", + "Inf", + "-1", + "16.0", + "256.0", + "0x7bff", + ] + ], + half_outputs=[ + [ + "NaN", + "NaN", + "NaN", + "-Inf", + "Inf", + "0x5801", + "0", + "NaN", + "0.25", + "0.0625", + "0x1C00", + ] + ], + ) + add_test_case_float_half( + "Round_ne", + ["Round_ne"], + "Epsilon", + 0, + [ + [ + "NaN", + "-Inf", + "-denorm", + "-0", + "0", + "denorm", + "Inf", + "10.0", + "10.4", + "10.5", + "10.6", + "11.5", + "-10.0", + "-10.4", + "-10.5", + "-10.6", + ] + ], + [ + [ + "NaN", + "-Inf", + "-0", + "-0", + "0", + "0", + "Inf", + "10.0", + "10.0", + "10.0", + "11.0", + "12.0", + "-10.0", + "-10.0", + "-10.0", + "-11.0", + ] + ], + "unary float", + "round", + ) + add_test_case_float_half( + "Round_ni", + ["Round_ni"], + "Epsilon", + 0, + [ + [ + "NaN", + "-Inf", + "-denorm", + "-0", + "0", + "denorm", + "Inf", + "10.0", + "10.4", + "10.5", + "10.6", + "-10.0", + "-10.4", + "-10.5", + "-10.6", + ] + ], + [ + [ + "NaN", + "-Inf", + "-0", + "-0", + "0", + "0", + "Inf", + "10.0", + "10.0", + "10.0", + "10.0", + "-10.0", + "-11.0", + "-11.0", + "-11.0", + ] + ], + "unary float", + "floor", + half_inputs=[ + [ + "NaN", + "-Inf", + "-denorm", + "-0", + "0", + "denorm", + "Inf", + "10.0", + "10.4", + "10.5", + "10.6", + "-10.0", + "-10.4", + "-10.5", + "-10.6", + ] + ], + half_outputs=[ + [ + "NaN", + "-Inf", + "-1", + "-0", + "0", + "0", + "Inf", + "10.0", + "10.0", + "10.0", + "10.0", + "-10.0", + "-11.0", + "-11.0", + "-11.0", + ] + ], + ) + add_test_case_float_half( + "Round_pi", + ["Round_pi"], + "Epsilon", + 0, + [ + [ + "NaN", + "-Inf", + "-denorm", + "-0", + "0", + "denorm", + "Inf", + "10.0", + "10.4", + "10.5", + "10.6", + "-10.0", + "-10.4", + "-10.5", + "-10.6", + ] + ], + [ + [ + "NaN", + "-Inf", + "-0", + "-0", + "0", + "0", + "Inf", + "10.0", + "11.0", + "11.0", + "11.0", + "-10.0", + "-10.0", + "-10.0", + "-10.0", + ] + ], + "unary float", + "ceil", + half_inputs=[ + [ + "NaN", + "-Inf", + "-denorm", + "-0", + "0", + "denorm", + "Inf", + "10.0", + "10.4", + "10.5", + "10.6", + "-10.0", + "-10.4", + "-10.5", + "-10.6", + ] + ], + half_outputs=[ + [ + "NaN", + "-Inf", + "-0", + "-0", + "0", + "1", + "Inf", + "10.0", + "11.0", + "11.0", + "11.0", + "-10.0", + "-10.0", + "-10.0", + "-10.0", + ] + ], + ) + add_test_case_float_half( + "Round_z", + ["Round_z"], + "Epsilon", + 0, + [ + [ + "NaN", + "-Inf", + "-denorm", + "-0", + "0", + "denorm", + "Inf", + "10.0", + "10.4", + "10.5", + "10.6", + "-10.0", + "-10.4", + "-10.5", + "-10.6", + ] + ], + [ + [ + "NaN", + "-Inf", + "-0", + "-0", + "0", + "0", + "Inf", + "10.0", + "10.0", + "10.0", + "10.0", + "-10.0", + "-10.0", + "-10.0", + "-10.0", + ] + ], + "unary float", + "trunc", + ) + add_test_case_float_half( + "IsNaN", + ["IsNaN"], + "Epsilon", + 0, + [["NaN", "-Inf", "-denorm", "-0", "0", "denorm", "Inf", "1.0", "-1.0"]], + [["1", "0", "0", "0", "0", "0", "0", "0", "0"]], + "unary float bool", + "isnan", + ) + add_test_case_float_half( + "IsInf", + ["IsInf"], + "Epsilon", + 0, + [["NaN", "-Inf", "-denorm", "-0", "0", "denorm", "Inf", "1.0", "-1.0"]], + [["0", "1", "0", "0", "0", "0", "1", "0", "0"]], + "unary float bool", + "isinf", + ) + add_test_case_float_half( + "IsFinite", + ["IsFinite"], + "Epsilon", + 0, + [["NaN", "-Inf", "-denorm", "-0", "0", "denorm", "Inf", "1.0", "-1.0"]], + [["0", "0", "1", "1", "1", "1", "0", "1", "1"]], + "unary float bool", + "isfinite", + warp_version=16202, + ) + add_test_case_float_half( + "FAbs", + ["FAbs"], + "Epsilon", + 0, + [["NaN", "-Inf", "-denorm", "-0", "0", "denorm", "Inf", "1.0", "-1.0"]], + [["NaN", "Inf", "denorm", "0", "0", "denorm", "Inf", "1", "1"]], + "unary float", + "abs", + ) # Binary Float - add_test_case('FMin', ['FMin','FMax'], 'epsilon', 0, [[ - '-inf', '-inf', '-inf', '-inf', 'inf', 'inf', 'inf', 'inf', 'NaN', - 'NaN', 'NaN', 'NaN', '1.0', '1.0', '-1.0', '-1.0', '1.0' - ], [ - '-inf', 'inf', '1.0', 'NaN', '-inf', 'inf', '1.0', 'NaN', '-inf', - 'inf', '1.0', 'NaN', '-inf', 'inf', '1.0', 'NaN', '-1.0' - ]], [[ - '-inf', '-inf', '-inf', '-inf', '-inf', 'inf', '1.0', 'inf', '-inf', - 'inf', '1.0', 'NaN', '-inf', '1.0', '-1.0', '-1.0', '-1.0' - ], [ - '-inf', 'inf', '1.0', '-inf', 'inf', 'inf', 'inf', 'inf', '-inf', - 'inf', '1.0', 'NaN', '1.0', 'inf', '1.0', '-1.0', '1.0' - ]], 'cs_6_0', ''' struct SBinaryFPOp { + add_test_case( + "FMin", + ["FMin", "FMax"], + "epsilon", + 0, + [ + [ + "-inf", + "-inf", + "-inf", + "-inf", + "inf", + "inf", + "inf", + "inf", + "NaN", + "NaN", + "NaN", + "NaN", + "1.0", + "1.0", + "-1.0", + "-1.0", + "1.0", + ], + [ + "-inf", + "inf", + "1.0", + "NaN", + "-inf", + "inf", + "1.0", + "NaN", + "-inf", + "inf", + "1.0", + "NaN", + "-inf", + "inf", + "1.0", + "NaN", + "-1.0", + ], + ], + [ + [ + "-inf", + "-inf", + "-inf", + "-inf", + "-inf", + "inf", + "1.0", + "inf", + "-inf", + "inf", + "1.0", + "NaN", + "-inf", + "1.0", + "-1.0", + "-1.0", + "-1.0", + ], + [ + "-inf", + "inf", + "1.0", + "-inf", + "inf", + "inf", + "inf", + "inf", + "-inf", + "inf", + "1.0", + "NaN", + "1.0", + "inf", + "1.0", + "-1.0", + "1.0", + ], + ], + "cs_6_0", + """ struct SBinaryFPOp { float input1; float input2; float output1; @@ -810,20 +1712,95 @@ def add_test_cases(): l.output1 = min(l.input1, l.input2); l.output2 = max(l.input1, l.input2); g_buf[GI] = l; - };''') - add_test_case('FMinHalf', ['FMin','FMax'], 'epsilon', 0, [[ - '-inf', '-inf', '-inf', '-inf', 'inf', 'inf', 'inf', 'inf', 'NaN', - 'NaN', 'NaN', 'NaN', '1.0', '1.0', '-1.0', '-1.0', '1.0' - ], [ - '-inf', 'inf', '1.0', 'NaN', '-inf', 'inf', '1.0', 'NaN', '-inf', - 'inf', '1.0', 'NaN', '-inf', 'inf', '1.0', 'NaN', '-1.0' - ]], [[ - '-inf', '-inf', '-inf', '-inf', '-inf', 'inf', '1.0', 'inf', '-inf', - 'inf', '1.0', 'NaN', '-inf', '1.0', '-1.0', '-1.0', '-1.0' - ], [ - '-inf', 'inf', '1.0', '-inf', 'inf', 'inf', 'inf', 'inf', '-inf', - 'inf', '1.0', 'NaN', '1.0', 'inf', '1.0', '-1.0', '1.0' - ]], 'cs_6_2', ''' struct SBinaryHalfOp { + };""", + ) + add_test_case( + "FMinHalf", + ["FMin", "FMax"], + "epsilon", + 0, + [ + [ + "-inf", + "-inf", + "-inf", + "-inf", + "inf", + "inf", + "inf", + "inf", + "NaN", + "NaN", + "NaN", + "NaN", + "1.0", + "1.0", + "-1.0", + "-1.0", + "1.0", + ], + [ + "-inf", + "inf", + "1.0", + "NaN", + "-inf", + "inf", + "1.0", + "NaN", + "-inf", + "inf", + "1.0", + "NaN", + "-inf", + "inf", + "1.0", + "NaN", + "-1.0", + ], + ], + [ + [ + "-inf", + "-inf", + "-inf", + "-inf", + "-inf", + "inf", + "1.0", + "inf", + "-inf", + "inf", + "1.0", + "NaN", + "-inf", + "1.0", + "-1.0", + "-1.0", + "-1.0", + ], + [ + "-inf", + "inf", + "1.0", + "-inf", + "inf", + "inf", + "inf", + "inf", + "-inf", + "inf", + "1.0", + "NaN", + "1.0", + "inf", + "1.0", + "-1.0", + "1.0", + ], + ], + "cs_6_2", + """ struct SBinaryHalfOp { half input1; half input2; half output1; @@ -836,163 +1813,381 @@ def add_test_cases(): l.output1 = min(l.input1, l.input2); l.output2 = max(l.input1, l.input2); g_buf[GI] = l; - };''', shader_arguments="-enable-16bit-types") - add_test_case_float_half('FAdd', ['FAdd'], 'ulp', 1, [['-1.0', '1.0', '32.5', '1.0000001000'],['4', '5.5', '334.7', '0.5000001000']], [['3.0', '6.5', '367.2', '1.5000002000']], - "binary float", "+") - add_test_case_float_half('FSub', ['FSub'], 'ulp', 1, [['-1.0', '5.5', '32.5', '1.0000001000'],['4', '1.25', '334.7', '0.5000001000']], [['-5', '4.25', '-302.2', '0.5000']], - "binary float", "-") - add_test_case_float_half('FMul', ['FMul'], 'ulp', 1, [['-1.0', '5.5', '1.0000001'],['4', '1.25', '2.0']], [['-4.0', '6.875', '2.0000002']], - "binary float", "*") - add_test_case_float_half('FDiv', ['FDiv'], 'ulp', 1, [['-1.0', '5.5', '1.0000001'],['4', '1.25', '2.0']], [['-0.25', '4.4', '0.50000006']], - "binary float", "/") + };""", + shader_arguments="-enable-16bit-types", + ) + add_test_case_float_half( + "FAdd", + ["FAdd"], + "ulp", + 1, + [ + ["-1.0", "1.0", "32.5", "1.0000001000"], + ["4", "5.5", "334.7", "0.5000001000"], + ], + [["3.0", "6.5", "367.2", "1.5000002000"]], + "binary float", + "+", + ) + add_test_case_float_half( + "FSub", + ["FSub"], + "ulp", + 1, + [ + ["-1.0", "5.5", "32.5", "1.0000001000"], + ["4", "1.25", "334.7", "0.5000001000"], + ], + [["-5", "4.25", "-302.2", "0.5000"]], + "binary float", + "-", + ) + add_test_case_float_half( + "FMul", + ["FMul"], + "ulp", + 1, + [["-1.0", "5.5", "1.0000001"], ["4", "1.25", "2.0"]], + [["-4.0", "6.875", "2.0000002"]], + "binary float", + "*", + ) + add_test_case_float_half( + "FDiv", + ["FDiv"], + "ulp", + 1, + [["-1.0", "5.5", "1.0000001"], ["4", "1.25", "2.0"]], + [["-0.25", "4.4", "0.50000006"]], + "binary float", + "/", + ) # Denorm Binary Float - add_test_case_denorm('FAddDenorm', ['FAdd'], 'ulp', 1, - [['0x007E0000', '0x00200000', '0x007E0000', '0x007E0000'],['0x007E0000','0x00200000', '0x807E0000', '0x800E0000']], - [['0','0', '0', '0']], - [['0x00FC0000','0x00400000', '0', '0x00700000']], - 'cs_6_2', get_shader_text("binary float", "+")) - add_test_case_denorm('FSubDenorm', ['FSub'], 'ulp', 1, - [['0x007E0000', '0x007F0000', '0x00FF0000', '0x007A0000'],['0x007E0000', '0x807F0000', '0x00800000', '0']], - [['0x0', '0', '0', '0']], - [['0x0', '0x00FE0000', '0x007F0000', '0x007A0000']], - 'cs_6_2', get_shader_text("binary float", "-")) - add_test_case_denorm('FDivDenorm', ['FDiv'], 'ulp', 1, - [['0x007F0000', '0x807F0000', '0x20000000', '0x00800000'],['1', '4', '0x607F0000', '0x40000000']], - [['0', '0', '0', '0']], - [['0x007F0000', '0x801FC000', '0x00101010', '0x00400000']], - 'cs_6_2', get_shader_text("binary float", "/")) - add_test_case_denorm('FMulDenorm', ['FMul'], 'ulp', 1, - [['0x00000300', '0x007F0000', '0x007F0000', '0x001E0000', '0x00000300'],['128', '1', '0x007F0000', '20', '0x78000000']], - [['0', '0', '0', '0', '0']], - [['0x00018000','0x007F0000', '0', '0x01960000', '0x32400000']], - 'cs_6_2', get_shader_text("binary float", "*")) + add_test_case_denorm( + "FAddDenorm", + ["FAdd"], + "ulp", + 1, + [ + ["0x007E0000", "0x00200000", "0x007E0000", "0x007E0000"], + ["0x007E0000", "0x00200000", "0x807E0000", "0x800E0000"], + ], + [["0", "0", "0", "0"]], + [["0x00FC0000", "0x00400000", "0", "0x00700000"]], + "cs_6_2", + get_shader_text("binary float", "+"), + ) + add_test_case_denorm( + "FSubDenorm", + ["FSub"], + "ulp", + 1, + [ + ["0x007E0000", "0x007F0000", "0x00FF0000", "0x007A0000"], + ["0x007E0000", "0x807F0000", "0x00800000", "0"], + ], + [["0x0", "0", "0", "0"]], + [["0x0", "0x00FE0000", "0x007F0000", "0x007A0000"]], + "cs_6_2", + get_shader_text("binary float", "-"), + ) + add_test_case_denorm( + "FDivDenorm", + ["FDiv"], + "ulp", + 1, + [ + ["0x007F0000", "0x807F0000", "0x20000000", "0x00800000"], + ["1", "4", "0x607F0000", "0x40000000"], + ], + [["0", "0", "0", "0"]], + [["0x007F0000", "0x801FC000", "0x00101010", "0x00400000"]], + "cs_6_2", + get_shader_text("binary float", "/"), + ) + add_test_case_denorm( + "FMulDenorm", + ["FMul"], + "ulp", + 1, + [ + ["0x00000300", "0x007F0000", "0x007F0000", "0x001E0000", "0x00000300"], + ["128", "1", "0x007F0000", "20", "0x78000000"], + ], + [["0", "0", "0", "0", "0"]], + [["0x00018000", "0x007F0000", "0", "0x01960000", "0x32400000"]], + "cs_6_2", + get_shader_text("binary float", "*"), + ) # Tertiary Float - add_test_case_float_half('FMad', ['FMad'], 'ulp', 1, [[ - 'NaN', '-Inf', '-denorm', '-0', '0', 'denorm', 'Inf', '1.0', '-1.0', - '0', '1', '1.5' - ], [ - 'NaN', '-Inf', '-denorm', '-0', '0', 'denorm', 'Inf', '1.0', '-1.0', - '0', '1', '10' - ], [ - 'NaN', '-Inf', '-denorm', '-0', '0', 'denorm', 'Inf', '1.0', '-1.0', - '1', '0', '-5.5' - ]], [['NaN', 'NaN', '0', '0', '0', '0', 'Inf', '2', '0', '1', '1', '9.5']], - "tertiary float", "mad", - half_inputs=[[ - 'NaN', '-Inf', '0x03FF', '-0', '0', 'Inf', '1.0', '-1.0', - '0', '1', '1.5' - ], [ - 'NaN', '-Inf', '1', '-0', '0', 'Inf', '1.0', '-1.0', - '0', '1', '10' - ], [ - 'NaN', '-Inf', '0x03FF', '-0', '0', 'Inf', '1.0', '-1.0', - '1', '0', '-5.5' - ]], - half_outputs=[['NaN', 'NaN', '0x07FE', '0', '0', 'Inf', '2', '0', '1', '1', '9.5']]) + add_test_case_float_half( + "FMad", + ["FMad"], + "ulp", + 1, + [ + [ + "NaN", + "-Inf", + "-denorm", + "-0", + "0", + "denorm", + "Inf", + "1.0", + "-1.0", + "0", + "1", + "1.5", + ], + [ + "NaN", + "-Inf", + "-denorm", + "-0", + "0", + "denorm", + "Inf", + "1.0", + "-1.0", + "0", + "1", + "10", + ], + [ + "NaN", + "-Inf", + "-denorm", + "-0", + "0", + "denorm", + "Inf", + "1.0", + "-1.0", + "1", + "0", + "-5.5", + ], + ], + [["NaN", "NaN", "0", "0", "0", "0", "Inf", "2", "0", "1", "1", "9.5"]], + "tertiary float", + "mad", + half_inputs=[ + ["NaN", "-Inf", "0x03FF", "-0", "0", "Inf", "1.0", "-1.0", "0", "1", "1.5"], + ["NaN", "-Inf", "1", "-0", "0", "Inf", "1.0", "-1.0", "0", "1", "10"], + [ + "NaN", + "-Inf", + "0x03FF", + "-0", + "0", + "Inf", + "1.0", + "-1.0", + "1", + "0", + "-5.5", + ], + ], + half_outputs=[ + ["NaN", "NaN", "0x07FE", "0", "0", "Inf", "2", "0", "1", "1", "9.5"] + ], + ) # Denorm Tertiary Float - add_test_case_denorm('FMadDenorm', ['FMad'], 'ulp', 1, - [['0x80780000', '0x80780000', '0x00780000'], - ['1', '2', '2'], - ['0x80780000', '0x00800000', '0x00800000']], - [['0', '0x00800000', '0x00800000']], - [['0x80F00000', '0x80700000', '0x01380000']], - 'cs_6_2', get_shader_text("tertiary float", "mad")) + add_test_case_denorm( + "FMadDenorm", + ["FMad"], + "ulp", + 1, + [ + ["0x80780000", "0x80780000", "0x00780000"], + ["1", "2", "2"], + ["0x80780000", "0x00800000", "0x00800000"], + ], + [["0", "0x00800000", "0x00800000"]], + [["0x80F00000", "0x80700000", "0x01380000"]], + "cs_6_2", + get_shader_text("tertiary float", "mad"), + ) # Unary Int - int8_min, int8_max = '-128', '127' - int16_min, int16_max = '-32768', '32767' - int32_min, int32_max = '-2147483648', '2147483647' - uint16_max = '65535' - uint32_max = '4294967295' - add_test_case_int('Bfrev', ['Bfrev'], 'Epsilon', 0, [[ - int32_min, '-65536', '-8', '-1', '0', '1', '8', '65536', - int32_max - ]], [[ - '1', '65535', '536870911', '-1', '0', int32_min, '268435456', - '32768', '-2' - ]], "unary int", "reversebits", - input_16=[[int16_min, '-256', '-8', '-1', '0', '1', '8', '256', int16_max]], - output_16=[['1', '255', '8191', '-1', '0', int16_min, '4096', '128', '-2']]) + int8_min, int8_max = "-128", "127" + int16_min, int16_max = "-32768", "32767" + int32_min, int32_max = "-2147483648", "2147483647" + uint16_max = "65535" + uint32_max = "4294967295" + add_test_case_int( + "Bfrev", + ["Bfrev"], + "Epsilon", + 0, + [[int32_min, "-65536", "-8", "-1", "0", "1", "8", "65536", int32_max]], + [["1", "65535", "536870911", "-1", "0", int32_min, "268435456", "32768", "-2"]], + "unary int", + "reversebits", + input_16=[[int16_min, "-256", "-8", "-1", "0", "1", "8", "256", int16_max]], + output_16=[["1", "255", "8191", "-1", "0", int16_min, "4096", "128", "-2"]], + ) # firstbit_shi (s for signed) returns the # first 0 from the MSB if the number is negative, # else the first 1 from the MSB. # all the variants of the instruction return ~0 if no match was found - add_test_case_int('FirstbitSHi', ['FirstbitSHi'], 'Epsilon', 0, [[ - int32_min, '-65536', '-8', '-1', '0', '1', '8', '65536', - int32_max - ]], [['30', '15', '2', '-1', '-1', '0', '3', '16', '30']], - "unary int", "firstbithigh", - input_16=[[int16_min, '-256', '-8', '-1', '0', '1', '8', '256', int16_max]], - output_16=[['14', '7', '2', '-1', '-1', '0', '3', '8', '14']]) - add_test_case_int('FirstbitLo', ['FirstbitLo'], 'Epsilon', 0, [[ - int32_min, '-65536', '-8', '-1', '0', '1', '8', '65536', - int32_max - ]], [['31', '16', '3', '0', '-1', '0', '3', '16', '0']], - "unary int", "firstbitlow", - input_16=[[int16_min, '-256', '-8', '-1', '0', '1', '8', '256', int16_max]], - output_16=[['15', '8', '3', '0', '-1', '0', '3', '8', '0']]) + add_test_case_int( + "FirstbitSHi", + ["FirstbitSHi"], + "Epsilon", + 0, + [[int32_min, "-65536", "-8", "-1", "0", "1", "8", "65536", int32_max]], + [["30", "15", "2", "-1", "-1", "0", "3", "16", "30"]], + "unary int", + "firstbithigh", + input_16=[[int16_min, "-256", "-8", "-1", "0", "1", "8", "256", int16_max]], + output_16=[["14", "7", "2", "-1", "-1", "0", "3", "8", "14"]], + ) + add_test_case_int( + "FirstbitLo", + ["FirstbitLo"], + "Epsilon", + 0, + [[int32_min, "-65536", "-8", "-1", "0", "1", "8", "65536", int32_max]], + [["31", "16", "3", "0", "-1", "0", "3", "16", "0"]], + "unary int", + "firstbitlow", + input_16=[[int16_min, "-256", "-8", "-1", "0", "1", "8", "256", int16_max]], + output_16=[["15", "8", "3", "0", "-1", "0", "3", "8", "0"]], + ) # TODO: there is a known bug in countbits when passing in immediate values. # Fix this later - add_test_case('Countbits', ['Countbits'], 'Epsilon', 0, [[ - int32_min, '-65536', '-8', '-1', '0', '1', '8', '65536', - int32_max - ]], [['1', '16', '29', '32', '0', '1', '1', '1', '31']], - "cs_6_0", get_shader_text("unary int", "countbits")) + add_test_case( + "Countbits", + ["Countbits"], + "Epsilon", + 0, + [[int32_min, "-65536", "-8", "-1", "0", "1", "8", "65536", int32_max]], + [["1", "16", "29", "32", "0", "1", "1", "1", "31"]], + "cs_6_0", + get_shader_text("unary int", "countbits"), + ) # Unary uint - add_test_case_int('FirstbitHi', ['FirstbitHi'], 'Epsilon', 0, - [['0', '1', '8', '65536', int32_max, uint32_max]], - [['-1', '0', '3', '16', '30', '31']], - "unary uint", "firstbithigh", - input_16=[['0', '1', '8', uint16_max]], - output_16=[['-1', '0', '3', '15']]) + add_test_case_int( + "FirstbitHi", + ["FirstbitHi"], + "Epsilon", + 0, + [["0", "1", "8", "65536", int32_max, uint32_max]], + [["-1", "0", "3", "16", "30", "31"]], + "unary uint", + "firstbithigh", + input_16=[["0", "1", "8", uint16_max]], + output_16=[["-1", "0", "3", "15"]], + ) # Binary Int - add_test_case_int('IAdd', ['Add'], 'Epsilon', 0, - [[int32_min, '-10', '0', '0', '10', int32_max, '486'], - ['0', '10', '-10', '10', '10', '0', '54238']], - [[int32_min, '0', '-10', '10', '20', int32_max, '54724']], - "binary int", "+", - input_16=[[int16_min, '-10', '0', '0', '10', int16_max], - ['0', '10', '-3114', '272', '15', '0']], - output_16=[[int16_min, '0', '-3114', '272', '25', int16_max]]) - add_test_case_int('ISub', ['Sub'], 'Epsilon', 0, - [[int32_min, '-10', '0', '0', '10', int32_max, '486'], - ['0', '10', '-10', '10', '10', '0', '54238']], - [[int32_min, '-20', '10', '-10', '0', int32_max, '-53752']], - "binary int", "-", - input_16=[[int16_min, '-10', '0', '0', '10', int16_max], - ['0', '10', '-3114', '272', '15', '0']], - output_16=[[int16_min, '-20', '3114', '-272', '-5', int16_max]]) - add_test_case_int('IMax', ['IMax'], 'Epsilon', 0, - [[int32_min, '-10', '0', '0', '10', int32_max], - ['0', '10', '-10', '10', '10', '0']], - [['0', '10', '0', '10', '10', int32_max]], - "binary int call", "max", - input_16=[[int16_min, '-10', '0', '0', '10', int16_max], - ['0', '10', '-3114', '272', '15', '0']], - output_16=[['0', '10', '0', '272', '15', int16_max]]) - add_test_case_int('IMin', ['IMin'], 'Epsilon', 0, - [[int32_min, '-10', '0', '0', '10', int32_max], - ['0', '10', '-10', '10', '10', '0']], - [[int32_min, '-10', '-10', '0', '10', '0']], - "binary int call", "min", - input_16=[[int16_min, '-10', '0', '0', '10', int16_max], - ['0', '10', '-3114', '272', '15', '0']], - output_16=[[int16_min, '-10', '-3114', '0', '10', '0']]) - add_test_case_int('IMul', ['Mul'], 'Epsilon', 0, [ - [ int32_min, '-10', '-1', '0', '1', '10', '10000', int32_max, int32_max ], - ['-10', '-10', '10', '0', '256', '4', '10001', '0', int32_max]], - [['0', '100', '-10', '0', '256', '40', '100010000', '0', '1']], - "binary int", "*", - input_16=[[ int16_min, '-10', '-1', '0', '1', '10', int16_max], - ['-10', '-10', '10', '0', '256', '4', '0']], - output_16=[['0', '100', '-10', '0', '256', '40', '0']]) - add_test_case('IDiv', ['SDiv', 'SRem'], 'Epsilon', 0, - [['1', '1', '10', '10000', int32_max, int32_max, '-1'], - ['1', '256', '4', '10001', '2', int32_max, '1']], - [['1', '0', '2', '0', '1073741823', '1', '-1'], - ['0', '1', '2', '10000', '1', '0', '0']], "cs_6_0", - ''' struct SBinaryIntOp { + add_test_case_int( + "IAdd", + ["Add"], + "Epsilon", + 0, + [ + [int32_min, "-10", "0", "0", "10", int32_max, "486"], + ["0", "10", "-10", "10", "10", "0", "54238"], + ], + [[int32_min, "0", "-10", "10", "20", int32_max, "54724"]], + "binary int", + "+", + input_16=[ + [int16_min, "-10", "0", "0", "10", int16_max], + ["0", "10", "-3114", "272", "15", "0"], + ], + output_16=[[int16_min, "0", "-3114", "272", "25", int16_max]], + ) + add_test_case_int( + "ISub", + ["Sub"], + "Epsilon", + 0, + [ + [int32_min, "-10", "0", "0", "10", int32_max, "486"], + ["0", "10", "-10", "10", "10", "0", "54238"], + ], + [[int32_min, "-20", "10", "-10", "0", int32_max, "-53752"]], + "binary int", + "-", + input_16=[ + [int16_min, "-10", "0", "0", "10", int16_max], + ["0", "10", "-3114", "272", "15", "0"], + ], + output_16=[[int16_min, "-20", "3114", "-272", "-5", int16_max]], + ) + add_test_case_int( + "IMax", + ["IMax"], + "Epsilon", + 0, + [ + [int32_min, "-10", "0", "0", "10", int32_max], + ["0", "10", "-10", "10", "10", "0"], + ], + [["0", "10", "0", "10", "10", int32_max]], + "binary int call", + "max", + input_16=[ + [int16_min, "-10", "0", "0", "10", int16_max], + ["0", "10", "-3114", "272", "15", "0"], + ], + output_16=[["0", "10", "0", "272", "15", int16_max]], + ) + add_test_case_int( + "IMin", + ["IMin"], + "Epsilon", + 0, + [ + [int32_min, "-10", "0", "0", "10", int32_max], + ["0", "10", "-10", "10", "10", "0"], + ], + [[int32_min, "-10", "-10", "0", "10", "0"]], + "binary int call", + "min", + input_16=[ + [int16_min, "-10", "0", "0", "10", int16_max], + ["0", "10", "-3114", "272", "15", "0"], + ], + output_16=[[int16_min, "-10", "-3114", "0", "10", "0"]], + ) + add_test_case_int( + "IMul", + ["Mul"], + "Epsilon", + 0, + [ + [int32_min, "-10", "-1", "0", "1", "10", "10000", int32_max, int32_max], + ["-10", "-10", "10", "0", "256", "4", "10001", "0", int32_max], + ], + [["0", "100", "-10", "0", "256", "40", "100010000", "0", "1"]], + "binary int", + "*", + input_16=[ + [int16_min, "-10", "-1", "0", "1", "10", int16_max], + ["-10", "-10", "10", "0", "256", "4", "0"], + ], + output_16=[["0", "100", "-10", "0", "256", "40", "0"]], + ) + add_test_case( + "IDiv", + ["SDiv", "SRem"], + "Epsilon", + 0, + [ + ["1", "1", "10", "10000", int32_max, int32_max, "-1"], + ["1", "256", "4", "10001", "2", int32_max, "1"], + ], + [ + ["1", "0", "2", "0", "1073741823", "1", "-1"], + ["0", "1", "2", "10000", "1", "0", "0"], + ], + "cs_6_0", + """ struct SBinaryIntOp { int input1; int input2; int output1; @@ -1005,99 +2200,311 @@ def add_test_cases(): l.output1 = l.input1 / l.input2; l.output2 = l.input1 % l.input2; g_buf[GI] = l; - };''') - add_test_case_int('Shl', ['Shl'], 'Epsilon', 0, - [['1', '1', '0x1010', '0xa', '-1', '0x12341234', '-1'], - ['0', '259', '4', '2', '0', '15', '3']], - [['0x1', '0x8', '0x10100', '0x28', '-1','0x091a0000', '-8']], - "binary int", "<<", - input_16=[['1', '1', '0x0101', '0xa', '-1', '0x1234', '-1'], - ['0', '259', '4', '2', '0', '13', '3']], - output_16=[['0x1', '0x8', '0x1010', '0x28', '-1','0x8000', '-8']]) - add_test_case_int("LShr", ['LShr'], 'Epsilon', 0, - [['1', '1', '0xffff', '0x7fffffff', '0x70001234', '0x12340ab3', '0x7fffffff'], - ['0', '1', '4', '30', '15', '16', '1']], - [['1', '0', '0xfff', '1', '0xe000', '0x1234', '0x3fffffff']], - "binary int", ">>", - input_16=[['1', '1', '0x7fff', '0x7fff'], - ['0', '1', '4', '14']], - output_16=[['1', '0', '0x07ff', '1']] - ) - add_test_case_int("And", ['And'], 'Epsilon', 0, - [['0x1', '0x01', '0x7fff0000', '0x33333333', '0x137f', '0x12345678', '0xa341', '-1'], - ['0x1', '0xf0', '0x0000ffff', '0x22222222', '0xec80', '-1', '0x3471', '-1']], - [['0x1', '0x00', '0x0', '0x22222222', '0x0', '0x12345678', '0x2041', '-1']], - "binary int", "&", - input_16=[['0x1', '0x01', '0x7fff', '0x3333', '0x137f', '0x1234', '0xa341', '-1'], - ['0x1', '0xf0', '0x0000', '0x2222', '0xec80', '-1', '0x3471', '-1']], - output_16=[['0x1', '0x00', '0x0', '0x2222', '0x0', '0x1234', '0x2041', '-1']], - ) - add_test_case_int("Or", ['Or'], 'Epsilon', 0, - [['0x1', '0x01', '0x7fff0000', '0x11111111', '0x137f', '0x0', '0x12345678', '0xa341', '-1'], - ['0x1', '0xf0', '0x0000ffff', '0x22222222', '0xec80', '0x0', '0x00000000', '0x3471', '-1']], - [['0x1', '0xf1', '0x7fffffff', '0x33333333', '0xffff', '0x0', '0x12345678', '0xb771', '-1']], - "binary int", "|", - input_16=[['0x1', '0x01', '0x7fff', '0x3333', '0x137f', '0x1234', '0xa341', '-1'], - ['0x1', '0xf0', '0x0000', '0x2222', '0xec80', '0xffff', '0x3471', '-1']], - output_16=[['0x1', '0xf1', '0x7fff', '0x3333', '0xffff', '0xffff', '0xb771', '-1']], - ) - add_test_case_int("Xor", ['Xor'], 'Epsilon', 0, - [['0x1', '0x01', '0x7fff0000', '0x11111111', '0x137f', '0x0', '0x12345678', '0xa341', '-1'], - ['0x1', '0xf0', '0x0000ffff', '0x22222222', '0xec80', '0x0', '0x00000000', '0x3471', '-1']], - [['0x0', '0xf1', '0x7fffffff', '0x33333333', '0xffff', '0x0', '0x12345678', '0x9730', '0x00000000']], - "binary int", "^", - input_16=[['0x1', '0x01', '0x7fff', '0x1111', '0x137f', '0x0', '0x1234', '0xa341', '-1'], - ['0x1', '0xf0', '0x0000', '0x2222', '0xec80', '0x0', '0x0000', '0x3471', '-1']], - output_16=[['0x0', '0xf1', '0x7fff', '0x3333', '0xffff', '0x0', '0x1234', '0x9730', '0x0000']], + };""", + ) + add_test_case_int( + "Shl", + ["Shl"], + "Epsilon", + 0, + [ + ["1", "1", "0x1010", "0xa", "-1", "0x12341234", "-1"], + ["0", "259", "4", "2", "0", "15", "3"], + ], + [["0x1", "0x8", "0x10100", "0x28", "-1", "0x091a0000", "-8"]], + "binary int", + "<<", + input_16=[ + ["1", "1", "0x0101", "0xa", "-1", "0x1234", "-1"], + ["0", "259", "4", "2", "0", "13", "3"], + ], + output_16=[["0x1", "0x8", "0x1010", "0x28", "-1", "0x8000", "-8"]], + ) + add_test_case_int( + "LShr", + ["LShr"], + "Epsilon", + 0, + [ + [ + "1", + "1", + "0xffff", + "0x7fffffff", + "0x70001234", + "0x12340ab3", + "0x7fffffff", + ], + ["0", "1", "4", "30", "15", "16", "1"], + ], + [["1", "0", "0xfff", "1", "0xe000", "0x1234", "0x3fffffff"]], + "binary int", + ">>", + input_16=[["1", "1", "0x7fff", "0x7fff"], ["0", "1", "4", "14"]], + output_16=[["1", "0", "0x07ff", "1"]], + ) + add_test_case_int( + "And", + ["And"], + "Epsilon", + 0, + [ + [ + "0x1", + "0x01", + "0x7fff0000", + "0x33333333", + "0x137f", + "0x12345678", + "0xa341", + "-1", + ], + ["0x1", "0xf0", "0x0000ffff", "0x22222222", "0xec80", "-1", "0x3471", "-1"], + ], + [["0x1", "0x00", "0x0", "0x22222222", "0x0", "0x12345678", "0x2041", "-1"]], + "binary int", + "&", + input_16=[ + ["0x1", "0x01", "0x7fff", "0x3333", "0x137f", "0x1234", "0xa341", "-1"], + ["0x1", "0xf0", "0x0000", "0x2222", "0xec80", "-1", "0x3471", "-1"], + ], + output_16=[["0x1", "0x00", "0x0", "0x2222", "0x0", "0x1234", "0x2041", "-1"]], + ) + add_test_case_int( + "Or", + ["Or"], + "Epsilon", + 0, + [ + [ + "0x1", + "0x01", + "0x7fff0000", + "0x11111111", + "0x137f", + "0x0", + "0x12345678", + "0xa341", + "-1", + ], + [ + "0x1", + "0xf0", + "0x0000ffff", + "0x22222222", + "0xec80", + "0x0", + "0x00000000", + "0x3471", + "-1", + ], + ], + [ + [ + "0x1", + "0xf1", + "0x7fffffff", + "0x33333333", + "0xffff", + "0x0", + "0x12345678", + "0xb771", + "-1", + ] + ], + "binary int", + "|", + input_16=[ + ["0x1", "0x01", "0x7fff", "0x3333", "0x137f", "0x1234", "0xa341", "-1"], + ["0x1", "0xf0", "0x0000", "0x2222", "0xec80", "0xffff", "0x3471", "-1"], + ], + output_16=[ + ["0x1", "0xf1", "0x7fff", "0x3333", "0xffff", "0xffff", "0xb771", "-1"] + ], + ) + add_test_case_int( + "Xor", + ["Xor"], + "Epsilon", + 0, + [ + [ + "0x1", + "0x01", + "0x7fff0000", + "0x11111111", + "0x137f", + "0x0", + "0x12345678", + "0xa341", + "-1", + ], + [ + "0x1", + "0xf0", + "0x0000ffff", + "0x22222222", + "0xec80", + "0x0", + "0x00000000", + "0x3471", + "-1", + ], + ], + [ + [ + "0x0", + "0xf1", + "0x7fffffff", + "0x33333333", + "0xffff", + "0x0", + "0x12345678", + "0x9730", + "0x00000000", + ] + ], + "binary int", + "^", + input_16=[ + [ + "0x1", + "0x01", + "0x7fff", + "0x1111", + "0x137f", + "0x0", + "0x1234", + "0xa341", + "-1", + ], + [ + "0x1", + "0xf0", + "0x0000", + "0x2222", + "0xec80", + "0x0", + "0x0000", + "0x3471", + "-1", + ], + ], + output_16=[ + [ + "0x0", + "0xf1", + "0x7fff", + "0x3333", + "0xffff", + "0x0", + "0x1234", + "0x9730", + "0x0000", + ] + ], ) # Binary Uint - add_test_case_int('UAdd', ['Add'], 'Epsilon', 0, - [['2147483648', '4294967285', '0', '0', '10', int32_max, '486'], - ['0', '10', '0', '10', '10', '0', '54238']], - [['2147483648', uint32_max, '0', '10', '20', int32_max, '54724']], - "binary uint", "+", - input_16=[['323', '0xfff5', '0', '0', '10', uint16_max, '486'], - ['0', '10', '0', '10', '10', '0', '334']], - output_16=[['323', uint16_max, '0', '10', '20', uint16_max, '820']]) - add_test_case_int('USub', ['Sub'], 'Epsilon', 0, - [['2147483648', uint32_max, '0', '0', '30', int32_max, '54724'], - ['0', '10', '0', '10', '10', '0', '54238']], - [['2147483648', '4294967285', '0', '4294967286', '20', int32_max, '486']], - "binary uint", "-", - input_16=[['323', uint16_max, '0', '0', '10', uint16_max, '486'], - ['0', '10', '0', '10', '10', '0', '334']], - output_16=[['323', '0xfff5', '0', '-10', '0', uint16_max, '152']]) - add_test_case_int('UMax', ['UMax'], 'Epsilon', 0, - [['0', '0', '10', '10000', int32_max, uint32_max], - ['0', '256', '4', '10001', '0', uint32_max]], - [['0', '256', '10', '10001', int32_max, uint32_max]], - "binary uint call", "max", - input_16=[['0', '0', '10', '10000', int16_max, uint16_max], - ['0', '256', '4', '10001', '0', uint16_max]], - output_16=[['0', '256', '10', '10001', int16_max, uint16_max]]) - add_test_case_int('UMin', ['UMin'], 'Epsilon', 0, - [['0', '0', '10', '10000', int32_max, uint32_max], - ['0', '256', '4', '10001', '0', uint32_max]], - [['0', '0', '4', '10000', '0', uint32_max]], - "binary uint call", "min", - input_16=[['0', '0', '10', '10000', int16_max, uint16_max], - ['0', '256', '4', '10001', '0', uint16_max]], - output_16=[['0', '0', '4', '10000', '0', uint16_max]]) - add_test_case_int('UMul', ['Mul'], 'Epsilon', 0, - [['0', '1', '10', '10000', int32_max], - ['0', '256', '4', '10001', '0']], - [['0', '256', '40', '100010000', '0']], - "binary uint", "*", - input_16=[['0', '0', '10', '100', int16_max], - ['0', '256', '4', '101', '0']], - output_16=[['0', '0', '40', '10100', '0']]) - add_test_case('UDiv', ['UDiv', 'URem'], 'Epsilon', 0, - [['1', '1', '10', '10000', int32_max, int32_max, '0xffffffff'], - ['0', '256', '4', '10001', '0', int32_max, '1']], - [['0xffffffff', '0', '2', '0', '0xffffffff', '1', '0xffffffff'], - ['0xffffffff', '1', '2', '10000', '0xffffffff', '0', '0']], 'cs_6_0', - ''' struct SBinaryUintOp { + add_test_case_int( + "UAdd", + ["Add"], + "Epsilon", + 0, + [ + ["2147483648", "4294967285", "0", "0", "10", int32_max, "486"], + ["0", "10", "0", "10", "10", "0", "54238"], + ], + [["2147483648", uint32_max, "0", "10", "20", int32_max, "54724"]], + "binary uint", + "+", + input_16=[ + ["323", "0xfff5", "0", "0", "10", uint16_max, "486"], + ["0", "10", "0", "10", "10", "0", "334"], + ], + output_16=[["323", uint16_max, "0", "10", "20", uint16_max, "820"]], + ) + add_test_case_int( + "USub", + ["Sub"], + "Epsilon", + 0, + [ + ["2147483648", uint32_max, "0", "0", "30", int32_max, "54724"], + ["0", "10", "0", "10", "10", "0", "54238"], + ], + [["2147483648", "4294967285", "0", "4294967286", "20", int32_max, "486"]], + "binary uint", + "-", + input_16=[ + ["323", uint16_max, "0", "0", "10", uint16_max, "486"], + ["0", "10", "0", "10", "10", "0", "334"], + ], + output_16=[["323", "0xfff5", "0", "-10", "0", uint16_max, "152"]], + ) + add_test_case_int( + "UMax", + ["UMax"], + "Epsilon", + 0, + [ + ["0", "0", "10", "10000", int32_max, uint32_max], + ["0", "256", "4", "10001", "0", uint32_max], + ], + [["0", "256", "10", "10001", int32_max, uint32_max]], + "binary uint call", + "max", + input_16=[ + ["0", "0", "10", "10000", int16_max, uint16_max], + ["0", "256", "4", "10001", "0", uint16_max], + ], + output_16=[["0", "256", "10", "10001", int16_max, uint16_max]], + ) + add_test_case_int( + "UMin", + ["UMin"], + "Epsilon", + 0, + [ + ["0", "0", "10", "10000", int32_max, uint32_max], + ["0", "256", "4", "10001", "0", uint32_max], + ], + [["0", "0", "4", "10000", "0", uint32_max]], + "binary uint call", + "min", + input_16=[ + ["0", "0", "10", "10000", int16_max, uint16_max], + ["0", "256", "4", "10001", "0", uint16_max], + ], + output_16=[["0", "0", "4", "10000", "0", uint16_max]], + ) + add_test_case_int( + "UMul", + ["Mul"], + "Epsilon", + 0, + [["0", "1", "10", "10000", int32_max], ["0", "256", "4", "10001", "0"]], + [["0", "256", "40", "100010000", "0"]], + "binary uint", + "*", + input_16=[["0", "0", "10", "100", int16_max], ["0", "256", "4", "101", "0"]], + output_16=[["0", "0", "40", "10100", "0"]], + ) + add_test_case( + "UDiv", + ["UDiv", "URem"], + "Epsilon", + 0, + [ + ["1", "1", "10", "10000", int32_max, int32_max, "0xffffffff"], + ["0", "256", "4", "10001", "0", int32_max, "1"], + ], + [ + ["0xffffffff", "0", "2", "0", "0xffffffff", "1", "0xffffffff"], + ["0xffffffff", "1", "2", "10000", "0xffffffff", "0", "0"], + ], + "cs_6_0", + """ struct SBinaryUintOp { uint input1; uint input2; uint output1; @@ -1110,13 +2517,23 @@ def add_test_cases(): l.output1 = l.input1 / l.input2; l.output2 = l.input1 % l.input2; g_buf[GI] = l; - };''') - add_test_case('UAddc', ['UAddc'], 'Epsilon', 0, - [['1', '1', '10000', '0x80000000', '0x7fffffff', '0xffffffff'], - ['0', '256', '10001', '1', '0x7fffffff', '0x7fffffff']], - [['2', '2', '20000', '0', '0xfffffffe', '0xfffffffe'], - ['0', '512', '20002', '3', '0xfffffffe', '0xffffffff']], 'cs_6_0', - ''' struct SBinaryUintOp { + };""", + ) + add_test_case( + "UAddc", + ["UAddc"], + "Epsilon", + 0, + [ + ["1", "1", "10000", "0x80000000", "0x7fffffff", "0xffffffff"], + ["0", "256", "10001", "1", "0x7fffffff", "0x7fffffff"], + ], + [ + ["2", "2", "20000", "0", "0xfffffffe", "0xfffffffe"], + ["0", "512", "20002", "3", "0xfffffffe", "0xffffffff"], + ], + "cs_6_0", + """ struct SBinaryUintOp { uint input1; uint input2; uint output1; @@ -1131,53 +2548,132 @@ def add_test_cases(): l.output1 = y.x; l.output2 = y.y; g_buf[GI] = l; - };''') + };""", + ) # Tertiary Int - add_test_case_int('IMad', ['IMad'], 'epsilon', 0, [[ - '-2147483647', '-256', '-1', '0', '1', '2', '16', int32_max, '1', - '-1', '1', '10' - ], ['1', '-256', '-1', '0', '1', '3', '16', '0', '1', '-1', '10', '100'], [ - '0', '0', '0', '0', '1', '3', '1', '255', '2147483646', '-2147483647', - '-10', '-2000' - ]], [[ - '-2147483647', '65536', '1', '0', '2', '9', '257', '255', int32_max, - '-2147483646', '0', '-1000' - ]], "tertiary int", "mad", - input_16=[[int16_min, '-256', '-1', '0', '1', '2', '16', int16_max], - ['1','8','-1', '0', '1', '3', '16','1'], - ['0', '0', '1', '3', '250', '-30', int16_min, '-50']], - output_16=[[int16_min, '-2048', '2', '3', '251', '-24', '-32512', '32717']] - ) - - add_test_case_int('UMad', ['UMad'], 'epsilon', 0, - [['0', '1', '2', '16', int32_max, '0', '10'], [ - '0', '1', '2', '16', '1', '0', '10' - ], ['0', '0', '1', '15', '0', '10', '10']], - [['0', '1', '5', '271', int32_max, '10', '110']], - "tertiary uint", "mad", - input_16=[['0', '1', '2', '16', int16_max, '0', '10'], [ - '0', '1', '2', '16', '1', '0', '10' - ], ['0', '0', '1', '15', '0', '10', '10']], - output_16=[['0', '1', '5', '271', int16_max, '10', '110']], + add_test_case_int( + "IMad", + ["IMad"], + "epsilon", + 0, + [ + [ + "-2147483647", + "-256", + "-1", + "0", + "1", + "2", + "16", + int32_max, + "1", + "-1", + "1", + "10", + ], + ["1", "-256", "-1", "0", "1", "3", "16", "0", "1", "-1", "10", "100"], + [ + "0", + "0", + "0", + "0", + "1", + "3", + "1", + "255", + "2147483646", + "-2147483647", + "-10", + "-2000", + ], + ], + [ + [ + "-2147483647", + "65536", + "1", + "0", + "2", + "9", + "257", + "255", + int32_max, + "-2147483646", + "0", + "-1000", + ] + ], + "tertiary int", + "mad", + input_16=[ + [int16_min, "-256", "-1", "0", "1", "2", "16", int16_max], + ["1", "8", "-1", "0", "1", "3", "16", "1"], + ["0", "0", "1", "3", "250", "-30", int16_min, "-50"], + ], + output_16=[[int16_min, "-2048", "2", "3", "251", "-24", "-32512", "32717"]], + ) + + add_test_case_int( + "UMad", + ["UMad"], + "epsilon", + 0, + [ + ["0", "1", "2", "16", int32_max, "0", "10"], + ["0", "1", "2", "16", "1", "0", "10"], + ["0", "0", "1", "15", "0", "10", "10"], + ], + [["0", "1", "5", "271", int32_max, "10", "110"]], + "tertiary uint", + "mad", + input_16=[ + ["0", "1", "2", "16", int16_max, "0", "10"], + ["0", "1", "2", "16", "1", "0", "10"], + ["0", "0", "1", "15", "0", "10", "10"], + ], + output_16=[["0", "1", "5", "271", int16_max, "10", "110"]], ) # Dot - add_test_case('Dot', ['Dot2', 'Dot3', 'Dot4'], 'epsilon', 0.008, [[ - 'NaN,NaN,NaN,NaN', '-Inf,-Inf,-Inf,-Inf', - '-denorm,-denorm,-denorm,-denorm', '-0,-0,-0,-0', '0,0,0,0', - 'denorm,denorm,denorm,denorm', 'Inf,Inf,Inf,Inf', '1,1,1,1', - '-10,0,0,10', 'Inf,Inf,Inf,-Inf' - ], [ - 'NaN,NaN,NaN,NaN', '-Inf,-Inf,-Inf,-Inf', - '-denorm,-denorm,-denorm,-denorm', '-0,-0,-0,-0', '0,0,0,0', - 'denorm,denorm,denorm,denorm', 'Inf,Inf,Inf,Inf', '1,1,1,1', - '10,0,0,10', 'Inf,Inf,Inf,Inf' - ]], [ - [nan, p_inf, 0, 0, 0, 0, p_inf, 2, -100, p_inf], - [nan, p_inf, 0, 0, 0, 0, p_inf, 3, -100, p_inf], - [nan, p_inf, 0, 0, 0, 0, p_inf, 4, 0, nan], - ], 'cs_6_0', ''' struct SDotOp { + add_test_case( + "Dot", + ["Dot2", "Dot3", "Dot4"], + "epsilon", + 0.008, + [ + [ + "NaN,NaN,NaN,NaN", + "-Inf,-Inf,-Inf,-Inf", + "-denorm,-denorm,-denorm,-denorm", + "-0,-0,-0,-0", + "0,0,0,0", + "denorm,denorm,denorm,denorm", + "Inf,Inf,Inf,Inf", + "1,1,1,1", + "-10,0,0,10", + "Inf,Inf,Inf,-Inf", + ], + [ + "NaN,NaN,NaN,NaN", + "-Inf,-Inf,-Inf,-Inf", + "-denorm,-denorm,-denorm,-denorm", + "-0,-0,-0,-0", + "0,0,0,0", + "denorm,denorm,denorm,denorm", + "Inf,Inf,Inf,Inf", + "1,1,1,1", + "10,0,0,10", + "Inf,Inf,Inf,Inf", + ], + ], + [ + [nan, p_inf, 0, 0, 0, 0, p_inf, 2, -100, p_inf], + [nan, p_inf, 0, 0, 0, 0, p_inf, 3, -100, p_inf], + [nan, p_inf, 0, 0, 0, 0, p_inf, 4, 0, nan], + ], + "cs_6_0", + """ struct SDotOp { float4 input1; float4 input2; float o_dot2; @@ -1192,25 +2688,93 @@ def add_test_cases(): l.o_dot3 = dot(l.input1.xyz, l.input2.xyz); l.o_dot4 = dot(l.input1.xyzw, l.input2.xyzw); g_buf[GI] = l; - };''') + };""", + ) # Dot2AddHalf - add_test_case('Dot2AddHalf', ['Dot2AddHalf'], 'epsilon', 0.008, [[ - '1,2', '1,-2', '1,2', '-1,2', '1,2', '-1,2', '1,2', '-1,-2', - '65504,1', '-65504,1', '1,65504', '1,-65504', 'inf,inf', - 'denorm,denorm', '-denorm,-denorm', 'nan,nan' - ], [ - '3,4', '-3,4', '3,4', '3,-4', '3,4', '-3,4', '3,4', '-3,-4', - '1,65504', '1,-65504', '65504,1', '-65504,1', 'inf,inf', - 'denorm,denorm', '-denorm,-denorm', 'nan,nan' - ], [ - '0', '0', '10', '10', '-5', '-5', '-30', '-30', '0', '0', - '10000000', '-10000000', 'inf', 'denorm', '-denorm', - 'nan' - ]], [ - [11, -11, 21, -1, 6, 6, -19, -19, 131008, -131008, 10131008, - -10131008, p_inf, 0, 0, nan], - ], 'cs_6_4', ''' struct SDot2AddHalfOp { + add_test_case( + "Dot2AddHalf", + ["Dot2AddHalf"], + "epsilon", + 0.008, + [ + [ + "1,2", + "1,-2", + "1,2", + "-1,2", + "1,2", + "-1,2", + "1,2", + "-1,-2", + "65504,1", + "-65504,1", + "1,65504", + "1,-65504", + "inf,inf", + "denorm,denorm", + "-denorm,-denorm", + "nan,nan", + ], + [ + "3,4", + "-3,4", + "3,4", + "3,-4", + "3,4", + "-3,4", + "3,4", + "-3,-4", + "1,65504", + "1,-65504", + "65504,1", + "-65504,1", + "inf,inf", + "denorm,denorm", + "-denorm,-denorm", + "nan,nan", + ], + [ + "0", + "0", + "10", + "10", + "-5", + "-5", + "-30", + "-30", + "0", + "0", + "10000000", + "-10000000", + "inf", + "denorm", + "-denorm", + "nan", + ], + ], + [ + [ + 11, + -11, + 21, + -1, + 6, + 6, + -19, + -19, + 131008, + -131008, + 10131008, + -10131008, + p_inf, + 0, + 0, + nan, + ], + ], + "cs_6_4", + """ struct SDot2AddHalfOp { half2 input1; half2 input2; float acc; @@ -1222,22 +2786,48 @@ def add_test_cases(): SDot2AddHalfOp l = g_buf[GI]; l.result = dot2add(l.input1, l.input2, l.acc); g_buf[GI] = l; - };''', shader_arguments='-enable-16bit-types') + };""", + shader_arguments="-enable-16bit-types", + ) # Dot4AddI8Packed - add_test_case('Dot4AddI8Packed', ['Dot4AddI8Packed'], 'epsilon', 0, [[ - '0x00000102', '0x00000102', '0x00000102', '0x00000102', - '0XFFFFFFFF', '0x80808080', '0x80808080', '0x807F807F', - '0x7F7F7F7F', '0x80808080' - ], [ - '0x00000304', '0x00000304', '0x00000304', '0x00000304', - '0xFFFFFFFF', '0x01010101', '0x7F7F7F7F', '0x807F807F', - '0x7F7F7F7F', '0x80808080' - ], [ - '0', '10', '-5', '-30', '0', '0', '0', '0', '0', '0' - ]], [ - [11, 21, 6, -19, 4, -512, -65024, 65026, 64516, 65536], - ], 'cs_6_4', ''' struct SDot4AddI8PackedOp { + add_test_case( + "Dot4AddI8Packed", + ["Dot4AddI8Packed"], + "epsilon", + 0, + [ + [ + "0x00000102", + "0x00000102", + "0x00000102", + "0x00000102", + "0XFFFFFFFF", + "0x80808080", + "0x80808080", + "0x807F807F", + "0x7F7F7F7F", + "0x80808080", + ], + [ + "0x00000304", + "0x00000304", + "0x00000304", + "0x00000304", + "0xFFFFFFFF", + "0x01010101", + "0x7F7F7F7F", + "0x807F807F", + "0x7F7F7F7F", + "0x80808080", + ], + ["0", "10", "-5", "-30", "0", "0", "0", "0", "0", "0"], + ], + [ + [11, 21, 6, -19, 4, -512, -65024, 65026, 64516, 65536], + ], + "cs_6_4", + """ struct SDot4AddI8PackedOp { dword input1; dword input2; int acc; @@ -1249,20 +2839,25 @@ def add_test_cases(): SDot4AddI8PackedOp l = g_buf[GI]; l.result = dot4add_i8packed(l.input1, l.input2, l.acc); g_buf[GI] = l; - };''') + };""", + ) # Dot4AddU8Packed - add_test_case('Dot4AddU8Packed', ['Dot4AddU8Packed'], 'epsilon', 0, [[ - '0x00000102', '0x00000102', '0x01234567', '0xFFFFFFFF', - '0xFFFFFFFF' - ], [ - '0x00000304', '0x00000304', '0x23456789', '0xFFFFFFFF', - '0xFFFFFFFF' - ], [ - '0', '10', '10000', '0', '3000000000' - ]], [ - [11, 21, 33668, 260100, 3000260100], - ], 'cs_6_4', ''' struct SDot4AddU8PackedOp { + add_test_case( + "Dot4AddU8Packed", + ["Dot4AddU8Packed"], + "epsilon", + 0, + [ + ["0x00000102", "0x00000102", "0x01234567", "0xFFFFFFFF", "0xFFFFFFFF"], + ["0x00000304", "0x00000304", "0x23456789", "0xFFFFFFFF", "0xFFFFFFFF"], + ["0", "10", "10000", "0", "3000000000"], + ], + [ + [11, 21, 33668, 260100, 3000260100], + ], + "cs_6_4", + """ struct SDot4AddU8PackedOp { dword input1; dword input2; dword acc; @@ -1274,17 +2869,29 @@ def add_test_cases(): SDot4AddU8PackedOp l = g_buf[GI]; l.result = dot4add_u8packed(l.input1, l.input2, l.acc); g_buf[GI] = l; - };''') + };""", + ) # Quaternary # Msad4 intrinsic calls both Bfi and Msad. Currently this is the only way to call bfi instruction from HLSL - add_test_case('Bfi', ['Bfi', 'Msad'], 'epsilon', 0, - [["0xA100B2C3", "0x00000000", "0xFFFF01C1", "0xFFFFFFFF"], [ - "0xD7B0C372, 0x4F57C2A3", "0xFFFFFFFF, 0x00000000", - "0x38A03AEF, 0x38194DA3", "0xFFFFFFFF, 0x00000000" - ], ["1,2,3,4", "1,2,3,4", "0,0,0,0", "10,10,10,10"]], - [['153,6,92,113', '1,2,3,4', '397,585,358,707', '10,265,520,775']], - 'cs_6_0', ''' struct SMsad4 { + add_test_case( + "Bfi", + ["Bfi", "Msad"], + "epsilon", + 0, + [ + ["0xA100B2C3", "0x00000000", "0xFFFF01C1", "0xFFFFFFFF"], + [ + "0xD7B0C372, 0x4F57C2A3", + "0xFFFFFFFF, 0x00000000", + "0x38A03AEF, 0x38194DA3", + "0xFFFFFFFF, 0x00000000", + ], + ["1,2,3,4", "1,2,3,4", "0,0,0,0", "10,10,10,10"], + ], + [["153,6,92,113", "1,2,3,4", "397,585,358,707", "10,265,520,775"]], + "cs_6_0", + """ struct SMsad4 { uint ref; uint2 source; uint4 accum; @@ -1296,614 +2903,861 @@ def add_test_cases(): SMsad4 l = g_buf[GI]; l.result = msad4(l.ref, l.source, l.accum); g_buf[GI] = l; - };''') + };""", + ) # Wave Active Tests - add_test_case('WaveActiveSum', ['WaveActiveOp', 'WaveReadLaneFirst', 'WaveReadLaneAt'], 'Epsilon', 0, - [['1', '2', '3', '4'], ['0'], ['2', '4', '8', '-64']], [], - 'cs_6_0', get_shader_text("wave op int", "WaveActiveSum")) - add_test_case('WaveActiveProduct', ['WaveActiveOp', 'WaveReadLaneFirst', 'WaveReadLaneAt'], 'Epsilon', 0, - [['1', '2', '3', '4'], ['0'], ['1', '2', '4', '-64']], [], - 'cs_6_0', get_shader_text("wave op int", "WaveActiveProduct")) - - add_test_case('WaveActiveCountBits', ['WaveAllBitCount', 'WaveReadLaneFirst', 'WaveReadLaneAt'], 'Epsilon', 0, - [['1', '2', '3', '4'], ['0'], ['1', '10', '-4', '-64'], - ['-100', '-1000', '300']], [], 'cs_6_0', - get_shader_text("wave op int count", "WaveActiveCountBits")) - add_test_case('WaveActiveMax', ['WaveActiveOp', 'WaveReadLaneFirst', 'WaveReadLaneAt'], 'Epsilon', 0, - [['1', '2', '3', '4'], ['0'], ['1', '10', '-4', '-64'], - ['-100', '-1000', '300']], [], 'cs_6_0', - get_shader_text("wave op int", "WaveActiveMax")) - add_test_case('WaveActiveMin', ['WaveActiveOp', 'WaveReadLaneFirst', 'WaveReadLaneAt'], 'Epsilon', 0, - [['1', '2', '3', '4', '5', '6', '7', '8', '9', '10'], ['0'], - ['1', '10', '-4', '-64'], ['-100', '-1000', '300']], [], - 'cs_6_0', get_shader_text("wave op int", "WaveActiveMin")) - add_test_case('WaveActiveAllEqual', ['WaveActiveAllEqual'], 'Epsilon', 0, - [['1', '2', '3', '4', '1', '1', '1', '1'], ['3'], ['-10']], - [], 'cs_6_0', get_shader_text("wave op int", "WaveActiveAllEqual")) - add_test_case('WaveActiveAnyTrue', ['WaveAnyTrue', 'WaveReadLaneFirst', 'WaveReadLaneAt'], 'Epsilon', 0, - [['1', '0', '1', '0', '1'], ['1'], ['0']], [], 'cs_6_0', - get_shader_text("wave op int", "WaveActiveAnyTrue")) - add_test_case('WaveActiveAllTrue', ['WaveAllTrue', 'WaveReadLaneFirst', 'WaveReadLaneAt'], 'Epsilon', 0, - [['1', '0', '1', '0', '1'], ['1'], ['1']], [], 'cs_6_0', - get_shader_text("wave op int", "WaveActiveAllTrue")) - - add_test_case('WaveActiveUSum', ['WaveActiveOp', 'WaveReadLaneFirst', 'WaveReadLaneAt'], 'Epsilon', 0, - [['1', '2', '3', '4'], ['0'], ['2', '4', '8', '64']], [], - 'cs_6_0', get_shader_text("wave op uint", "WaveActiveSum")) - add_test_case('WaveActiveUProduct', ['WaveActiveOp', 'WaveReadLaneFirst', 'WaveReadLaneAt'], 'Epsilon', 0, - [['1', '2', '3', '4'], ['0'], ['1', '2', '4', '64']], [], - 'cs_6_0', get_shader_text("wave op uint", "WaveActiveProduct")) - add_test_case('WaveActiveUMax', ['WaveActiveOp', 'WaveReadLaneFirst', 'WaveReadLaneAt'], 'Epsilon', 0, - [['1', '2', '3', '4'], ['0'], ['1', '10', '4', '64']], [], - 'cs_6_0', get_shader_text("wave op uint", "WaveActiveMax")) - add_test_case('WaveActiveUMin', ['WaveActiveOp', 'WaveReadLaneFirst', 'WaveReadLaneAt'], 'Epsilon', 0, - [['1', '2', '3', '4', '5', '6', '7', '8', '9', '10'], ['0'], - ['1', '10', '4', '64']], [], 'cs_6_0', - get_shader_text("wave op uint", "WaveActiveMin")) - add_test_case('WaveActiveBitOr', ['WaveActiveBit'], 'Epsilon', 0, [[ - '0xe0000000', '0x0d000000', '0x00b00000', '0x00070000', '0x0000e000', - '0x00000d00', '0x000000b0', '0x00000007' - ], ['0xedb7edb7', '0xdb7edb7e', '0xb7edb7ed', '0x7edb7edb'], [ - '0x12481248', '0x24812481', '0x48124812', '0x81248124' - ], ['0x00000000', '0xffffffff']], [], 'cs_6_0', get_shader_text("wave op uint", "WaveActiveBitOr")) - add_test_case('WaveActiveBitAnd', ['WaveActiveBit'], 'Epsilon', 0, [[ - '0xefffffff', '0xfdffffff', '0xffbfffff', '0xfff7ffff', '0xffffefff', - '0xfffffdff', '0xffffffbf', '0xfffffff7' - ], ['0xedb7edb7', '0xdb7edb7e', '0xb7edb7ed', '0x7edb7edb'], [ - '0x12481248', '0x24812481', '0x48124812', '0x81248124' - ], ['0x00000000', '0xffffffff']], [], 'cs_6_0', get_shader_text("wave op uint", "WaveActiveBitAnd")) - add_test_case('WaveActiveBitXor', ['WaveActiveBit'], 'Epsilon', 0, [[ - '0xe0000000', '0x0d000000', '0x00b00000', '0x00070000', '0x0000e000', - '0x00000d00', '0x000000b0', '0x00000007' - ], ['0xedb7edb7', '0xdb7edb7e', '0xb7edb7ed', '0x7edb7edb'], [ - '0x12481248', '0x24812481', '0x48124812', '0x81248124' - ], ['0x00000000', '0xffffffff']], [], 'cs_6_0', get_shader_text("wave op uint", "WaveActiveBitXor")) - add_test_case('WavePrefixCountBits', ['WavePrefixBitCount'], 'Epsilon', 0, - [['1', '2', '3', '4', '5'], ['0'], ['1', '10', '-4', '-64'], - ['-100', '-1000', '300']], [], 'cs_6_0', - get_shader_text("wave op int count", "WavePrefixCountBits")) - add_test_case('WavePrefixSum', ['WavePrefixOp'], 'Epsilon', 0, - [['1', '2', '3', '4', '5'], ['0', '1'], ['1', '2', '4', '-64', '128']], - [], 'cs_6_0', get_shader_text("wave op int", "WavePrefixSum")) - add_test_case('WavePrefixProduct', ['WavePrefixOp'], 'Epsilon', 0, - [['1', '2', '3', '4', '5'], ['0', '1'], ['1', '2', '4', '-64', '128']], - [], 'cs_6_0', get_shader_text("wave op int", "WavePrefixProduct")) - add_test_case('WavePrefixUSum', ['WavePrefixOp'], 'Epsilon', 0, - [['1', '2', '3', '4', '5'], ['0', '1'], ['1', '2', '4', '128']], [], - 'cs_6_0', get_shader_text("wave op uint", "WavePrefixSum")) - add_test_case('WavePrefixUProduct', ['WavePrefixOp'], 'Epsilon', 0, - [['1', '2', '3', '4', '5'], ['0', '1'], ['1', '2', '4', '128']], [], - 'cs_6_0', get_shader_text("wave op uint", "WavePrefixProduct")) - - #Wave Multi Prefix Tests - add_test_case('WaveMultiPrefixBitAnd', ['WaveMultiPrefixOp'], 'Epsilon', 0, - [['0', '3', '1', '5', '4'], ['10', '42', '1', '64', '11', '76', '90', '111', '9', '6', '79', '34']], [], - 'cs_6_5', get_shader_text("wave op multi prefix int", "WaveMultiPrefixBitAnd")) - add_test_case('WaveMultiPrefixBitOr', ['WaveMultiPrefixOp'], 'Epsilon', 0, - [['0', '3', '1', '5', '4'], ['10', '42', '1', '64', '11', '76', '90', '111', '9', '6', '79', '34']], [], - 'cs_6_5', get_shader_text("wave op multi prefix int", "WaveMultiPrefixBitOr")) - add_test_case('WaveMultiPrefixBitXor', ['WaveMultiPrefixOp'], 'Epsilon', 0, - [['0', '3', '1', '5', '4'], ['10', '42', '1', '64', '11', '76', '90', '111', '9', '6', '79', '34']], [], - 'cs_6_5', get_shader_text("wave op multi prefix int", "WaveMultiPrefixBitXor")) - add_test_case('WaveMultiPrefixSum', ['WaveMultiPrefixOp'], 'Epsilon', 0, - [['0', '3', '1', '5', '4'], ['10', '42', '1', '64', '11', '76', '90', '111', '9', '6', '79', '34']], [], - 'cs_6_5', get_shader_text("wave op multi prefix int", "WaveMultiPrefixSum")) - add_test_case('WaveMultiPrefixProduct', ['WaveMultiPrefixOp'], 'Epsilon', 0, - [['0', '3', '1', '5', '4'], ['10', '42', '1', '64', '11', '76', '90', '111', '9', '6', '79', '34']], [], - 'cs_6_5', get_shader_text("wave op multi prefix int", "WaveMultiPrefixProduct")) - add_test_case('WaveMultiPrefixCountBits', ['WaveMultiPrefixOp'], 'Epsilon', 0, - [['0', '3', '1', '5', '4'], ['0', '42', '0', '64', '11', '76', '90', '111', '0', '0', '79', '34']], [], - 'cs_6_5', get_shader_text("wave op multi prefix int", "WaveMultiPrefixCountBits")) - - add_test_case('WaveMultiPrefixUBitAnd', ['WaveMultiPrefixOp'], 'Epsilon', 0, - [['0', '3', '1', '5', '4'], ['10', '42', '1', '64', '11', '76', '90', '111', '9', '6', '79', '34']], [], - 'cs_6_5', get_shader_text("wave op multi prefix uint", "WaveMultiPrefixBitAnd")) - add_test_case('WaveMultiPrefixUBitOr', ['WaveMultiPrefixOp'], 'Epsilon', 0, - [['0', '3', '1', '5', '4'], ['10', '42', '1', '64', '11', '76', '90', '111', '9', '6', '79', '34']], [], - 'cs_6_5', get_shader_text("wave op multi prefix uint", "WaveMultiPrefixBitOr")) - add_test_case('WaveMultiPrefixUBitXor', ['WaveMultiPrefixOp'], 'Epsilon', 0, - [['0', '3', '1', '5', '4'], ['10', '42', '1', '64', '11', '76', '90', '111', '9', '6', '79', '34']], [], - 'cs_6_5', get_shader_text("wave op multi prefix uint", "WaveMultiPrefixBitXor")) - add_test_case('WaveMultiPrefixUSum', ['WaveMultiPrefixOp'], 'Epsilon', 0, - [['0', '3', '1', '5', '4'], ['10', '42', '1', '64', '11', '76', '90', '111', '9', '6', '79', '34']], [], - 'cs_6_5', get_shader_text("wave op multi prefix uint", "WaveMultiPrefixSum")) - add_test_case('WaveMultiPrefixUProduct', ['WaveMultiPrefixOp'], 'Epsilon', 0, - [['0', '3', '1', '5', '4'], ['10', '42', '1', '64', '11', '76', '90', '111', '9', '6', '79', '34']], [], - 'cs_6_5', get_shader_text("wave op multi prefix uint", "WaveMultiPrefixProduct")) - add_test_case('WaveMultiPrefixUCountBits', ['WaveMultiPrefixOp'], 'Epsilon', 0, - [['0', '3', '1', '5', '4'], ['0', '42', '0', '64', '11', '76', '90', '111', '0', '0', '79', '34']], [], - 'cs_6_5', get_shader_text("wave op multi prefix uint", "WaveMultiPrefixCountBits")) + add_test_case( + "WaveActiveSum", + ["WaveActiveOp", "WaveReadLaneFirst", "WaveReadLaneAt"], + "Epsilon", + 0, + [["1", "2", "3", "4"], ["0"], ["2", "4", "8", "-64"]], + [], + "cs_6_0", + get_shader_text("wave op int", "WaveActiveSum"), + ) + add_test_case( + "WaveActiveProduct", + ["WaveActiveOp", "WaveReadLaneFirst", "WaveReadLaneAt"], + "Epsilon", + 0, + [["1", "2", "3", "4"], ["0"], ["1", "2", "4", "-64"]], + [], + "cs_6_0", + get_shader_text("wave op int", "WaveActiveProduct"), + ) + + add_test_case( + "WaveActiveCountBits", + ["WaveAllBitCount", "WaveReadLaneFirst", "WaveReadLaneAt"], + "Epsilon", + 0, + [ + ["1", "2", "3", "4"], + ["0"], + ["1", "10", "-4", "-64"], + ["-100", "-1000", "300"], + ], + [], + "cs_6_0", + get_shader_text("wave op int count", "WaveActiveCountBits"), + ) + add_test_case( + "WaveActiveMax", + ["WaveActiveOp", "WaveReadLaneFirst", "WaveReadLaneAt"], + "Epsilon", + 0, + [ + ["1", "2", "3", "4"], + ["0"], + ["1", "10", "-4", "-64"], + ["-100", "-1000", "300"], + ], + [], + "cs_6_0", + get_shader_text("wave op int", "WaveActiveMax"), + ) + add_test_case( + "WaveActiveMin", + ["WaveActiveOp", "WaveReadLaneFirst", "WaveReadLaneAt"], + "Epsilon", + 0, + [ + ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10"], + ["0"], + ["1", "10", "-4", "-64"], + ["-100", "-1000", "300"], + ], + [], + "cs_6_0", + get_shader_text("wave op int", "WaveActiveMin"), + ) + add_test_case( + "WaveActiveAllEqual", + ["WaveActiveAllEqual"], + "Epsilon", + 0, + [["1", "2", "3", "4", "1", "1", "1", "1"], ["3"], ["-10"]], + [], + "cs_6_0", + get_shader_text("wave op int", "WaveActiveAllEqual"), + ) + add_test_case( + "WaveActiveAnyTrue", + ["WaveAnyTrue", "WaveReadLaneFirst", "WaveReadLaneAt"], + "Epsilon", + 0, + [["1", "0", "1", "0", "1"], ["1"], ["0"]], + [], + "cs_6_0", + get_shader_text("wave op int", "WaveActiveAnyTrue"), + ) + add_test_case( + "WaveActiveAllTrue", + ["WaveAllTrue", "WaveReadLaneFirst", "WaveReadLaneAt"], + "Epsilon", + 0, + [["1", "0", "1", "0", "1"], ["1"], ["1"]], + [], + "cs_6_0", + get_shader_text("wave op int", "WaveActiveAllTrue"), + ) + + add_test_case( + "WaveActiveUSum", + ["WaveActiveOp", "WaveReadLaneFirst", "WaveReadLaneAt"], + "Epsilon", + 0, + [["1", "2", "3", "4"], ["0"], ["2", "4", "8", "64"]], + [], + "cs_6_0", + get_shader_text("wave op uint", "WaveActiveSum"), + ) + add_test_case( + "WaveActiveUProduct", + ["WaveActiveOp", "WaveReadLaneFirst", "WaveReadLaneAt"], + "Epsilon", + 0, + [["1", "2", "3", "4"], ["0"], ["1", "2", "4", "64"]], + [], + "cs_6_0", + get_shader_text("wave op uint", "WaveActiveProduct"), + ) + add_test_case( + "WaveActiveUMax", + ["WaveActiveOp", "WaveReadLaneFirst", "WaveReadLaneAt"], + "Epsilon", + 0, + [["1", "2", "3", "4"], ["0"], ["1", "10", "4", "64"]], + [], + "cs_6_0", + get_shader_text("wave op uint", "WaveActiveMax"), + ) + add_test_case( + "WaveActiveUMin", + ["WaveActiveOp", "WaveReadLaneFirst", "WaveReadLaneAt"], + "Epsilon", + 0, + [ + ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10"], + ["0"], + ["1", "10", "4", "64"], + ], + [], + "cs_6_0", + get_shader_text("wave op uint", "WaveActiveMin"), + ) + add_test_case( + "WaveActiveBitOr", + ["WaveActiveBit"], + "Epsilon", + 0, + [ + [ + "0xe0000000", + "0x0d000000", + "0x00b00000", + "0x00070000", + "0x0000e000", + "0x00000d00", + "0x000000b0", + "0x00000007", + ], + ["0xedb7edb7", "0xdb7edb7e", "0xb7edb7ed", "0x7edb7edb"], + ["0x12481248", "0x24812481", "0x48124812", "0x81248124"], + ["0x00000000", "0xffffffff"], + ], + [], + "cs_6_0", + get_shader_text("wave op uint", "WaveActiveBitOr"), + ) + add_test_case( + "WaveActiveBitAnd", + ["WaveActiveBit"], + "Epsilon", + 0, + [ + [ + "0xefffffff", + "0xfdffffff", + "0xffbfffff", + "0xfff7ffff", + "0xffffefff", + "0xfffffdff", + "0xffffffbf", + "0xfffffff7", + ], + ["0xedb7edb7", "0xdb7edb7e", "0xb7edb7ed", "0x7edb7edb"], + ["0x12481248", "0x24812481", "0x48124812", "0x81248124"], + ["0x00000000", "0xffffffff"], + ], + [], + "cs_6_0", + get_shader_text("wave op uint", "WaveActiveBitAnd"), + ) + add_test_case( + "WaveActiveBitXor", + ["WaveActiveBit"], + "Epsilon", + 0, + [ + [ + "0xe0000000", + "0x0d000000", + "0x00b00000", + "0x00070000", + "0x0000e000", + "0x00000d00", + "0x000000b0", + "0x00000007", + ], + ["0xedb7edb7", "0xdb7edb7e", "0xb7edb7ed", "0x7edb7edb"], + ["0x12481248", "0x24812481", "0x48124812", "0x81248124"], + ["0x00000000", "0xffffffff"], + ], + [], + "cs_6_0", + get_shader_text("wave op uint", "WaveActiveBitXor"), + ) + add_test_case( + "WavePrefixCountBits", + ["WavePrefixBitCount"], + "Epsilon", + 0, + [ + ["1", "2", "3", "4", "5"], + ["0"], + ["1", "10", "-4", "-64"], + ["-100", "-1000", "300"], + ], + [], + "cs_6_0", + get_shader_text("wave op int count", "WavePrefixCountBits"), + ) + add_test_case( + "WavePrefixSum", + ["WavePrefixOp"], + "Epsilon", + 0, + [["1", "2", "3", "4", "5"], ["0", "1"], ["1", "2", "4", "-64", "128"]], + [], + "cs_6_0", + get_shader_text("wave op int", "WavePrefixSum"), + ) + add_test_case( + "WavePrefixProduct", + ["WavePrefixOp"], + "Epsilon", + 0, + [["1", "2", "3", "4", "5"], ["0", "1"], ["1", "2", "4", "-64", "128"]], + [], + "cs_6_0", + get_shader_text("wave op int", "WavePrefixProduct"), + ) + add_test_case( + "WavePrefixUSum", + ["WavePrefixOp"], + "Epsilon", + 0, + [["1", "2", "3", "4", "5"], ["0", "1"], ["1", "2", "4", "128"]], + [], + "cs_6_0", + get_shader_text("wave op uint", "WavePrefixSum"), + ) + add_test_case( + "WavePrefixUProduct", + ["WavePrefixOp"], + "Epsilon", + 0, + [["1", "2", "3", "4", "5"], ["0", "1"], ["1", "2", "4", "128"]], + [], + "cs_6_0", + get_shader_text("wave op uint", "WavePrefixProduct"), + ) + + # Wave Multi Prefix Tests + add_test_case( + "WaveMultiPrefixBitAnd", + ["WaveMultiPrefixOp"], + "Epsilon", + 0, + [ + ["0", "3", "1", "5", "4"], + ["10", "42", "1", "64", "11", "76", "90", "111", "9", "6", "79", "34"], + ], + [], + "cs_6_5", + get_shader_text("wave op multi prefix int", "WaveMultiPrefixBitAnd"), + ) + add_test_case( + "WaveMultiPrefixBitOr", + ["WaveMultiPrefixOp"], + "Epsilon", + 0, + [ + ["0", "3", "1", "5", "4"], + ["10", "42", "1", "64", "11", "76", "90", "111", "9", "6", "79", "34"], + ], + [], + "cs_6_5", + get_shader_text("wave op multi prefix int", "WaveMultiPrefixBitOr"), + ) + add_test_case( + "WaveMultiPrefixBitXor", + ["WaveMultiPrefixOp"], + "Epsilon", + 0, + [ + ["0", "3", "1", "5", "4"], + ["10", "42", "1", "64", "11", "76", "90", "111", "9", "6", "79", "34"], + ], + [], + "cs_6_5", + get_shader_text("wave op multi prefix int", "WaveMultiPrefixBitXor"), + ) + add_test_case( + "WaveMultiPrefixSum", + ["WaveMultiPrefixOp"], + "Epsilon", + 0, + [ + ["0", "3", "1", "5", "4"], + ["10", "42", "1", "64", "11", "76", "90", "111", "9", "6", "79", "34"], + ], + [], + "cs_6_5", + get_shader_text("wave op multi prefix int", "WaveMultiPrefixSum"), + ) + add_test_case( + "WaveMultiPrefixProduct", + ["WaveMultiPrefixOp"], + "Epsilon", + 0, + [ + ["0", "3", "1", "5", "4"], + ["10", "42", "1", "64", "11", "76", "90", "111", "9", "6", "79", "34"], + ], + [], + "cs_6_5", + get_shader_text("wave op multi prefix int", "WaveMultiPrefixProduct"), + ) + add_test_case( + "WaveMultiPrefixCountBits", + ["WaveMultiPrefixOp"], + "Epsilon", + 0, + [ + ["0", "3", "1", "5", "4"], + ["0", "42", "0", "64", "11", "76", "90", "111", "0", "0", "79", "34"], + ], + [], + "cs_6_5", + get_shader_text("wave op multi prefix int", "WaveMultiPrefixCountBits"), + ) + + add_test_case( + "WaveMultiPrefixUBitAnd", + ["WaveMultiPrefixOp"], + "Epsilon", + 0, + [ + ["0", "3", "1", "5", "4"], + ["10", "42", "1", "64", "11", "76", "90", "111", "9", "6", "79", "34"], + ], + [], + "cs_6_5", + get_shader_text("wave op multi prefix uint", "WaveMultiPrefixBitAnd"), + ) + add_test_case( + "WaveMultiPrefixUBitOr", + ["WaveMultiPrefixOp"], + "Epsilon", + 0, + [ + ["0", "3", "1", "5", "4"], + ["10", "42", "1", "64", "11", "76", "90", "111", "9", "6", "79", "34"], + ], + [], + "cs_6_5", + get_shader_text("wave op multi prefix uint", "WaveMultiPrefixBitOr"), + ) + add_test_case( + "WaveMultiPrefixUBitXor", + ["WaveMultiPrefixOp"], + "Epsilon", + 0, + [ + ["0", "3", "1", "5", "4"], + ["10", "42", "1", "64", "11", "76", "90", "111", "9", "6", "79", "34"], + ], + [], + "cs_6_5", + get_shader_text("wave op multi prefix uint", "WaveMultiPrefixBitXor"), + ) + add_test_case( + "WaveMultiPrefixUSum", + ["WaveMultiPrefixOp"], + "Epsilon", + 0, + [ + ["0", "3", "1", "5", "4"], + ["10", "42", "1", "64", "11", "76", "90", "111", "9", "6", "79", "34"], + ], + [], + "cs_6_5", + get_shader_text("wave op multi prefix uint", "WaveMultiPrefixSum"), + ) + add_test_case( + "WaveMultiPrefixUProduct", + ["WaveMultiPrefixOp"], + "Epsilon", + 0, + [ + ["0", "3", "1", "5", "4"], + ["10", "42", "1", "64", "11", "76", "90", "111", "9", "6", "79", "34"], + ], + [], + "cs_6_5", + get_shader_text("wave op multi prefix uint", "WaveMultiPrefixProduct"), + ) + add_test_case( + "WaveMultiPrefixUCountBits", + ["WaveMultiPrefixOp"], + "Epsilon", + 0, + [ + ["0", "3", "1", "5", "4"], + ["0", "42", "0", "64", "11", "76", "90", "111", "0", "0", "79", "34"], + ], + [], + "cs_6_5", + get_shader_text("wave op multi prefix uint", "WaveMultiPrefixCountBits"), + ) # generating xml file for execution test using data driven method # TODO: ElementTree is not generating formatted XML. Currently xml file is checked in after VS Code formatter. # Implement xml formatter or import formatter library and use that instead. -def generate_parameter_types(table, num_inputs, num_outputs, has_known_warp_issue=False): + +def generate_parameter_types( + table, num_inputs, num_outputs, has_known_warp_issue=False +): param_types = ET.SubElement(table, "ParameterTypes") ET.SubElement( - param_types, "ParameterType", attrib={ - "Name": "ShaderOp.Target" - }).text = "String" + param_types, "ParameterType", attrib={"Name": "ShaderOp.Target"} + ).text = "String" ET.SubElement( - param_types, "ParameterType", attrib={ - "Name": "ShaderOp.Arguments" - }).text = "String" + param_types, "ParameterType", attrib={"Name": "ShaderOp.Arguments"} + ).text = "String" ET.SubElement( - param_types, "ParameterType", attrib={ - "Name": "ShaderOp.Text" - }).text = "String" + param_types, "ParameterType", attrib={"Name": "ShaderOp.Text"} + ).text = "String" ET.SubElement( - param_types, "ParameterType", attrib={ - "Name": "Validation.Type" - }).text = "String" + param_types, "ParameterType", attrib={"Name": "Validation.Type"} + ).text = "String" ET.SubElement( - param_types, "ParameterType", attrib={ - "Name": "Validation.Tolerance" - }).text = "double" + param_types, "ParameterType", attrib={"Name": "Validation.Tolerance"} + ).text = "double" for i in range(0, num_inputs): ET.SubElement( param_types, "ParameterType", - attrib={ - "Name": 'Validation.Input{}'.format(i + 1), - 'Array': 'true' - }).text = "String" + attrib={"Name": "Validation.Input{}".format(i + 1), "Array": "true"}, + ).text = "String" for i in range(0, num_outputs): ET.SubElement( param_types, "ParameterType", - attrib={ - "Name": 'Validation.Expected{}'.format(i + 1), - 'Array': 'true' - }).text = "String" + attrib={"Name": "Validation.Expected{}".format(i + 1), "Array": "true"}, + ).text = "String" if has_known_warp_issue: - ET.SubElement(param_types, "ParameterType", attrib={"Name":"Warp.Version"}).text = "unsigned int" + ET.SubElement( + param_types, "ParameterType", attrib={"Name": "Warp.Version"} + ).text = "unsigned int" + def generate_parameter_types_wave(table): param_types = ET.SubElement(table, "ParameterTypes") ET.SubElement( - param_types, "ParameterType", attrib={ - "Name": "ShaderOp.Target" - }).text = "String" + param_types, "ParameterType", attrib={"Name": "ShaderOp.Target"} + ).text = "String" ET.SubElement( - param_types, "ParameterType", attrib={ - "Name": "ShaderOp.Text" - }).text = "String" + param_types, "ParameterType", attrib={"Name": "ShaderOp.Text"} + ).text = "String" ET.SubElement( - param_types, - "ParameterType", - attrib={ - "Name": "Validation.NumInputSet" - }).text = "String" + param_types, "ParameterType", attrib={"Name": "Validation.NumInputSet"} + ).text = "String" ET.SubElement( param_types, "ParameterType", - attrib={ - "Name": "Validation.InputSet1", - "Array": "true" - }).text = "String" + attrib={"Name": "Validation.InputSet1", "Array": "true"}, + ).text = "String" ET.SubElement( param_types, "ParameterType", - attrib={ - "Name": "Validation.InputSet2", - "Array": "true" - }).text = "String" + attrib={"Name": "Validation.InputSet2", "Array": "true"}, + ).text = "String" ET.SubElement( param_types, "ParameterType", - attrib={ - "Name": "Validation.InputSet3", - "Array": "true" - }).text = "String" + attrib={"Name": "Validation.InputSet3", "Array": "true"}, + ).text = "String" ET.SubElement( param_types, "ParameterType", - attrib={ - "Name": "Validation.InputSet4", - "Array": "true" - }).text = "String" + attrib={"Name": "Validation.InputSet4", "Array": "true"}, + ).text = "String" + def generate_parameter_types_wave_multi_prefix(table): param_types = ET.SubElement(table, "ParameterTypes") ET.SubElement( - param_types, "ParameterType", attrib={ - "Name": "ShaderOp.Target" - }).text = "String" + param_types, "ParameterType", attrib={"Name": "ShaderOp.Target"} + ).text = "String" ET.SubElement( - param_types, "ParameterType", attrib={ - "Name": "ShaderOp.Text" - }).text = "String" + param_types, "ParameterType", attrib={"Name": "ShaderOp.Text"} + ).text = "String" ET.SubElement( param_types, "ParameterType", - attrib={ - "Name": "Validation.Keys", - "Array": "true" - }).text = "String" + attrib={"Name": "Validation.Keys", "Array": "true"}, + ).text = "String" ET.SubElement( param_types, "ParameterType", - attrib={ - "Name": "Validation.Values", - "Array": "true" - }).text = "String" + attrib={"Name": "Validation.Values", "Array": "true"}, + ).text = "String" + def generate_parameter_types_msad(table): param_types = ET.SubElement(table, "ParameterTypes") ET.SubElement( - param_types, "ParameterType", attrib={ - "Name": "ShaderOp.Text" - }).text = "String" + param_types, "ParameterType", attrib={"Name": "ShaderOp.Text"} + ).text = "String" ET.SubElement( - param_types, "ParameterType", attrib={ - "Name": "Validation.Tolerance" - }).text = "int" + param_types, "ParameterType", attrib={"Name": "Validation.Tolerance"} + ).text = "int" ET.SubElement( param_types, "ParameterType", - attrib={ - "Name": "Validation.Input1", - "Array": "true" - }).text = "unsigned int" + attrib={"Name": "Validation.Input1", "Array": "true"}, + ).text = "unsigned int" ET.SubElement( param_types, "ParameterType", - attrib={ - "Name": "Validation.Input2", - "Array": "true" - }).text = "String" + attrib={"Name": "Validation.Input2", "Array": "true"}, + ).text = "String" ET.SubElement( param_types, "ParameterType", - attrib={ - "Name": "Validation.Input3", - "Array": "true" - }).text = "String" + attrib={"Name": "Validation.Input3", "Array": "true"}, + ).text = "String" ET.SubElement( param_types, "ParameterType", - attrib={ - "Name": "Validation.Expected1", - "Array": "true" - }).text = "String" + attrib={"Name": "Validation.Expected1", "Array": "true"}, + ).text = "String" + def generate_row(table, case): row = ET.SubElement(table, "Row", {"Name": case.test_name}) - ET.SubElement(row, "Parameter", { - "Name": "Validation.Type" - }).text = case.validation_type - ET.SubElement(row, "Parameter", { - "Name": "Validation.Tolerance" - }).text = str(case.validation_tolerance) - ET.SubElement(row, "Parameter", { - "Name": "ShaderOp.Text" - }).text = case.shader_text - ET.SubElement(row, "Parameter", { - "Name": "ShaderOp.Target" - }).text = case.shader_target + ET.SubElement( + row, "Parameter", {"Name": "Validation.Type"} + ).text = case.validation_type + ET.SubElement(row, "Parameter", {"Name": "Validation.Tolerance"}).text = str( + case.validation_tolerance + ) + ET.SubElement(row, "Parameter", {"Name": "ShaderOp.Text"}).text = case.shader_text + ET.SubElement( + row, "Parameter", {"Name": "ShaderOp.Target"} + ).text = case.shader_target for i in range(len(case.input_lists)): - inputs = ET.SubElement(row, "Parameter", { - "Name": "Validation.Input{}".format(i + 1) - }) + inputs = ET.SubElement( + row, "Parameter", {"Name": "Validation.Input{}".format(i + 1)} + ) for val in case.input_lists[i]: ET.SubElement(inputs, "Value").text = str(val) for i in range(len(case.output_lists)): - outputs = ET.SubElement(row, "Parameter", { - "Name": "Validation.Expected{}".format(i + 1) - }) + outputs = ET.SubElement( + row, "Parameter", {"Name": "Validation.Expected{}".format(i + 1)} + ) for val in case.output_lists[i]: ET.SubElement(outputs, "Value").text = str(val) # Optional parameters if case.warp_version > 0: - ET.SubElement(row, "Parameter", {"Name":"Warp.Version"}).text = str(case.warp_version) + ET.SubElement(row, "Parameter", {"Name": "Warp.Version"}).text = str( + case.warp_version + ) if case.shader_arguments != "": - ET.SubElement(row, "Parameter", {"Name":"ShaderOp.Arguments"}).text = case.shader_arguments + ET.SubElement( + row, "Parameter", {"Name": "ShaderOp.Arguments"} + ).text = case.shader_arguments + def generate_row_wave(table, case): row = ET.SubElement(table, "Row", {"Name": case.test_name}) - ET.SubElement(row, "Parameter", { - "Name": "ShaderOp.Name" - }).text = case.test_name - ET.SubElement(row, "Parameter", { - "Name": "ShaderOp.Text" - }).text = case.shader_text - ET.SubElement(row, "Parameter", { - "Name": "Validation.NumInputSet" - }).text = str(len(case.input_lists)) + ET.SubElement(row, "Parameter", {"Name": "ShaderOp.Name"}).text = case.test_name + ET.SubElement(row, "Parameter", {"Name": "ShaderOp.Text"}).text = case.shader_text + ET.SubElement(row, "Parameter", {"Name": "Validation.NumInputSet"}).text = str( + len(case.input_lists) + ) for i in range(len(case.input_lists)): - inputs = ET.SubElement(row, "Parameter", { - "Name": "Validation.InputSet{}".format(i + 1) - }) + inputs = ET.SubElement( + row, "Parameter", {"Name": "Validation.InputSet{}".format(i + 1)} + ) for val in case.input_lists[i]: ET.SubElement(inputs, "Value").text = str(val) + def generate_row_wave_multi(table, case): row = ET.SubElement(table, "Row", {"Name": case.test_name}) - ET.SubElement(row, "Parameter", { - "Name": "ShaderOp.Name" - }).text = case.test_name - ET.SubElement(row, "Parameter", { - "Name": "ShaderOp.Target" - }).text = case.shader_target - ET.SubElement(row, "Parameter", { - "Name": "ShaderOp.Text" - }).text = case.shader_text - inputs = ET.SubElement(row, "Parameter", { - "Name": "Validation.Keys" - }) + ET.SubElement(row, "Parameter", {"Name": "ShaderOp.Name"}).text = case.test_name + ET.SubElement( + row, "Parameter", {"Name": "ShaderOp.Target"} + ).text = case.shader_target + ET.SubElement(row, "Parameter", {"Name": "ShaderOp.Text"}).text = case.shader_text + inputs = ET.SubElement(row, "Parameter", {"Name": "Validation.Keys"}) for val in case.input_lists[0]: ET.SubElement(inputs, "Value").text = str(val) - inputs = ET.SubElement(row, "Parameter", { - "Name": "Validation.Values" - }) + inputs = ET.SubElement(row, "Parameter", {"Name": "Validation.Values"}) for val in case.input_lists[1]: ET.SubElement(inputs, "Value").text = str(val) + def generate_table_for_taef(): - with open("..\\..\\tools\\clang\\unittests\\HLSL\\ShaderOpArithTable.xml", - 'w') as f: + with open( + "..\\..\\tools\\clang\\unittests\\HLSL\\ShaderOpArithTable.xml", "w" + ) as f: tree = ET.ElementTree() - root = ET.Element('Data') + root = ET.Element("Data") # Create tables generate_parameter_types( - ET.SubElement(root, "Table", attrib={ - "Id": "UnaryFloatOpTable" - }), 1, 1, True) + ET.SubElement(root, "Table", attrib={"Id": "UnaryFloatOpTable"}), 1, 1, True + ) generate_parameter_types( - ET.SubElement(root, "Table", attrib={ - "Id": "BinaryFloatOpTable" - }), 2, 2) + ET.SubElement(root, "Table", attrib={"Id": "BinaryFloatOpTable"}), 2, 2 + ) generate_parameter_types( - ET.SubElement(root, "Table", attrib={ - "Id": "TertiaryFloatOpTable" - }), 3, 1) + ET.SubElement(root, "Table", attrib={"Id": "TertiaryFloatOpTable"}), 3, 1 + ) generate_parameter_types( - ET.SubElement(root, "Table", attrib={ - "Id": "UnaryHalfOpTable" - }), 1, 1, True) + ET.SubElement(root, "Table", attrib={"Id": "UnaryHalfOpTable"}), 1, 1, True + ) generate_parameter_types( - ET.SubElement(root, "Table", attrib={ - "Id": "BinaryHalfOpTable" - }), 2, 2) + ET.SubElement(root, "Table", attrib={"Id": "BinaryHalfOpTable"}), 2, 2 + ) generate_parameter_types( - ET.SubElement(root, "Table", attrib={ - "Id": "TertiaryHalfOpTable" - }), 3, 1) + ET.SubElement(root, "Table", attrib={"Id": "TertiaryHalfOpTable"}), 3, 1 + ) generate_parameter_types( - ET.SubElement(root, "Table", attrib={ - "Id": "UnaryIntOpTable" - }), 1, 1) + ET.SubElement(root, "Table", attrib={"Id": "UnaryIntOpTable"}), 1, 1 + ) generate_parameter_types( - ET.SubElement(root, "Table", attrib={ - "Id": "BinaryIntOpTable" - }), 2, 2) + ET.SubElement(root, "Table", attrib={"Id": "BinaryIntOpTable"}), 2, 2 + ) generate_parameter_types( - ET.SubElement(root, "Table", attrib={ - "Id": "TertiaryIntOpTable" - }), 3, 1) + ET.SubElement(root, "Table", attrib={"Id": "TertiaryIntOpTable"}), 3, 1 + ) generate_parameter_types( - ET.SubElement(root, "Table", attrib={ - "Id": "UnaryInt16OpTable" - }), 1, 1) + ET.SubElement(root, "Table", attrib={"Id": "UnaryInt16OpTable"}), 1, 1 + ) generate_parameter_types( - ET.SubElement(root, "Table", attrib={ - "Id": "BinaryInt16OpTable" - }), 2, 2) + ET.SubElement(root, "Table", attrib={"Id": "BinaryInt16OpTable"}), 2, 2 + ) generate_parameter_types( - ET.SubElement(root, "Table", attrib={ - "Id": "TertiaryInt16OpTable" - }), 3, 1) + ET.SubElement(root, "Table", attrib={"Id": "TertiaryInt16OpTable"}), 3, 1 + ) generate_parameter_types( - ET.SubElement(root, "Table", attrib={ - "Id": "UnaryUintOpTable" - }), 1, 1) + ET.SubElement(root, "Table", attrib={"Id": "UnaryUintOpTable"}), 1, 1 + ) generate_parameter_types( - ET.SubElement(root, "Table", attrib={ - "Id": "BinaryUintOpTable" - }), 2, 2) + ET.SubElement(root, "Table", attrib={"Id": "BinaryUintOpTable"}), 2, 2 + ) generate_parameter_types( - ET.SubElement(root, "Table", attrib={ - "Id": "TertiaryUintOpTable" - }), 3, 1) + ET.SubElement(root, "Table", attrib={"Id": "TertiaryUintOpTable"}), 3, 1 + ) generate_parameter_types( - ET.SubElement(root, "Table", attrib={ - "Id": "UnaryUint16OpTable" - }), 1, 1) + ET.SubElement(root, "Table", attrib={"Id": "UnaryUint16OpTable"}), 1, 1 + ) generate_parameter_types( - ET.SubElement(root, "Table", attrib={ - "Id": "BinaryUint16OpTable" - }), 2, 2) + ET.SubElement(root, "Table", attrib={"Id": "BinaryUint16OpTable"}), 2, 2 + ) generate_parameter_types( - ET.SubElement(root, "Table", attrib={ - "Id": "TertiaryUint16OpTable" - }), 3, 1) + ET.SubElement(root, "Table", attrib={"Id": "TertiaryUint16OpTable"}), 3, 1 + ) generate_parameter_types( - ET.SubElement(root, "Table", attrib={ - "Id": "DotOpTable" - }), 2, 3) + ET.SubElement(root, "Table", attrib={"Id": "DotOpTable"}), 2, 3 + ) generate_parameter_types( - ET.SubElement(root, "Table", attrib={ - "Id": "Dot2AddHalfOpTable" - }), 3, 1) + ET.SubElement(root, "Table", attrib={"Id": "Dot2AddHalfOpTable"}), 3, 1 + ) generate_parameter_types( - ET.SubElement(root, "Table", attrib={ - "Id": "Dot4AddI8PackedOpTable" - }), 3, 1) + ET.SubElement(root, "Table", attrib={"Id": "Dot4AddI8PackedOpTable"}), 3, 1 + ) generate_parameter_types( - ET.SubElement(root, "Table", attrib={ - "Id": "Dot4AddU8PackedOpTable" - }), 3, 1) + ET.SubElement(root, "Table", attrib={"Id": "Dot4AddU8PackedOpTable"}), 3, 1 + ) generate_parameter_types_msad( - ET.SubElement(root, "Table", attrib={ - "Id": "Msad4Table" - })) + ET.SubElement(root, "Table", attrib={"Id": "Msad4Table"}) + ) generate_parameter_types_wave( - ET.SubElement( - root, "Table", attrib={ - "Id": "WaveIntrinsicsActiveIntTable" - })) + ET.SubElement(root, "Table", attrib={"Id": "WaveIntrinsicsActiveIntTable"}) + ) generate_parameter_types_wave( - ET.SubElement( - root, "Table", attrib={ - "Id": "WaveIntrinsicsActiveUintTable" - })) + ET.SubElement(root, "Table", attrib={"Id": "WaveIntrinsicsActiveUintTable"}) + ) generate_parameter_types_wave( - ET.SubElement( - root, "Table", attrib={ - "Id": "WaveIntrinsicsPrefixIntTable" - })) + ET.SubElement(root, "Table", attrib={"Id": "WaveIntrinsicsPrefixIntTable"}) + ) generate_parameter_types_wave( - ET.SubElement( - root, "Table", attrib={ - "Id": "WaveIntrinsicsPrefixUintTable" - })) + ET.SubElement(root, "Table", attrib={"Id": "WaveIntrinsicsPrefixUintTable"}) + ) generate_parameter_types_wave_multi_prefix( ET.SubElement( - root, "Table", attrib={ - "Id": "WaveIntrinsicsMultiPrefixIntTable" - })) + root, "Table", attrib={"Id": "WaveIntrinsicsMultiPrefixIntTable"} + ) + ) generate_parameter_types_wave_multi_prefix( ET.SubElement( - root, "Table", attrib={ - "Id": "WaveIntrinsicsMultiPrefixUintTable" - })) + root, "Table", attrib={"Id": "WaveIntrinsicsMultiPrefixUintTable"} + ) + ) generate_parameter_types( - ET.SubElement( - root, "Table", attrib={ - "Id": "DenormBinaryFloatOpTable" - }), 2, 2) # 2 sets of expected values for any mode + ET.SubElement(root, "Table", attrib={"Id": "DenormBinaryFloatOpTable"}), + 2, + 2, + ) # 2 sets of expected values for any mode generate_parameter_types( - ET.SubElement( - root, "Table", attrib={ - "Id": "DenormTertiaryFloatOpTable" - }), 3, 2) + ET.SubElement(root, "Table", attrib={"Id": "DenormTertiaryFloatOpTable"}), + 3, + 2, + ) for case in g_test_cases.values(): cur_inst = case.insts[0] if cur_inst.is_cast or cur_inst.category.startswith("Unary"): if "f" in cur_inst.oload_types and not "Half" in case.test_name: - generate_row( - root.find("./Table[@Id='UnaryFloatOpTable']"), - case) + generate_row(root.find("./Table[@Id='UnaryFloatOpTable']"), case) if "h" in cur_inst.oload_types and "Half" in case.test_name: - generate_row(root.find("./Table[@Id='UnaryHalfOpTable']"),case) + generate_row(root.find("./Table[@Id='UnaryHalfOpTable']"), case) if "i" in cur_inst.oload_types and "Bit16" not in case.test_name: if cur_inst.category.startswith("Unary int"): - generate_row( - root.find("./Table[@Id='UnaryIntOpTable']"), - case) + generate_row(root.find("./Table[@Id='UnaryIntOpTable']"), case) elif cur_inst.category.startswith("Unary uint"): - generate_row( - root.find("./Table[@Id='UnaryUintOpTable']"), - case) + generate_row(root.find("./Table[@Id='UnaryUintOpTable']"), case) else: print("unknown op: " + cur_inst.name) print(cur_inst.dxil_class) if "w" in cur_inst.oload_types and "Bit16" in case.test_name: if cur_inst.category.startswith("Unary int"): generate_row( - root.find("./Table[@Id='UnaryInt16OpTable']"), - case) + root.find("./Table[@Id='UnaryInt16OpTable']"), case + ) elif cur_inst.category.startswith("Unary uint"): generate_row( - root.find("./Table[@Id='UnaryUint16OpTable']"), - case) + root.find("./Table[@Id='UnaryUint16OpTable']"), case + ) else: print("unknown op: " + cur_inst.name) print(cur_inst.dxil_class) - elif cur_inst.is_binary or cur_inst.category.startswith( - "Binary"): + elif cur_inst.is_binary or cur_inst.category.startswith("Binary"): if "f" in cur_inst.oload_types and not "Half" in case.test_name: - if case.test_name in g_denorm_tests: # for denorm tests + if case.test_name in g_denorm_tests: # for denorm tests generate_row( - root.find("./Table[@Id='DenormBinaryFloatOpTable']"), - case) + root.find("./Table[@Id='DenormBinaryFloatOpTable']"), case + ) else: generate_row( - root.find("./Table[@Id='BinaryFloatOpTable']"), - case) + root.find("./Table[@Id='BinaryFloatOpTable']"), case + ) if "h" in cur_inst.oload_types and "Half" in case.test_name: - generate_row(root.find("./Table[@Id='BinaryHalfOpTable']"),case) + generate_row(root.find("./Table[@Id='BinaryHalfOpTable']"), case) if "i" in cur_inst.oload_types and "Bit16" not in case.test_name: if cur_inst.category.startswith("Binary int"): - if case.test_name in ['UAdd', 'USub', 'UMul']: # Add, Sub, Mul use same operations for int and uint. + if case.test_name in [ + "UAdd", + "USub", + "UMul", + ]: # Add, Sub, Mul use same operations for int and uint. generate_row( - root.find("./Table[@Id='BinaryUintOpTable']"), - case) + root.find("./Table[@Id='BinaryUintOpTable']"), case + ) else: generate_row( - root.find("./Table[@Id='BinaryIntOpTable']"), - case) + root.find("./Table[@Id='BinaryIntOpTable']"), case + ) elif cur_inst.category.startswith("Binary uint"): generate_row( - root.find("./Table[@Id='BinaryUintOpTable']"), - case) + root.find("./Table[@Id='BinaryUintOpTable']"), case + ) else: print("unknown op: " + cur_inst.name) print(cur_inst.dxil_class) if "w" in cur_inst.oload_types and "Bit16" in case.test_name: if cur_inst.category.startswith("Binary int"): - if case.test_name in ['UAdd', 'USub', 'UMul']: # Add, Sub, Mul use same operations for int and uint. + if case.test_name in [ + "UAdd", + "USub", + "UMul", + ]: # Add, Sub, Mul use same operations for int and uint. generate_row( - root.find("./Table[@Id='BinaryUint16OpTable']"), - case) + root.find("./Table[@Id='BinaryUint16OpTable']"), case + ) else: generate_row( - root.find("./Table[@Id='BinaryInt16OpTable']"), - case) + root.find("./Table[@Id='BinaryInt16OpTable']"), case + ) elif cur_inst.category.startswith("Binary uint"): generate_row( - root.find("./Table[@Id='BinaryUint16OpTable']"), - case) + root.find("./Table[@Id='BinaryUint16OpTable']"), case + ) else: print("unknown op: " + cur_inst.name) print(cur_inst.dxil_class) elif cur_inst.category.startswith("Tertiary"): if "f" in cur_inst.oload_types and not "Half" in case.test_name: - if case.test_name in g_denorm_tests: # for denorm tests + if case.test_name in g_denorm_tests: # for denorm tests generate_row( - root.find("./Table[@Id='DenormTertiaryFloatOpTable']"),case) + root.find("./Table[@Id='DenormTertiaryFloatOpTable']"), case + ) else: generate_row( - root.find("./Table[@Id='TertiaryFloatOpTable']"),case) + root.find("./Table[@Id='TertiaryFloatOpTable']"), case + ) if "h" in cur_inst.oload_types and "Half" in case.test_name: - generate_row(root.find("./Table[@Id='TertiaryHalfOpTable']"),case) + generate_row(root.find("./Table[@Id='TertiaryHalfOpTable']"), case) if "i" in cur_inst.oload_types and "Bit16" not in case.test_name: if cur_inst.category.startswith("Tertiary int"): generate_row( - root.find("./Table[@Id='TertiaryIntOpTable']"), - case) + root.find("./Table[@Id='TertiaryIntOpTable']"), case + ) elif cur_inst.category.startswith("Tertiary uint"): generate_row( - root.find( - "./Table[@Id='TertiaryUintOpTable']"), - case) + root.find("./Table[@Id='TertiaryUintOpTable']"), case + ) else: print("unknown op: " + cur_inst.name) print(cur_inst.dxil_class) if "w" in cur_inst.oload_types and "Bit16" in case.test_name: if cur_inst.category.startswith("Tertiary int"): generate_row( - root.find("./Table[@Id='TertiaryInt16OpTable']"), - case) + root.find("./Table[@Id='TertiaryInt16OpTable']"), case + ) elif cur_inst.category.startswith("Tertiary uint"): generate_row( - root.find( - "./Table[@Id='TertiaryUint16OpTable']"), - case) + root.find("./Table[@Id='TertiaryUint16OpTable']"), case + ) else: print("unknown op: " + cur_inst.name) print(cur_inst.dxil_class) elif cur_inst.category.startswith("Quaternary"): if cur_inst.name == "Bfi": - generate_row( - root.find("./Table[@Id='Msad4Table']"), case) + generate_row(root.find("./Table[@Id='Msad4Table']"), case) else: print("unknown op: " + cur_inst.name) print(cur_inst.dxil_class) @@ -1913,71 +3767,83 @@ def generate_table_for_taef(): if cur_inst.name == "Dot2AddHalf": generate_row(root.find("./Table[@Id='Dot2AddHalfOpTable']"), case) elif cur_inst.name == "Dot4AddI8Packed": - generate_row(root.find("./Table[@Id='Dot4AddI8PackedOpTable']"), case) + generate_row( + root.find("./Table[@Id='Dot4AddI8PackedOpTable']"), case + ) elif cur_inst.name == "Dot4AddU8Packed": - generate_row(root.find("./Table[@Id='Dot4AddU8PackedOpTable']"), case) + generate_row( + root.find("./Table[@Id='Dot4AddU8PackedOpTable']"), case + ) else: print("unknown op: " + cur_inst.name) print(cur_inst.dxil_class) - elif cur_inst.dxil_class in ["WaveActiveOp", "WaveAllOp","WaveActiveAllEqual","WaveAnyTrue","WaveAllTrue"]: + elif cur_inst.dxil_class in [ + "WaveActiveOp", + "WaveAllOp", + "WaveActiveAllEqual", + "WaveAnyTrue", + "WaveAllTrue", + ]: if case.test_name.startswith("WaveActiveU"): generate_row_wave( - root.find( - "./Table[@Id='WaveIntrinsicsActiveUintTable']" - ), case) + root.find("./Table[@Id='WaveIntrinsicsActiveUintTable']"), case + ) else: generate_row_wave( - root.find( - "./Table[@Id='WaveIntrinsicsActiveIntTable']"), - case) + root.find("./Table[@Id='WaveIntrinsicsActiveIntTable']"), case + ) elif cur_inst.dxil_class == "WaveActiveBit": generate_row_wave( - root.find( - "./Table[@Id='WaveIntrinsicsActiveUintTable']"), - case) + root.find("./Table[@Id='WaveIntrinsicsActiveUintTable']"), case + ) elif cur_inst.dxil_class == "WavePrefixOp": if case.test_name.startswith("WavePrefixU"): generate_row_wave( - root.find( - "./Table[@Id='WaveIntrinsicsPrefixUintTable']" - ), case) + root.find("./Table[@Id='WaveIntrinsicsPrefixUintTable']"), case + ) else: generate_row_wave( - root.find( - "./Table[@Id='WaveIntrinsicsPrefixIntTable']"), - case) + root.find("./Table[@Id='WaveIntrinsicsPrefixIntTable']"), case + ) elif cur_inst.dxil_class == "WaveMultiPrefixOp": if case.test_name.startswith("WaveMultiPrefixU"): generate_row_wave_multi( - root.find( - "./Table[@Id='WaveIntrinsicsMultiPrefixUintTable']" - ), case) + root.find("./Table[@Id='WaveIntrinsicsMultiPrefixUintTable']"), + case, + ) else: generate_row_wave_multi( - root.find( - "./Table[@Id='WaveIntrinsicsMultiPrefixIntTable']"), - case) + root.find("./Table[@Id='WaveIntrinsicsMultiPrefixIntTable']"), + case, + ) else: print("unknown op: " + cur_inst.name) print(cur_inst.dxil_class) tree._setroot(root) from xml.dom.minidom import parseString + pretty_xml = parseString(ET.tostring(root)).toprettyxml(indent=" ") f.write(pretty_xml) print("Saved file at: " + f.name) f.close() + def print_untested_inst(): lst = [] - for name in [node.inst.name for node in g_instruction_nodes.values() if len(node.test_cases) == 0]: + for name in [ + node.inst.name + for node in g_instruction_nodes.values() + if len(node.test_cases) == 0 + ]: lst += [name] lst.sort() print("Untested dxil ops: ") for name in lst: print(name) print("Total uncovered dxil ops: " + str(len(lst))) - print("Total covered dxil ops: " + str(len(g_instruction_nodes)-len(lst))) + print("Total covered dxil ops: " + str(len(g_instruction_nodes) - len(lst))) + # inst name to instruction dict g_instruction_nodes = {} @@ -1991,7 +3857,7 @@ def print_untested_inst(): add_test_cases() args = vars(parser.parse_args()) - mode = args['mode'] + mode = args["mode"] if mode == "info": print_untested_inst() elif mode == "gen-xml": diff --git a/utils/hct/hctgen.py b/utils/hct/hctgen.py index 338ed4cbac..fd64893a02 100755 --- a/utils/hct/hctgen.py +++ b/utils/hct/hctgen.py @@ -7,180 +7,238 @@ import CodeTags parser = argparse.ArgumentParser() -parser.add_argument('mode', choices=['HLSLIntrinsicOp', - 'DxilConstants', - 'DxilInstructions', - 'DxilSigPoint', - 'DxilIntrinsicTables', - 'DxilOperations', - 'DxilDocs', - 'DxilShaderModelInc', - 'DxilShaderModel', - 'DxilValidationInc', - 'DxilValidation', - 'HLSLOptions', - 'DxcOptimizer', - 'DxilPIXPasses', - 'DxcDisassembler', - 'DxilCounters', - 'DxilMetadata', - 'RDAT_LibraryTypes' - ]) -parser.add_argument('--output', required=True) -parser.add_argument('--input', default=None) -parser.add_argument('--force-lf', action='store_true',) -parser.add_argument('--force-crlf', action='store_true',) +parser.add_argument( + "mode", + choices=[ + "HLSLIntrinsicOp", + "DxilConstants", + "DxilInstructions", + "DxilSigPoint", + "DxilIntrinsicTables", + "DxilOperations", + "DxilDocs", + "DxilShaderModelInc", + "DxilShaderModel", + "DxilValidationInc", + "DxilValidation", + "HLSLOptions", + "DxcOptimizer", + "DxilPIXPasses", + "DxcDisassembler", + "DxilCounters", + "DxilMetadata", + "RDAT_LibraryTypes", + ], +) +parser.add_argument("--output", required=True) +parser.add_argument("--input", default=None) +parser.add_argument( + "--force-lf", + action="store_true", +) +parser.add_argument( + "--force-crlf", + action="store_true", +) + def eprint(*args, **kwargs): - print(*args, file=sys.stderr, **kwargs) + print(*args, file=sys.stderr, **kwargs) + def getNewline(args): - if args.force_lf: - return '\n' - if args.force_crlf: - return '\r\n' - return None + if args.force_lf: + return "\n" + if args.force_crlf: + return "\r\n" + return None + def writeCodeTag(args): - out = openOutput(args) - if not args.input: - eprint('Writing %s requires --input' % args.mode) - return 1 + out = openOutput(args) + if not args.input: + eprint("Writing %s requires --input" % args.mode) + return 1 + + argsList = [args.input, args.output] + result = CodeTags.main(argsList, getNewline(args)) + return 0 - argsList = [args.input, args.output] - result = CodeTags.main(argsList, getNewline(args)) - return 0 def openOutput(args): - outputDir = os.path.dirname(os.path.realpath(args.output)) - if not os.path.exists(outputDir): - os.makedirs(outputDir) - return open(args.output, 'w', newline=getNewline(args)) + outputDir = os.path.dirname(os.path.realpath(args.output)) + if not os.path.exists(outputDir): + os.makedirs(outputDir) + return open(args.output, "w", newline=getNewline(args)) + def printHeader(out, filename): - out.write('// %s - Generated by hctgen.py\n' % filename) - out.write('// DO NOT MODIFY!!!\n') - out.write('// Changes to this code are made in gen_intrin_main.txt\n\n') + out.write("// %s - Generated by hctgen.py\n" % filename) + out.write("// DO NOT MODIFY!!!\n") + out.write("// Changes to this code are made in gen_intrin_main.txt\n\n") + def writeHLSLIntrinsicOp(args): - out = openOutput(args) - printHeader(out, 'HlslIntrinsicOp.h') - out.write('\n'.join(['#pragma once', - 'namespace hlsl {', - 'enum class IntrinsicOp {'])) - out.write(enum_hlsl_intrinsics()) - out.write('};\n') - out.write('\n'.join(['inline bool HasUnsignedIntrinsicOpcode(IntrinsicOp opcode) {', - ' switch (opcode) {'])) - out.write(has_unsigned_hlsl_intrinsics()) - - out.write('\n'.join([ - ' return true;', - ' default:', - ' return false;', - ' }', - '}', - 'inline unsigned GetUnsignedIntrinsicOpcode(IntrinsicOp opcode) {', - ' switch (opcode) {'])) - out.write(get_unsigned_hlsl_intrinsics()) - out.write('\n'.join([ - ' default:', - ' return static_cast(opcode);', - ' }', - '}', - '} // namespace hlsl\n'])) - return 0 + out = openOutput(args) + printHeader(out, "HlslIntrinsicOp.h") + out.write( + "\n".join(["#pragma once", "namespace hlsl {", "enum class IntrinsicOp {"]) + ) + out.write(enum_hlsl_intrinsics()) + out.write("};\n") + out.write( + "\n".join( + [ + "inline bool HasUnsignedIntrinsicOpcode(IntrinsicOp opcode) {", + " switch (opcode) {", + ] + ) + ) + out.write(has_unsigned_hlsl_intrinsics()) + + out.write( + "\n".join( + [ + " return true;", + " default:", + " return false;", + " }", + "}", + "inline unsigned GetUnsignedIntrinsicOpcode(IntrinsicOp opcode) {", + " switch (opcode) {", + ] + ) + ) + out.write(get_unsigned_hlsl_intrinsics()) + out.write( + "\n".join( + [ + " default:", + " return static_cast(opcode);", + " }", + "}", + "} // namespace hlsl\n", + ] + ) + ) + return 0 + def writeDxilIntrinsicTables(args): - out = openOutput(args) - printHeader(out, "gen_intrin_main_tables_15.h") - out.write(get_hlsl_intrinsics()) - out.write(get_hlsl_intrinsic_stats()) - return 0 + out = openOutput(args) + printHeader(out, "gen_intrin_main_tables_15.h") + out.write(get_hlsl_intrinsics()) + out.write(get_hlsl_intrinsic_stats()) + return 0 + def writeDxcDisassembler(args): - out = openOutput(args) - printHeader(out, "DxcDisassembler.inc") - out.write(get_opsigs()) - out.write('\n') - return 0 + out = openOutput(args) + printHeader(out, "DxcDisassembler.inc") + out.write(get_opsigs()) + out.write("\n") + return 0 + def writeDxcOptimizer(args): - out = openOutput(args) - printHeader(out, "DxcOptimizer.inc") - out.write('\n'.join([ - 'namespace hlsl {', - 'HRESULT SetupRegistryPassForHLSL() {', - ' try {', - ' PassRegistry &Registry = *PassRegistry::getPassRegistry();\n'])) - out.write(get_init_passes(set(["llvm", "dxil_gen"]))) - out.write('\n'.join([ - ' // Not schematized - exclusively for compiler authors.', - ' initializeCFGPrinterPasses(Registry);', - ' }', - ' CATCH_CPP_RETURN_HRESULT();', - ' return S_OK;', - '}', - '} // namespace hlsl\n', - 'static ArrayRef GetPassArgNames(LPCSTR passName) {', - ])) - out.write(get_pass_arg_names()) - out.write('\nreturn ArrayRef();\n}\n\n') - out.write('static ArrayRef GetPassArgDescriptions(LPCSTR passName) {\n') - out.write(get_pass_arg_descs()) - out.write('\nreturn ArrayRef();\n}\n\n') - out.write('static bool IsPassOptionName(StringRef S) {\n') - out.write(get_is_pass_option_name()) - out.write('}\n') - return 0 + out = openOutput(args) + printHeader(out, "DxcOptimizer.inc") + out.write( + "\n".join( + [ + "namespace hlsl {", + "HRESULT SetupRegistryPassForHLSL() {", + " try {", + " PassRegistry &Registry = *PassRegistry::getPassRegistry();\n", + ] + ) + ) + out.write(get_init_passes(set(["llvm", "dxil_gen"]))) + out.write( + "\n".join( + [ + " // Not schematized - exclusively for compiler authors.", + " initializeCFGPrinterPasses(Registry);", + " }", + " CATCH_CPP_RETURN_HRESULT();", + " return S_OK;", + "}", + "} // namespace hlsl\n", + "static ArrayRef GetPassArgNames(LPCSTR passName) {", + ] + ) + ) + out.write(get_pass_arg_names()) + out.write("\nreturn ArrayRef();\n}\n\n") + out.write("static ArrayRef GetPassArgDescriptions(LPCSTR passName) {\n") + out.write(get_pass_arg_descs()) + out.write("\nreturn ArrayRef();\n}\n\n") + out.write("static bool IsPassOptionName(StringRef S) {\n") + out.write(get_is_pass_option_name()) + out.write("}\n") + return 0 + def writeDxilValidationInc(args): - out = openOutput(args) - printHeader(out, "DxilValidation.inc") - out.write(get_valrule_enum()) - out.write('\n') - return 0 + out = openOutput(args) + printHeader(out, "DxilValidation.inc") + out.write(get_valrule_enum()) + out.write("\n") + return 0 + def writeDxilValidation(args): - out = openOutput(args) - printHeader(out, "DxilValidationImpl.inc") - out.write('const char *hlsl::GetValidationRuleText(ValidationRule value) {\n') - out.write(get_valrule_text()) - out.write('\n'.join([ - ' llvm_unreachable("invalid value");', - ' return "";', - '}\nnamespace hlsl {\n', - 'static bool ValidateOpcodeInProfile(DXIL::OpCode opcode,', - ' DXIL::ShaderKind SK,', - ' unsigned major,', - ' unsigned minor) {', - ' unsigned op = (unsigned)opcode;' - ])) - out.write(get_valopcode_sm_text()) - out.write('\n'.join([ - '}\n', - 'static bool IsLLVMInstructionAllowed(llvm::Instruction &I) {', - ' unsigned op = I.getOpcode();', - ])) - out.write(get_instrs_pred("op", lambda i: not i.is_dxil_op and i.is_allowed, "llvm_id")) - out.write('}\n\nvoid GetValidationVersion(unsigned *pMajor, unsigned *pMinor) {') - out.write(get_validation_version()) - out.write('}\n}\n') - return 0 + out = openOutput(args) + printHeader(out, "DxilValidationImpl.inc") + out.write("const char *hlsl::GetValidationRuleText(ValidationRule value) {\n") + out.write(get_valrule_text()) + out.write( + "\n".join( + [ + ' llvm_unreachable("invalid value");', + ' return "";', + "}\nnamespace hlsl {\n", + "static bool ValidateOpcodeInProfile(DXIL::OpCode opcode,", + " DXIL::ShaderKind SK,", + " unsigned major,", + " unsigned minor) {", + " unsigned op = (unsigned)opcode;", + ] + ) + ) + out.write(get_valopcode_sm_text()) + out.write( + "\n".join( + [ + "}\n", + "static bool IsLLVMInstructionAllowed(llvm::Instruction &I) {", + " unsigned op = I.getOpcode();", + ] + ) + ) + out.write( + get_instrs_pred("op", lambda i: not i.is_dxil_op and i.is_allowed, "llvm_id") + ) + out.write("}\n\nvoid GetValidationVersion(unsigned *pMajor, unsigned *pMinor) {") + out.write(get_validation_version()) + out.write("}\n}\n") + return 0 + def writeDxilPIXPasses(args): - out = openOutput(args) - printHeader(out, "DxilPIXPasses.inc") - out.write(get_init_passes(set(["pix"]))) - out.write('\n') - return 0 + out = openOutput(args) + printHeader(out, "DxilPIXPasses.inc") + out.write(get_init_passes(set(["pix"]))) + out.write("\n") + return 0 + args = parser.parse_args() if args.force_lf and args.force_crlf: - eprint('--force-lf and --force-crlf are mutually exclusive, only pass one') - exit(1) -writeFnName = 'write%s' % args.mode + eprint("--force-lf and --force-crlf are mutually exclusive, only pass one") + exit(1) +writeFnName = "write%s" % args.mode if writeFnName in locals(): - exit(locals()[writeFnName](args)) + exit(locals()[writeFnName](args)) else: - exit(writeCodeTag(args)) + exit(writeCodeTag(args)) diff --git a/utils/hct/hctgettaef.py b/utils/hct/hctgettaef.py index 91306d03ad..06200bef7f 100644 --- a/utils/hct/hctgettaef.py +++ b/utils/hct/hctgettaef.py @@ -4,26 +4,35 @@ import zipfile url = "https://github.com/Microsoft/WinObjC/raw/develop/deps/prebuilt/nuget/taef.redist.wlk.1.0.170206001-nativetargets.nupkg" -zipfile_name = os.path.join(os.environ['TEMP'], "taef.redist.wlk.1.0.170206001-nativetargets.nupkg.zip") -src_dir = os.environ['HLSL_SRC_DIR'] +zipfile_name = os.path.join( + os.environ["TEMP"], "taef.redist.wlk.1.0.170206001-nativetargets.nupkg.zip" +) +src_dir = os.environ["HLSL_SRC_DIR"] taef_dir = os.path.join(src_dir, "external", "taef") if not os.path.isdir(taef_dir): - os.makedirs(taef_dir) + os.makedirs(taef_dir) try: - ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1_2) - response = urllib.request.urlopen(url, context=ctx) - f = open(zipfile_name, 'wb') - f.write(response.read()) - f.close() + ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1_2) + response = urllib.request.urlopen(url, context=ctx) + f = open(zipfile_name, "wb") + f.write(response.read()) + f.close() except: - print("Unable to read file with urllib, trying via powershell...") - from subprocess import check_call - cmd = "" - cmd += "[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.SecurityProtocolType]::Tls12;" - cmd += "(new-object System.Net.WebClient).DownloadFile('" + url + "', '" + zipfile_name + "')" - check_call(['powershell.exe', '-Command', cmd]) + print("Unable to read file with urllib, trying via powershell...") + from subprocess import check_call + + cmd = "" + cmd += "[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.SecurityProtocolType]::Tls12;" + cmd += ( + "(new-object System.Net.WebClient).DownloadFile('" + + url + + "', '" + + zipfile_name + + "')" + ) + check_call(["powershell.exe", "-Command", cmd]) z = zipfile.ZipFile(zipfile_name) z.extractall(taef_dir) diff --git a/utils/hct/hcttest-samples.py b/utils/hct/hcttest-samples.py index 75c8b95d97..9f54ab2d2f 100644 --- a/utils/hct/hcttest-samples.py +++ b/utils/hct/hcttest-samples.py @@ -12,17 +12,22 @@ except ImportError: import xml.etree.ElementTree as ET + # Comment namespace to make working with ElementTree easier: def ReadXmlString(text): global xmlheader - text = text.replace('xmlns=', 'xmlns_commented=') - xmlheader = text[:text.find('\n')+1] + text = text.replace("xmlns=", "xmlns_commented=") + xmlheader = text[: text.find("\n") + 1] # TODO: read xml and return xml root return ET.fromstring(text) + + def WriteXmlString(root): global xmlheader text = ET.tostring(root, encoding="utf-8") - return xmlheader + text.replace('xmlns_commented=', 'xmlns=') + return xmlheader + text.replace("xmlns_commented=", "xmlns=") + + def DeepCopyElement(e): cpy = ET.Element(e.tag, e.attrib) cpy.text = e.text @@ -31,13 +36,14 @@ def DeepCopyElement(e): cpy.append(DeepCopyElement(child)) return cpy + sample_names = [ "D3D1211On12", "D3D12Bundles", "D3D12DynamicIndexing", "D3D12ExecuteIndirect", "D3D12Fullscreen", -# "D3D12HelloWorld", + # "D3D12HelloWorld", "D3D12HelloWorld\\src\\HelloBundles", "D3D12HelloWorld\\src\\HelloConstBuffers", "D3D12HelloWorld\\src\\HelloFrameBuffering", @@ -45,21 +51,23 @@ def DeepCopyElement(e): "D3D12HelloWorld\\src\\HelloTriangle", "D3D12HelloWorld\\src\\HelloWindow", "D3D12HeterogeneousMultiadapter", - # WarpAssert in ReadPointerOperand: pInfoSrc->getName().startswith("dx.var.x"). - # Fix tested - incorrect rendered result produced. - # Worked around in sample shaders for now by moving to non-static locals. - "D3D12Multithreading", # works and is visually impressive! - "D3D12nBodyGravity", # expected empty cbuffer culling due to static members causes this to fail! FIXED! + # WarpAssert in ReadPointerOperand: pInfoSrc->getName().startswith("dx.var.x"). + # Fix tested - incorrect rendered result produced. + # Worked around in sample shaders for now by moving to non-static locals. + "D3D12Multithreading", # works and is visually impressive! + "D3D12nBodyGravity", # expected empty cbuffer culling due to static members causes this to fail! FIXED! "D3D12PipelineStateCache", # Requires workaround for static globals "D3D12PredicationQueries", "D3D12ReservedResources", - "D3D12Residency", # has problems on x86 due to mem limitations. The following seems to help: - # change NumTextures to 1024 * 1, and add min with 1GB here: - # UINT64 memoryToUse = UINT64 (float(min(memoryInfo.Budget, UINT64(1 << 30))) * 0.95f); - # Still produces a bunch of these errors: - # D3D12 ERROR: ID3D12CommandAllocator::Reset: A command allocator is being reset before previous executions associated with the allocator have completed. [ EXECUTION ERROR #552: COMMAND_ALLOCATOR_SYNC] - # but at least it no longer crashes - "D3D12SmallResources"] + "D3D12Residency", # has problems on x86 due to mem limitations. The following seems to help: + # change NumTextures to 1024 * 1, and add min with 1GB here: + # UINT64 memoryToUse = UINT64 (float(min(memoryInfo.Budget, UINT64(1 << 30))) * 0.95f); + # Still produces a bunch of these errors: + # D3D12 ERROR: ID3D12CommandAllocator::Reset: A command allocator is being reset before previous executions associated with the allocator have completed. [ EXECUTION ERROR #552: COMMAND_ALLOCATOR_SYNC] + # but at least it no longer crashes + "D3D12SmallResources", +] + class Sample(object): def __init__(self, name): @@ -67,8 +75,10 @@ def __init__(self, name): self.preBuild = [] self.postBuild = [] + samples = dict([(name, Sample(name)) for name in sample_names]) + def SetSampleActions(): # Actions called with (name, args, dxil) # Actions for all projects: @@ -76,7 +86,9 @@ def SetSampleActions(): sample.postBuild.append(ActionCopyD3DBins) sample.postBuild.append(ActionCopySDKLayers) sample.postBuild.append(ActionCopyWarp12) - sample.postBuild.append(ActionCopyCompilerBins) # Do this for all projects for now + sample.postBuild.append( + ActionCopyCompilerBins + ) # Do this for all projects for now # TODO: limit ActionCopyCompilerBins action to ones that do run-time compilation. # # Runtime HLSL compilation: # for name in [ "D3D1211On12", @@ -85,56 +97,112 @@ def SetSampleActions(): # ]: # samples[name].postBuild.append(ActionCopyCompilerBins) + def CopyFiles(source_path, dest_path, filenames, symbols=False): for filename in filenames: renamed = filename try: - filename, renamed = filename.split(';') - print('Copying %s from %s to %s' % (filename, source_path, dest_path)) - print('.. with new name: %s' % (renamed)) + filename, renamed = filename.split(";") + print("Copying %s from %s to %s" % (filename, source_path, dest_path)) + print(".. with new name: %s" % (renamed)) except: - print('Copying %s from %s to %s' % (filename, source_path, dest_path)) + print("Copying %s from %s to %s" % (filename, source_path, dest_path)) try: - shutil.copy2(os.path.join(source_path, filename), os.path.join(dest_path, renamed)) + shutil.copy2( + os.path.join(source_path, filename), os.path.join(dest_path, renamed) + ) except: - print('Error copying "%s" from "%s" to "%s"' % (filename, source_path, dest_path)) + print( + 'Error copying "%s" from "%s" to "%s"' + % (filename, source_path, dest_path) + ) # sys.excepthook(*sys.exc_info()) continue - if symbols and (filename.endswith('.exe') or filename.endswith('.dll')): - symbol_filename = filename[:-4] + '.pdb' + if symbols and (filename.endswith(".exe") or filename.endswith(".dll")): + symbol_filename = filename[:-4] + ".pdb" try: - shutil.copy2(os.path.join(source_path, symbol_filename), os.path.join(dest_path, symbol_filename)) + shutil.copy2( + os.path.join(source_path, symbol_filename), + os.path.join(dest_path, symbol_filename), + ) except: - print('Error copying symbols "%s" from "%s" to "%s"' % (symbol_filename, source_path, dest_path)) + print( + 'Error copying symbols "%s" from "%s" to "%s"' + % (symbol_filename, source_path, dest_path) + ) + + def CopyBins(args, name, dxil, filenames, symbols=False): samples_path = args.samples - config = dxil and 'DxilDebug' or 'Debug' - CopyFiles(args.bins, os.path.join(PathToSampleSrc(samples_path, name), 'bin', args.arch, config), filenames, symbols) + config = dxil and "DxilDebug" or "Debug" + CopyFiles( + args.bins, + os.path.join(PathToSampleSrc(samples_path, name), "bin", args.arch, config), + filenames, + symbols, + ) + + def ActionCopyCompilerBins(args, name, dxil): if dxil: - CopyBins(args, name, dxil, [ - 'dxcompiler.dll', - 'dxil.dll', - 'd3dcompiler_dxc_bridge.dll;d3dcompiler_47.dll', # Wrapper version that calls into dxcompiler.dll - ], args.symbols) + CopyBins( + args, + name, + dxil, + [ + "dxcompiler.dll", + "dxil.dll", + "d3dcompiler_dxc_bridge.dll;d3dcompiler_47.dll", # Wrapper version that calls into dxcompiler.dll + ], + args.symbols, + ) + + def ActionCopyD3DBins(args, name, dxil): if dxil: - CopyBins(args, name, dxil, [ - 'd3d12.dll', - ], args.symbols) + CopyBins( + args, + name, + dxil, + [ + "d3d12.dll", + ], + args.symbols, + ) + + def ActionCopySDKLayers(args, name, dxil): - CopyBins(args, name, dxil, [ - 'D3D11_3SDKLayers.dll', - 'D3D12SDKLayers.dll', - 'DXGIDebug.dll', - ], args.symbols) + CopyBins( + args, + name, + dxil, + [ + "D3D11_3SDKLayers.dll", + "D3D12SDKLayers.dll", + "DXGIDebug.dll", + ], + args.symbols, + ) + + def ActionCopyWarp12(args, name, dxil): - CopyBins(args, name, dxil, [ - 'd3d12warp.dll', - ], args.symbols) + CopyBins( + args, + name, + dxil, + [ + "d3d12warp.dll", + ], + args.symbols, + ) + + def MakeD3D12WarpCopy(bin_path): # Copy d3d10warp.dll to d3d12warp.dll - shutil.copy2(os.path.join(bin_path, 'd3d10warp.dll'), os.path.join(bin_path, 'd3d12warp.dll')) + shutil.copy2( + os.path.join(bin_path, "d3d10warp.dll"), os.path.join(bin_path, "d3d12warp.dll") + ) + def PathSplitAll(p): s = filter(None, os.path.split(p)) @@ -143,26 +211,33 @@ def PathSplitAll(p): else: return (s[0],) + def GetBinPath(args, name): return os.path.join(args.bins, name) + def GetProjectBinFilePath(args, samples_path, sample_name, file_name): src = PathToSampleSrc(samples_path, sample_name) return os.path.join(src, "bin", args.arch, file_name) + def ListRuntimeCompilePaths(args): - return [os.path.join(args.bins, name) for name in [ - 'fxc.exe', - 'dxc.exe', - 'dxcompiler.dll', - 'dxil.dll', - 'd3dcompiler_47.dll', - 'd3d12.dll', - 'D3D11_3SDKLayers.dll', - 'D3D12SDKLayers.dll', - 'DXGIDebug.dll', - 'd3d12warp.dll', - ]] + return [ + os.path.join(args.bins, name) + for name in [ + "fxc.exe", + "dxc.exe", + "dxcompiler.dll", + "dxil.dll", + "d3dcompiler_47.dll", + "d3d12.dll", + "D3D11_3SDKLayers.dll", + "D3D12SDKLayers.dll", + "DXGIDebug.dll", + "d3d12warp.dll", + ] + ] + def CheckEnvironment(args): if not args.bins: @@ -175,9 +250,16 @@ def CheckEnvironment(args): if not os.path.exists(fn): print("Expected file '" + fn + "' not found.") exit(1) - if os.path.getmtime(GetBinPath(args, 'fxc.exe')) != os.path.getmtime(GetBinPath(args, 'dxc.exe')): + if os.path.getmtime(GetBinPath(args, "fxc.exe")) != os.path.getmtime( + GetBinPath(args, "dxc.exe") + ): print("fxc.exe should be a copy of dxc.exe.") - print("Please copy " + GetBinPath(args, 'dxc.exe') + " " + GetBinPath(args, 'fxc.exe')) + print( + "Please copy " + + GetBinPath(args, "dxc.exe") + + " " + + GetBinPath(args, "fxc.exe") + ) exit(1) try: msbuild_version = subprocess.check_output(["msbuild", "-nologo", "-ver"]) @@ -187,103 +269,131 @@ def CheckEnvironment(args): print("This command should be run from a Developer Command Prompt") exit(1) + def SampleIsNested(name): return "\\src\\" in name + def PathToSampleSrc(basePath, sampleName): if SampleIsNested(sampleName): return os.path.join(basePath, "Samples", "Desktop", sampleName) return os.path.join(basePath, "Samples", "Desktop", sampleName, "src") -reConfig = r'(Debug|Release|DxilDebug|DxilRelease)\|(Win32|x64)' + +reConfig = r"(Debug|Release|DxilDebug|DxilRelease)\|(Win32|x64)" + def AddProjectConfigs(root, args): rxConfig = re.compile(reConfig) changed = False - for e in root.findall('.//WindowsTargetPlatformVersion'): - if e.text == '10.0.10240.0': - e.text = '10.0.10586.0' + for e in root.findall(".//WindowsTargetPlatformVersion"): + if e.text == "10.0.10240.0": + e.text = "10.0.10586.0" changed = True # Override fxc path for Dxil configs: - for config in ['DxilDebug', 'DxilRelease']: - for arch in ['Win32', 'x64']: - if not root.find('''./PropertyGroup[@Condition="'$(Configuration)|$(Platform)'=='%s|%s'"]/FXCToolPath''' % (config, arch)): - e = ET.Element('PropertyGroup', {'Condition': "'$(Configuration)|$(Platform)'=='%s|%s'" % (config, arch)}) - e.text = '\n ' - e.tail = '\n ' + for config in ["DxilDebug", "DxilRelease"]: + for arch in ["Win32", "x64"]: + if not root.find( + """./PropertyGroup[@Condition="'$(Configuration)|$(Platform)'=='%s|%s'"]/FXCToolPath""" + % (config, arch) + ): + e = ET.Element( + "PropertyGroup", + { + "Condition": "'$(Configuration)|$(Platform)'=='%s|%s'" + % (config, arch) + }, + ) + e.text = "\n " + e.tail = "\n " root.insert(0, e) - e = ET.SubElement(e, 'FXCToolPath') - e.text = '$(DXC_BIN_PATH)' # args.bins - e.tail = '\n ' + e = ET.SubElement(e, "FXCToolPath") + e.text = "$(DXC_BIN_PATH)" # args.bins + e.tail = "\n " # Extend ProjectConfiguration for Win32 and Dxil configs ig = root.find('./ItemGroup[@Label="ProjectConfigurations"]') or [] - debug_config = release_config = None # ProjectConfiguration + debug_config = release_config = None # ProjectConfiguration configs = {} for e in ig: try: - m = rxConfig.match(e.attrib['Include']) + m = rxConfig.match(e.attrib["Include"]) if m: key = m.groups() configs[key] = e - if m.group(1) == 'Debug': + if m.group(1) == "Debug": debug_config = key, e - elif m.group(1) == 'Release': + elif m.group(1) == "Release": release_config = key, e except: continue - parents = root.findall('''.//*[@Condition="'$(Configuration)|$(Platform)'=='%s|%s'"]/..''' % ('Debug', 'x64')) + parents = root.findall( + """.//*[@Condition="'$(Configuration)|$(Platform)'=='%s|%s'"]/..""" + % ("Debug", "x64") + ) if not configs or not debug_config or not release_config: - print('No ProjectConfigurations found') + print("No ProjectConfigurations found") return False - for arch in ['Win32', 'x64']: - for config in ['Debug', 'DxilDebug', 'Release', 'DxilRelease']: - if config in ('Debug', 'DxilDebug'): - t_config = 'Debug', 'x64' + for arch in ["Win32", "x64"]: + for config in ["Debug", "DxilDebug", "Release", "DxilRelease"]: + if config in ("Debug", "DxilDebug"): + t_config = "Debug", "x64" else: - t_config = 'Release', 'x64' + t_config = "Release", "x64" config_condition = "'$(Configuration)|$(Platform)'=='%s|%s'" % t_config if not configs.get((config, arch), None): changed = True - if config in ('Debug', 'DxilDebug'): + if config in ("Debug", "DxilDebug"): e = DeepCopyElement(debug_config[1]) else: e = DeepCopyElement(release_config[1]) - e.set('Include', '%s|%s' % (config, arch)) - e.find('./Configuration').text = config - e.find('./Platform').text = arch + e.set("Include", "%s|%s" % (config, arch)) + e.find("./Configuration").text = config + e.find("./Platform").text = arch ig.append(e) for parent in reversed(parents): for n, e in reversed(list(enumerate(parent))): try: - cond = e.attrib['Condition'] + cond = e.attrib["Condition"] except KeyError: continue if cond == config_condition: e = DeepCopyElement(e) # Override DisableOptimizations for DxilDebug since this flag is problematic right now - if e.tag == 'ItemDefinitionGroup' and config == 'DxilDebug': - FxCompile = e.find('./FxCompile') or ET.SubElement(e, 'FxCompile') - DisableOptimizations = FxCompile.find('./DisableOptimizations') or ET.SubElement(FxCompile, 'DisableOptimizations') - DisableOptimizations.text = 'false' - e.attrib['Condition'] = "'$(Configuration)|$(Platform)'=='%s|%s'" % (config, arch) - parent.insert(n+1, e) + if e.tag == "ItemDefinitionGroup" and config == "DxilDebug": + FxCompile = e.find("./FxCompile") or ET.SubElement( + e, "FxCompile" + ) + DisableOptimizations = FxCompile.find( + "./DisableOptimizations" + ) or ET.SubElement(FxCompile, "DisableOptimizations") + DisableOptimizations.text = "false" + e.attrib[ + "Condition" + ] = "'$(Configuration)|$(Platform)'=='%s|%s'" % ( + config, + arch, + ) + parent.insert(n + 1, e) return changed + def AddSlnConfigs(sln_text): # sln: GlobalSection(SolutionConfigurationPlatforms) - rxSlnConfig = re.compile(r'^\s+%s = \1\|\2$' % reConfig) + rxSlnConfig = re.compile(r"^\s+%s = \1\|\2$" % reConfig) # sln: GlobalSection(ProjectConfigurationPlatforms) - rxActiveCfg = re.compile(r'^\s+\{[0-9A-Z-]+\}\.%s\.ActiveCfg = \1\|\2$' % reConfig) - rxBuild = re.compile(r'^\s+\{[0-9A-Z-]+\}\.%s\.Build\.0 = \1\|\2$' % reConfig) + rxActiveCfg = re.compile(r"^\s+\{[0-9A-Z-]+\}\.%s\.ActiveCfg = \1\|\2$" % reConfig) + rxBuild = re.compile(r"^\s+\{[0-9A-Z-]+\}\.%s\.Build\.0 = \1\|\2$" % reConfig) sln_changed = [] line_set = set(sln_text.splitlines()) + def add_line(lst, line): "Prevent duplicates from being added" if line not in line_set: lst.append(line) + for line in sln_text.splitlines(): - if line == 'VisualStudioVersion = 14.0.23107.0': - sln_changed.append('VisualStudioVersion = 14.0.25123.0') + if line == "VisualStudioVersion = 14.0.23107.0": + sln_changed.append("VisualStudioVersion = 14.0.25123.0") continue m = rxSlnConfig.match(line) if not m: @@ -293,56 +403,67 @@ def add_line(lst, line): if m: sln_changed.append(line) config = m.group(1) - if config in ('Debug', 'Release') and m.group(2) == 'x64': - add_line(sln_changed, line.replace('x64', 'Win32')) - add_line(sln_changed, line.replace(config, 'Dxil' + config)) - add_line(sln_changed, line.replace(config, 'Dxil' + config).replace('x64', 'Win32')) + if config in ("Debug", "Release") and m.group(2) == "x64": + add_line(sln_changed, line.replace("x64", "Win32")) + add_line(sln_changed, line.replace(config, "Dxil" + config)) + add_line( + sln_changed, + line.replace(config, "Dxil" + config).replace("x64", "Win32"), + ) continue sln_changed.append(line) - return '\n'.join(sln_changed) + return "\n".join(sln_changed) + def PatchProjects(args): - for name in sample_names + ['D3D12HelloWorld']: + for name in sample_names + ["D3D12HelloWorld"]: sample_path = PathToSampleSrc(args.samples, name) print("Patching " + name + " in " + sample_path) for proj_path in glob.glob(os.path.join(sample_path, "*.vcxproj")): # Consider looking for msbuild and other tool paths in registry, etg: # reg query HKLM\Software\Microsoft\MSBuild\ToolsVersions\14.0 - with open (proj_path, "r") as proj_file: + with open(proj_path, "r") as proj_file: proj_text = proj_file.read() root = ReadXmlString(proj_text) if AddProjectConfigs(root, args): changed_text = WriteXmlString(root) print("Patching the Windows SDK version in " + proj_path) - with open (proj_path, "w") as proj_file: + with open(proj_path, "w") as proj_file: proj_file.write(changed_text) # Extend project configs in solution file for sln_path in glob.glob(os.path.join(sample_path, "*.sln")): - with open (sln_path, "r") as sln_file: + with open(sln_path, "r") as sln_file: sln_text = sln_file.read() changed_text = AddSlnConfigs(sln_text) if changed_text != sln_text: print("Adding additional configurations to " + sln_path) - with open (sln_path, "w") as sln_file: + with open(sln_path, "w") as sln_file: sln_file.write(changed_text) + def BuildSample(samples_path, name, x86, dxil): sample_path = PathToSampleSrc(samples_path, name) if not SampleIsNested(name): print("Building " + name + " in " + sample_path) - Platform = x86 and 'Win32' or 'x64' - Configuration = dxil and 'DxilDebug' or 'Debug' - subprocess.check_call(["msbuild", "-nologo", - '/p:Configuration=%s;Platform=%s' % (Configuration, Platform), - '/t:Rebuild'], - cwd=sample_path) + Platform = x86 and "Win32" or "x64" + Configuration = dxil and "DxilDebug" or "Debug" + subprocess.check_call( + [ + "msbuild", + "-nologo", + "/p:Configuration=%s;Platform=%s" % (Configuration, Platform), + "/t:Rebuild", + ], + cwd=sample_path, + ) + def BuildSamples(args, dxil): samples_path = args.samples rxSample = args.sample and re.compile(args.sample, re.I) buildHelloWorld = False - os.environ['DXC_BIN_PATH'] = args.bins + os.environ["DXC_BIN_PATH"] = args.bins for sample_name in sample_names: if rxSample and not rxSample.match(sample_name): continue @@ -354,6 +475,7 @@ def BuildSamples(args, dxil): # HelloWorld containts sub-samples that must be built from the solution file. BuildSample(samples_path, "D3D12HelloWorld", args.x86, dxil) + def PatchSample(args, name, dxil, afterBuild): if args.sample and not re.match(args.sample, name, re.I): return @@ -362,24 +484,29 @@ def PatchSample(args, name, dxil, afterBuild): except: print("Error: selected sample missing from sample map '" + name + "'.") return - if afterBuild: actions = sample.postBuild - else: actions = sample.preBuild + if afterBuild: + actions = sample.postBuild + else: + actions = sample.preBuild for action in actions: action(args, name, dxil) + def PatchSamplesAfterBuild(args, dxil): for sample_name in sample_names: PatchSample(args, sample_name, dxil, True) + def PatchSamplesBeforeBuild(args, dxil): for sample_name in sample_names: PatchSample(args, sample_name, dxil, False) + def RunSampleTests(args): CheckEnvironment(args) print("Building Debug config ...") BuildSamples(args, False) - + print("Building DxilDebug config ...") BuildSamples(args, True) @@ -387,17 +514,28 @@ def RunSampleTests(args): PatchSamplesAfterBuild(args, False) PatchSamplesAfterBuild(args, True) - print("TODO - run Debug config vs. DxilDebug config and verify results are the same") + print( + "TODO - run Debug config vs. DxilDebug config and verify results are the same" + ) + if __name__ == "__main__": parser = argparse.ArgumentParser(description="Run D3D sample tests...") parser.add_argument("-x86", action="store_true", help="add x86 targets") parser.add_argument("-samples", help="path to root of D3D12 samples") parser.add_argument("-bins", help="path to dxcompiler.dll and related binaries") - parser.add_argument("-sample", help="choose a single sample to build/test (* wildcard supported)") - parser.add_argument("-postbuild", action="store_true", help="only perform post-build operations") + parser.add_argument( + "-sample", help="choose a single sample to build/test (* wildcard supported)" + ) + parser.add_argument( + "-postbuild", action="store_true", help="only perform post-build operations" + ) parser.add_argument("-patch", action="store_true", help="patch projects") - parser.add_argument("-symbols", action="store_true", help="try to copy symbols for various dependencies") + parser.add_argument( + "-symbols", + action="store_true", + help="try to copy symbols for various dependencies", + ) args = parser.parse_args() SetSampleActions() @@ -414,12 +552,12 @@ def RunSampleTests(args): exit(1) if args.sample: - print('Applying sample filter: %s' % args.sample) - args.sample = re.escape(args.sample).replace('\\*', '.*') + print("Applying sample filter: %s" % args.sample) + args.sample = re.escape(args.sample).replace("\\*", ".*") rxSample = re.compile(args.sample, re.I) for name in samples: if rxSample.match(name): - print(' %s' % name) + print(" %s" % name) if args.postbuild: print("Applying patch to post-build binaries to enable dxc ...") @@ -430,4 +568,3 @@ def RunSampleTests(args): PatchProjects(args) else: RunSampleTests(args) - diff --git a/utils/hct/hcttest-system-values.py b/utils/hct/hcttest-system-values.py index 6198cbbfea..ee7cc48e65 100644 --- a/utils/hct/hcttest-system-values.py +++ b/utils/hct/hcttest-system-values.py @@ -6,23 +6,23 @@ import re SignaturePoints = [ - # sig point, stage, tessfactors already present - ('VSIn', 'vs', False), - ('VSOut', 'vs', False), - ('PCIn', 'hs', False), - ('HSIn', 'hs', False), - ('HSCPIn', 'hs', False), - ('HSCPOut', 'hs', False), - ('PCOut', 'hs', True ), - ('DSIn', 'ds', True ), - ('DSCPIn', 'ds', False), - ('DSOut', 'ds', False), - ('GSVIn', 'gs', False), - ('GSIn', 'gs', False), - ('GSOut', 'gs', False), - ('PSIn', 'ps', False), - ('PSOut', 'ps', False), - ('CSIn', 'cs', False), + # sig point, stage, tessfactors already present + ("VSIn", "vs", False), + ("VSOut", "vs", False), + ("PCIn", "hs", False), + ("HSIn", "hs", False), + ("HSCPIn", "hs", False), + ("HSCPOut", "hs", False), + ("PCOut", "hs", True), + ("DSIn", "ds", True), + ("DSCPIn", "ds", False), + ("DSOut", "ds", False), + ("GSVIn", "gs", False), + ("GSIn", "gs", False), + ("GSOut", "gs", False), + ("PSIn", "ps", False), + ("PSOut", "ps", False), + ("CSIn", "cs", False), ] SysValues = """ @@ -54,23 +54,26 @@ InsideTessFactor """.split() + def run(cmd, output_filename=None): - import os - print(cmd) - if output_filename: - if os.path.isfile(output_filename): - os.unlink(output_filename) - with file(output_filename, 'wt') as f: - f.write('%s\n\n' % cmd) - ret = os.system(cmd + ' >> "%s" 2>&1' % output_filename) - output = '' - if os.path.isfile(output_filename): - with open(output_filename, 'rt') as f: - output = f.read() - return ret, output - else: - ret = os.system(cmd) - return ret, None + import os + + print(cmd) + if output_filename: + if os.path.isfile(output_filename): + os.unlink(output_filename) + with file(output_filename, "wt") as f: + f.write("%s\n\n" % cmd) + ret = os.system(cmd + ' >> "%s" 2>&1' % output_filename) + output = "" + if os.path.isfile(output_filename): + with open(output_filename, "rt") as f: + output = f.read() + return ret, output + else: + ret = os.system(cmd) + return ret, None + sig_examples = """ // Patch Constant signature: @@ -100,44 +103,50 @@ def run(cmd, output_filename=None): // Arb 0 x 0 NONE float x """ -rxSigBegin = re.compile(r'^// (Input|Output|Patch Constant) signature:\s*$') -rxSigElementsBegin = re.compile(r'^// -------------------- ----- ------ -------- -------- ------- ------\s*$') +rxSigBegin = re.compile(r"^// (Input|Output|Patch Constant) signature:\s*$") +rxSigElementsBegin = re.compile( + r"^// -------------------- ----- ------ -------- -------- ------- ------\s*$" +) # // SV_Target 1 xyzw 1 TARGET float xyzw -rxSigElement = re.compile(r'^// ([^\s]+)\s+([^\s]+)\s+([^\s]+)\s+([^\s]+)\s+([^\s]+)\s+([^\s]+)\s*([^\s]+)?\s*$') +rxSigElement = re.compile( + r"^// ([^\s]+)\s+([^\s]+)\s+([^\s]+)\s+([^\s]+)\s+([^\s]+)\s+([^\s]+)\s*([^\s]+)?\s*$" +) # Name, Index, Mask, Register, SysValue, Format, Used = m.groups() + # For now, ParseSigs just looks for a matching semantic name and reports whether it uses # a separate register (unpacked) and whether it's treated as arbitrary. def ParseSigs(text, semantic): - "return separate_reg, as_arb for matching semantic" - it = iter(text.splitlines()) - sigtype = None - try: - while True: - line = it.next() - m = rxSigBegin.match(line) - if m: - sigtype = m.group(1) - continue - m = rxSigElementsBegin.match(line) - if m: + "return separate_reg, as_arb for matching semantic" + it = iter(text.splitlines()) + sigtype = None + try: while True: - line = it.next() - m = rxSigElement.match(line) - if m: - Name, Index, Mask, Register, SysValue, Format, Used = m.groups() - if Name.lower() == semantic.lower(): - try: - regnum = int(Register) - reg = False - except: - reg = True - arb = SysValue == 'NONE' - return reg, arb - except StopIteration: - pass - return None + line = it.next() + m = rxSigBegin.match(line) + if m: + sigtype = m.group(1) + continue + m = rxSigElementsBegin.match(line) + if m: + while True: + line = it.next() + m = rxSigElement.match(line) + if m: + Name, Index, Mask, Register, SysValue, Format, Used = m.groups() + if Name.lower() == semantic.lower(): + try: + regnum = int(Register) + reg = False + except: + reg = True + arb = SysValue == "NONE" + return reg, arb + except StopIteration: + pass + return None + # Internal error or validation error: rxInternalError = re.compile(r"^(internal error:.*|error X8000:.*)$") @@ -150,162 +159,210 @@ def ParseSigs(text, semantic): # also errors for unsupported shader models # error X3660: cs_4_0 does not support interlocked operations rxSemanticErrors = [ - re.compile(r".*?\.hlsl.*?: error X4502: invalid .*? semantic '(\w+)'"), - re.compile(r".*?\.hlsl.*?: error X4502: (\w+) .*? supported on \w+"), - re.compile(r".*?\.hlsl.*?: error X3514: (\w+) is an invalid input semantic for geometry shader primitives, it must be its own parameter\."), - re.compile(r".*?\.hlsl.*?: error X3514: 'GSMain': input parameter '\w+' must have a geometry specifier"), - ] + re.compile(r".*?\.hlsl.*?: error X4502: invalid .*? semantic '(\w+)'"), + re.compile(r".*?\.hlsl.*?: error X4502: (\w+) .*? supported on \w+"), + re.compile( + r".*?\.hlsl.*?: error X3514: (\w+) is an invalid input semantic for geometry shader primitives, it must be its own parameter\." + ), + re.compile( + r".*?\.hlsl.*?: error X3514: 'GSMain': input parameter '\w+' must have a geometry specifier" + ), +] + + def map_gen(fn, *sequences): - "generator style map" - iters = map(iter, sequences) - while True: - yield fn(*map(next, iters)) + "generator style map" + iters = map(iter, sequences) + while True: + yield fn(*map(next, iters)) + + def firstTrue(iterable): - "returns first non-False element, or None." - for it in iterable: - if it: - return it + "returns first non-False element, or None." + for it in iterable: + if it: + return it + def ParseSVError(text, semantic): - "return true if error is about illegal use of matching semantic" - for line in text.splitlines(): - m = firstTrue(map_gen(lambda rx: rx.match(line), rxSemanticErrors)) - if m: - if len(m.groups()) < 1 or m.group(1).lower() == semantic.lower(): - return True - else: - m = rxInternalError.match(line) - if m: - print('#### Internal error detected!') - print(m.group(1)) - return 'InternalError' - return False + "return true if error is about illegal use of matching semantic" + for line in text.splitlines(): + m = firstTrue(map_gen(lambda rx: rx.match(line), rxSemanticErrors)) + if m: + if len(m.groups()) < 1 or m.group(1).lower() == semantic.lower(): + return True + else: + m = rxInternalError.match(line) + if m: + print("#### Internal error detected!") + print(m.group(1)) + return "InternalError" + return False + # TODO: Fill in the correct error pattern # error X4576: Non system-generated input signature parameter (Arb) cannot appear after a system generated value. -rxMustBeLastError = re.compile(r".*?\.hlsl.*?: error X4576: Non system-generated input signature parameter \(\w+\) cannot appear after a system generated value.") +rxMustBeLastError = re.compile( + r".*?\.hlsl.*?: error X4576: Non system-generated input signature parameter \(\w+\) cannot appear after a system generated value." +) + + def ParseSGVError(text, semantic): - "return true if error is about matching semantic having to be declared last" - for line in text.splitlines(): - m = rxMustBeLastError.match(line) - if m: - return True - else: - m = rxInternalError.match(line) - if m: - print('#### Internal error detected!') - print(m.group(1)) - return 'InternalError' - return False - -hlsl_filename = os.abspath(os.path.join() - os.environ['HLSL_SRC_DIR'], - r'tools\clang\test\HLSL', - 'system-values.hlsl')) + "return true if error is about matching semantic having to be declared last" + for line in text.splitlines(): + m = rxMustBeLastError.match(line) + if m: + return True + else: + m = rxInternalError.match(line) + if m: + print("#### Internal error detected!") + print(m.group(1)) + return "InternalError" + return False + + +hlsl_filename = os.abspath( + os.path.join( + os.environ["HLSL_SRC_DIR"], r"tools\clang\test\HLSL", "system-values.hlsl" + ) +) + def main(): - do('5_1') - do('5_0') - do('4_1') - do('4_0') + do("5_1") + do("5_0") + do("4_1") + do("4_0") + def do(sm): - import os, sys - # set up table: - table = [[None] * len(SignaturePoints) for sv in SysValues] - null_filename = 'output\\test_sv_null.txt' - - for col, (sigpoint, stage, tfpresent) in enumerate(SignaturePoints): - entry = stage.upper() + 'Main' - target = stage + '_%s' % sm - - # test arb support: - ret, output = run('fxc %s /E %s /T %s /D%s_Defs=Def_Arb(float,Arb1,Arb1)' % - (hlsl_filename, entry, target, sigpoint), - null_filename) - arb_supported = ret == 0 - - # iterate all system values - sysvalues = tfpresent and SysValues[:-2] or SysValues - for row, sv in enumerate(sysvalues): - output_filename = 'output\\test_sv_output_%s_%s_%s.txt' % (sm, sv, sigpoint) - separate_reg, as_arb, def_last, result = False, False, False, 'NotInSig' - - ret, output = run('fxc %s /E %s /T %s /D%s_Defs=Def_%s' % - (hlsl_filename, entry, target, sigpoint, sv), - output_filename) - if ret: - # Failed, look for expected error message: - found = ParseSVError(output, 'SV_'+sv) - if found == 'InternalError': - table[row][col] = 'InternalError' - print('#### Internal error from ParseSVError - see "%s"' % output_filename) - elif not found: - table[row][col] = 'ParseSVError' - print('#### Error from ParseSVError - see "%s"' % output_filename) - else: - table[row][col] = 'NA' - if os.path.isfile(output_filename): - os.unlink(output_filename) - continue - - parse_result = ParseSigs(output, 'SV_'+sv) - if parse_result: - separate_reg, as_arb = parse_result - if as_arb: - if separate_reg: - table[row][col] = 'Error: both as_arb and separate_reg set!' - print('#### Error from ParseSigs, both as_arb and separate_reg set - see "%s"' % output_filename) - continue - result = 'Arb' - else: - if separate_reg: - result = 'NotPacked' - else: - result = 'SV' - if os.path.isfile(output_filename): - os.unlink(output_filename) - else: - print('## Not in signature? See "%s"' % output_filename) - - if arb_supported and not as_arb and not separate_reg: - output_filename = 'output\\test_sv_output_last_%s_%s_%s.txt' % (sm, sv, sigpoint) - # must system value be declared last? test by adding arb last if arb support - ret, output = run('fxc %s /E %s /T %s /D%s_Defs="Def_%s Def_Arb(float,Arb1,Arb1)"' % - (hlsl_filename, entry, target, sigpoint, sv), - output_filename) - if ret: - found = ParseSGVError(output, 'SV_'+sv) - if found == 'InternalError': - result += ' | InternalError found with ParseSGVError' - print('#### Internal error from ParseSGVError - see "%s"' % output_filename) - elif not found: - result += ' | ParseSGVError' - print('#### Error from ParseSGVError - see "%s"' % output_filename) - elif result == 'SV': - result = 'SGV' - if os.path.isfile(output_filename): - os.unlink(output_filename) - else: - result += ' | Error: last required detected, but not SV?' - print('#### Error: last required detected, but not SV? - see "%s"' % output_filename) - else: - if os.path.isfile(output_filename): - os.unlink(output_filename) + import os, sys + + # set up table: + table = [[None] * len(SignaturePoints) for sv in SysValues] + null_filename = "output\\test_sv_null.txt" + + for col, (sigpoint, stage, tfpresent) in enumerate(SignaturePoints): + entry = stage.upper() + "Main" + target = stage + "_%s" % sm + + # test arb support: + ret, output = run( + "fxc %s /E %s /T %s /D%s_Defs=Def_Arb(float,Arb1,Arb1)" + % (hlsl_filename, entry, target, sigpoint), + null_filename, + ) + arb_supported = ret == 0 + + # iterate all system values + sysvalues = tfpresent and SysValues[:-2] or SysValues + for row, sv in enumerate(sysvalues): + output_filename = "output\\test_sv_output_%s_%s_%s.txt" % (sm, sv, sigpoint) + separate_reg, as_arb, def_last, result = False, False, False, "NotInSig" + + ret, output = run( + "fxc %s /E %s /T %s /D%s_Defs=Def_%s" + % (hlsl_filename, entry, target, sigpoint, sv), + output_filename, + ) + if ret: + # Failed, look for expected error message: + found = ParseSVError(output, "SV_" + sv) + if found == "InternalError": + table[row][col] = "InternalError" + print( + '#### Internal error from ParseSVError - see "%s"' + % output_filename + ) + elif not found: + table[row][col] = "ParseSVError" + print('#### Error from ParseSVError - see "%s"' % output_filename) + else: + table[row][col] = "NA" + if os.path.isfile(output_filename): + os.unlink(output_filename) + continue + + parse_result = ParseSigs(output, "SV_" + sv) + if parse_result: + separate_reg, as_arb = parse_result + if as_arb: + if separate_reg: + table[row][col] = "Error: both as_arb and separate_reg set!" + print( + '#### Error from ParseSigs, both as_arb and separate_reg set - see "%s"' + % output_filename + ) + continue + result = "Arb" + else: + if separate_reg: + result = "NotPacked" + else: + result = "SV" + if os.path.isfile(output_filename): + os.unlink(output_filename) + else: + print('## Not in signature? See "%s"' % output_filename) + + if arb_supported and not as_arb and not separate_reg: + output_filename = "output\\test_sv_output_last_%s_%s_%s.txt" % ( + sm, + sv, + sigpoint, + ) + # must system value be declared last? test by adding arb last if arb support + ret, output = run( + 'fxc %s /E %s /T %s /D%s_Defs="Def_%s Def_Arb(float,Arb1,Arb1)"' + % (hlsl_filename, entry, target, sigpoint, sv), + output_filename, + ) + if ret: + found = ParseSGVError(output, "SV_" + sv) + if found == "InternalError": + result += " | InternalError found with ParseSGVError" + print( + '#### Internal error from ParseSGVError - see "%s"' + % output_filename + ) + elif not found: + result += " | ParseSGVError" + print( + '#### Error from ParseSGVError - see "%s"' % output_filename + ) + elif result == "SV": + result = "SGV" + if os.path.isfile(output_filename): + os.unlink(output_filename) + else: + result += " | Error: last required detected, but not SV?" + print( + '#### Error: last required detected, but not SV? - see "%s"' + % output_filename + ) + else: + if os.path.isfile(output_filename): + os.unlink(output_filename) + + table[row][col] = result - table[row][col] = result + for row in range(row + 1, len(SysValues)): + table[row][col] = "TessFactor" - for row in range(row+1, len(SysValues)): - table[row][col] = 'TessFactor' + def WriteTable(writefn, table): + writefn( + "Semantic," + + ",".join([sigpoint for sigpoint, stage, tfpresent in SignaturePoints]) + + "\n" + ) + for n, row in enumerate(table): + writefn((SysValues[n]) + ",".join(row) + "\n") - def WriteTable(writefn, table): - writefn('Semantic,' + ','.join([sigpoint for sigpoint, stage, tfpresent in SignaturePoints]) + '\n') - for n, row in enumerate(table): - writefn((SysValues[n]) + ','.join(row) + '\n') + WriteTable(sys.stdout.write, table) + with open("fxc_sig_packing_table_%s.csv" % sm, "wt") as f: + WriteTable(f.write, table) - WriteTable(sys.stdout.write, table) - with open('fxc_sig_packing_table_%s.csv' % sm, 'wt') as f: - WriteTable(f.write, table) -if __name__ == '__main__': - main() +if __name__ == "__main__": + main() diff --git a/utils/hct/hcttracei.py b/utils/hct/hcttracei.py index 433f7818af..0dc2d18430 100644 --- a/utils/hct/hcttracei.py +++ b/utils/hct/hcttracei.py @@ -9,77 +9,93 @@ import xml.etree.ElementTree as ET # Task values. -DXCompilerInitialization = 1; -DXCompilerShutdown = 2; -DXCompilerCreateInstance = 3; -DXCompilerIntelliSenseParse = 4; -DXCompilerCompile = 5; -DXCompilerPreprocess = 6; -DXCompilerDisassemble = 7; +DXCompilerInitialization = 1 +DXCompilerShutdown = 2 +DXCompilerCreateInstance = 3 +DXCompilerIntelliSenseParse = 4 +DXCompilerCompile = 5 +DXCompilerPreprocess = 6 +DXCompilerDisassemble = 7 # Opcode values -OpcodeStart = 1; -OpcodeStop = 2; +OpcodeStart = 1 +OpcodeStop = 2 # Namespace dictionary. -ns = {'e': 'http://schemas.microsoft.com/win/2004/08/events/event'} +ns = {"e": "http://schemas.microsoft.com/win/2004/08/events/event"} + def write_basic_info(node): - '''Writes computer information''' + """Writes computer information""" print("Basic information:") - print("CPU Speed: %s" % node.find("e:Data[@Name='CPUSpeed']", ns). text) - print("Processor count: %s" % node.find("e:Data[@Name='NumberOfProcessors']", ns). text) - print("Events lost: %s" % node.find("e:Data[@Name='EventsLost']", ns). text) - print("Pointer size: %s" % node.find("e:Data[@Name='PointerSize']", ns). text) + print("CPU Speed: %s" % node.find("e:Data[@Name='CPUSpeed']", ns).text) + print( + "Processor count: %s" % node.find("e:Data[@Name='NumberOfProcessors']", ns).text + ) + print("Events lost: %s" % node.find("e:Data[@Name='EventsLost']", ns).text) + print("Pointer size: %s" % node.find("e:Data[@Name='PointerSize']", ns).text) def write_compile_times(root): - '''Prints out compilation times.''' + """Prints out compilation times.""" compilations = {} for e in root: system_node = e.find("e:System", ns) if system_node is None: continue channel = system_node.find("e:Channel", ns) - if channel is None or channel.text <> "Microsoft-Windows-DXCompiler-API/Analytic": + if ( + channel is None + or channel.text != "Microsoft-Windows-DXCompiler-API/Analytic" + ): continue task = int(system_node.find("e:Task", ns).text) opcode = int(system_node.find("e:Opcode", ns).text) - pid = int(system_node.find("e:Execution", ns).attrib['ProcessID']) - tid = int(system_node.find("e:Execution", ns).attrib['ThreadID']) - time_created = system_node.find("e:TimeCreated", ns).attrib['SystemTime'] + pid = int(system_node.find("e:Execution", ns).attrib["ProcessID"]) + tid = int(system_node.find("e:Execution", ns).attrib["ThreadID"]) + time_created = system_node.find("e:TimeCreated", ns).attrib["SystemTime"] # Something like: # 2016-02-02T00:10:51.619434100Z # Unfortunately datetime doesn't have enough precision, so we make do with this: # 2016-02-02T00:10:39.630081 if task == DXCompilerCompile: time_created = time_created[:26] - cid = '{0},{1}'.format(pid, tid) - parsed_time_created = datetime.datetime.strptime(time_created, "%Y-%m-%dT%H:%M:%S.%f") + cid = "{0},{1}".format(pid, tid) + parsed_time_created = datetime.datetime.strptime( + time_created, "%Y-%m-%dT%H:%M:%S.%f" + ) if opcode == OpcodeStart: - #print "Start at %s" % time_created + # print("Start at %s" % time_created) compilations[cid] = parsed_time_created else: old_parsed_time_created = compilations[cid] - print "Compilation took %s" % str(parsed_time_created - old_parsed_time_created) + print( + "Compilation took %s" + % str(parsed_time_created - old_parsed_time_created) + ) def main(): - parser = argparse.ArgumentParser(description=__doc__) - parser.add_argument('-v', '--verbose', action='store_true', - help='Show verbose output') - parser.add_argument('dumpfiles', nargs='+') - args = parser.parse_args() + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument( + "-v", "--verbose", action="store_true", help="Show verbose output" + ) + parser.add_argument("dumpfiles", nargs="+") + args = parser.parse_args() + + for dumpfile in args.dumpfiles: + if args.verbose: + print( + "Scanning for dxcompiler events in dumpfile: %s" % (dumpfile,), + file=sys.stderr, + ) + tree = ET.parse(dumpfile) + root = tree.getroot() + write_basic_info(root.find("e:Event/e:EventData", ns)) + write_compile_times(root) + # Other interesting things: + # errors, working set, additional stats - for dumpfile in args.dumpfiles: - if args.verbose: - print >>sys.stderr, 'Scanning for dxcompiler events in dumpfile: %s' % (dumpfile,) - tree = ET.parse(dumpfile) - root = tree.getroot() - write_basic_info(root.find('e:Event/e:EventData', ns)) - write_compile_times(root) - # Other interesting things: - # errors, working set, additional stats -if __name__ == '__main__': - main() +if __name__ == "__main__": + main() diff --git a/utils/hct/query.py b/utils/hct/query.py index 657bcc7c97..e16eeb0637 100644 --- a/utils/hct/query.py +++ b/utils/hct/query.py @@ -2,14 +2,14 @@ from hctdb_instrhelp import get_db_hlsl import argparse + # user defined function def inst_query_dxil(insts, inst): # example - + if inst.ret_type == "v" and inst.fn_attr != "": return True return False - # example """ @@ -57,18 +57,18 @@ def set_ret_type_and_args(self, dxil_inst): ops = [] for op in dxil_inst.ops: ops.append(op.llvm_type) - + if len(ops) > 0: - self.ret_type = ops[0] - + self.ret_type = ops[0] + if len(ops) > 1: self.args = ops[1:] def __init__(self, dxil_inst): - self.dxil_inst = dxil_inst # db_dxil_inst type, defined in hctdb.py + self.dxil_inst = dxil_inst # db_dxil_inst type, defined in hctdb.py self.name = dxil_inst.name self.fn_attr = dxil_inst.fn_attr - self.wave = dxil_inst.is_wave # bool + self.wave = dxil_inst.is_wave # bool self.ret_type = "" self.args = [] self.set_ret_type_and_args(dxil_inst) @@ -77,38 +77,38 @@ def __str__(self): str_args = ", ".join(self.args) return "[{}] {} {}({})".format(self.fn_attr, self.ret_type, self.name, str_args) + class HLOperationWrapper: def set_ret_type_and_args(self, hl_op): ops = hl_op.params if len(ops) > 0: - self.ret_type = ops[0].type_name - + self.ret_type = ops[0].type_name + if len(ops) > 1: self.args = [x.name + " " + x.type_name for x in ops[1:]] def __init__(self, hl_op): - self.hl_op = hl_op # db_hlsl_intrinsic type, defined in hctdb.py + self.hl_op = hl_op # db_hlsl_intrinsic type, defined in hctdb.py self.name = hl_op.name self.fn_attr = "rn" if hl_op.readnone else "" - self.fn_attr += "ro" if hl_op.readonly else "" - self.wave = hl_op.wave # bool + self.fn_attr += "ro" if hl_op.readonly else "" + self.wave = hl_op.wave # bool self.ret_type = "" self.args = [] self.set_ret_type_and_args(hl_op) def __str__(self): - str_args = ", ".join(self.args) + str_args = ", ".join(self.args) return "[{}] {} {}({})".format(self.fn_attr, self.ret_type, self.name, str_args) def parse_query_hlsl(db, options): - HLInstructions = [] # The query function should be using the HLOperationWrapper interface # because that is what's being loaded into the instructions list. for hl_op in db.intrinsics: - new_op = HLOperationWrapper(hl_op) + new_op = HLOperationWrapper(hl_op) HLInstructions.append(new_op) # apply the query filter @@ -117,9 +117,8 @@ def parse_query_hlsl(db, options): if inst_query_hlsl(HLInstructions, instruction): print(instruction) -def parse_query_dxil(db, options): - +def parse_query_dxil(db, options): DxilInstructions = [] # The query function should use the DxilInstructionWrapper interface @@ -134,8 +133,11 @@ def parse_query_dxil(db, options): if inst_query_dxil(DxilInstructions, instruction): print(instruction) + parser = argparse.ArgumentParser(description="Query instructions.") -parser.add_argument("-query", choices=["dxil", "hlsl"], help="type of instructions to query.") +parser.add_argument( + "-query", choices=["dxil", "hlsl"], help="type of instructions to query." +) args = parser.parse_args() if args.query == "dxil": @@ -145,4 +147,4 @@ def parse_query_dxil(db, options): if args.query == "hlsl": db_hlsl = get_db_hlsl() - parse_query_hlsl(db_hlsl, args) \ No newline at end of file + parse_query_hlsl(db_hlsl, args)