mirror of
https://github.com/microsoft/DirectX-Headers.git
synced 2024-11-27 03:43:27 +08:00
1299 lines
50 KiB
C++
1299 lines
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 |