From 6c8ae19be66cee247980a48e736a4e05d14de179 Mon Sep 17 00:00:00 2001 From: 3gg <3gg@shellblade.net> Date: Tue, 2 Dec 2025 16:39:36 -0800 Subject: Immediate-mode renderer, triangle demo, shader compilation in cmake, Agility SDK --- .../googletest/CMakeLists.txt | 45 + .../googletest/MockDevice.hpp | 1299 +++++++++++++++++++ .../googletest/feature_support_test.cpp | 1354 ++++++++++++++++++++ .../DirectX-Headers-1.618.2/googletest/meson.build | 13 + 4 files changed, 2711 insertions(+) create mode 100644 contrib/DirectX-Headers-1.618.2/googletest/CMakeLists.txt create mode 100644 contrib/DirectX-Headers-1.618.2/googletest/MockDevice.hpp create mode 100644 contrib/DirectX-Headers-1.618.2/googletest/feature_support_test.cpp create mode 100644 contrib/DirectX-Headers-1.618.2/googletest/meson.build (limited to 'contrib/DirectX-Headers-1.618.2/googletest') diff --git a/contrib/DirectX-Headers-1.618.2/googletest/CMakeLists.txt b/contrib/DirectX-Headers-1.618.2/googletest/CMakeLists.txt new file mode 100644 index 0000000..ff979d9 --- /dev/null +++ b/contrib/DirectX-Headers-1.618.2/googletest/CMakeLists.txt @@ -0,0 +1,45 @@ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. +include(FetchContent) + +set(gtest_force_shared_crt ON CACHE BOOL "" FORCE) +FetchContent_Declare( + googletest + GIT_REPOSITORY https://github.com/google/googletest.git + GIT_TAG main # Live at head +) +FetchContent_MakeAvailable(googletest) + +list(APPEND dxlibs "") +if(EXISTS "/usr/lib/wsl/lib/") + find_library(libd3d12 d3d12 HINTS /usr/lib/wsl/lib) + list(APPEND dxlibs ${libd3d12}) +else() +# Fallback to default: let CMake look for libs + list(APPEND dxlibs d3d12) +endif() + +project(DirectX-Headers-GoogleTest-Suite + DESCRIPTION "DirectX-Header tests using GooleTest" + HOMEPAGE_URL "https://github.com/microsoft/DirectX-Headers/" + LANGUAGES CXX) + +set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD_REQUIRED ON) +set(CMAKE_CXX_EXTENSIONS OFF) + +add_executable(Feature-Support-Test feature_support_test.cpp) +target_link_libraries(Feature-Support-Test DirectX-Headers DirectX-Guids ${dxlibs} gtest_main) +add_test(Feature-Support-Test Feature-Support-Test) + +if ( CMAKE_CXX_COMPILER_ID MATCHES "Clang" ) + target_compile_options(Feature-Support-Test PRIVATE -Wno-unused-variable) +endif() + +if(WIN32) + target_compile_definitions(Feature-Support-Test PRIVATE _UNICODE UNICODE _WIN32_WINNT=0x0A00) + + if(WINDOWS_STORE) + target_compile_definitions(Feature-Support-Test PRIVATE WINAPI_FAMILY=WINAPI_FAMILY_APP) + endif() +endif() diff --git a/contrib/DirectX-Headers-1.618.2/googletest/MockDevice.hpp b/contrib/DirectX-Headers-1.618.2/googletest/MockDevice.hpp new file mode 100644 index 0000000..748d5ba --- /dev/null +++ b/contrib/DirectX-Headers-1.618.2/googletest/MockDevice.hpp @@ -0,0 +1,1299 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +#ifndef DIRECTX_HEADERS_MOCK_DEVICE_HPP +#define DIRECTX_HEADERS_MOCK_DEVICE_HPP +#include + +#ifndef __RPC_FAR +#define __RPC_FAR +#endif + +#include +#include +#include +#include "dxguids/dxguids.h" + +class MockDevice : public ID3D12Device +{ +public: // Constructors and custom functions + MockDevice(UINT NodeCount = 1) + : m_NodeCount(NodeCount) + , m_TileBasedRenderer(m_NodeCount, false) + , m_UMA(m_NodeCount, false) + , m_CacheCoherentUMA(m_NodeCount, false) + , m_IsolatedMMU(m_NodeCount, false) + , m_ProtectedResourceSessionSupport(m_NodeCount, D3D12_PROTECTED_RESOURCE_SESSION_SUPPORT_FLAG_NONE) + , m_HeapSerializationTier(m_NodeCount, D3D12_HEAP_SERIALIZATION_TIER_0) + , m_ProtectedResourceSessionTypeCount(m_NodeCount, 0) + , m_ProtectedResourceSessionTypes(m_NodeCount) + { + + } + + virtual ~MockDevice() = default; + + void SetNodeCount(UINT NewCount) + { + m_NodeCount = NewCount; + m_TileBasedRenderer.resize(NewCount); + m_UMA.resize(NewCount); + m_CacheCoherentUMA.resize(NewCount); + m_IsolatedMMU.resize(NewCount); + m_ProtectedResourceSessionSupport.resize(NewCount); + m_HeapSerializationTier.resize(NewCount); + m_ProtectedResourceSessionTypeCount.resize(NewCount); + m_ProtectedResourceSessionTypes.resize(NewCount); + } + +public: // ID3D12Device + UINT STDMETHODCALLTYPE GetNodeCount() override + { + return m_NodeCount; + } + + HRESULT STDMETHODCALLTYPE CreateCommandQueue( + _In_ const D3D12_COMMAND_QUEUE_DESC *pDesc, + REFIID riid, + _COM_Outptr_ void **ppCommandQueue + ) override + { + return S_OK; + } + + HRESULT STDMETHODCALLTYPE CreateCommandAllocator( + _In_ D3D12_COMMAND_LIST_TYPE type, + REFIID riid, + _COM_Outptr_ void **ppCommandAllocator + ) override + { + return S_OK; + } + + HRESULT STDMETHODCALLTYPE CreateGraphicsPipelineState( + _In_ const D3D12_GRAPHICS_PIPELINE_STATE_DESC *pDesc, + REFIID riid, + _COM_Outptr_ void **ppPipelineState + ) override + { + return S_OK; + } + + HRESULT STDMETHODCALLTYPE CreateComputePipelineState( + _In_ const D3D12_COMPUTE_PIPELINE_STATE_DESC *pDesc, + REFIID riid, + _COM_Outptr_ void **ppPipelineState + ) override + { + return S_OK; + } + + HRESULT STDMETHODCALLTYPE CreateCommandList( + _In_ UINT nodeMask, + _In_ D3D12_COMMAND_LIST_TYPE type, + _In_ ID3D12CommandAllocator *pCommandAllocator, + _In_opt_ ID3D12PipelineState *pInitialState, + REFIID riid, + _COM_Outptr_ void **ppCommandList + ) override + { + return S_OK; + } + + virtual HRESULT STDMETHODCALLTYPE CreateDescriptorHeap( + _In_ const D3D12_DESCRIPTOR_HEAP_DESC *pDescriptorHeapDesc, + REFIID riid, + _COM_Outptr_ void **ppvHeap + ) override + { + return S_OK; + } + + virtual UINT STDMETHODCALLTYPE GetDescriptorHandleIncrementSize( + _In_ D3D12_DESCRIPTOR_HEAP_TYPE DescriptorHeapType + ) override + { + return 0; + } + + virtual HRESULT STDMETHODCALLTYPE CreateRootSignature( + _In_ UINT nodeMask, + _In_reads_(blobLengthInBytes) const void *pBlobWithRootSignature, + _In_ SIZE_T blobLengthInBytes, + REFIID riid, + _COM_Outptr_ void **ppvRootSignature + ) override + { + return S_OK; + } + + virtual void STDMETHODCALLTYPE CreateConstantBufferView( + _In_opt_ const D3D12_CONSTANT_BUFFER_VIEW_DESC *pDesc, + _In_ D3D12_CPU_DESCRIPTOR_HANDLE DestDescriptor + ) override + { + return; + } + + virtual void STDMETHODCALLTYPE CreateShaderResourceView( + _In_opt_ ID3D12Resource *pResource, + _In_opt_ const D3D12_SHADER_RESOURCE_VIEW_DESC *pDesc, + _In_ D3D12_CPU_DESCRIPTOR_HANDLE DestDescriptor + ) override + { + return; + } + + virtual void STDMETHODCALLTYPE CreateUnorderedAccessView( + _In_opt_ ID3D12Resource *pResource, + _In_opt_ ID3D12Resource *pCounterResource, + _In_opt_ const D3D12_UNORDERED_ACCESS_VIEW_DESC *pDesc, + _In_ D3D12_CPU_DESCRIPTOR_HANDLE DestDescriptor + ) override + { + return; + } + + virtual void STDMETHODCALLTYPE CreateRenderTargetView( + _In_opt_ ID3D12Resource *pResource, + _In_opt_ const D3D12_RENDER_TARGET_VIEW_DESC *pDesc, + _In_ D3D12_CPU_DESCRIPTOR_HANDLE DestDescriptor + ) override + { + return; + } + + virtual void STDMETHODCALLTYPE CreateDepthStencilView( + _In_opt_ ID3D12Resource *pResource, + _In_opt_ const D3D12_DEPTH_STENCIL_VIEW_DESC *pDesc, + _In_ D3D12_CPU_DESCRIPTOR_HANDLE DestDescriptor) override + { + return; + } + + virtual void STDMETHODCALLTYPE CreateSampler( + _In_ const D3D12_SAMPLER_DESC *pDesc, + _In_ D3D12_CPU_DESCRIPTOR_HANDLE DestDescriptor) override + { + return; + } + + virtual void STDMETHODCALLTYPE CopyDescriptors( + _In_ UINT NumDestDescriptorRanges, + _In_reads_(NumDestDescriptorRanges) const D3D12_CPU_DESCRIPTOR_HANDLE *pDestDescriptorRangeStarts, + _In_reads_opt_(NumDestDescriptorRanges) const UINT *pDestDescriptorRangeSizes, + _In_ UINT NumSrcDescriptorRanges, + _In_reads_(NumSrcDescriptorRanges) const D3D12_CPU_DESCRIPTOR_HANDLE *pSrcDescriptorRangeStarts, + _In_reads_opt_(NumSrcDescriptorRanges) const UINT *pSrcDescriptorRangeSizes, + _In_ D3D12_DESCRIPTOR_HEAP_TYPE DescriptorHeapsType) override + { + return; + } + + virtual void STDMETHODCALLTYPE CopyDescriptorsSimple( + _In_ UINT NumDescriptors, + _In_ D3D12_CPU_DESCRIPTOR_HANDLE DestDescriptorRangeStart, + _In_ D3D12_CPU_DESCRIPTOR_HANDLE SrcDescriptorRangeStart, + _In_ D3D12_DESCRIPTOR_HEAP_TYPE DescriptorHeapsType) override + { + return; + } + +#if defined(_MSC_VER) || !defined(_WIN32) + virtual D3D12_RESOURCE_ALLOCATION_INFO STDMETHODCALLTYPE GetResourceAllocationInfo( + _In_ UINT visibleMask, + _In_ UINT numResourceDescs, + _In_reads_(numResourceDescs) const D3D12_RESOURCE_DESC *pResourceDescs) override + { + D3D12_RESOURCE_ALLOCATION_INFO mockInfo = {}; + return mockInfo; + } +#else + virtual D3D12_RESOURCE_ALLOCATION_INFO *STDMETHODCALLTYPE GetResourceAllocationInfo( + D3D12_RESOURCE_ALLOCATION_INFO * RetVal, + _In_ UINT visibleMask, + _In_ UINT numResourceDescs, + _In_reads_(numResourceDescs) const D3D12_RESOURCE_DESC *pResourceDescs) override + { + if (RetVal) + { + *RetVal = {}; + } + return RetVal; + } +#endif + +#if defined(_MSC_VER) || !defined(_WIN32) + virtual D3D12_HEAP_PROPERTIES STDMETHODCALLTYPE GetCustomHeapProperties( + _In_ UINT nodeMask, + D3D12_HEAP_TYPE heapType) override + { + D3D12_HEAP_PROPERTIES mockProps = {}; + return mockProps; + } +#else + virtual D3D12_HEAP_PROPERTIES *STDMETHODCALLTYPE GetCustomHeapProperties( + D3D12_HEAP_PROPERTIES * RetVal, + _In_ UINT nodeMask, + D3D12_HEAP_TYPE heapType) override + { + if (RetVal) + { + *RetVal = {}; + } + return RetVal; + } +#endif + + virtual HRESULT STDMETHODCALLTYPE CreateCommittedResource( + _In_ const D3D12_HEAP_PROPERTIES *pHeapProperties, + D3D12_HEAP_FLAGS HeapFlags, + _In_ const D3D12_RESOURCE_DESC *pDesc, + D3D12_RESOURCE_STATES InitialResourceState, + _In_opt_ const D3D12_CLEAR_VALUE *pOptimizedClearValue, + REFIID riidResource, + _COM_Outptr_opt_ void **ppvResource) override + { + return S_OK; + } + + virtual HRESULT STDMETHODCALLTYPE CreateHeap( + _In_ const D3D12_HEAP_DESC *pDesc, + REFIID riid, + _COM_Outptr_opt_ void **ppvHeap) override + { + return S_OK; + } + + virtual HRESULT STDMETHODCALLTYPE CreatePlacedResource( + _In_ ID3D12Heap *pHeap, + UINT64 HeapOffset, + _In_ const D3D12_RESOURCE_DESC *pDesc, + D3D12_RESOURCE_STATES InitialState, + _In_opt_ const D3D12_CLEAR_VALUE *pOptimizedClearValue, + REFIID riid, + _COM_Outptr_opt_ void **ppvResource) override + { + return S_OK; + } + + virtual HRESULT STDMETHODCALLTYPE CreateReservedResource( + _In_ const D3D12_RESOURCE_DESC *pDesc, + D3D12_RESOURCE_STATES InitialState, + _In_opt_ const D3D12_CLEAR_VALUE *pOptimizedClearValue, + REFIID riid, + _COM_Outptr_opt_ void **ppvResource) override + { + return S_OK; + } + + virtual HRESULT STDMETHODCALLTYPE CreateSharedHandle( + _In_ ID3D12DeviceChild *pObject, + _In_opt_ const SECURITY_ATTRIBUTES *pAttributes, + DWORD Access, + _In_opt_ LPCWSTR Name, + _Out_ HANDLE *pHandle) override + { + return S_OK; + } + + virtual HRESULT STDMETHODCALLTYPE OpenSharedHandle( + _In_ HANDLE NTHandle, + REFIID riid, + _COM_Outptr_opt_ void **ppvObj) override + { + return S_OK; + } + + virtual HRESULT STDMETHODCALLTYPE OpenSharedHandleByName( + _In_ LPCWSTR Name, + DWORD Access, + /* [annotation][out] */ + _Out_ HANDLE *pNTHandle) override + { + return S_OK; + } + + virtual HRESULT STDMETHODCALLTYPE MakeResident( + UINT NumObjects, + _In_reads_(NumObjects) ID3D12Pageable *const *ppObjects) override + { + return S_OK; + } + + virtual HRESULT STDMETHODCALLTYPE Evict( + UINT NumObjects, + _In_reads_(NumObjects) ID3D12Pageable *const *ppObjects) override + { + return S_OK; + } + + virtual HRESULT STDMETHODCALLTYPE CreateFence( + UINT64 InitialValue, + D3D12_FENCE_FLAGS Flags, + REFIID riid, + _COM_Outptr_ void **ppFence) override + { + return S_OK; + } + + virtual HRESULT STDMETHODCALLTYPE GetDeviceRemovedReason( void) override + { + return S_OK; + } + + virtual void STDMETHODCALLTYPE GetCopyableFootprints( + _In_ const D3D12_RESOURCE_DESC *pResourceDesc, + _In_range_(0,D3D12_REQ_SUBRESOURCES) UINT FirstSubresource, + _In_range_(0,D3D12_REQ_SUBRESOURCES-FirstSubresource) UINT NumSubresources, + UINT64 BaseOffset, + _Out_writes_opt_(NumSubresources) D3D12_PLACED_SUBRESOURCE_FOOTPRINT *pLayouts, + _Out_writes_opt_(NumSubresources) UINT *pNumRows, + _Out_writes_opt_(NumSubresources) UINT64 *pRowSizeInBytes, + _Out_opt_ UINT64 *pTotalBytes) override + { + return; + } + + virtual HRESULT STDMETHODCALLTYPE CreateQueryHeap( + _In_ const D3D12_QUERY_HEAP_DESC *pDesc, + REFIID riid, + _COM_Outptr_opt_ void **ppvHeap) override + { + return S_OK; + } + + virtual HRESULT STDMETHODCALLTYPE SetStablePowerState( + BOOL Enable) override + { + return S_OK; + } + + virtual HRESULT STDMETHODCALLTYPE CreateCommandSignature( + _In_ const D3D12_COMMAND_SIGNATURE_DESC *pDesc, + _In_opt_ ID3D12RootSignature *pRootSignature, + REFIID riid, + _COM_Outptr_opt_ void **ppvCommandSignature) override + { + return S_OK; + } + + virtual void STDMETHODCALLTYPE GetResourceTiling( + _In_ ID3D12Resource *pTiledResource, + _Out_opt_ UINT *pNumTilesForEntireResource, + _Out_opt_ D3D12_PACKED_MIP_INFO *pPackedMipDesc, + _Out_opt_ D3D12_TILE_SHAPE *pStandardTileShapeForNonPackedMips, + _Inout_opt_ UINT *pNumSubresourceTilings, + _In_ UINT FirstSubresourceTilingToGet, + _Out_writes_(*pNumSubresourceTilings) D3D12_SUBRESOURCE_TILING *pSubresourceTilingsForNonPackedMips) override + { + return; + } + +#if defined(_MSC_VER) || !defined(_WIN32) + virtual LUID STDMETHODCALLTYPE GetAdapterLuid( void) override + { + LUID mockLuid = {}; + return mockLuid; + } +#else + virtual LUID *STDMETHODCALLTYPE GetAdapterLuid( + LUID * RetVal) override + { + if (RetVal) + { + *RetVal = {}; + } + return RetVal; + } +#endif + +public: // ID3D12Object + virtual HRESULT STDMETHODCALLTYPE GetPrivateData( + _In_ REFGUID guid, + _Inout_ UINT *pDataSize, + _Out_writes_bytes_opt_( *pDataSize ) void *pData) override + { + return S_OK; + } + + virtual HRESULT STDMETHODCALLTYPE SetPrivateData( + _In_ REFGUID guid, + _In_ UINT DataSize, + _In_reads_bytes_opt_( DataSize ) const void *pData) override + { + return S_OK; + } + + virtual HRESULT STDMETHODCALLTYPE SetPrivateDataInterface( + _In_ REFGUID guid, + _In_opt_ const IUnknown *pData) override + { + return S_OK; + } + + virtual HRESULT STDMETHODCALLTYPE SetName( + _In_z_ LPCWSTR Name) override + { + return S_OK; + } + +public: // IUnknown + virtual HRESULT STDMETHODCALLTYPE QueryInterface( + /* [in] */ REFIID riid, + /* [iid_is][out] */ _COM_Outptr_ void __RPC_FAR *__RPC_FAR *ppvObject) override + { + *ppvObject = this; + return S_OK; + } + + virtual ULONG STDMETHODCALLTYPE AddRef() override + { + // Casual implementation. No actual actions + return 0; + } + + virtual ULONG STDMETHODCALLTYPE Release() override + { + return 0; + } + + + // Major function we need to work with + virtual HRESULT STDMETHODCALLTYPE CheckFeatureSupport( + D3D12_FEATURE Feature, + _Inout_updates_bytes_(FeatureSupportDataSize) void *pFeatureSupportData, + UINT FeatureSupportDataSize + ) override + { + switch( Feature ) + { + case D3D12_FEATURE_D3D12_OPTIONS: + { + D3D12_FEATURE_DATA_D3D12_OPTIONS* pD3D12Options = static_cast(pFeatureSupportData); + if (FeatureSupportDataSize != sizeof(D3D12_FEATURE_DATA_D3D12_OPTIONS)) + { + return E_INVALIDARG; + } + pD3D12Options->DoublePrecisionFloatShaderOps = m_DoublePrecisionFloatShaderOps; + pD3D12Options->OutputMergerLogicOp = m_OutputMergerLogicOp; + pD3D12Options->MinPrecisionSupport = m_ShaderMinPrecisionSupport10Bit | m_ShaderMinPrecisionSupport16Bit; + pD3D12Options->TiledResourcesTier = m_TiledResourcesTier; + pD3D12Options->ResourceBindingTier = m_ResourceBindingTier; + pD3D12Options->PSSpecifiedStencilRefSupported = (m_FeatureLevel >= D3D_FEATURE_LEVEL_11_1) && m_PSSpecifiedStencilRefSupported; + pD3D12Options->TypedUAVLoadAdditionalFormats = (m_FeatureLevel >= D3D_FEATURE_LEVEL_11_0) && m_TypedUAVLoadAdditionalFormats; + pD3D12Options->ROVsSupported = (m_FeatureLevel >= D3D_FEATURE_LEVEL_11_0) && m_ROVsSupported; + pD3D12Options->ConservativeRasterizationTier = (m_FeatureLevel >= D3D_FEATURE_LEVEL_11_1) ? m_ConservativeRasterizationTier : D3D12_CONSERVATIVE_RASTERIZATION_TIER_NOT_SUPPORTED; + pD3D12Options->MaxGPUVirtualAddressBitsPerResource = m_MaxGPUVirtualAddressBitsPerResource; + pD3D12Options->StandardSwizzle64KBSupported = m_StandardSwizzle64KBSupported; + #ifdef DX_ASTC_PROTOTYPE_ENABLED + pD3D12Options->ASTCProfile = ASTCProfile(); + #endif + pD3D12Options->CrossNodeSharingTier = m_CrossNodeSharingTier; + pD3D12Options->CrossAdapterRowMajorTextureSupported = m_CrossAdapterRowMajorTextureSupported; + pD3D12Options->VPAndRTArrayIndexFromAnyShaderFeedingRasterizerSupportedWithoutGSEmulation = m_VPAndRTArrayIndexFromAnyShaderFeedingRasterizerSupportedWithoutGSEmulation; + pD3D12Options->ResourceHeapTier = m_ResourceHeapTier; + } return S_OK; + + case D3D12_FEATURE_D3D12_OPTIONS1: + { + if (!m_Options1Available) + { + return E_INVALIDARG; + } + D3D12_FEATURE_DATA_D3D12_OPTIONS1* pD3D12Options1 = static_cast(pFeatureSupportData); + if (FeatureSupportDataSize != sizeof(D3D12_FEATURE_DATA_D3D12_OPTIONS1)) + { + return E_INVALIDARG; + } + pD3D12Options1->WaveOps = m_WaveOpsSupported; + pD3D12Options1->WaveLaneCountMin = m_WaveLaneCountMin; + pD3D12Options1->WaveLaneCountMax = m_WaveLaneCountMax; + pD3D12Options1->TotalLaneCount = m_TotalLaneCount; + pD3D12Options1->ExpandedComputeResourceStates = m_ExpandedComputeResourceStates; + pD3D12Options1->Int64ShaderOps = m_Int64ShaderOpsSupported; + } return S_OK; + + + case D3D12_FEATURE_D3D12_OPTIONS2: + { + if (!m_Options2Available) + { + return E_INVALIDARG; + } + + D3D12_FEATURE_DATA_D3D12_OPTIONS2* pD3D12Options2 = static_cast(pFeatureSupportData); + if (FeatureSupportDataSize != sizeof(D3D12_FEATURE_DATA_D3D12_OPTIONS2)) + { + return E_INVALIDARG; + } + pD3D12Options2->DepthBoundsTestSupported = m_DepthBoundsTestSupport; + pD3D12Options2->ProgrammableSamplePositionsTier = m_ProgrammableSamplePositionsTier; + } return S_OK; + + case D3D12_FEATURE_ROOT_SIGNATURE: + { + if (!m_RootSignatureAvailable) + { + return E_INVALIDARG; + } + D3D12_FEATURE_DATA_ROOT_SIGNATURE* pRootSig = static_cast(pFeatureSupportData); + if (FeatureSupportDataSize != sizeof(D3D12_FEATURE_DATA_ROOT_SIGNATURE)) + { + return E_INVALIDARG; + } + switch (pRootSig->HighestVersion) + { + case D3D_ROOT_SIGNATURE_VERSION_1_0: + case D3D_ROOT_SIGNATURE_VERSION_1_1: + break; + default: + return E_INVALIDARG; + } + pRootSig->HighestVersion = static_cast(std::min(pRootSig->HighestVersion, m_RootSignatureHighestVersion)); + } return S_OK; + + + case D3D12_FEATURE_ARCHITECTURE: + { + D3D12_FEATURE_DATA_ARCHITECTURE* pFData = + static_cast< D3D12_FEATURE_DATA_ARCHITECTURE* >( pFeatureSupportData ); + if (FeatureSupportDataSize != sizeof( *pFData )) + { + return E_INVALIDARG; + } + + // Testing only + // If Architecture1 is available, use data from architecture1 + if (m_Architecture1Available) + { + D3D12_FEATURE_DATA_ARCHITECTURE1 CurFData; + CurFData.NodeIndex = pFData->NodeIndex; + + HRESULT hr; + if (FAILED( hr = CheckFeatureSupport( D3D12_FEATURE_ARCHITECTURE1, &CurFData, sizeof( CurFData ) ) )) + { + return hr; + } + + pFData->TileBasedRenderer = CurFData.TileBasedRenderer; + pFData->UMA = CurFData.UMA; + pFData->CacheCoherentUMA = CurFData.CacheCoherentUMA; + } + else // Otherwise, load the data directly + { + // The original procedure will generate and return an E_INVALIDARG error if the NodeIndex is out of scope + // Mocking the behavior here by returning the rror + if (!(pFData->NodeIndex < m_NodeCount)) + { + return E_INVALIDARG; + } + pFData->TileBasedRenderer = m_TileBasedRenderer[pFData->NodeIndex]; + pFData->UMA = m_UMA[pFData->NodeIndex]; + pFData->CacheCoherentUMA = m_CacheCoherentUMA[pFData->NodeIndex]; + // Note that Architecture doesn't have the IsolatedMMU field. + } + } return S_OK; + case D3D12_FEATURE_ARCHITECTURE1: + { + // Mocking the case where ARCHITECTURE1 is not supported + if (!m_Architecture1Available || !m_ArchitectureSucceed) { + return E_INVALIDARG; + } + + D3D12_FEATURE_DATA_ARCHITECTURE1* pFData = + static_cast< D3D12_FEATURE_DATA_ARCHITECTURE1* >( pFeatureSupportData ); + if (FeatureSupportDataSize != sizeof( *pFData )) + { + return E_INVALIDARG; + } + + // The original procedure will generate and return an E_INVALIDARG error if the NodeIndex is out of scope + // Mocking the behavior here by returning the rror + if (!(pFData->NodeIndex < m_NodeCount)) + { + return E_INVALIDARG; + } + + UINT localIndex = pFData->NodeIndex; + pFData->TileBasedRenderer = m_TileBasedRenderer[localIndex]; + pFData->UMA = m_UMA[localIndex]; + pFData->CacheCoherentUMA = m_CacheCoherentUMA[localIndex]; + pFData->IsolatedMMU = m_IsolatedMMU[localIndex]; + + } return S_OK; + + case D3D12_FEATURE_FEATURE_LEVELS: + { + D3D12_FEATURE_DATA_FEATURE_LEVELS* pFData = + static_cast< D3D12_FEATURE_DATA_FEATURE_LEVELS* >( pFeatureSupportData ); + if (FeatureSupportDataSize != sizeof( *pFData )) + { + return E_INVALIDARG; + } + + if (pFData->NumFeatureLevels == 0 || pFData->pFeatureLevelsRequested == nullptr) + { + return E_INVALIDARG; + } + + pFData->MaxSupportedFeatureLevel = D3D_FEATURE_LEVEL(0); + for (UINT i = 0; i < pFData->NumFeatureLevels; ++i) + { + if (pFData->pFeatureLevelsRequested[i] <= m_FeatureLevel && + pFData->pFeatureLevelsRequested[i] > pFData->MaxSupportedFeatureLevel) + { + pFData->MaxSupportedFeatureLevel = pFData->pFeatureLevelsRequested[i]; + } + } + return pFData->MaxSupportedFeatureLevel == D3D_FEATURE_LEVEL(0) ? + DXGI_ERROR_UNSUPPORTED : S_OK; + } + + case D3D12_FEATURE_FORMAT_SUPPORT: + { + D3D12_FEATURE_DATA_FORMAT_SUPPORT* pFData = + static_cast< D3D12_FEATURE_DATA_FORMAT_SUPPORT* >( pFeatureSupportData ); + if (FeatureSupportDataSize != sizeof( *pFData )) + { + return E_INVALIDARG; + } + m_FormatReceived = pFData->Format; + pFData->Support1 = m_FormatSupport1; + pFData->Support2 = m_FormatSupport2; + // Based on the original implementation, if there's no support for the format, return an E_FAIL + if (m_FormatSupport1 == D3D12_FORMAT_SUPPORT1_NONE && m_FormatSupport2 == D3D12_FORMAT_SUPPORT2_NONE) + { + return E_FAIL; + } + } return S_OK; + + case D3D12_FEATURE_MULTISAMPLE_QUALITY_LEVELS: + { + D3D12_FEATURE_DATA_MULTISAMPLE_QUALITY_LEVELS* pFData = + static_cast< D3D12_FEATURE_DATA_MULTISAMPLE_QUALITY_LEVELS* >( pFeatureSupportData ); + if (FeatureSupportDataSize != sizeof( *pFData )) + { + return E_INVALIDARG; + } + + m_FormatReceived = pFData->Format; + m_SampleCountReceived = pFData->SampleCount; + m_MultisampleQualityLevelFlagsReceived = pFData->Flags; + + // The original check implementation may return E_FAIL + // Valid results are non-negative values including 0, smaller than D3D11_MAX_MULTISAMPLE_SAMPLE_COUNT + if (!m_MultisampleQualityLevelsSucceed) + { + // NumQualityLevels will be set to 0 should the check fails + pFData->NumQualityLevels = 0; + return E_FAIL; + } + + pFData->NumQualityLevels = m_NumQualityLevels; + } return S_OK; + case D3D12_FEATURE_FORMAT_INFO: + { + D3D12_FEATURE_DATA_FORMAT_INFO* pFData = + static_cast< D3D12_FEATURE_DATA_FORMAT_INFO* > ( pFeatureSupportData ); + if (FeatureSupportDataSize != sizeof( *pFData )) + { + return E_INVALIDARG; + } + + m_FormatReceived = pFData->Format; + + // If the format is not supported, an E_INVALIDARG will be returned + if (!m_DXGIFormatSupported) + { + return E_INVALIDARG; + } + + pFData->PlaneCount = m_PlaneCount; + + } return S_OK; + case D3D12_FEATURE_GPU_VIRTUAL_ADDRESS_SUPPORT: + { + D3D12_FEATURE_DATA_GPU_VIRTUAL_ADDRESS_SUPPORT* pFData = + static_cast< D3D12_FEATURE_DATA_GPU_VIRTUAL_ADDRESS_SUPPORT* >( pFeatureSupportData ); + if (FeatureSupportDataSize != sizeof( *pFData )) + { + return E_INVALIDARG; + } + pFData->MaxGPUVirtualAddressBitsPerProcess = m_MaxGPUVirtualAddressBitsPerProcess; + pFData->MaxGPUVirtualAddressBitsPerResource = m_MaxGPUVirtualAddressBitsPerResource; + + } return S_OK; + case D3D12_FEATURE_SHADER_MODEL: + { + D3D12_FEATURE_DATA_SHADER_MODEL* pSM = + static_cast(pFeatureSupportData); + if (FeatureSupportDataSize != sizeof(*pSM)) + { + return E_INVALIDARG; + } + switch (pSM->HighestShaderModel) + { + case D3D_SHADER_MODEL_5_1: + case D3D_SHADER_MODEL_6_0: + case D3D_SHADER_MODEL_6_1: + case D3D_SHADER_MODEL_6_2: + case D3D_SHADER_MODEL_6_3: + case D3D_SHADER_MODEL_6_4: + case D3D_SHADER_MODEL_6_5: + case D3D_SHADER_MODEL_6_6: + case D3D_SHADER_MODEL_6_7: + break; + default: + return E_INVALIDARG; + } + pSM->HighestShaderModel = static_cast(std::min(pSM->HighestShaderModel,m_HighestSupportedShaderModel)); + } return S_OK; + case D3D12_FEATURE_SHADER_CACHE: + { + if (!m_ShaderCacheAvailable) + { + return E_INVALIDARG; + } + D3D12_FEATURE_DATA_SHADER_CACHE* pFlags = + static_cast(pFeatureSupportData); + if (FeatureSupportDataSize != sizeof(*pFlags)) + { + return E_INVALIDARG; + } + pFlags->SupportFlags = m_ShaderCacheSupportFlags; + } return S_OK; + case D3D12_FEATURE_COMMAND_QUEUE_PRIORITY: + { + if (!m_CommandQueuePriorityAvailable) + { + return E_INVALIDARG; + } + D3D12_FEATURE_DATA_COMMAND_QUEUE_PRIORITY* pFlags = + static_cast(pFeatureSupportData); + if (FeatureSupportDataSize != sizeof(*pFlags)) + { + return E_INVALIDARG; + } + + if (pFlags->CommandListType >= D3D12_COMMAND_LIST_TYPE_VIDEO_ENCODE+1) + { + return E_INVALIDARG; + } + + if (pFlags->Priority == D3D12_COMMAND_QUEUE_PRIORITY_NORMAL || pFlags->Priority == D3D12_COMMAND_QUEUE_PRIORITY_HIGH) + { + pFlags->PriorityForTypeIsSupported = TRUE; + } + else if (pFlags->Priority == D3D12_COMMAND_QUEUE_PRIORITY_GLOBAL_REALTIME) + { + pFlags->PriorityForTypeIsSupported = m_GlobalRealtimeCommandQueueSupport; // Simplified + } + else + { + return E_INVALIDARG; + } + + } return S_OK; + + case D3D12_FEATURE_PROTECTED_RESOURCE_SESSION_SUPPORT: + { + if (!m_ProtectedResourceSessionAvailable) + { + return E_INVALIDARG; + } + D3D12_FEATURE_DATA_PROTECTED_RESOURCE_SESSION_SUPPORT* pProtectedResourceSessionSupport = + static_cast(pFeatureSupportData); + if ( FeatureSupportDataSize != sizeof(*pProtectedResourceSessionSupport) + || pProtectedResourceSessionSupport->NodeIndex >= GetNodeCount()) + { + return E_INVALIDARG; + } + + pProtectedResourceSessionSupport->Support = m_ContentProtectionSupported ? + m_ProtectedResourceSessionSupport[pProtectedResourceSessionSupport->NodeIndex] + : D3D12_PROTECTED_RESOURCE_SESSION_SUPPORT_FLAG_NONE; + + } return S_OK; + + case D3D12_FEATURE_D3D12_OPTIONS3: + { + if (!m_Options3Available) + { + return E_INVALIDARG; + } + D3D12_FEATURE_DATA_D3D12_OPTIONS3* pD3D12Options3 = static_cast(pFeatureSupportData); + if (FeatureSupportDataSize != sizeof(D3D12_FEATURE_DATA_D3D12_OPTIONS3)) + { + return E_INVALIDARG; + } + pD3D12Options3->CopyQueueTimestampQueriesSupported = m_CopyQueueTimestampQueriesSupported; + pD3D12Options3->CastingFullyTypedFormatSupported = m_CastingFullyTypedFormatsSupported; + pD3D12Options3->WriteBufferImmediateSupportFlags = m_GetCachedWriteBufferImmediateSupportFlags; + pD3D12Options3->ViewInstancingTier = m_ViewInstancingTier; + pD3D12Options3->BarycentricsSupported = m_BarycentricsSupported; + + } return S_OK; + case D3D12_FEATURE_EXISTING_HEAPS: + { + if (!m_ExistingHeapsAvailable) + { + return E_INVALIDARG; + } + auto* pSupport = static_cast(pFeatureSupportData); + if (FeatureSupportDataSize != sizeof(*pSupport)) + { + return E_INVALIDARG; + } + pSupport->Supported = m_ExistingHeapCaps; + } return S_OK; + case D3D12_FEATURE_D3D12_OPTIONS4: + { + if (!m_Options4Available) + { + return E_INVALIDARG; + } + auto* pD3D12Options4 = static_cast(pFeatureSupportData); + if (FeatureSupportDataSize != sizeof(*pD3D12Options4)) + { + return E_INVALIDARG; + } + + // Reserved Buffer Placement was cut, except for 64KB Aligned MSAA Textures + pD3D12Options4->MSAA64KBAlignedTextureSupported = m_MSAA64KBAlignedTextureSupported; + pD3D12Options4->SharedResourceCompatibilityTier = m_SharedResourceCompatibilityTier; // Simplified + pD3D12Options4->Native16BitShaderOpsSupported = m_Native16BitShaderOpsSupported; + } return S_OK; + case D3D12_FEATURE_SERIALIZATION: + { + if (!m_SerializationAvailable) + { + return E_INVALIDARG; + } + auto* pSerialization = static_cast(pFeatureSupportData); + if (FeatureSupportDataSize != sizeof(*pSerialization)) + { + return E_INVALIDARG; + } + + const UINT NodeIndex = pSerialization->NodeIndex; + if (NodeIndex >= m_NodeCount) + { + return E_INVALIDARG; + } + pSerialization->HeapSerializationTier = m_HeapSerializationTier[NodeIndex]; + } return S_OK; + case D3D12_FEATURE_CROSS_NODE: + { + if (!m_CrossNodeAvailable) + { + return E_INVALIDARG; + } + auto* pCrossNode = static_cast(pFeatureSupportData); + if (FeatureSupportDataSize != sizeof(*pCrossNode)) + { + return E_INVALIDARG; + } + + pCrossNode->SharingTier = m_CrossNodeSharingTier; + pCrossNode->AtomicShaderInstructions = m_AtomicShaderInstructions; + } return S_OK; + case D3D12_FEATURE_D3D12_OPTIONS5: + { + if (!m_Options5Available) + { + return E_INVALIDARG; + } + auto* pD3D12Options5 = static_cast(pFeatureSupportData); + if (FeatureSupportDataSize != sizeof(*pD3D12Options5)) + { + return E_INVALIDARG; + } + + pD3D12Options5->RaytracingTier = m_RaytracingTier; + pD3D12Options5->RenderPassesTier = m_RenderPassesTier; + pD3D12Options5->SRVOnlyTiledResourceTier3 = m_SRVOnlyTiledResourceTier3; + } return S_OK; + case D3D12_FEATURE_DISPLAYABLE: + { + if (!m_DisplayableAvailable) + { + return E_INVALIDARG; + } + auto* pD3D12Displayable = static_cast(pFeatureSupportData); + if (FeatureSupportDataSize != sizeof(*pD3D12Displayable)) // Feature_D3D1XDisplayable + { + return E_INVALIDARG; + } + + pD3D12Displayable->DisplayableTexture = m_DisplayableTexture; + pD3D12Displayable->SharedResourceCompatibilityTier = m_SharedResourceCompatibilityTier; + } return S_OK; + + case D3D12_FEATURE_D3D12_OPTIONS6: + { + if (!m_Options6Available) + { + return E_INVALIDARG; + } + + auto* pD3D12Options6 = static_cast(pFeatureSupportData); + if (FeatureSupportDataSize != sizeof(*pD3D12Options6)) + { + return E_INVALIDARG; + } + pD3D12Options6->AdditionalShadingRatesSupported = m_AdditionalShadingRatesSupported; + pD3D12Options6->BackgroundProcessingSupported = m_BackgroundProcessingSupported; + pD3D12Options6->PerPrimitiveShadingRateSupportedWithViewportIndexing = m_PerPrimitiveShadingRateSupportedWithViewportIndexing; + pD3D12Options6->ShadingRateImageTileSize = m_ShadingRateImageTileSize; + pD3D12Options6->VariableShadingRateTier = m_VariableShadingRateTier; + } return S_OK; + case D3D12_FEATURE_QUERY_META_COMMAND: + { + if (m_QueryMetaCommandAvailable) + { + if (FeatureSupportDataSize != sizeof(D3D12_FEATURE_DATA_QUERY_META_COMMAND)) + { + return E_INVALIDARG; + } + + // Only checks inputs and outputs + auto* pQueryData = static_cast(pFeatureSupportData); + m_CommandID = pQueryData->CommandId; + m_pQueryInputData = pQueryData->pQueryInputData; + m_NodeMask = pQueryData->NodeMask; + m_QueryInputDataSizeInBytes = pQueryData->QueryInputDataSizeInBytes; + + pQueryData->QueryOutputDataSizeInBytes = m_QueryOutputDataSizeInBytes; + pQueryData->pQueryOutputData = m_pQueryOutputData; + } + else + { + return E_INVALIDARG; + } + } return S_OK; + case D3D12_FEATURE_D3D12_OPTIONS7: + { + if (!m_Options7Available) + { + return E_INVALIDARG; + } + auto* pD3D12Options7 = static_cast(pFeatureSupportData); + if (FeatureSupportDataSize != sizeof(*pD3D12Options7)) + { + return E_INVALIDARG; + } + + pD3D12Options7->MeshShaderTier = m_MeshShaderTier; + pD3D12Options7->SamplerFeedbackTier = m_SamplerFeedbackTier; + } return S_OK; + case D3D12_FEATURE_PROTECTED_RESOURCE_SESSION_TYPE_COUNT: + { + if (!m_ProtectedResourceSessionTypeCountAvailable) + { + return E_INVALIDARG; + } + auto* pProtectedResourceSessionTypesCount = + static_cast(pFeatureSupportData); + if ( FeatureSupportDataSize != sizeof(*pProtectedResourceSessionTypesCount) + || pProtectedResourceSessionTypesCount->NodeIndex >= GetNodeCount()) + { + return E_INVALIDARG; + } + + pProtectedResourceSessionTypesCount->Count = m_ProtectedResourceSessionTypeCount[pProtectedResourceSessionTypesCount->NodeIndex]; + } return S_OK; + case D3D12_FEATURE_PROTECTED_RESOURCE_SESSION_TYPES: + { + if (!m_ProtectedResourceSessionTypesAvailable) + { + return E_INVALIDARG; + } + auto* pProtectedResourceSessionTypes = + static_cast(pFeatureSupportData); + if ( FeatureSupportDataSize != sizeof(*pProtectedResourceSessionTypes) + || pProtectedResourceSessionTypes->NodeIndex >= GetNodeCount()) + { + return E_INVALIDARG; + } + UINT ExpectedCount = m_ProtectedResourceSessionTypeCount[pProtectedResourceSessionTypes->NodeIndex]; + if (pProtectedResourceSessionTypes->Count != ExpectedCount) + { + return E_INVALIDARG; + } + + if (ExpectedCount > 0) + { + memcpy(pProtectedResourceSessionTypes->pTypes, m_ProtectedResourceSessionTypes[pProtectedResourceSessionTypes->NodeIndex].data(), ExpectedCount * sizeof(*pProtectedResourceSessionTypes->pTypes)); + } + + } return S_OK; + + case D3D12_FEATURE_D3D12_OPTIONS8: + { + if (!m_Options8Available) + { + return E_INVALIDARG; + } + D3D12_FEATURE_DATA_D3D12_OPTIONS8 *pD3D12Options8 = static_cast(pFeatureSupportData); + if (FeatureSupportDataSize != sizeof(*pD3D12Options8)) + { + return E_INVALIDARG; + } + + pD3D12Options8->UnalignedBlockTexturesSupported = m_UnalignedBlockTexturesSupported; + } return S_OK; + case D3D12_FEATURE_D3D12_OPTIONS9: + { + if (!m_Options9Available) + { + return E_INVALIDARG; + } + D3D12_FEATURE_DATA_D3D12_OPTIONS9 *pD3D12Options9 = static_cast(pFeatureSupportData); + if (FeatureSupportDataSize != sizeof(*pD3D12Options9)) + { + return E_INVALIDARG; + } + + pD3D12Options9->AtomicInt64OnGroupSharedSupported = m_AtomicInt64OnGroupSharedSupported; + pD3D12Options9->AtomicInt64OnTypedResourceSupported = m_AtomicInt64OnTypedResourceSupported; + pD3D12Options9->DerivativesInMeshAndAmplificationShadersSupported = m_DerivativesInMeshAndAmplificationShadersSupported; + pD3D12Options9->MeshShaderPipelineStatsSupported = m_MeshShaderPipelineStatsSupported; + pD3D12Options9->MeshShaderSupportsFullRangeRenderTargetArrayIndex = m_MeshShaderSupportsFullRangeRenderTargetArrayIndex; + pD3D12Options9->WaveMMATier = m_WaveMMATier; + } return S_OK; + case D3D12_FEATURE_D3D12_OPTIONS10: + { + if (!m_Options10Available) + { + return E_INVALIDARG; + } + D3D12_FEATURE_DATA_D3D12_OPTIONS10* pD3D12Options10 = static_cast(pFeatureSupportData); + if (FeatureSupportDataSize != sizeof(*pD3D12Options10)) + { + return E_INVALIDARG; + } + + pD3D12Options10->MeshShaderPerPrimitiveShadingRateSupported = m_MeshShaderPerPrimitiveShadingRateSupported; + pD3D12Options10->VariableRateShadingSumCombinerSupported = m_VariableRateShadingSumCombinerSupported; + } return S_OK; + case D3D12_FEATURE_D3D12_OPTIONS11: + { + if (!m_Options11Available) + { + return E_INVALIDARG; + } + D3D12_FEATURE_DATA_D3D12_OPTIONS11* pD3D12Options11 = static_cast(pFeatureSupportData); + if (FeatureSupportDataSize != sizeof(*pD3D12Options11)) + { + return E_INVALIDARG; + } + + pD3D12Options11->AtomicInt64OnDescriptorHeapResourceSupported = m_AtomicInt64OnDescriptorHeapResourceSupported; + } return S_OK; + case D3D12_FEATURE_D3D12_OPTIONS12: + { + if (!m_Options12Available) + { + return E_INVALIDARG; + } + D3D12_FEATURE_DATA_D3D12_OPTIONS12* pD3D12Options12 = static_cast(pFeatureSupportData); + if (FeatureSupportDataSize != sizeof(*pD3D12Options12)) + { + return E_INVALIDARG; + } + + pD3D12Options12->MSPrimitivesPipelineStatisticIncludesCulledPrimitives = m_MSPrimitivesPipelineStatisticIncludesCulledPrimitives; + pD3D12Options12->EnhancedBarriersSupported = m_EnhancedBarriersSupported; + } return S_OK; + + default: + return E_INVALIDARG; + } + } + +public: // For simplicity, allow tests to set the internal state values for this mock class + // General + UINT m_NodeCount; // Simulated number of computing nodes + + // 0: Options + bool m_D3D12OptionsAvailable = true; + BOOL m_DoublePrecisionFloatShaderOps = false; + BOOL m_OutputMergerLogicOp = false; + D3D12_SHADER_MIN_PRECISION_SUPPORT m_ShaderMinPrecisionSupport10Bit = D3D12_SHADER_MIN_PRECISION_SUPPORT_NONE; + D3D12_SHADER_MIN_PRECISION_SUPPORT m_ShaderMinPrecisionSupport16Bit = D3D12_SHADER_MIN_PRECISION_SUPPORT_NONE; + D3D12_TILED_RESOURCES_TIER m_TiledResourcesTier = D3D12_TILED_RESOURCES_TIER_NOT_SUPPORTED; + D3D12_RESOURCE_BINDING_TIER m_ResourceBindingTier = (D3D12_RESOURCE_BINDING_TIER)0; + BOOL m_PSSpecifiedStencilRefSupported = false; + BOOL m_TypedUAVLoadAdditionalFormats = false; + BOOL m_ROVsSupported = false; + D3D12_CONSERVATIVE_RASTERIZATION_TIER m_ConservativeRasterizationTier = D3D12_CONSERVATIVE_RASTERIZATION_TIER_NOT_SUPPORTED; + UINT m_MaxGPUVirtualAddressBitsPerResource = 0; + BOOL m_StandardSwizzle64KBSupported = false; + D3D12_CROSS_NODE_SHARING_TIER m_CrossNodeSharingTier = D3D12_CROSS_NODE_SHARING_TIER_NOT_SUPPORTED; + BOOL m_CrossAdapterRowMajorTextureSupported = false; + BOOL m_VPAndRTArrayIndexFromAnyShaderFeedingRasterizerSupportedWithoutGSEmulation = false; + D3D12_RESOURCE_HEAP_TIER m_ResourceHeapTier = (D3D12_RESOURCE_HEAP_TIER)0; + + // 1: Architecture & 16: Architecture1 + bool m_ArchitectureSucceed = true; + bool m_Architecture1Available = false; // Mock the case where Architecture1 is not supported + std::vector m_TileBasedRenderer; + std::vector m_UMA; + std::vector m_CacheCoherentUMA; + std::vector m_IsolatedMMU; + + // 2: Feature Levels + bool m_FeatureLevelsAvailable = true; + D3D_FEATURE_LEVEL m_FeatureLevel = D3D_FEATURE_LEVEL_12_0; // Set higher to allow other tests to pass correctly + + // 3: Feature Format Support + // Forwarding call only. Make sure that the input parameters are correctly forwarded + bool m_FormatSupportAvailable = true; + DXGI_FORMAT m_FormatReceived; + D3D12_FORMAT_SUPPORT1 m_FormatSupport1 = D3D12_FORMAT_SUPPORT1_NONE; + D3D12_FORMAT_SUPPORT2 m_FormatSupport2 = D3D12_FORMAT_SUPPORT2_NONE; + + // 4: Multisample Quality Levels + bool m_MultisampleQualityLevelsSucceed = true; + UINT m_SampleCountReceived; + D3D12_MULTISAMPLE_QUALITY_LEVEL_FLAGS m_MultisampleQualityLevelFlagsReceived; + UINT m_NumQualityLevels = 0; + + // 5: Format Info + bool m_DXGIFormatSupported = true; + UINT m_PlaneCount = 0; + + // 6: GPU Virtual Address Support + bool m_GPUVASupportAvailable = true; + UINT m_MaxGPUVirtualAddressBitsPerProcess = 0; + + // 7: Shader Model + D3D_SHADER_MODEL m_HighestSupportedShaderModel = D3D_SHADER_MODEL_5_1; + + // 8: Options1 + bool m_Options1Available = true; + bool m_WaveOpsSupported = false; + UINT m_WaveLaneCountMin = 0; + UINT m_WaveLaneCountMax = 0; + UINT m_TotalLaneCount = 0; + bool m_ExpandedComputeResourceStates = false; + bool m_Int64ShaderOpsSupported = false; + + // 10: Protected Resource Session Support + bool m_ProtectedResourceSessionAvailable = true; + bool m_ContentProtectionSupported = true; + std::vector m_ProtectedResourceSessionSupport; + + // 12: Root Signature + bool m_RootSignatureAvailable = true; + D3D_ROOT_SIGNATURE_VERSION m_RootSignatureHighestVersion = (D3D_ROOT_SIGNATURE_VERSION)0; + + // 18: D3D12 Options2 + bool m_Options2Available = true; + bool m_DepthBoundsTestSupport = false; + D3D12_PROGRAMMABLE_SAMPLE_POSITIONS_TIER m_ProgrammableSamplePositionsTier = D3D12_PROGRAMMABLE_SAMPLE_POSITIONS_TIER_NOT_SUPPORTED; + + // 19: Shader Cache + bool m_ShaderCacheAvailable = true; + D3D12_SHADER_CACHE_SUPPORT_FLAGS m_ShaderCacheSupportFlags = D3D12_SHADER_CACHE_SUPPORT_NONE; // Lazy implementation + + // 20: Command Queue Priority + bool m_CommandQueuePriorityAvailable = true; + bool m_GlobalRealtimeCommandQueueSupport = false; + + // 21: Options3 + bool m_Options3Available = true; + bool m_CopyQueueTimestampQueriesSupported = false; + bool m_CastingFullyTypedFormatsSupported = false; + D3D12_COMMAND_LIST_SUPPORT_FLAGS m_GetCachedWriteBufferImmediateSupportFlags = D3D12_COMMAND_LIST_SUPPORT_FLAG_NONE; + D3D12_VIEW_INSTANCING_TIER m_ViewInstancingTier = D3D12_VIEW_INSTANCING_TIER_NOT_SUPPORTED; + bool m_BarycentricsSupported = false; + + // 22: Existing Heaps + bool m_ExistingHeapsAvailable = true; + bool m_ExistingHeapCaps = false; + + // 23: Options4 + bool m_Options4Available = true; + bool m_MSAA64KBAlignedTextureSupported = false; + D3D12_SHARED_RESOURCE_COMPATIBILITY_TIER m_SharedResourceCompatibilityTier = D3D12_SHARED_RESOURCE_COMPATIBILITY_TIER_0; + bool m_Native16BitShaderOpsSupported = false; + + // 24: Serialization + bool m_SerializationAvailable = true; + std::vector m_HeapSerializationTier; + + // 25: Cross Node + bool m_CrossNodeAvailable = true; + bool m_AtomicShaderInstructions = false; + + // 27: Options5 + bool m_Options5Available = true; + bool m_SRVOnlyTiledResourceTier3 = false; + D3D12_RENDER_PASS_TIER m_RenderPassesTier = D3D12_RENDER_PASS_TIER_0; + D3D12_RAYTRACING_TIER m_RaytracingTier = D3D12_RAYTRACING_TIER_NOT_SUPPORTED; + + // 28: Displayable + bool m_DisplayableAvailable = true; + bool m_DisplayableTexture = false; + // SharedResourceCompatibilityTier is located in Options4 + + // 30: Options6 + bool m_Options6Available = true; + bool m_AdditionalShadingRatesSupported = false; + bool m_PerPrimitiveShadingRateSupportedWithViewportIndexing = false; + D3D12_VARIABLE_SHADING_RATE_TIER m_VariableShadingRateTier = D3D12_VARIABLE_SHADING_RATE_TIER_NOT_SUPPORTED; + UINT m_ShadingRateImageTileSize = 0; + bool m_BackgroundProcessingSupported = false; + + // 31: Query Meta Command + bool m_QueryMetaCommandAvailable = true; + GUID m_CommandID = {}; + UINT m_NodeMask = 0; + const void* m_pQueryInputData = nullptr; + SIZE_T m_QueryInputDataSizeInBytes = 0; + void* m_pQueryOutputData = nullptr; + SIZE_T m_QueryOutputDataSizeInBytes = 0; + + // 32: Options7 + bool m_Options7Available = true; + D3D12_MESH_SHADER_TIER m_MeshShaderTier = D3D12_MESH_SHADER_TIER_NOT_SUPPORTED; + D3D12_SAMPLER_FEEDBACK_TIER m_SamplerFeedbackTier = D3D12_SAMPLER_FEEDBACK_TIER_NOT_SUPPORTED; + + // 33: Protected Resource Session Type Count + bool m_ProtectedResourceSessionTypeCountAvailable = true; + std::vector m_ProtectedResourceSessionTypeCount; + + // 34: Protected Resource Session Types + bool m_ProtectedResourceSessionTypesAvailable = true; + std::vector> m_ProtectedResourceSessionTypes; + + // 36: Options8 + bool m_Options8Available = true; + bool m_UnalignedBlockTexturesSupported = false; + + // 37: Options9 + bool m_Options9Available = true; + bool m_MeshShaderPipelineStatsSupported = false; + bool m_MeshShaderSupportsFullRangeRenderTargetArrayIndex = false; + bool m_AtomicInt64OnTypedResourceSupported = false; + bool m_AtomicInt64OnGroupSharedSupported = false; + bool m_DerivativesInMeshAndAmplificationShadersSupported = false; + D3D12_WAVE_MMA_TIER m_WaveMMATier = D3D12_WAVE_MMA_TIER_NOT_SUPPORTED; + + // 39: Options10 + bool m_Options10Available = true; + bool m_VariableRateShadingSumCombinerSupported = false; + bool m_MeshShaderPerPrimitiveShadingRateSupported = false; + + // 40: Options11 + bool m_Options11Available = true; + bool m_AtomicInt64OnDescriptorHeapResourceSupported = false; + + // 41: Options12 + bool m_Options12Available = true; + D3D12_TRI_STATE m_MSPrimitivesPipelineStatisticIncludesCulledPrimitives = D3D12_TRI_STATE_UNKNOWN; + bool m_EnhancedBarriersSupported = false; +}; + +#endif \ No newline at end of file diff --git a/contrib/DirectX-Headers-1.618.2/googletest/feature_support_test.cpp b/contrib/DirectX-Headers-1.618.2/googletest/feature_support_test.cpp new file mode 100644 index 0000000..0394384 --- /dev/null +++ b/contrib/DirectX-Headers-1.618.2/googletest/feature_support_test.cpp @@ -0,0 +1,1354 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +#include "gtest/gtest.h" + +#include + +#include +#include +#include +#include "dxguids/dxguids.h" + +#include "MockDevice.hpp" + +// Initiliaze the CD3DX12FeatureSupport instance +// Can be modified to use new initialization methods if any comes up in the future +#define INIT_FEATURES() \ + CD3DX12FeatureSupport features; \ + HRESULT InitResult = features.Init(device); \ + EXPECT_EQ(features.GetStatus(), S_OK); + +// Testing class setup +class FeatureSupportTest : public ::testing::Test { +protected: + void SetUp() override { + device = new MockDevice(1); + } + + void TearDown() override { + delete device; + } + + MockDevice* device = nullptr; +}; + +// Test if the class can be initialized correctly +TEST_F(FeatureSupportTest, Initialization) { + CD3DX12FeatureSupport features; + EXPECT_EQ(features.Init(device), S_OK); + EXPECT_EQ(features.GetStatus(), S_OK); +} + +// 0: D3D12_OPTIONS +// Arbitarily set support status for caps and see if the returned results are correct +TEST_F(FeatureSupportTest, D3D12Options) { + device->m_DoublePrecisionFloatShaderOps = true; + device->m_OutputMergerLogicOp = true; + device->m_ShaderMinPrecisionSupport10Bit = D3D12_SHADER_MIN_PRECISION_SUPPORT_10_BIT; + device->m_ShaderMinPrecisionSupport16Bit = D3D12_SHADER_MIN_PRECISION_SUPPORT_16_BIT; + device->m_TiledResourcesTier = D3D12_TILED_RESOURCES_TIER_3; + device->m_ResourceBindingTier = D3D12_RESOURCE_BINDING_TIER_3; + device->m_PSSpecifiedStencilRefSupported = true; + device->m_ConservativeRasterizationTier = D3D12_CONSERVATIVE_RASTERIZATION_TIER_2; + device->m_MaxGPUVirtualAddressBitsPerResource = 10; + device->m_ResourceHeapTier = D3D12_RESOURCE_HEAP_TIER_2; + + INIT_FEATURES(); + EXPECT_TRUE(features.DoublePrecisionFloatShaderOps()); + EXPECT_TRUE(features.OutputMergerLogicOp()); + EXPECT_EQ(features.MinPrecisionSupport(), D3D12_SHADER_MIN_PRECISION_SUPPORT_10_BIT | D3D12_SHADER_MIN_PRECISION_SUPPORT_16_BIT); + EXPECT_EQ(features.TiledResourcesTier(), D3D12_TILED_RESOURCES_TIER_3); + EXPECT_EQ(features.ResourceBindingTier(), D3D12_RESOURCE_BINDING_TIER_3); + EXPECT_TRUE(features.PSSpecifiedStencilRefSupported()); + EXPECT_FALSE(features.TypedUAVLoadAdditionalFormats()); + EXPECT_FALSE(features.ROVsSupported()); + EXPECT_EQ(features.ConservativeRasterizationTier(), D3D12_CONSERVATIVE_RASTERIZATION_TIER_2); + EXPECT_EQ(features.MaxGPUVirtualAddressBitsPerResource(), 10); + EXPECT_FALSE(features.StandardSwizzle64KBSupported()); + EXPECT_EQ(features.CrossNodeSharingTier(), D3D12_CROSS_NODE_SHARING_TIER_NOT_SUPPORTED); + EXPECT_FALSE(features.CrossAdapterRowMajorTextureSupported()); + EXPECT_FALSE(features.VPAndRTArrayIndexFromAnyShaderFeedingRasterizerSupportedWithoutGSEmulation()); + EXPECT_EQ(features.ResourceHeapTier(), D3D12_RESOURCE_HEAP_TIER_2); +} + +// 1: Architecture & 16: Architecture1 +// Test where architecture1 is available +TEST_F(FeatureSupportTest, Architecture1Available) +{ + device->m_Architecture1Available = true; + device->m_TileBasedRenderer[0] = false; + device->m_UMA[0] = true; + device->m_CacheCoherentUMA[0] = true; + device->m_IsolatedMMU[0] = true; + + INIT_FEATURES(); + EXPECT_FALSE(features.TileBasedRenderer(0)); + EXPECT_TRUE(features.UMA(0)); + EXPECT_TRUE(features.CacheCoherentUMA(0)); + EXPECT_TRUE(features.IsolatedMMU(0)); +} + +// Test where architecture1 is not available +TEST_F(FeatureSupportTest, Architecture1Unavailable) +{ + device->m_Architecture1Available = false; // Architecture1 not available + device->m_TileBasedRenderer[0] = false; + device->m_UMA[0] = true; + device->m_CacheCoherentUMA[0] = false; + device->m_IsolatedMMU[0] = true; // Notice that if architecture1 is not available, IslatedMMU cap should not be present + + INIT_FEATURES(); + EXPECT_FALSE(features.TileBasedRenderer(0)); + EXPECT_TRUE(features.UMA(0)); + EXPECT_FALSE(features.CacheCoherentUMA(0)); + EXPECT_FALSE(features.IsolatedMMU(0)); // If Architecture1 is not available, IsolatedMMU should not be available +} + +// Test on devices with more than one graphics node +TEST_F(FeatureSupportTest, ArchitectureMultinode) +{ + device->SetNodeCount(3); + device->m_Architecture1Available = true; + device->m_TileBasedRenderer = {false, true, true}; + device->m_UMA = {true, false, false}; + device->m_CacheCoherentUMA = {false, false, true}; + device->m_IsolatedMMU = {false, true, false}; + + INIT_FEATURES(); + + EXPECT_FALSE(features.TileBasedRenderer(0)); + EXPECT_TRUE(features.TileBasedRenderer(1)); + EXPECT_TRUE(features.TileBasedRenderer(2)); + + EXPECT_TRUE(features.UMA(0)); + EXPECT_FALSE(features.UMA(1)); + EXPECT_FALSE(features.UMA(2)); + + EXPECT_FALSE(features.CacheCoherentUMA(0)); + EXPECT_FALSE(features.CacheCoherentUMA(1)); + EXPECT_TRUE(features.CacheCoherentUMA(2)); + + EXPECT_FALSE(features.IsolatedMMU(0)); + EXPECT_TRUE(features.IsolatedMMU(1)); + EXPECT_FALSE(features.IsolatedMMU(2)); +} + +// 2: Feature Levels +// Basic test with a high feature level +TEST_F(FeatureSupportTest, FeatureLevelBasic) +{ + device->m_FeatureLevel = D3D_FEATURE_LEVEL_12_2; + + INIT_FEATURES(); + EXPECT_EQ(features.MaxSupportedFeatureLevel(), D3D_FEATURE_LEVEL_12_2); +} + +// Test through all supported feature levels +TEST_F(FeatureSupportTest, FeatureLevelAll) +{ + std::vector allLevels = + { + D3D_FEATURE_LEVEL_1_0_CORE, + D3D_FEATURE_LEVEL_9_1, + D3D_FEATURE_LEVEL_9_2, + D3D_FEATURE_LEVEL_9_3, + D3D_FEATURE_LEVEL_10_0, + D3D_FEATURE_LEVEL_10_1, + D3D_FEATURE_LEVEL_11_0, + D3D_FEATURE_LEVEL_11_1, + D3D_FEATURE_LEVEL_12_0, + D3D_FEATURE_LEVEL_12_1, + D3D_FEATURE_LEVEL_12_2 + }; + + for (unsigned int i = 0; i < allLevels.size(); i++) + { + device->m_FeatureLevel = allLevels[i]; + INIT_FEATURES(); + EXPECT_EQ(features.MaxSupportedFeatureLevel(), allLevels[i]); + } +} + +// Test with a feature level higher than the current highest level +TEST_F(FeatureSupportTest, FeatureLevelHigher) +{ + device->m_FeatureLevel = (D3D_FEATURE_LEVEL)(D3D_FEATURE_LEVEL_12_2 + 1); + INIT_FEATURES(); + EXPECT_EQ(features.MaxSupportedFeatureLevel(), D3D_FEATURE_LEVEL_12_2); +} + +// 3: Format Support +// Forward call to the old API. Basic correctness check +// Note: The input and return value of this test is arbitrary and does not reflect the results of running on real devices +// The test only checks if the input and output are correctly passed to the inner API and the user. +// Same applies to Multisample Quality Levels (4) and Format Info (5) +TEST_F(FeatureSupportTest, FormatSupportPositive) +{ + device->m_FormatSupport1 = D3D12_FORMAT_SUPPORT1_BUFFER | D3D12_FORMAT_SUPPORT1_TEXTURE3D | D3D12_FORMAT_SUPPORT1_SHADER_SAMPLE_COMPARISON | D3D12_FORMAT_SUPPORT1_DECODER_OUTPUT; + device->m_FormatSupport2 = D3D12_FORMAT_SUPPORT2_UAV_ATOMIC_ADD | D3D12_FORMAT_SUPPORT2_TILED; + + INIT_FEATURES(); + + D3D12_FORMAT_SUPPORT1 support1; + D3D12_FORMAT_SUPPORT2 support2; + + HRESULT result = features.FormatSupport(DXGI_FORMAT_R32G32_UINT, support1, support2); // Some random input + EXPECT_EQ(support1, D3D12_FORMAT_SUPPORT1_BUFFER | D3D12_FORMAT_SUPPORT1_TEXTURE3D | D3D12_FORMAT_SUPPORT1_SHADER_SAMPLE_COMPARISON | D3D12_FORMAT_SUPPORT1_DECODER_OUTPUT); + EXPECT_EQ(support2, D3D12_FORMAT_SUPPORT2_UAV_ATOMIC_ADD | D3D12_FORMAT_SUPPORT2_TILED); + EXPECT_EQ(result, S_OK); +} + +// Negative test +TEST_F(FeatureSupportTest, FormatSupportNegative) +{ + device->m_FormatSupport1 = D3D12_FORMAT_SUPPORT1_NONE; + device->m_FormatSupport2 = D3D12_FORMAT_SUPPORT2_NONE; + INIT_FEATURES(); + + D3D12_FORMAT_SUPPORT1 support1; + D3D12_FORMAT_SUPPORT2 support2; + + HRESULT result = features.FormatSupport(DXGI_FORMAT_UNKNOWN, support1, support2); + EXPECT_EQ(support1, D3D12_FORMAT_SUPPORT1_NONE); + EXPECT_EQ(support2, D3D12_FORMAT_SUPPORT2_NONE); + EXPECT_EQ(result, E_FAIL); +} + +// 4: Multisample Quality Levels +// Forwarding call. Check if the API received the correct information. +TEST_F(FeatureSupportTest, MultisampleQualityLevelsPositive) +{ + device->m_NumQualityLevels = 42; // Arbitrary return value + + INIT_FEATURES(); + + DXGI_FORMAT inFormat = DXGI_FORMAT_R16G16B16A16_FLOAT; + UINT inSampleCount = 10; + D3D12_MULTISAMPLE_QUALITY_LEVEL_FLAGS inFlags = D3D12_MULTISAMPLE_QUALITY_LEVELS_FLAG_NONE; + UINT NumQualityLevels; + + HRESULT result = features.MultisampleQualityLevels(inFormat, inSampleCount, inFlags, NumQualityLevels); + + EXPECT_EQ(device->m_FormatReceived, inFormat); + EXPECT_EQ(device->m_SampleCountReceived, inSampleCount); + EXPECT_EQ(device->m_MultisampleQualityLevelFlagsReceived, inFlags); + EXPECT_EQ(result, S_OK); + EXPECT_EQ(NumQualityLevels, 42); +} + +// Test where the feature check fails +TEST_F(FeatureSupportTest, MultisampleQualityLevelsNegative) +{ + device->m_NumQualityLevels = 42; + device->m_MultisampleQualityLevelsSucceed = false; // Simulate failure + + INIT_FEATURES(); + + DXGI_FORMAT inFormat = DXGI_FORMAT_R16G16B16A16_FLOAT; + UINT inSampleCount = 6; + D3D12_MULTISAMPLE_QUALITY_LEVEL_FLAGS inFlags = D3D12_MULTISAMPLE_QUALITY_LEVELS_FLAG_NONE; + UINT NumQualityLevels; + + HRESULT result = features.MultisampleQualityLevels(inFormat, inSampleCount, inFlags, NumQualityLevels); + + EXPECT_EQ(device->m_FormatReceived, inFormat); + EXPECT_EQ(device->m_SampleCountReceived, inSampleCount); + EXPECT_EQ(device->m_MultisampleQualityLevelFlagsReceived, inFlags); + EXPECT_EQ(result, E_FAIL); + EXPECT_EQ(NumQualityLevels, 0); +} + +// 5: Format Info +// Forward call to old API. Basic check +TEST_F(FeatureSupportTest, FormatInfoPositive) +{ + device->m_PlaneCount = 4; + + INIT_FEATURES(); + + DXGI_FORMAT inFormat = DXGI_FORMAT_D32_FLOAT; + UINT8 PlaneCount; + HRESULT result = features.FormatInfo(inFormat, PlaneCount); + + EXPECT_EQ(PlaneCount, 4); + EXPECT_EQ(result, S_OK); + EXPECT_EQ(device->m_FormatReceived, inFormat); +} + +// Test when feature check fails +TEST_F(FeatureSupportTest, FormatInfoNegative) +{ + device->m_PlaneCount = 6; + device->m_DXGIFormatSupported = false; + + INIT_FEATURES(); + + DXGI_FORMAT inFormat = DXGI_FORMAT_BC1_UNORM; + UINT8 PlaneCount; + HRESULT result = features.FormatInfo(inFormat, PlaneCount); + + EXPECT_EQ(result, E_INVALIDARG); + EXPECT_EQ(PlaneCount, 0); + EXPECT_EQ(device->m_FormatReceived, inFormat); +} + +// 6: GPUVA Support +TEST_F(FeatureSupportTest, GPUVASupport) +{ + device->m_MaxGPUVirtualAddressBitsPerProcess = 16; + device->m_MaxGPUVirtualAddressBitsPerResource = 12; + + INIT_FEATURES(); + + EXPECT_EQ(features.MaxGPUVirtualAddressBitsPerProcess(), 16); + EXPECT_EQ(features.MaxGPUVirtualAddressBitsPerResource(), 12); +} + +/* + Starting from Options1, all features should have an "unavailable test" + to ensure the new API returns the desired default values + when a device does not support that feature +*/ + +// 8: Options1 +// Basic tests +TEST_F(FeatureSupportTest, Options1Basic) +{ + device->m_WaveOpsSupported = true; + device->m_WaveLaneCountMin = 2; + device->m_WaveLaneCountMax = 4; + device->m_TotalLaneCount = 8; + device->m_ExpandedComputeResourceStates = true; + device->m_Int64ShaderOpsSupported = true; + + INIT_FEATURES(); + + EXPECT_TRUE(features.WaveOps()); + EXPECT_EQ(features.WaveLaneCountMin(), 2); + EXPECT_EQ(features.WaveLaneCountMax(), 4); + EXPECT_EQ(features.TotalLaneCount(), 8); + EXPECT_TRUE(features.ExpandedComputeResourceStates()); + EXPECT_TRUE(features.Int64ShaderOps()); +} + +// Unavailable test +// Test where device does not support Options1 +TEST_F(FeatureSupportTest, Options1Unavailable) +{ + device->m_Options1Available = false; + device->m_WaveOpsSupported = true; + device->m_WaveLaneCountMin = 2; + device->m_WaveLaneCountMax = 4; + device->m_TotalLaneCount = 8; + device->m_ExpandedComputeResourceStates = true; + device->m_Int64ShaderOpsSupported = true; + + INIT_FEATURES(); + + EXPECT_FALSE(features.WaveOps()); + EXPECT_EQ(features.WaveLaneCountMin(), 0); + EXPECT_EQ(features.WaveLaneCountMax(), 0); + EXPECT_EQ(features.TotalLaneCount(), 0); + EXPECT_FALSE(features.ExpandedComputeResourceStates()); + EXPECT_FALSE(features.Int64ShaderOps()); +} + +// 10: Protected Resource Session Support +// Basic test +TEST_F(FeatureSupportTest, ProtectedResourceSessionSupportBasic) +{ + device->m_ProtectedResourceSessionSupport[0] = D3D12_PROTECTED_RESOURCE_SESSION_SUPPORT_FLAG_SUPPORTED; + + INIT_FEATURES(); + + EXPECT_EQ(features.ProtectedResourceSessionSupport(0), D3D12_PROTECTED_RESOURCE_SESSION_SUPPORT_FLAG_SUPPORTED); +} + +// Negative test +TEST_F(FeatureSupportTest, ProtectedResourceSessionSupportNegative) +{ + device->m_ProtectedResourceSessionSupport[0] = D3D12_PROTECTED_RESOURCE_SESSION_SUPPORT_FLAG_SUPPORTED; + device->m_ContentProtectionSupported = false; + + INIT_FEATURES(); + + EXPECT_EQ(features.ProtectedResourceSessionSupport(), D3D12_PROTECTED_RESOURCE_SESSION_SUPPORT_FLAG_NONE); +} + +// Multinode test +TEST_F(FeatureSupportTest, ProtectedResourceSessionSupportMultinode) +{ + device->SetNodeCount(4); + device->m_ProtectedResourceSessionSupport = + { + D3D12_PROTECTED_RESOURCE_SESSION_SUPPORT_FLAG_NONE, + D3D12_PROTECTED_RESOURCE_SESSION_SUPPORT_FLAG_SUPPORTED, + D3D12_PROTECTED_RESOURCE_SESSION_SUPPORT_FLAG_SUPPORTED, + D3D12_PROTECTED_RESOURCE_SESSION_SUPPORT_FLAG_NONE + }; + + INIT_FEATURES(); + + EXPECT_EQ(features.ProtectedResourceSessionSupport(0), D3D12_PROTECTED_RESOURCE_SESSION_SUPPORT_FLAG_NONE); + EXPECT_EQ(features.ProtectedResourceSessionSupport(1), D3D12_PROTECTED_RESOURCE_SESSION_SUPPORT_FLAG_SUPPORTED); + EXPECT_EQ(features.ProtectedResourceSessionSupport(2), D3D12_PROTECTED_RESOURCE_SESSION_SUPPORT_FLAG_SUPPORTED); + EXPECT_EQ(features.ProtectedResourceSessionSupport(3), D3D12_PROTECTED_RESOURCE_SESSION_SUPPORT_FLAG_NONE); +} + +// Unavailable test +TEST_F(FeatureSupportTest, ProtectedResourceSessionSupportNotAvailable) +{ + device->m_ProtectedResourceSessionAvailable = false; + device->m_ProtectedResourceSessionSupport[0] = D3D12_PROTECTED_RESOURCE_SESSION_SUPPORT_FLAG_SUPPORTED; + + INIT_FEATURES(); + + EXPECT_EQ(features.ProtectedResourceSessionSupport(0), D3D12_PROTECTED_RESOURCE_SESSION_SUPPORT_FLAG_NONE); +} + + +// Multinode Unavailable test +TEST_F(FeatureSupportTest, ProtectedResourceSessionSupportNotAvailableMultinode) +{ + device->m_ProtectedResourceSessionAvailable = false; + device->SetNodeCount(4); + device->m_ProtectedResourceSessionSupport = + { + D3D12_PROTECTED_RESOURCE_SESSION_SUPPORT_FLAG_NONE, + D3D12_PROTECTED_RESOURCE_SESSION_SUPPORT_FLAG_SUPPORTED, + D3D12_PROTECTED_RESOURCE_SESSION_SUPPORT_FLAG_SUPPORTED, + D3D12_PROTECTED_RESOURCE_SESSION_SUPPORT_FLAG_NONE + }; + + INIT_FEATURES(); + + EXPECT_EQ(features.ProtectedResourceSessionSupport(0), D3D12_PROTECTED_RESOURCE_SESSION_SUPPORT_FLAG_NONE); + EXPECT_EQ(features.ProtectedResourceSessionSupport(1), D3D12_PROTECTED_RESOURCE_SESSION_SUPPORT_FLAG_NONE); + EXPECT_EQ(features.ProtectedResourceSessionSupport(2), D3D12_PROTECTED_RESOURCE_SESSION_SUPPORT_FLAG_NONE); + EXPECT_EQ(features.ProtectedResourceSessionSupport(3), D3D12_PROTECTED_RESOURCE_SESSION_SUPPORT_FLAG_NONE); +} + +// 12: Root Signature +// Basic test (highest supported version in header) +TEST_F(FeatureSupportTest, RootSignatureBasic) +{ + device->m_RootSignatureHighestVersion = D3D_ROOT_SIGNATURE_VERSION_1_1; + INIT_FEATURES(); + EXPECT_EQ(features.HighestRootSignatureVersion(), D3D_ROOT_SIGNATURE_VERSION_1_1); +} + +// Lower version test +TEST_F(FeatureSupportTest, RootSignatureLower) +{ + device->m_RootSignatureHighestVersion = D3D_ROOT_SIGNATURE_VERSION_1; + INIT_FEATURES(); + EXPECT_EQ(features.HighestRootSignatureVersion(), D3D_ROOT_SIGNATURE_VERSION_1); +} + +// Higher version test +TEST_F(FeatureSupportTest, RootSignatureHigher) +{ + device->m_RootSignatureHighestVersion = (D3D_ROOT_SIGNATURE_VERSION)(D3D_ROOT_SIGNATURE_VERSION_1_1 + 1); + INIT_FEATURES(); + EXPECT_EQ(features.HighestRootSignatureVersion(), D3D_ROOT_SIGNATURE_VERSION_1_1); +} + +// Unavailable test +TEST_F(FeatureSupportTest, RootSignatureUnavailable) +{ + device->m_RootSignatureAvailable = false; + device->m_RootSignatureHighestVersion = D3D_ROOT_SIGNATURE_VERSION_1_1; + INIT_FEATURES(); + EXPECT_EQ(features.HighestRootSignatureVersion(), 0); +} + +// 18: Options2 +// Basic test +TEST_F(FeatureSupportTest, D3D12Options2Basic) +{ + device->m_DepthBoundsTestSupport = true; + device->m_ProgrammableSamplePositionsTier = D3D12_PROGRAMMABLE_SAMPLE_POSITIONS_TIER_2; + INIT_FEATURES(); + EXPECT_TRUE(features.DepthBoundsTestSupported()); + EXPECT_EQ(features.ProgrammableSamplePositionsTier(), D3D12_PROGRAMMABLE_SAMPLE_POSITIONS_TIER_2); +} + +// Unavailable test +TEST_F(FeatureSupportTest, D3D12Options2Unavailable) +{ + device->m_Options2Available = false; + device->m_DepthBoundsTestSupport = true; + device->m_ProgrammableSamplePositionsTier = D3D12_PROGRAMMABLE_SAMPLE_POSITIONS_TIER_2; + INIT_FEATURES(); + EXPECT_FALSE(features.DepthBoundsTestSupported()); + EXPECT_EQ(features.ProgrammableSamplePositionsTier(), D3D12_PROGRAMMABLE_SAMPLE_POSITIONS_TIER_NOT_SUPPORTED); +} + +// 19: Shader Cache +// Basic test +TEST_F(FeatureSupportTest, ShaderCacheBasic) +{ + D3D12_SHADER_CACHE_SUPPORT_FLAGS outFlags = D3D12_SHADER_CACHE_SUPPORT_SINGLE_PSO + | D3D12_SHADER_CACHE_SUPPORT_LIBRARY + | D3D12_SHADER_CACHE_SUPPORT_AUTOMATIC_INPROC_CACHE + | D3D12_SHADER_CACHE_SUPPORT_DRIVER_MANAGED_CACHE + | D3D12_SHADER_CACHE_SUPPORT_SHADER_CONTROL_CLEAR + | D3D12_SHADER_CACHE_SUPPORT_SHADER_SESSION_DELETE; + device->m_ShaderCacheSupportFlags = outFlags; + + INIT_FEATURES(); + EXPECT_EQ(features.ShaderCacheSupportFlags(), outFlags); +} + +// Unavailable test +TEST_F(FeatureSupportTest, ShaderCacheUnavailable) +{ + device->m_ShaderCacheAvailable = false; + D3D12_SHADER_CACHE_SUPPORT_FLAGS outFlags = D3D12_SHADER_CACHE_SUPPORT_SINGLE_PSO + | D3D12_SHADER_CACHE_SUPPORT_LIBRARY + | D3D12_SHADER_CACHE_SUPPORT_AUTOMATIC_INPROC_CACHE + | D3D12_SHADER_CACHE_SUPPORT_DRIVER_MANAGED_CACHE + | D3D12_SHADER_CACHE_SUPPORT_SHADER_CONTROL_CLEAR + | D3D12_SHADER_CACHE_SUPPORT_SHADER_SESSION_DELETE; + device->m_ShaderCacheSupportFlags = outFlags; + + INIT_FEATURES(); + EXPECT_EQ(features.ShaderCacheSupportFlags(), D3D12_SHADER_CACHE_SUPPORT_NONE); +} + +// 20: Command Queue Priority +// Basic positive test +TEST_F(FeatureSupportTest, CommandQueuePriorityBasic) +{ + device->m_GlobalRealtimeCommandQueueSupport = true; + INIT_FEATURES(); + EXPECT_TRUE(features.CommandQueuePrioritySupported(D3D12_COMMAND_LIST_TYPE_DIRECT, D3D12_COMMAND_QUEUE_PRIORITY_NORMAL)); + EXPECT_TRUE(features.CommandQueuePrioritySupported(D3D12_COMMAND_LIST_TYPE_DIRECT, D3D12_COMMAND_QUEUE_PRIORITY_HIGH)); + EXPECT_TRUE(features.CommandQueuePrioritySupported(D3D12_COMMAND_LIST_TYPE_DIRECT, D3D12_COMMAND_QUEUE_PRIORITY_GLOBAL_REALTIME)); +} + +// Negative tests +TEST_F(FeatureSupportTest, CommandQueuePriorityNegative) +{ + device->m_GlobalRealtimeCommandQueueSupport = false; + INIT_FEATURES(); + EXPECT_FALSE(features.CommandQueuePrioritySupported(D3D12_COMMAND_LIST_TYPE_VIDEO_ENCODE, D3D12_COMMAND_QUEUE_PRIORITY_GLOBAL_REALTIME)); // Global realtime not on + EXPECT_FALSE(features.CommandQueuePrioritySupported((D3D12_COMMAND_LIST_TYPE)(D3D12_COMMAND_LIST_TYPE_VIDEO_ENCODE+1), D3D12_COMMAND_QUEUE_PRIORITY_NORMAL)); // Unknown command list type + EXPECT_FALSE(features.CommandQueuePrioritySupported(D3D12_COMMAND_LIST_TYPE_COMPUTE, (D3D12_COMMAND_QUEUE_PRIORITY)10)); // Unknown Priority level +} + +// Unavailable test +TEST_F(FeatureSupportTest, CommandQueuePriorityUnavailable) +{ + device->m_CommandQueuePriorityAvailable = false; + + device->m_GlobalRealtimeCommandQueueSupport = true; + INIT_FEATURES(); + EXPECT_FALSE(features.CommandQueuePrioritySupported(D3D12_COMMAND_LIST_TYPE_DIRECT, D3D12_COMMAND_QUEUE_PRIORITY_NORMAL)); + EXPECT_FALSE(features.CommandQueuePrioritySupported(D3D12_COMMAND_LIST_TYPE_DIRECT, D3D12_COMMAND_QUEUE_PRIORITY_HIGH)); + EXPECT_FALSE(features.CommandQueuePrioritySupported(D3D12_COMMAND_LIST_TYPE_DIRECT, D3D12_COMMAND_QUEUE_PRIORITY_GLOBAL_REALTIME)); +} + +// 21: Options3 +// Basic Test +TEST_F(FeatureSupportTest, Options3Basic) +{ + device->m_CopyQueueTimestampQueriesSupported = true; + device->m_CastingFullyTypedFormatsSupported = true; + device->m_GetCachedWriteBufferImmediateSupportFlags = D3D12_COMMAND_LIST_SUPPORT_FLAG_DIRECT | D3D12_COMMAND_LIST_SUPPORT_FLAG_COMPUTE; + device->m_ViewInstancingTier = D3D12_VIEW_INSTANCING_TIER_3; + device->m_BarycentricsSupported = true; + + INIT_FEATURES(); + + EXPECT_TRUE(features.CopyQueueTimestampQueriesSupported()); + EXPECT_TRUE(features.CastingFullyTypedFormatSupported()); + EXPECT_EQ(features.WriteBufferImmediateSupportFlags(), D3D12_COMMAND_LIST_SUPPORT_FLAG_DIRECT | D3D12_COMMAND_LIST_SUPPORT_FLAG_COMPUTE); + EXPECT_EQ(features.ViewInstancingTier(), D3D12_VIEW_INSTANCING_TIER_3); + EXPECT_TRUE(features.BarycentricsSupported()); +} + +// Unavailable Test +TEST_F(FeatureSupportTest, Options3Unavailable) +{ + device->m_Options3Available = false; + device->m_CopyQueueTimestampQueriesSupported = true; + device->m_CastingFullyTypedFormatsSupported = true; + device->m_GetCachedWriteBufferImmediateSupportFlags = D3D12_COMMAND_LIST_SUPPORT_FLAG_DIRECT | D3D12_COMMAND_LIST_SUPPORT_FLAG_COMPUTE; + device->m_ViewInstancingTier = D3D12_VIEW_INSTANCING_TIER_3; + device->m_BarycentricsSupported = true; + + INIT_FEATURES(); + + EXPECT_FALSE(features.CopyQueueTimestampQueriesSupported()); + EXPECT_FALSE(features.CastingFullyTypedFormatSupported()); + EXPECT_EQ(features.WriteBufferImmediateSupportFlags(), D3D12_COMMAND_LIST_SUPPORT_FLAG_NONE); + EXPECT_EQ(features.ViewInstancingTier(), D3D12_VIEW_INSTANCING_TIER_NOT_SUPPORTED); + EXPECT_FALSE(features.BarycentricsSupported()); +} + +// 22: Existing Heaps +// Basic Test +TEST_F(FeatureSupportTest, ExistingHeapsBasic) +{ + device->m_ExistingHeapCaps = true; + INIT_FEATURES(); + EXPECT_TRUE(features.ExistingHeapsSupported()); +} + +// Unavailable Test +TEST_F(FeatureSupportTest, ExistingHeapsUnavailable) +{ + device->m_ExistingHeapsAvailable = false; + device->m_ExistingHeapCaps = true; + INIT_FEATURES(); + EXPECT_FALSE(features.ExistingHeapsSupported()); +} + +// 23: Options4 +// Basic Test +TEST_F(FeatureSupportTest, Options4Basic) +{ + device->m_MSAA64KBAlignedTextureSupported = true; + device->m_SharedResourceCompatibilityTier = D3D12_SHARED_RESOURCE_COMPATIBILITY_TIER_2; // Duplicate member + device->m_Native16BitShaderOpsSupported = true; + + INIT_FEATURES(); + EXPECT_TRUE(features.MSAA64KBAlignedTextureSupported()); + EXPECT_EQ(features.SharedResourceCompatibilityTier(), D3D12_SHARED_RESOURCE_COMPATIBILITY_TIER_2); + EXPECT_TRUE(features.Native16BitShaderOpsSupported()); +} + +// Unavailable Test +TEST_F(FeatureSupportTest, Options4Unavailable) +{ + device->m_Options4Available = false; + device->m_MSAA64KBAlignedTextureSupported = true; + device->m_SharedResourceCompatibilityTier = D3D12_SHARED_RESOURCE_COMPATIBILITY_TIER_2; // Duplicate member + device->m_Native16BitShaderOpsSupported = true; + + INIT_FEATURES(); + EXPECT_FALSE(features.MSAA64KBAlignedTextureSupported()); + EXPECT_EQ(features.SharedResourceCompatibilityTier(), D3D12_SHARED_RESOURCE_COMPATIBILITY_TIER_0); + EXPECT_FALSE(features.Native16BitShaderOpsSupported()); +} + +// 24: Serialization +// Basic Test +TEST_F(FeatureSupportTest, SerializationBasic) +{ + device->m_HeapSerializationTier[0] = D3D12_HEAP_SERIALIZATION_TIER_10; + + INIT_FEATURES(); + + EXPECT_EQ(features.HeapSerializationTier(), D3D12_HEAP_SERIALIZATION_TIER_10); +} + +// Multinode Test +TEST_F(FeatureSupportTest, SerializationMultinode) +{ + device->SetNodeCount(3); + device->m_HeapSerializationTier = + { + D3D12_HEAP_SERIALIZATION_TIER_10, + D3D12_HEAP_SERIALIZATION_TIER_0, + D3D12_HEAP_SERIALIZATION_TIER_10 + }; + + INIT_FEATURES(); + + EXPECT_EQ(features.HeapSerializationTier(), D3D12_HEAP_SERIALIZATION_TIER_10); + EXPECT_EQ(features.HeapSerializationTier(1), D3D12_HEAP_SERIALIZATION_TIER_0); + EXPECT_EQ(features.HeapSerializationTier(2), D3D12_HEAP_SERIALIZATION_TIER_10); +} + +// Unavailable Test +TEST_F(FeatureSupportTest, SerializationUnavailable) +{ + device->m_SerializationAvailable = false; + device->SetNodeCount(3); + device->m_HeapSerializationTier = + { + D3D12_HEAP_SERIALIZATION_TIER_10, + D3D12_HEAP_SERIALIZATION_TIER_0, + D3D12_HEAP_SERIALIZATION_TIER_10 + }; + + INIT_FEATURES(); + + EXPECT_EQ(features.HeapSerializationTier(), D3D12_HEAP_SERIALIZATION_TIER_0); + EXPECT_EQ(features.HeapSerializationTier(1), D3D12_HEAP_SERIALIZATION_TIER_0); + EXPECT_EQ(features.HeapSerializationTier(2), D3D12_HEAP_SERIALIZATION_TIER_0); +} + +// 25: Cross Node +// Basic Test +TEST_F(FeatureSupportTest, CrossNodeBasic) +{ + device->m_CrossNodeSharingTier = D3D12_CROSS_NODE_SHARING_TIER_3; // Duplicated Cap + device->m_AtomicShaderInstructions = true; + + INIT_FEATURES(); + + EXPECT_EQ(features.CrossNodeSharingTier(), D3D12_CROSS_NODE_SHARING_TIER_3); + EXPECT_TRUE(features.CrossNodeAtomicShaderInstructions()); +} + +// Unavailable Test +TEST_F(FeatureSupportTest, CrossNodeUnavailable) +{ + device->m_CrossNodeAvailable = false; + device->m_CrossNodeSharingTier = D3D12_CROSS_NODE_SHARING_TIER_3; // Duplicated Cap + device->m_AtomicShaderInstructions = true; + + INIT_FEATURES(); + + EXPECT_EQ(features.CrossNodeSharingTier(), D3D12_CROSS_NODE_SHARING_TIER_3); // It is still correctly initialized by Options1 + EXPECT_FALSE(features.CrossNodeAtomicShaderInstructions()); +} + +// 27: Options5 +// Basic Test +TEST_F(FeatureSupportTest, Options5Basic) +{ + device->m_RaytracingTier = D3D12_RAYTRACING_TIER_1_1; + device->m_RenderPassesTier = D3D12_RENDER_PASS_TIER_2; + device->m_SRVOnlyTiledResourceTier3 = true; + + INIT_FEATURES(); + + EXPECT_EQ(features.RaytracingTier(), D3D12_RAYTRACING_TIER_1_1); + EXPECT_EQ(features.RenderPassesTier(), D3D12_RENDER_PASS_TIER_2); + EXPECT_TRUE(features.SRVOnlyTiledResourceTier3()); +} + +// Unavailable Test +TEST_F(FeatureSupportTest, Options5Unavailable) +{ + device->m_Options5Available = false; + device->m_RaytracingTier = D3D12_RAYTRACING_TIER_1_1; + device->m_RenderPassesTier = D3D12_RENDER_PASS_TIER_2; + device->m_SRVOnlyTiledResourceTier3 = true; + + INIT_FEATURES(); + + EXPECT_EQ(features.RaytracingTier(), D3D12_RAYTRACING_TIER_NOT_SUPPORTED); + EXPECT_EQ(features.RenderPassesTier(), D3D12_RENDER_PASS_TIER_0); + EXPECT_FALSE(features.SRVOnlyTiledResourceTier3()); +} + +// 28: Displayable +// Basic Test +TEST_F(FeatureSupportTest, DisplayableBasic) +{ + device->m_DisplayableTexture = true; + device->m_SharedResourceCompatibilityTier = D3D12_SHARED_RESOURCE_COMPATIBILITY_TIER_2; + + INIT_FEATURES(); + + EXPECT_TRUE(features.DisplayableTexture()); + EXPECT_EQ(features.SharedResourceCompatibilityTier(), D3D12_SHARED_RESOURCE_COMPATIBILITY_TIER_2); +} + +// Unavailable Test +TEST_F(FeatureSupportTest, DisplayableUnavailable) +{ + device->m_DisplayableAvailable = false; + device->m_DisplayableTexture = true; + device->m_SharedResourceCompatibilityTier = D3D12_SHARED_RESOURCE_COMPATIBILITY_TIER_2; + + INIT_FEATURES(); + + EXPECT_FALSE(features.DisplayableTexture()); + EXPECT_EQ(features.SharedResourceCompatibilityTier(), D3D12_SHARED_RESOURCE_COMPATIBILITY_TIER_2); // Still initialized by Options4 +} + +// 30: D3D12 Options6 +// Basic Test +TEST_F(FeatureSupportTest, Options6Basic) +{ + device->m_AdditionalShadingRatesSupported = true; + device->m_BackgroundProcessingSupported = true; + device->m_PerPrimitiveShadingRateSupportedWithViewportIndexing = true; + device->m_ShadingRateImageTileSize = 10; + device->m_VariableShadingRateTier = D3D12_VARIABLE_SHADING_RATE_TIER_2; + + INIT_FEATURES(); + + EXPECT_TRUE(features.AdditionalShadingRatesSupported()); + EXPECT_TRUE(features.BackgroundProcessingSupported()); + EXPECT_TRUE(features.PerPrimitiveShadingRateSupportedWithViewportIndexing()); + EXPECT_EQ(features.ShadingRateImageTileSize(), 10); + EXPECT_EQ(features.VariableShadingRateTier(), D3D12_VARIABLE_SHADING_RATE_TIER_2); +} + +// Unavailable Test +TEST_F(FeatureSupportTest, Options6Unavailable) +{ + device->m_Options6Available = false; + device->m_AdditionalShadingRatesSupported = true; + device->m_BackgroundProcessingSupported = true; + device->m_PerPrimitiveShadingRateSupportedWithViewportIndexing = true; + device->m_ShadingRateImageTileSize = 10; + device->m_VariableShadingRateTier = D3D12_VARIABLE_SHADING_RATE_TIER_2; + + INIT_FEATURES(); + + EXPECT_FALSE(features.AdditionalShadingRatesSupported()); + EXPECT_FALSE(features.BackgroundProcessingSupported()); + EXPECT_FALSE(features.PerPrimitiveShadingRateSupportedWithViewportIndexing()); + EXPECT_EQ(features.ShadingRateImageTileSize(), 0); + EXPECT_EQ(features.VariableShadingRateTier(), D3D12_VARIABLE_SHADING_RATE_TIER_NOT_SUPPORTED); +} + +// 31: Query Meta Command +// Only performs input and output consistency checks; not reflecting results from real device +// Basic Test +TEST_F(FeatureSupportTest, QueryMetaCommandBasic) +{ + UINT MockOutput[2] = {2, 8}; + UINT MockOutputSize = sizeof(MockOutput); + device->m_pQueryOutputData = MockOutput; + device->m_QueryOutputDataSizeInBytes = MockOutputSize; + + UINT MockInput[3] = {3, 6, 42}; + UINT MockInputSize = sizeof(MockInput); + GUID MockCommandID = {1, 5, 9, {12, 17, 23, 38}}; // Not a real CommandID + UINT MockNodeMask = 0x12; + + D3D12_FEATURE_DATA_QUERY_META_COMMAND QueryData; + QueryData.CommandId = MockCommandID; + QueryData.NodeMask = MockNodeMask; + QueryData.QueryInputDataSizeInBytes = MockInputSize; + QueryData.pQueryInputData = MockInput; + QueryData.QueryOutputDataSizeInBytes = MockOutputSize; + QueryData.pQueryOutputData = MockOutput; + + INIT_FEATURES(); + + HRESULT result = features.QueryMetaCommand(QueryData); + EXPECT_EQ(result, S_OK); + EXPECT_EQ(device->m_CommandID, MockCommandID); + EXPECT_EQ(device->m_NodeMask, MockNodeMask); + EXPECT_EQ(device->m_QueryInputDataSizeInBytes, MockInputSize); + EXPECT_EQ(device->m_pQueryInputData, MockInput); + EXPECT_EQ(QueryData.QueryOutputDataSizeInBytes, MockOutputSize); + EXPECT_EQ(QueryData.pQueryOutputData, MockOutput); +} + +// 32: Options7 +// Basic Test +TEST_F(FeatureSupportTest, Options7Basic) +{ + device->m_MeshShaderTier = D3D12_MESH_SHADER_TIER_1; + device->m_SamplerFeedbackTier = D3D12_SAMPLER_FEEDBACK_TIER_1_0; + + INIT_FEATURES(); + + EXPECT_EQ(features.MeshShaderTier(), D3D12_MESH_SHADER_TIER_1); + EXPECT_EQ(features.SamplerFeedbackTier(), D3D12_SAMPLER_FEEDBACK_TIER_1_0); +} + +// Unavailable Test +TEST_F(FeatureSupportTest, Options7Unavailable) +{ + device->m_Options7Available = false; + device->m_MeshShaderTier = D3D12_MESH_SHADER_TIER_1; + device->m_SamplerFeedbackTier = D3D12_SAMPLER_FEEDBACK_TIER_1_0; + + INIT_FEATURES(); + + EXPECT_EQ(features.MeshShaderTier(), D3D12_MESH_SHADER_TIER_NOT_SUPPORTED); + EXPECT_EQ(features.SamplerFeedbackTier(), D3D12_SAMPLER_FEEDBACK_TIER_NOT_SUPPORTED); +} + +// 33: Protected Resource Session Type Count +// Basic Test +TEST_F(FeatureSupportTest, ProtectedResourceSessionTypeCountBasic) +{ + device->m_ProtectedResourceSessionTypeCount[0] = 5; + device->m_ProtectedResourceSessionTypes[0].resize(5); // Must set the session types to a correct number + + INIT_FEATURES(); + + EXPECT_EQ(features.ProtectedResourceSessionTypeCount(0), 5); +} + +// Multinode Test +TEST_F(FeatureSupportTest, ProtectedResourceSessionTypeCountMultinode) +{ + device->SetNodeCount(3); + device->m_ProtectedResourceSessionTypeCount = {3, 14, 21}; + device->m_ProtectedResourceSessionTypes[0].resize(3); + device->m_ProtectedResourceSessionTypes[1].resize(14); + device->m_ProtectedResourceSessionTypes[2].resize(21); + + INIT_FEATURES(); + + EXPECT_EQ(features.ProtectedResourceSessionTypeCount(0), 3); + EXPECT_EQ(features.ProtectedResourceSessionTypeCount(1), 14); + EXPECT_EQ(features.ProtectedResourceSessionTypeCount(2), 21); +} + +// Unavailable Test +TEST_F(FeatureSupportTest, ProtectedResourceSessionTypeCountUnavailable) +{ + device->m_ProtectedResourceSessionTypeCountAvailable = false; + device->SetNodeCount(3); + device->m_ProtectedResourceSessionTypeCount = {3, 14, 21}; + device->m_ProtectedResourceSessionTypes[0].resize(3); + device->m_ProtectedResourceSessionTypes[1].resize(14); + device->m_ProtectedResourceSessionTypes[2].resize(21); + + INIT_FEATURES(); + + EXPECT_EQ(features.ProtectedResourceSessionTypeCount(0), 0); + EXPECT_EQ(features.ProtectedResourceSessionTypeCount(1), 0); + EXPECT_EQ(features.ProtectedResourceSessionTypeCount(2), 0); +} + +// 34: Protected Resource Session Types +// Note: Protected Resource Seesion Type Count must be correctly set for this feature +// Basic Test +TEST_F(FeatureSupportTest, ProtectedResourceSessionTypesBasic) +{ + device->m_ProtectedResourceSessionTypeCount[0] = 2; + device->m_ProtectedResourceSessionTypes[0] = {{1, 1, 2, {3, 5, 8, 13}}, {1, 4, 9, {16, 25, 36, 49}}}; // Some random GUID test data + + INIT_FEATURES(); + + EXPECT_EQ(features.ProtectedResourceSessionTypes(), device->m_ProtectedResourceSessionTypes[0]); +} + +// Multinode Test +TEST_F(FeatureSupportTest, ProtectedResourceSessionTypesMultinode) +{ + device->SetNodeCount(2); + device->m_ProtectedResourceSessionTypeCount = {2, 1}; + device->m_ProtectedResourceSessionTypes[0] = {{1, 1, 2, {3, 5, 8, 13}}, {1, 4, 9, {16, 25, 36, 49}}}; // Some random GUID test data + device->m_ProtectedResourceSessionTypes[1] = {{5, 7, 9, {11, 13, 15, 17}}}; + + INIT_FEATURES(); + + EXPECT_EQ(features.ProtectedResourceSessionTypes(0), device->m_ProtectedResourceSessionTypes[0]); + EXPECT_EQ(features.ProtectedResourceSessionTypes(1), device->m_ProtectedResourceSessionTypes[1]); +} + +// Unavailable Test +TEST_F(FeatureSupportTest, ProtectedResourceSessionTypesUnavailable) +{ + device->m_ProtectedResourceSessionTypesAvailable = false; + device->m_ProtectedResourceSessionTypeCount[0] = 2; + device->m_ProtectedResourceSessionTypes[0] = {{1, 1, 2, {3, 5, 8, 13}}, {1, 4, 9, {16, 25, 36, 49}}}; // Some random GUID test data + + INIT_FEATURES(); + + // If the check fails, the types vector should remain empty + EXPECT_EQ(features.ProtectedResourceSessionTypes(0).size(), 0); +} + +// Test where ProtectedResourceSessiontTypeCount is unavailable +TEST_F(FeatureSupportTest, ProtectedResourceSessionTypesCascadeUnavailable) +{ + device->m_ProtectedResourceSessionTypeCountAvailable = false; + device->m_ProtectedResourceSessionTypeCount[0] = 2; + device->m_ProtectedResourceSessionTypes[0] = {{1, 1, 2, {3, 5, 8, 13}}, {1, 4, 9, {16, 25, 36, 49}}}; // Some random GUID test data + + INIT_FEATURES(); + + EXPECT_EQ(features.ProtectedResourceSessionTypeCount(0), 0); + EXPECT_EQ(features.ProtectedResourceSessionTypes(0).size(), 0); +} + +// 36: Options8 +// Basic Test +TEST_F(FeatureSupportTest, Options8Basic) +{ + device->m_UnalignedBlockTexturesSupported = true; + INIT_FEATURES(); + EXPECT_TRUE(features.UnalignedBlockTexturesSupported()); +} + +// Unavailable Test +TEST_F(FeatureSupportTest, Options8Unavailable) +{ + device->m_Options8Available = false; + device->m_UnalignedBlockTexturesSupported = true; + INIT_FEATURES(); + EXPECT_FALSE(features.UnalignedBlockTexturesSupported()); +} + +// 37: Options9 +// Basic Test +TEST_F(FeatureSupportTest, Options9Basic) +{ + device->m_MeshShaderPipelineStatsSupported = true; + device->m_MeshShaderSupportsFullRangeRenderTargetArrayIndex = true; + device->m_AtomicInt64OnTypedResourceSupported = true; + device->m_AtomicInt64OnGroupSharedSupported = true; + device->m_DerivativesInMeshAndAmplificationShadersSupported = true; + device->m_WaveMMATier = D3D12_WAVE_MMA_TIER_1_0; + + INIT_FEATURES(); + + EXPECT_TRUE(features.MeshShaderPipelineStatsSupported()); + EXPECT_TRUE(features.MeshShaderSupportsFullRangeRenderTargetArrayIndex()); + EXPECT_TRUE(features.AtomicInt64OnTypedResourceSupported()); + EXPECT_TRUE(features.AtomicInt64OnGroupSharedSupported()); + EXPECT_TRUE(features.DerivativesInMeshAndAmplificationShadersSupported()); + EXPECT_EQ(features.WaveMMATier(), D3D12_WAVE_MMA_TIER_1_0); +} + +// Unavailable Test +TEST_F(FeatureSupportTest, Options9Unavailable) +{ + device->m_Options9Available = false; + device->m_MeshShaderPipelineStatsSupported = true; + device->m_MeshShaderSupportsFullRangeRenderTargetArrayIndex = true; + device->m_AtomicInt64OnTypedResourceSupported = true; + device->m_AtomicInt64OnGroupSharedSupported = true; + device->m_DerivativesInMeshAndAmplificationShadersSupported = true; + device->m_WaveMMATier = D3D12_WAVE_MMA_TIER_1_0; + + INIT_FEATURES(); + + EXPECT_FALSE(features.MeshShaderPipelineStatsSupported()); + EXPECT_FALSE(features.MeshShaderSupportsFullRangeRenderTargetArrayIndex()); + EXPECT_FALSE(features.AtomicInt64OnTypedResourceSupported()); + EXPECT_FALSE(features.AtomicInt64OnGroupSharedSupported()); + EXPECT_FALSE(features.DerivativesInMeshAndAmplificationShadersSupported()); + EXPECT_EQ(features.WaveMMATier(), D3D12_WAVE_MMA_TIER_NOT_SUPPORTED); +} + +// 39: Options10 +// Basic Test +TEST_F(FeatureSupportTest, Options10Basic) +{ + device->m_VariableRateShadingSumCombinerSupported = true; + device->m_MeshShaderPerPrimitiveShadingRateSupported = true; + + INIT_FEATURES(); + + EXPECT_TRUE(features.VariableRateShadingSumCombinerSupported()); + EXPECT_TRUE(features.MeshShaderPerPrimitiveShadingRateSupported()); +} + +// Unavailable Test +TEST_F(FeatureSupportTest, Options10Unavailable) +{ + device->m_Options10Available = false; + device->m_VariableRateShadingSumCombinerSupported = true; + device->m_MeshShaderPerPrimitiveShadingRateSupported = true; + + INIT_FEATURES(); + + EXPECT_FALSE(features.VariableRateShadingSumCombinerSupported()); + EXPECT_FALSE(features.MeshShaderPerPrimitiveShadingRateSupported()); +} + +// 40: Options11 +// Basic Test +TEST_F(FeatureSupportTest, Options11Basic) +{ + device->m_AtomicInt64OnDescriptorHeapResourceSupported = true; + INIT_FEATURES(); + EXPECT_TRUE(features.AtomicInt64OnDescriptorHeapResourceSupported()); +} + +// Unavailable Test +TEST_F(FeatureSupportTest, Options11Unavailable) +{ + device->m_Options11Available = false; + device->m_AtomicInt64OnDescriptorHeapResourceSupported = true; + INIT_FEATURES(); + EXPECT_FALSE(features.AtomicInt64OnDescriptorHeapResourceSupported()); +} + +// 41: Options12 +// Basic Test +TEST_F(FeatureSupportTest, Options12Basic) +{ + device->m_MSPrimitivesPipelineStatisticIncludesCulledPrimitives = D3D12_TRI_STATE_TRUE; + device->m_EnhancedBarriersSupported = true; + INIT_FEATURES(); + EXPECT_EQ(features.MSPrimitivesPipelineStatisticIncludesCulledPrimitives(), D3D12_TRI_STATE_TRUE); + EXPECT_TRUE(features.EnhancedBarriersSupported()); +} + +// Unavailable Test +TEST_F(FeatureSupportTest, Options12Unavailable) +{ + device->m_Options12Available = false; + device->m_MSPrimitivesPipelineStatisticIncludesCulledPrimitives = D3D12_TRI_STATE_TRUE; + device->m_EnhancedBarriersSupported = true; + INIT_FEATURES(); + EXPECT_EQ(features.MSPrimitivesPipelineStatisticIncludesCulledPrimitives(), D3D12_TRI_STATE_UNKNOWN); + EXPECT_FALSE(features.EnhancedBarriersSupported()); +} + +// Duplicate Caps Tests +// This test ensures that caps that are present in more than one features reports correctly +// when either of them are unavailable on the runtime + +// Cross Node Sharing Tier: D3D12Options, CrossNode +TEST_F(FeatureSupportTest, DuplicateCrossNodeSharingTier) +{ + device->m_CrossNodeSharingTier = D3D12_CROSS_NODE_SHARING_TIER_3; + device->m_CrossNodeAvailable = false; + + INIT_FEATURES(); + + EXPECT_EQ(features.CrossNodeSharingTier(), D3D12_CROSS_NODE_SHARING_TIER_3); +} + +// Shared Resource Compatibility Tier: D3D12Options4, Displayable +TEST_F(FeatureSupportTest, DuplicateSharedResourceCompatibilityTier) +{ + device->m_SharedResourceCompatibilityTier = D3D12_SHARED_RESOURCE_COMPATIBILITY_TIER_2; + device->m_DisplayableAvailable = false; + + INIT_FEATURES(); + EXPECT_EQ(features.SharedResourceCompatibilityTier(), D3D12_SHARED_RESOURCE_COMPATIBILITY_TIER_2); +} + +// Test where both features are unavailable +TEST_F(FeatureSupportTest, DuplicateSharedResourceCompatibilityTierNegatvie) +{ + device->m_SharedResourceCompatibilityTier = D3D12_SHARED_RESOURCE_COMPATIBILITY_TIER_2; + device->m_DisplayableAvailable = false; + device->m_Options4Available = false; + + INIT_FEATURES(); + EXPECT_EQ(features.SharedResourceCompatibilityTier(), D3D12_SHARED_RESOURCE_COMPATIBILITY_TIER_0); // Fallback to default value +} + +// MaxGPUVirtualAddressBitsPerResource also has duplicates, +// but since the two features are always supported, no explicit tests are needed. + +// System Test +// Test if the system works when all features are initialized and queries +// Skips functions that only does forwarding +TEST_F(FeatureSupportTest, SystemTest) +{ + device->SetNodeCount(2); + device->m_DoublePrecisionFloatShaderOps = true; + device->m_OutputMergerLogicOp = true; + device->m_ShaderMinPrecisionSupport10Bit = D3D12_SHADER_MIN_PRECISION_SUPPORT_10_BIT; + device->m_ShaderMinPrecisionSupport16Bit = D3D12_SHADER_MIN_PRECISION_SUPPORT_16_BIT; + device->m_TiledResourcesTier = D3D12_TILED_RESOURCES_TIER_3; + device->m_ResourceBindingTier = D3D12_RESOURCE_BINDING_TIER_3; + device->m_PSSpecifiedStencilRefSupported = true; + device->m_ConservativeRasterizationTier = D3D12_CONSERVATIVE_RASTERIZATION_TIER_2; + device->m_MaxGPUVirtualAddressBitsPerResource = 10; + device->m_ResourceHeapTier = D3D12_RESOURCE_HEAP_TIER_2; + device->m_TypedUAVLoadAdditionalFormats = true; + device->m_ROVsSupported = true; + device->m_StandardSwizzle64KBSupported = true; + device->m_CrossNodeSharingTier = D3D12_CROSS_NODE_SHARING_TIER_3; + device->m_CrossAdapterRowMajorTextureSupported = true; + device->m_VPAndRTArrayIndexFromAnyShaderFeedingRasterizerSupportedWithoutGSEmulation = true; + + device->m_Architecture1Available = true; + device->m_TileBasedRenderer = {false, true}; + device->m_UMA = {true, false}; + device->m_CacheCoherentUMA = {false, true}; + device->m_IsolatedMMU = {true, true}; + + device->m_FeatureLevel = D3D_FEATURE_LEVEL_12_2; + + device->m_MaxGPUVirtualAddressBitsPerProcess = 16; + + device->m_WaveOpsSupported = true; + device->m_WaveLaneCountMin = 2; + device->m_WaveLaneCountMax = 4; + device->m_TotalLaneCount = 8; + device->m_ExpandedComputeResourceStates = true; + device->m_Int64ShaderOpsSupported = true; + + device->m_ProtectedResourceSessionSupport = + { + D3D12_PROTECTED_RESOURCE_SESSION_SUPPORT_FLAG_NONE, + D3D12_PROTECTED_RESOURCE_SESSION_SUPPORT_FLAG_SUPPORTED, + }; + + device->m_RootSignatureHighestVersion = D3D_ROOT_SIGNATURE_VERSION_1_1; + + device->m_DepthBoundsTestSupport = true; + device->m_ProgrammableSamplePositionsTier = D3D12_PROGRAMMABLE_SAMPLE_POSITIONS_TIER_2; + + D3D12_SHADER_CACHE_SUPPORT_FLAGS outFlags = D3D12_SHADER_CACHE_SUPPORT_SINGLE_PSO + | D3D12_SHADER_CACHE_SUPPORT_LIBRARY + | D3D12_SHADER_CACHE_SUPPORT_AUTOMATIC_INPROC_CACHE + | D3D12_SHADER_CACHE_SUPPORT_DRIVER_MANAGED_CACHE + | D3D12_SHADER_CACHE_SUPPORT_SHADER_CONTROL_CLEAR + | D3D12_SHADER_CACHE_SUPPORT_SHADER_SESSION_DELETE; + device->m_ShaderCacheSupportFlags = outFlags; + + device->m_GlobalRealtimeCommandQueueSupport = true; + + device->m_CopyQueueTimestampQueriesSupported = true; + device->m_CastingFullyTypedFormatsSupported = true; + device->m_GetCachedWriteBufferImmediateSupportFlags = D3D12_COMMAND_LIST_SUPPORT_FLAG_DIRECT | D3D12_COMMAND_LIST_SUPPORT_FLAG_COMPUTE; + device->m_ViewInstancingTier = D3D12_VIEW_INSTANCING_TIER_3; + device->m_BarycentricsSupported = true; + + device->m_ExistingHeapCaps = true; + + device->m_MSAA64KBAlignedTextureSupported = true; + device->m_SharedResourceCompatibilityTier = D3D12_SHARED_RESOURCE_COMPATIBILITY_TIER_2; + device->m_Native16BitShaderOpsSupported = true; + + device->m_HeapSerializationTier = + { + D3D12_HEAP_SERIALIZATION_TIER_10, + D3D12_HEAP_SERIALIZATION_TIER_10, + }; + + device->m_AtomicShaderInstructions = true; + + device->m_RaytracingTier = D3D12_RAYTRACING_TIER_1_1; + device->m_RenderPassesTier = D3D12_RENDER_PASS_TIER_2; + device->m_SRVOnlyTiledResourceTier3 = true; + + device->m_DisplayableTexture = true; + + device->m_AdditionalShadingRatesSupported = true; + device->m_BackgroundProcessingSupported = true; + device->m_PerPrimitiveShadingRateSupportedWithViewportIndexing = true; + device->m_ShadingRateImageTileSize = 10; + device->m_VariableShadingRateTier = D3D12_VARIABLE_SHADING_RATE_TIER_2; + + device->m_MeshShaderTier = D3D12_MESH_SHADER_TIER_1; + device->m_SamplerFeedbackTier = D3D12_SAMPLER_FEEDBACK_TIER_1_0; + + device->m_ProtectedResourceSessionTypeCount = {2, 1}; + device->m_ProtectedResourceSessionTypes[0].resize(3); + device->m_ProtectedResourceSessionTypes[1].resize(14); + + device->m_ProtectedResourceSessionTypes[0] = {{1, 1, 2, {3, 5, 8, 13}}, {1, 4, 9, {16, 25, 36, 49}}}; // Some random GUID test data + device->m_ProtectedResourceSessionTypes[1] = {{5, 7, 9, {11, 13, 15, 17}}}; + + device->m_UnalignedBlockTexturesSupported = true; + + device->m_MeshShaderPipelineStatsSupported = true; + device->m_MeshShaderSupportsFullRangeRenderTargetArrayIndex = true; + device->m_AtomicInt64OnTypedResourceSupported = true; + device->m_AtomicInt64OnGroupSharedSupported = true; + device->m_DerivativesInMeshAndAmplificationShadersSupported = true; + device->m_WaveMMATier = D3D12_WAVE_MMA_TIER_1_0; + + device->m_VariableRateShadingSumCombinerSupported = true; + device->m_MeshShaderPerPrimitiveShadingRateSupported = true; + + device->m_AtomicInt64OnDescriptorHeapResourceSupported = true; + + device->m_MSPrimitivesPipelineStatisticIncludesCulledPrimitives = D3D12_TRI_STATE_TRUE; + device->m_EnhancedBarriersSupported = true; + + INIT_FEATURES(); + + EXPECT_TRUE(features.DoublePrecisionFloatShaderOps()); + EXPECT_TRUE(features.OutputMergerLogicOp()); + EXPECT_EQ(features.MinPrecisionSupport(), D3D12_SHADER_MIN_PRECISION_SUPPORT_10_BIT | D3D12_SHADER_MIN_PRECISION_SUPPORT_16_BIT); + EXPECT_EQ(features.TiledResourcesTier(), D3D12_TILED_RESOURCES_TIER_3); + EXPECT_EQ(features.ResourceBindingTier(), D3D12_RESOURCE_BINDING_TIER_3); + EXPECT_TRUE(features.PSSpecifiedStencilRefSupported()); + EXPECT_TRUE(features.TypedUAVLoadAdditionalFormats()); + EXPECT_TRUE(features.ROVsSupported()); + EXPECT_EQ(features.ConservativeRasterizationTier(), D3D12_CONSERVATIVE_RASTERIZATION_TIER_2); + EXPECT_EQ(features.MaxGPUVirtualAddressBitsPerResource(), 10); + EXPECT_TRUE(features.StandardSwizzle64KBSupported()); + EXPECT_EQ(features.CrossNodeSharingTier(), D3D12_CROSS_NODE_SHARING_TIER_3); + EXPECT_TRUE(features.CrossAdapterRowMajorTextureSupported()); + EXPECT_TRUE(features.VPAndRTArrayIndexFromAnyShaderFeedingRasterizerSupportedWithoutGSEmulation()); + EXPECT_EQ(features.ResourceHeapTier(), D3D12_RESOURCE_HEAP_TIER_2); + + EXPECT_FALSE(features.TileBasedRenderer(0)); + EXPECT_TRUE(features.TileBasedRenderer(1)); + EXPECT_TRUE(features.UMA(0)); + EXPECT_FALSE(features.UMA(1)); + EXPECT_FALSE(features.CacheCoherentUMA(0)); + EXPECT_TRUE(features.CacheCoherentUMA(1)); + EXPECT_TRUE(features.IsolatedMMU(0)); + EXPECT_TRUE(features.IsolatedMMU(1)); + + EXPECT_EQ(features.MaxSupportedFeatureLevel(), D3D_FEATURE_LEVEL_12_2); + + EXPECT_EQ(features.MaxGPUVirtualAddressBitsPerProcess(), 16); + + EXPECT_TRUE(features.WaveOps()); + EXPECT_EQ(features.WaveLaneCountMin(), 2); + EXPECT_EQ(features.WaveLaneCountMax(), 4); + EXPECT_EQ(features.TotalLaneCount(), 8); + EXPECT_TRUE(features.ExpandedComputeResourceStates()); + EXPECT_TRUE(features.Int64ShaderOps()); + + EXPECT_EQ(features.ProtectedResourceSessionSupport(0), D3D12_PROTECTED_RESOURCE_SESSION_SUPPORT_FLAG_NONE); + EXPECT_EQ(features.ProtectedResourceSessionSupport(1), D3D12_PROTECTED_RESOURCE_SESSION_SUPPORT_FLAG_SUPPORTED); + + EXPECT_EQ(features.HighestRootSignatureVersion(), D3D_ROOT_SIGNATURE_VERSION_1_1); + + EXPECT_TRUE(features.DepthBoundsTestSupported()); + EXPECT_EQ(features.ProgrammableSamplePositionsTier(), D3D12_PROGRAMMABLE_SAMPLE_POSITIONS_TIER_2); + + EXPECT_EQ(features.ShaderCacheSupportFlags(), outFlags); + + EXPECT_TRUE(features.CommandQueuePrioritySupported(D3D12_COMMAND_LIST_TYPE_DIRECT, D3D12_COMMAND_QUEUE_PRIORITY_NORMAL)); + EXPECT_TRUE(features.CommandQueuePrioritySupported(D3D12_COMMAND_LIST_TYPE_DIRECT, D3D12_COMMAND_QUEUE_PRIORITY_HIGH)); + EXPECT_TRUE(features.CommandQueuePrioritySupported(D3D12_COMMAND_LIST_TYPE_DIRECT, D3D12_COMMAND_QUEUE_PRIORITY_GLOBAL_REALTIME)); + + EXPECT_TRUE(features.CopyQueueTimestampQueriesSupported()); + EXPECT_TRUE(features.CastingFullyTypedFormatSupported()); + EXPECT_EQ(features.WriteBufferImmediateSupportFlags(), D3D12_COMMAND_LIST_SUPPORT_FLAG_DIRECT | D3D12_COMMAND_LIST_SUPPORT_FLAG_COMPUTE); + EXPECT_EQ(features.ViewInstancingTier(), D3D12_VIEW_INSTANCING_TIER_3); + EXPECT_TRUE(features.BarycentricsSupported()); + + EXPECT_TRUE(features.ExistingHeapsSupported()); + + EXPECT_TRUE(features.MSAA64KBAlignedTextureSupported()); + EXPECT_EQ(features.SharedResourceCompatibilityTier(), D3D12_SHARED_RESOURCE_COMPATIBILITY_TIER_2); + EXPECT_TRUE(features.Native16BitShaderOpsSupported()); + + EXPECT_EQ(features.HeapSerializationTier(), D3D12_HEAP_SERIALIZATION_TIER_10); + EXPECT_EQ(features.HeapSerializationTier(1), D3D12_HEAP_SERIALIZATION_TIER_10); + + EXPECT_EQ(features.CrossNodeSharingTier(), D3D12_CROSS_NODE_SHARING_TIER_3); + EXPECT_TRUE(features.CrossNodeAtomicShaderInstructions()); + + EXPECT_EQ(features.RaytracingTier(), D3D12_RAYTRACING_TIER_1_1); + EXPECT_EQ(features.RenderPassesTier(), D3D12_RENDER_PASS_TIER_2); + EXPECT_TRUE(features.SRVOnlyTiledResourceTier3()); + + EXPECT_TRUE(features.DisplayableTexture()); + + EXPECT_TRUE(features.AdditionalShadingRatesSupported()); + EXPECT_TRUE(features.BackgroundProcessingSupported()); + EXPECT_TRUE(features.PerPrimitiveShadingRateSupportedWithViewportIndexing()); + EXPECT_EQ(features.ShadingRateImageTileSize(), 10); + EXPECT_EQ(features.VariableShadingRateTier(), D3D12_VARIABLE_SHADING_RATE_TIER_2); + + EXPECT_EQ(features.MeshShaderTier(), D3D12_MESH_SHADER_TIER_1); + EXPECT_EQ(features.SamplerFeedbackTier(), D3D12_SAMPLER_FEEDBACK_TIER_1_0); + + EXPECT_EQ(features.ProtectedResourceSessionTypeCount(0), 2); + EXPECT_EQ(features.ProtectedResourceSessionTypeCount(1), 1); + EXPECT_EQ(features.ProtectedResourceSessionTypes(0), device->m_ProtectedResourceSessionTypes[0]); + EXPECT_EQ(features.ProtectedResourceSessionTypes(1), device->m_ProtectedResourceSessionTypes[1]); + + EXPECT_TRUE(features.UnalignedBlockTexturesSupported()); + + EXPECT_TRUE(features.MeshShaderPipelineStatsSupported()); + EXPECT_TRUE(features.MeshShaderSupportsFullRangeRenderTargetArrayIndex()); + EXPECT_TRUE(features.AtomicInt64OnTypedResourceSupported()); + EXPECT_TRUE(features.AtomicInt64OnGroupSharedSupported()); + EXPECT_TRUE(features.DerivativesInMeshAndAmplificationShadersSupported()); + EXPECT_EQ(features.WaveMMATier(), D3D12_WAVE_MMA_TIER_1_0); + + EXPECT_TRUE(features.VariableRateShadingSumCombinerSupported()); + EXPECT_TRUE(features.MeshShaderPerPrimitiveShadingRateSupported()); + + EXPECT_TRUE(features.AtomicInt64OnDescriptorHeapResourceSupported()); + + EXPECT_EQ(features.MSPrimitivesPipelineStatisticIncludesCulledPrimitives(), D3D12_TRI_STATE_TRUE); + EXPECT_TRUE(features.EnhancedBarriersSupported()); +} \ No newline at end of file diff --git a/contrib/DirectX-Headers-1.618.2/googletest/meson.build b/contrib/DirectX-Headers-1.618.2/googletest/meson.build new file mode 100644 index 0000000..a839782 --- /dev/null +++ b/contrib/DirectX-Headers-1.618.2/googletest/meson.build @@ -0,0 +1,13 @@ +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. + +gtest = cpp.find_library('gtest', required: false) +gtest_main = cpp.find_library('gtest_main', required: false) + +if gtest.found() and gtest_main.found() + feature_support_test = executable('Feature-Support-Test', 'feature_support_test.cpp', + dependencies : [gtest, gtest_main, dep_dxheaders, d3d12_lib, dxcore_lib], + cpp_args : test_compile_opts, + c_args : test_compile_opts) + test('Feature-Support-Test', feature_support_test) +endif -- cgit v1.2.3