DirectX-Headers/googletest/MockDevice.hpp

1299 строки
50 KiB
C++

// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
#ifndef DIRECTX_HEADERS_MOCK_DEVICE_HPP
#define DIRECTX_HEADERS_MOCK_DEVICE_HPP
#include <unordered_map>
#ifndef __RPC_FAR
#define __RPC_FAR
#endif
#include <directx/d3d12.h>
#include <directx/dxcore.h>
#include <directx/d3dx12.h>
#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<D3D12_FEATURE_DATA_D3D12_OPTIONS*>(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<D3D12_FEATURE_DATA_D3D12_OPTIONS1*>(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<D3D12_FEATURE_DATA_D3D12_OPTIONS2*>(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<D3D12_FEATURE_DATA_ROOT_SIGNATURE*>(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<D3D_ROOT_SIGNATURE_VERSION>(std::min<int>(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<D3D12_FEATURE_DATA_SHADER_MODEL*>(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<D3D_SHADER_MODEL>(std::min<int>(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<D3D12_FEATURE_DATA_SHADER_CACHE*>(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<D3D12_FEATURE_DATA_COMMAND_QUEUE_PRIORITY*>(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<D3D12_FEATURE_DATA_PROTECTED_RESOURCE_SESSION_SUPPORT*>(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<D3D12_FEATURE_DATA_D3D12_OPTIONS3*>(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<D3D12_FEATURE_DATA_EXISTING_HEAPS*>(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<D3D12_FEATURE_DATA_D3D12_OPTIONS4*>(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<D3D12_FEATURE_DATA_SERIALIZATION*>(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<D3D12_FEATURE_DATA_CROSS_NODE*>(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<D3D12_FEATURE_DATA_D3D12_OPTIONS5*>(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<D3D12_FEATURE_DATA_DISPLAYABLE*>(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<D3D12_FEATURE_DATA_D3D12_OPTIONS6*>(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<D3D12_FEATURE_DATA_QUERY_META_COMMAND*>(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<D3D12_FEATURE_DATA_D3D12_OPTIONS7*>(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<D3D12_FEATURE_DATA_PROTECTED_RESOURCE_SESSION_TYPE_COUNT*>(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<D3D12_FEATURE_DATA_PROTECTED_RESOURCE_SESSION_TYPES*>(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<D3D12_FEATURE_DATA_D3D12_OPTIONS8*>(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<D3D12_FEATURE_DATA_D3D12_OPTIONS9*>(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<D3D12_FEATURE_DATA_D3D12_OPTIONS10*>(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<D3D12_FEATURE_DATA_D3D12_OPTIONS11*>(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<D3D12_FEATURE_DATA_D3D12_OPTIONS12*>(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<BOOL> m_TileBasedRenderer;
std::vector<BOOL> m_UMA;
std::vector<BOOL> m_CacheCoherentUMA;
std::vector<BOOL> 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<D3D12_PROTECTED_RESOURCE_SESSION_SUPPORT_FLAGS> 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<D3D12_HEAP_SERIALIZATION_TIER> 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<UINT> m_ProtectedResourceSessionTypeCount;
// 34: Protected Resource Session Types
bool m_ProtectedResourceSessionTypesAvailable = true;
std::vector<std::vector<GUID>> 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