blob: f4a31f41098738ed4f2280ee1b8a216a2c6514a5 [file] [edit]
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
#ifndef _WIN32
#include <wsl/winadapter.h>
#endif
#include <iostream>
#include <directx/d3d12.h>
#include <directx/dxcore.h>
#include <directx/d3dx12.h>
#include "dxguids/dxguids.h"
// -----------------------------------------------------------------------------------------------------------------
// Helper Macros for verifying feature check results
// -----------------------------------------------------------------------------------------------------------------
// Verifies the correctness of a feature check that should not fail
#define VERIFY_FEATURE_CHECK_NO_DEFAULT(Feature) \
{ \
if (features.Feature() != Data.Feature) \
{ \
std::cout << "Verification failed: " << #Feature << std::endl \
<< "Old API: " << Data.Feature << std::endl \
<< "New API: " << features.Feature() << std::endl; \
return -1; \
} \
}
// Verifies the return value from a feature check with a different name from the old API that should not fail
#define VERIFY_RENAMED_FEATURE_CHECK_NO_DEFAULT(NewFeature, OldFeature) \
{ \
if (features.NewFeature() != Data.OldFeature) \
{ \
std::cout << "Verification failed: " << #NewFeature << std::endl \
<< "Old API: " << Data.OldFeature << std::endl \
<< "New API: " << features.NewFeature() << std::endl; \
return -1; \
} \
}
// Verifies if the feature check returns the correct default value upon failure
#define VERIFY_DEFAULT(Feature, Default) \
{ \
if (features.Feature() != Default) \
{ \
std::cout << "Verification failed: " << #Feature << std::endl \
<< "Default: " << Default << std::endl \
<< "Actual: " << features.Feature() << std::endl; \
return -1; \
} \
}
// Verifies the result of a feature check.
// If the feature check failed because it's not supported by runtime, ensures that it returns the default value
#define VERIFY_FEATURE_CHECK(Feature, Default) \
{ \
if (FAILED(InitResult)) \
{ \
VERIFY_DEFAULT(Feature, Default); \
} \
else \
{ \
VERIFY_FEATURE_CHECK_NO_DEFAULT(Feature); \
} \
}
// Verifies the result of a feature check. The requested capability may have a different name in the new API
// If the feature check failed because it's not supported by runtime, ensures that it returns the default value
#define VERIFY_RENAMED_FEATURE_CHECK(Feature, OldName, Default) \
{ \
if (FAILED(InitResult)) \
{ \
VERIFY_DEFAULT(Feature, Default); \
} \
else \
{ \
VERIFY_RENAMED_FEATURE_CHECK_NO_DEFAULT(Feature, OldName); \
} \
}
// Initialize the feature support data structure to be used in the original CheckFeatureSupport API
#define INITIALIZE_FEATURE_SUPPORT_DATA(FeatureName) \
HRESULT InitResult; \
if (FAILED(InitResult = device->CheckFeatureSupport(D3D12_FEATURE_##FeatureName, &Data, sizeof(D3D12_FEATURE_DATA_##FeatureName)))) \
{ \
std::cout << "Feature not supported by device: " << #FeatureName << std::endl; \
}
// Prints out the mismatched feature check result to stdout
#define PRINT_CHECK_FAILED_MESSAGE(FeatureName, OldFeature, NewFeature) \
std::cout << "Verification failed: " << #FeatureName << std::endl \
<< "Old API: " << OldFeature << std::endl \
<< "New API: " << NewFeature << std::endl;
// -----------------------------------------------------------------------------------------------------------------
// Main function
// -----------------------------------------------------------------------------------------------------------------
int main()
{
ID3D12Device *device = nullptr;
if (FAILED(D3D12CreateDevice(nullptr, D3D_FEATURE_LEVEL_11_0, IID_PPV_ARGS(&device))))
{
return -1;
}
// Initialize the new FeatureSupport class
// Notice that it is shared among all feature checks
CD3DX12FeatureSupport features;
if (FAILED(features.Init(device)))
{
return -1;
}
UINT NodeCount = device->GetNodeCount();
// Each feature comes with two code sections
// The first section shows how to use the API's of the new FeautreSupport class
// The second section contains tests that ensures the new API returns the same result as the old API
// 0: D3D12_OPTIONS
{
BOOL DoublePrecisionFloatShaderOps = features.DoublePrecisionFloatShaderOps();
BOOL OutputMergerLogicOp = features.OutputMergerLogicOp();
D3D12_TILED_RESOURCES_TIER TiledResourceTier = features.TiledResourcesTier();
D3D12_RESOURCE_BINDING_TIER ResourceBindingTier = features.ResourceBindingTier();
BOOL PSSpecifiedStencilRefSupported = features.PSSpecifiedStencilRefSupported();
BOOL TypedUAVLoadAdditionalFormats = features.TypedUAVLoadAdditionalFormats();
BOOL ROVsSupported = features.ROVsSupported();
D3D12_CONSERVATIVE_RASTERIZATION_TIER ConservativeRasterizationTier = features.ConservativeRasterizationTier();
BOOL StandardSwizzle64KBSupported = features.StandardSwizzle64KBSupported();
BOOL CrossAdapterRowMajorTextureSupported = features.CrossAdapterRowMajorTextureSupported();
BOOL VPAndRTArrayIndexFromAnyShaderFeedingRasterizerSupportedWithoutGSEmulation = features.VPAndRTArrayIndexFromAnyShaderFeedingRasterizerSupportedWithoutGSEmulation();
D3D12_RESOURCE_HEAP_TIER ResourceHeapTier = features.ResourceHeapTier();
D3D12_CROSS_NODE_SHARING_TIER CrossNodeSharingTier = features.CrossNodeSharingTier();
UINT MaxGPUVirtualAddressBitsPerResource = features.MaxGPUVirtualAddressBitsPerResource();
D3D12_FEATURE_DATA_D3D12_OPTIONS Data;
device->CheckFeatureSupport(D3D12_FEATURE_D3D12_OPTIONS, &Data, sizeof(D3D12_FEATURE_DATA_D3D12_OPTIONS));
VERIFY_FEATURE_CHECK_NO_DEFAULT(DoublePrecisionFloatShaderOps);
VERIFY_FEATURE_CHECK_NO_DEFAULT(OutputMergerLogicOp);
VERIFY_FEATURE_CHECK_NO_DEFAULT(TiledResourcesTier);
VERIFY_FEATURE_CHECK_NO_DEFAULT(ResourceBindingTier);
VERIFY_FEATURE_CHECK_NO_DEFAULT(PSSpecifiedStencilRefSupported);
VERIFY_FEATURE_CHECK_NO_DEFAULT(TypedUAVLoadAdditionalFormats);
VERIFY_FEATURE_CHECK_NO_DEFAULT(ROVsSupported);
VERIFY_FEATURE_CHECK_NO_DEFAULT(ConservativeRasterizationTier);
VERIFY_FEATURE_CHECK_NO_DEFAULT(StandardSwizzle64KBSupported);
VERIFY_FEATURE_CHECK_NO_DEFAULT(CrossAdapterRowMajorTextureSupported);
VERIFY_FEATURE_CHECK_NO_DEFAULT(VPAndRTArrayIndexFromAnyShaderFeedingRasterizerSupportedWithoutGSEmulation);
VERIFY_FEATURE_CHECK_NO_DEFAULT(ResourceHeapTier);
VERIFY_FEATURE_CHECK_NO_DEFAULT(CrossNodeSharingTier);
VERIFY_FEATURE_CHECK_NO_DEFAULT(MaxGPUVirtualAddressBitsPerResource);
}
// 2: Feature Levels
{
D3D_FEATURE_LEVEL HighestLevelSupported = features.MaxSupportedFeatureLevel();
D3D12_FEATURE_DATA_FEATURE_LEVELS Data;
D3D_FEATURE_LEVEL KnownFeatureLevels[] =
{
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
};
Data.pFeatureLevelsRequested = KnownFeatureLevels;
Data.NumFeatureLevels = sizeof(KnownFeatureLevels) / sizeof(D3D_FEATURE_LEVEL);
device->CheckFeatureSupport(D3D12_FEATURE_FEATURE_LEVELS, &Data, sizeof(D3D12_FEATURE_DATA_FEATURE_LEVELS));
VERIFY_FEATURE_CHECK_NO_DEFAULT(MaxSupportedFeatureLevel);
}
// 3: Format Support
{
D3D12_FORMAT_SUPPORT1 Support1;
D3D12_FORMAT_SUPPORT2 Support2;
if (FAILED(features.FormatSupport(DXGI_FORMAT_R16G16B16A16_FLOAT, Support1, Support2))) {
std::cout << "Error: FormatSupport failed" << std::endl;
return -1;
}
D3D12_FEATURE_DATA_FORMAT_SUPPORT Data;
Data.Format = DXGI_FORMAT_R16G16B16A16_FLOAT;
if (SUCCEEDED(device->CheckFeatureSupport(D3D12_FEATURE_FORMAT_SUPPORT, &Data, sizeof(D3D12_FEATURE_DATA_FORMAT_SUPPORT))))
{
if (Support1 != Data.Support1)
{
std::cout << "Verification failed: " << "FormatSupport1" << std::endl
<< "Old API: " << Data.Support1 << std::endl
<< "New API: " << Support1 << std::endl;
return -1;
}
if (Support2 != Data.Support2)
{
std::cout << "Verification failed: " << "FormatSupport2" << std::endl
<< "Old API: " << Data.Support2 << std::endl
<< "New API: " << Support2 << std::endl;
return -1;
}
}
}
// 4: Multisample Quality Support
{
UINT NumQualityLevels;
if (FAILED(features.MultisampleQualityLevels(DXGI_FORMAT_R16G16B16A16_FLOAT, 1, D3D12_MULTISAMPLE_QUALITY_LEVELS_FLAG_NONE, NumQualityLevels))) {
std::cout << "Error: MultisampleQualityLevels failed" << std::endl;
return -1;
}
D3D12_FEATURE_DATA_MULTISAMPLE_QUALITY_LEVELS Data;
Data.Format = DXGI_FORMAT_R16G16B16A16_FLOAT;
Data.Flags = D3D12_MULTISAMPLE_QUALITY_LEVELS_FLAG_NONE;
Data.SampleCount = 1;
device->CheckFeatureSupport(D3D12_FEATURE_MULTISAMPLE_QUALITY_LEVELS, &Data, sizeof(D3D12_FEATURE_DATA_MULTISAMPLE_QUALITY_LEVELS));
if (NumQualityLevels != Data.NumQualityLevels)
{
std::cout << "Verification failed: " << "MultisampleQualityLevels" << std::endl
<< "Old API: " << Data.NumQualityLevels << std::endl
<< "New API: " << NumQualityLevels << std::endl;
return -1;
}
}
// 5: Format Info
{
UINT8 PlaneCount;
if (FAILED(features.FormatInfo(DXGI_FORMAT_R16G16B16A16_FLOAT, PlaneCount)))
{
std::cout << "Error: FormatInfo failed" << std::endl;
return -1;
}
D3D12_FEATURE_DATA_FORMAT_INFO Data;
Data.Format = DXGI_FORMAT_R16G16B16A16_FLOAT;
device->CheckFeatureSupport(D3D12_FEATURE_FORMAT_INFO, &Data, sizeof(D3D12_FEATURE_DATA_FORMAT_INFO));
if (PlaneCount != Data.PlaneCount)
{
PRINT_CHECK_FAILED_MESSAGE(FormatInfo, Data.PlaneCount, PlaneCount);
}
}
// 6: GPU Virtual Address Support
{
UINT MaxGPUVABitsPerProcess = features.MaxGPUVirtualAddressBitsPerProcess();
UINT MaxGPUVABitsPerResource = features.MaxGPUVirtualAddressBitsPerResource();
D3D12_FEATURE_DATA_GPU_VIRTUAL_ADDRESS_SUPPORT Data;
device->CheckFeatureSupport(D3D12_FEATURE_GPU_VIRTUAL_ADDRESS_SUPPORT, &Data, sizeof(D3D12_FEATURE_DATA_GPU_VIRTUAL_ADDRESS_SUPPORT));
VERIFY_FEATURE_CHECK_NO_DEFAULT(MaxGPUVirtualAddressBitsPerProcess);
VERIFY_FEATURE_CHECK_NO_DEFAULT(MaxGPUVirtualAddressBitsPerResource);
}
// 7: Shader Model
{
D3D_SHADER_MODEL HighestShaderModel = features.HighestShaderModel();
D3D12_FEATURE_DATA_SHADER_MODEL Data;
D3D_SHADER_MODEL KnownShaderModels[] =
{
D3D_SHADER_MODEL_6_7,
D3D_SHADER_MODEL_6_6,
D3D_SHADER_MODEL_6_5,
D3D_SHADER_MODEL_6_4,
D3D_SHADER_MODEL_6_3,
D3D_SHADER_MODEL_6_2,
D3D_SHADER_MODEL_6_1,
D3D_SHADER_MODEL_6_0,
D3D_SHADER_MODEL_5_1
};
UINT NumKnownShaderModels = sizeof(KnownShaderModels) / sizeof(D3D_SHADER_MODEL);
for (UINT i = 0; i < NumKnownShaderModels; i++)
{
Data.HighestShaderModel = D3D_SHADER_MODEL_6_7; // Highest Known Shader Model
if (SUCCEEDED(device->CheckFeatureSupport(D3D12_FEATURE_SHADER_MODEL, &Data, sizeof(D3D12_FEATURE_DATA_SHADER_MODEL))))
{
VERIFY_FEATURE_CHECK_NO_DEFAULT(HighestShaderModel);
}
}
}
// 8: Options1
{
BOOL WaveOps = features.WaveOps();
UINT WaveLaneCountMin = features.WaveLaneCountMin();
UINT WaveLaneCountMax = features.WaveLaneCountMax();
D3D12_FEATURE_DATA_D3D12_OPTIONS1 Data;
INITIALIZE_FEATURE_SUPPORT_DATA(D3D12_OPTIONS1);
VERIFY_FEATURE_CHECK(WaveOps, false);
VERIFY_FEATURE_CHECK(WaveLaneCountMax, 0);
VERIFY_FEATURE_CHECK(WaveLaneCountMin, 0);
}
// 10: Protected Resource Session Support
for (UINT NodeId = 0; NodeId < NodeCount; NodeId++)
{
D3D12_PROTECTED_RESOURCE_SESSION_SUPPORT_FLAGS ProtectedResourceSessionSupport = features.ProtectedResourceSessionSupport(NodeId);
D3D12_FEATURE_DATA_PROTECTED_RESOURCE_SESSION_SUPPORT Data;
Data.NodeIndex = NodeId;
INITIALIZE_FEATURE_SUPPORT_DATA(PROTECTED_RESOURCE_SESSION_SUPPORT);
VERIFY_RENAMED_FEATURE_CHECK(ProtectedResourceSessionSupport, Support, D3D12_PROTECTED_RESOURCE_SESSION_SUPPORT_FLAG_NONE);
}
// 12: Root Signature
{
D3D_ROOT_SIGNATURE_VERSION HighestRootSignatureVersion = features.HighestRootSignatureVersion();
D3D12_FEATURE_DATA_ROOT_SIGNATURE Data;
Data.HighestVersion = D3D_ROOT_SIGNATURE_VERSION_1_1; // Highest Known Version
INITIALIZE_FEATURE_SUPPORT_DATA(ROOT_SIGNATURE);
VERIFY_RENAMED_FEATURE_CHECK(HighestRootSignatureVersion, HighestVersion, (D3D_ROOT_SIGNATURE_VERSION)0);
}
// 16: Architecture1
for (UINT NodeId = 0; NodeId < NodeCount; NodeId++)
{
BOOL IsolatedMMU = features.IsolatedMMU(NodeId);
BOOL TileBasedRenderer = features.TileBasedRenderer(NodeId);
BOOL UMA = features.UMA(NodeId);
BOOL CacheCoherentUMA = features.CacheCoherentUMA(NodeId);
D3D12_FEATURE_DATA_ARCHITECTURE1 Data;
Data.NodeIndex = NodeId;
INITIALIZE_FEATURE_SUPPORT_DATA(ARCHITECTURE1);
if (FAILED(InitResult))
{
D3D12_FEATURE_DATA_ARCHITECTURE Data;
Data.NodeIndex = NodeId;
INITIALIZE_FEATURE_SUPPORT_DATA(ARCHITECTURE);
VERIFY_FEATURE_CHECK_NO_DEFAULT(TileBasedRenderer);
VERIFY_FEATURE_CHECK_NO_DEFAULT(UMA);
VERIFY_FEATURE_CHECK_NO_DEFAULT(CacheCoherentUMA);
}
else
{
VERIFY_FEATURE_CHECK(TileBasedRenderer, false);
VERIFY_FEATURE_CHECK(UMA, false);
VERIFY_FEATURE_CHECK(CacheCoherentUMA, false);
}
VERIFY_FEATURE_CHECK(IsolatedMMU, false);
}
// 18: Options2
{
BOOL DepthBoundsTestSupported = features.DepthBoundsTestSupported();
D3D12_PROGRAMMABLE_SAMPLE_POSITIONS_TIER ProgrammableSamplePositionsTier = features.ProgrammableSamplePositionsTier();
D3D12_FEATURE_DATA_D3D12_OPTIONS2 Data;
INITIALIZE_FEATURE_SUPPORT_DATA(D3D12_OPTIONS2);
VERIFY_FEATURE_CHECK(DepthBoundsTestSupported, false);
VERIFY_FEATURE_CHECK(ProgrammableSamplePositionsTier, D3D12_PROGRAMMABLE_SAMPLE_POSITIONS_TIER_NOT_SUPPORTED);
}
// 19: Shader Cache
{
D3D12_SHADER_CACHE_SUPPORT_FLAGS ShaderCacheSupportFlags = features.ShaderCacheSupportFlags();
D3D12_FEATURE_DATA_SHADER_CACHE Data;
INITIALIZE_FEATURE_SUPPORT_DATA(SHADER_CACHE);
VERIFY_RENAMED_FEATURE_CHECK(ShaderCacheSupportFlags, SupportFlags, D3D12_SHADER_CACHE_FLAG_NONE);
}
// 20: Command Queue Prioirity
{
// Basic check
BOOL CommandQueuePrioritySupportedPositive = features.CommandQueuePrioritySupported(D3D12_COMMAND_LIST_TYPE_DIRECT, D3D12_COMMAND_QUEUE_PRIORITY_NORMAL);
// Check for Global Realtime support
BOOL CommandQueuePrioritySupportedRealtime = features.CommandQueuePrioritySupported(D3D12_COMMAND_LIST_TYPE_COPY, D3D12_COMMAND_QUEUE_PRIORITY_GLOBAL_REALTIME);
// Test on invalid inputs
BOOL CommandQueuePrioritySupportedInvalid = features.CommandQueuePrioritySupported((D3D12_COMMAND_LIST_TYPE)7, 0);
D3D12_FEATURE_DATA_COMMAND_QUEUE_PRIORITY Data;
{
Data.CommandListType = D3D12_COMMAND_LIST_TYPE_DIRECT;
Data.Priority = D3D12_COMMAND_QUEUE_PRIORITY_NORMAL;
INITIALIZE_FEATURE_SUPPORT_DATA(COMMAND_QUEUE_PRIORITY);
if (CommandQueuePrioritySupportedPositive != Data.PriorityForTypeIsSupported)
{
PRINT_CHECK_FAILED_MESSAGE(CommandQueuePriority, Data.PriorityForTypeIsSupported, CommandQueuePrioritySupportedPositive);
}
}
{
Data.CommandListType = D3D12_COMMAND_LIST_TYPE_COPY;
Data.Priority = D3D12_COMMAND_QUEUE_PRIORITY_GLOBAL_REALTIME;
INITIALIZE_FEATURE_SUPPORT_DATA(COMMAND_QUEUE_PRIORITY);
if (CommandQueuePrioritySupportedRealtime != Data.PriorityForTypeIsSupported)
{
PRINT_CHECK_FAILED_MESSAGE(CommandQueuePriority, Data.PriorityForTypeIsSupported, CommandQueuePrioritySupportedRealtime);
}
}
if (CommandQueuePrioritySupportedInvalid)
{
std::cout << "Error: Wrong result from Command Queue Priority - Invalid Test Case\n"
<< "New API returned true on invalid Command List Types\n"
<< "Check if the list of command list types has updated\n";
return -1;
}
}
// 21: Options3
{
BOOL CopyQueueTimestampQueriesSupported = features.CopyQueueTimestampQueriesSupported();
BOOL CastingFullyTypedFormatSupported = features.CastingFullyTypedFormatSupported();
D3D12_COMMAND_LIST_SUPPORT_FLAGS WriteBufferImmediateSupportFlags = features.WriteBufferImmediateSupportFlags();
D3D12_VIEW_INSTANCING_TIER ViewInstancingTier = features.ViewInstancingTier();
BOOL BarycentricsSupported = features.BarycentricsSupported();
D3D12_FEATURE_DATA_D3D12_OPTIONS3 Data;
INITIALIZE_FEATURE_SUPPORT_DATA(D3D12_OPTIONS3);
VERIFY_FEATURE_CHECK(CopyQueueTimestampQueriesSupported, false);
VERIFY_FEATURE_CHECK(CastingFullyTypedFormatSupported, false);
VERIFY_FEATURE_CHECK(WriteBufferImmediateSupportFlags, D3D12_COMMAND_LIST_SUPPORT_FLAG_NONE);
VERIFY_FEATURE_CHECK(ViewInstancingTier, D3D12_VIEW_INSTANCING_TIER_NOT_SUPPORTED);
VERIFY_FEATURE_CHECK(BarycentricsSupported, false);
}
// 22: Existing Heaps
{
BOOL ExistingHeapsSupported = features.ExistingHeapsSupported();
D3D12_FEATURE_DATA_EXISTING_HEAPS Data;
INITIALIZE_FEATURE_SUPPORT_DATA(EXISTING_HEAPS);
VERIFY_RENAMED_FEATURE_CHECK(ExistingHeapsSupported, Supported, false);
}
// 23: D3D12 Options4
{
BOOL MSAA64KBAlignedTextureSupported = features.MSAA64KBAlignedTextureSupported();
D3D12_SHARED_RESOURCE_COMPATIBILITY_TIER SharedResourceCompatibilityTier = features.SharedResourceCompatibilityTier();
BOOL Native16BitShaderOpsSupported = features.Native16BitShaderOpsSupported();
D3D12_FEATURE_DATA_D3D12_OPTIONS4 Data;
INITIALIZE_FEATURE_SUPPORT_DATA(D3D12_OPTIONS4);
VERIFY_FEATURE_CHECK(MSAA64KBAlignedTextureSupported, false);
VERIFY_FEATURE_CHECK(SharedResourceCompatibilityTier, D3D12_SHARED_RESOURCE_COMPATIBILITY_TIER_0);
VERIFY_FEATURE_CHECK(Native16BitShaderOpsSupported, false);
}
// 24: Serialization
{
D3D12_HEAP_SERIALIZATION_TIER HeapSerializationTier = features.HeapSerializationTier();
D3D12_FEATURE_DATA_SERIALIZATION Data;
INITIALIZE_FEATURE_SUPPORT_DATA(SERIALIZATION);
VERIFY_FEATURE_CHECK(HeapSerializationTier, D3D12_HEAP_SERIALIZATION_TIER_0);
}
// 25: Cross Node
{
BOOL CrossNodeAtomicShaderInstructions = features.CrossNodeAtomicShaderInstructions();
D3D12_FEATURE_DATA_CROSS_NODE Data;
INITIALIZE_FEATURE_SUPPORT_DATA(CROSS_NODE);
VERIFY_RENAMED_FEATURE_CHECK(CrossNodeAtomicShaderInstructions, AtomicShaderInstructions, false);
}
// 27: Options5
{
BOOL SRVOnlyTiledResourceTier3 = features.SRVOnlyTiledResourceTier3();
D3D12_RENDER_PASS_TIER RenderPassesTier = features.RenderPassesTier();
D3D12_RAYTRACING_TIER RaytracingTier = features.RaytracingTier();
D3D12_FEATURE_DATA_D3D12_OPTIONS5 Data;
INITIALIZE_FEATURE_SUPPORT_DATA(D3D12_OPTIONS5);
VERIFY_FEATURE_CHECK(SRVOnlyTiledResourceTier3, false);
VERIFY_FEATURE_CHECK(RenderPassesTier, D3D12_RENDER_PASS_TIER_0);
VERIFY_FEATURE_CHECK(RaytracingTier, D3D12_RAYTRACING_TIER_NOT_SUPPORTED);
}
// 28: Displayable
{
BOOL DisplayableTexture = features.DisplayableTexture();
D3D12_FEATURE_DATA_DISPLAYABLE Data;
INITIALIZE_FEATURE_SUPPORT_DATA(DISPLAYABLE);
VERIFY_FEATURE_CHECK(DisplayableTexture, false);
}
// 30: Options6
{
BOOL AdditionalShadingRatesSupported = features.AdditionalShadingRatesSupported();
BOOL PerPrimitiveShadingRateSupportedWithViewportIndexing = features.PerPrimitiveShadingRateSupportedWithViewportIndexing();
D3D12_VARIABLE_SHADING_RATE_TIER VariableShadingRateTier = features.VariableShadingRateTier();
BOOL ShadingRateImageTileSize = features.ShadingRateImageTileSize();
BOOL BackgroundProcessingSupported = features.BackgroundProcessingSupported();
D3D12_FEATURE_DATA_D3D12_OPTIONS6 Data;
INITIALIZE_FEATURE_SUPPORT_DATA(D3D12_OPTIONS6);
VERIFY_FEATURE_CHECK(AdditionalShadingRatesSupported, false);
VERIFY_FEATURE_CHECK(PerPrimitiveShadingRateSupportedWithViewportIndexing, false);
VERIFY_FEATURE_CHECK(VariableShadingRateTier, D3D12_VARIABLE_SHADING_RATE_TIER_NOT_SUPPORTED);
VERIFY_FEATURE_CHECK(ShadingRateImageTileSize, false);
VERIFY_FEATURE_CHECK(BackgroundProcessingSupported, false);
}
// 31: Query Metacommand
// The function is simply a forwarding call to the old API
// Takes in a pointer to D3D12_FEATURE_DATA_QUERY_METACOMMAND as input parameter
// No need to test specifically
// 32: Options7
{
D3D12_MESH_SHADER_TIER MeshShaderTier = features.MeshShaderTier();
D3D12_SAMPLER_FEEDBACK_TIER SamplerFeedbackTier = features.SamplerFeedbackTier();
D3D12_FEATURE_DATA_D3D12_OPTIONS7 Data;
INITIALIZE_FEATURE_SUPPORT_DATA(D3D12_OPTIONS7);
VERIFY_FEATURE_CHECK(MeshShaderTier, D3D12_MESH_SHADER_TIER_NOT_SUPPORTED);
VERIFY_FEATURE_CHECK(SamplerFeedbackTier, D3D12_SAMPLER_FEEDBACK_TIER_NOT_SUPPORTED);
}
// 33: Session Type Count
for (UINT NodeId = 0; NodeId < NodeCount; NodeId++)
{
UINT ProtectedResourceSessionTypeCount = features.ProtectedResourceSessionTypeCount(NodeId);
D3D12_FEATURE_DATA_PROTECTED_RESOURCE_SESSION_TYPE_COUNT Data;
Data.NodeIndex = NodeId;
INITIALIZE_FEATURE_SUPPORT_DATA(PROTECTED_RESOURCE_SESSION_TYPE_COUNT);
VERIFY_RENAMED_FEATURE_CHECK(ProtectedResourceSessionTypeCount, Count, 0);
}
// 34: Session Types
for (UINT NodeId = 0; NodeId < NodeCount; NodeId++)
{
std::vector<GUID> ProtectedResourceSessionTypes = features.ProtectedResourceSessionTypes(NodeId);
D3D12_FEATURE_DATA_PROTECTED_RESOURCE_SESSION_TYPE_COUNT CountData;
CountData.NodeIndex = NodeId;
if (FAILED(device->CheckFeatureSupport(D3D12_FEATURE_PROTECTED_RESOURCE_SESSION_TYPE_COUNT, &CountData, sizeof(D3D12_FEATURE_DATA_PROTECTED_RESOURCE_SESSION_TYPE_COUNT))))
{
if (ProtectedResourceSessionTypes.size() != 0)
{
std::cout << "Error: Wrong result from Protected Resource Session Types on Node " << NodeId << std::endl
<< "Type count check failed but types vector is not empty\n";
return -1;
}
continue;
}
if (CountData.Count != ProtectedResourceSessionTypes.size())
{
std::cout << "Error: Wrong result from Protected Resource Session Types on Node " << NodeId << std::endl
<< "Types vector size does not equal type count\n";
return -1;
}
D3D12_FEATURE_DATA_PROTECTED_RESOURCE_SESSION_TYPES Data;
Data.NodeIndex = NodeId;
Data.Count = CountData.Count;
Data.pTypes = new GUID[Data.Count];
INITIALIZE_FEATURE_SUPPORT_DATA(PROTECTED_RESOURCE_SESSION_TYPES);
if (SUCCEEDED(InitResult))
{
for (unsigned int i = 0; i < Data.Count; i++)
{
if (ProtectedResourceSessionTypes[i] != Data.pTypes[i])
{
std::cout << "Error: Result mismatch from Proteted Resource Session Types\n"
<< "Node Index: " << NodeId << std::endl
<< "Type Index: " << i << std::endl;
return -1;
}
}
}
}
// 36: Options8
{
BOOL UnalignedBlockTexturesSupported = features.UnalignedBlockTexturesSupported();
D3D12_FEATURE_DATA_D3D12_OPTIONS8 Data;
INITIALIZE_FEATURE_SUPPORT_DATA(D3D12_OPTIONS8);
VERIFY_FEATURE_CHECK(UnalignedBlockTexturesSupported, false);
}
// 37: Options9
{
BOOL MeshShaderPipelineStatsSupported = features.MeshShaderPipelineStatsSupported();
BOOL MeshShaderSupportsFullRangeRenderTargetArrayIndex = features.MeshShaderSupportsFullRangeRenderTargetArrayIndex();
D3D12_WAVE_MMA_TIER WaveMMATier = features.WaveMMATier();
D3D12_FEATURE_DATA_D3D12_OPTIONS9 Data;
INITIALIZE_FEATURE_SUPPORT_DATA(D3D12_OPTIONS9);
VERIFY_FEATURE_CHECK(MeshShaderPipelineStatsSupported, false);
VERIFY_FEATURE_CHECK(MeshShaderSupportsFullRangeRenderTargetArrayIndex, false);
VERIFY_FEATURE_CHECK(WaveMMATier, D3D12_WAVE_MMA_TIER_NOT_SUPPORTED);
}
// 39: Options10
{
BOOL VariableRateShadingSumCombinerSupported = features.VariableRateShadingSumCombinerSupported();
BOOL MeshShaderPerPrimitiveShadingRateSupported = features.MeshShaderPerPrimitiveShadingRateSupported();
D3D12_FEATURE_DATA_D3D12_OPTIONS10 Data;
INITIALIZE_FEATURE_SUPPORT_DATA(D3D12_OPTIONS10);
VERIFY_FEATURE_CHECK(VariableRateShadingSumCombinerSupported, false);
VERIFY_FEATURE_CHECK(MeshShaderPerPrimitiveShadingRateSupported, false);
}
// 40: Options11
{
BOOL AtomicInt64OnDescriptorHeapResourceSupported = features.AtomicInt64OnDescriptorHeapResourceSupported();
D3D12_FEATURE_DATA_D3D12_OPTIONS11 Data;
INITIALIZE_FEATURE_SUPPORT_DATA(D3D12_OPTIONS11);
VERIFY_FEATURE_CHECK(AtomicInt64OnDescriptorHeapResourceSupported, false);
}
std::cout << "Test completed with no errors." << std::endl;
return 0;
}