2022-09-03 22:45:58 +02:00
|
|
|
#include <array>
|
|
|
|
|
|
|
|
#include "d3d11_features.h"
|
|
|
|
|
|
|
|
namespace dxvk {
|
|
|
|
|
|
|
|
D3D11DeviceFeatures::D3D11DeviceFeatures() {
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
D3D11DeviceFeatures::D3D11DeviceFeatures(
|
|
|
|
const Rc<DxvkInstance>& Instance,
|
|
|
|
const Rc<DxvkAdapter>& Adapter,
|
|
|
|
D3D_FEATURE_LEVEL FeatureLevel)
|
|
|
|
: m_features (Adapter->features()),
|
|
|
|
m_properties (Adapter->devicePropertiesExt()) {
|
|
|
|
// Assume no TBDR. DXVK does not optimize for TBDR architectures
|
|
|
|
// anyway, and D3D11 does not really provide meaningful support.
|
|
|
|
m_architectureInfo.TileBasedDeferredRenderer = FALSE;
|
|
|
|
|
|
|
|
// D3D9 options. We unconditionally support all of these.
|
|
|
|
m_d3d9Options.FullNonPow2TextureSupport = TRUE;
|
|
|
|
|
|
|
|
m_d3d9Options1.FullNonPow2TextureSupported = TRUE;
|
|
|
|
m_d3d9Options1.DepthAsTextureWithLessEqualComparisonFilterSupported = TRUE;
|
|
|
|
m_d3d9Options1.SimpleInstancingSupported = TRUE;
|
|
|
|
m_d3d9Options1.TextureCubeFaceRenderTargetWithNonCubeDepthStencilSupported = TRUE;
|
|
|
|
|
|
|
|
m_d3d9Shadow.SupportsDepthAsTextureWithLessEqualComparisonFilter = TRUE;
|
|
|
|
|
|
|
|
m_d3d9SimpleInstancing.SimpleInstancingSupported = TRUE;
|
|
|
|
|
|
|
|
// D3D10 options. We unconditionally support compute shaders.
|
|
|
|
m_d3d10Options.ComputeShaders_Plus_RawAndStructuredBuffers_Via_Shader_4_x = TRUE;
|
|
|
|
|
|
|
|
// D3D11.1 options. All of these are required for Feature Level 11_1.
|
2022-09-11 16:03:57 +02:00
|
|
|
auto sharedResourceTier = DetermineSharedResourceTier(Adapter, FeatureLevel);
|
|
|
|
|
2022-09-03 22:45:58 +02:00
|
|
|
bool hasDoublePrecisionSupport = m_features.core.features.shaderFloat64
|
|
|
|
&& m_features.core.features.shaderInt64;
|
|
|
|
|
|
|
|
m_d3d11Options.DiscardAPIsSeenByDriver = TRUE;
|
|
|
|
m_d3d11Options.FlagsForUpdateAndCopySeenByDriver = TRUE;
|
|
|
|
m_d3d11Options.ClearView = TRUE;
|
|
|
|
m_d3d11Options.CopyWithOverlap = TRUE;
|
|
|
|
m_d3d11Options.ConstantBufferPartialUpdate = TRUE;
|
|
|
|
m_d3d11Options.ConstantBufferOffsetting = TRUE;
|
|
|
|
m_d3d11Options.MapNoOverwriteOnDynamicConstantBuffer = TRUE;
|
|
|
|
m_d3d11Options.MapNoOverwriteOnDynamicBufferSRV = TRUE;
|
2022-09-11 16:03:57 +02:00
|
|
|
m_d3d11Options.ExtendedResourceSharing = sharedResourceTier > D3D11_SHARED_RESOURCE_TIER_0;
|
2022-09-03 22:45:58 +02:00
|
|
|
|
|
|
|
if (FeatureLevel >= D3D_FEATURE_LEVEL_10_0) {
|
|
|
|
m_d3d11Options.OutputMergerLogicOp = m_features.core.features.logicOp;
|
|
|
|
m_d3d11Options.MultisampleRTVWithForcedSampleCountOne = TRUE; // Not really
|
|
|
|
}
|
|
|
|
|
|
|
|
if (FeatureLevel >= D3D_FEATURE_LEVEL_11_0) {
|
|
|
|
m_d3d11Options.UAVOnlyRenderingForcedSampleCount = TRUE;
|
|
|
|
m_d3d11Options.SAD4ShaderInstructions = TRUE;
|
|
|
|
m_d3d11Options.ExtendedDoublesShaderInstructions = hasDoublePrecisionSupport;
|
|
|
|
}
|
|
|
|
|
|
|
|
// D3D11.2 options.
|
|
|
|
auto tiledResourcesTier = DetermineTiledResourcesTier(FeatureLevel);
|
|
|
|
m_d3d11Options1.TiledResourcesTier = tiledResourcesTier;
|
|
|
|
m_d3d11Options1.MinMaxFiltering = tiledResourcesTier >= D3D11_TILED_RESOURCES_TIER_2;
|
|
|
|
m_d3d11Options1.ClearViewAlsoSupportsDepthOnlyFormats = TRUE;
|
|
|
|
|
|
|
|
if (FeatureLevel >= D3D_FEATURE_LEVEL_11_0)
|
|
|
|
m_d3d11Options1.MapOnDefaultBuffers = TRUE;
|
|
|
|
|
|
|
|
// D3D11.3 options
|
|
|
|
m_d3d11Options2.TypedUAVLoadAdditionalFormats = DetermineUavExtendedTypedLoadSupport(Adapter, FeatureLevel);
|
|
|
|
m_d3d11Options2.ConservativeRasterizationTier = DetermineConservativeRasterizationTier(FeatureLevel);
|
|
|
|
m_d3d11Options2.TiledResourcesTier = tiledResourcesTier;
|
|
|
|
m_d3d11Options2.StandardSwizzle = FALSE;
|
|
|
|
m_d3d11Options2.UnifiedMemoryArchitecture = FALSE;
|
|
|
|
|
|
|
|
if (FeatureLevel >= D3D_FEATURE_LEVEL_11_0)
|
|
|
|
m_d3d11Options2.MapOnDefaultTextures = TRUE;
|
|
|
|
|
|
|
|
if (FeatureLevel >= D3D_FEATURE_LEVEL_11_1) {
|
|
|
|
m_d3d11Options2.ROVsSupported = FALSE;
|
|
|
|
m_d3d11Options2.PSSpecifiedStencilRefSupported = m_features.extShaderStencilExport;
|
|
|
|
}
|
|
|
|
|
|
|
|
// More D3D11.3 options
|
|
|
|
if (FeatureLevel >= D3D_FEATURE_LEVEL_11_0) {
|
|
|
|
m_d3d11Options3.VPAndRTArrayIndexFromAnyShaderFeedingRasterizer =
|
|
|
|
m_features.vk12.shaderOutputViewportIndex &&
|
|
|
|
m_features.vk12.shaderOutputLayer;
|
|
|
|
}
|
|
|
|
|
|
|
|
// D3D11.4 options
|
2022-09-11 16:03:57 +02:00
|
|
|
m_d3d11Options4.ExtendedNV12SharedTextureSupported = sharedResourceTier > D3D11_SHARED_RESOURCE_TIER_0;
|
2022-09-03 22:45:58 +02:00
|
|
|
|
|
|
|
// More D3D11.4 options
|
2022-09-11 16:03:57 +02:00
|
|
|
m_d3d11Options5.SharedResourceTier = sharedResourceTier;
|
2022-09-03 22:45:58 +02:00
|
|
|
|
|
|
|
// Double-precision support
|
|
|
|
if (FeatureLevel >= D3D_FEATURE_LEVEL_11_0)
|
|
|
|
m_doubles.DoublePrecisionFloatShaderOps = hasDoublePrecisionSupport;
|
|
|
|
|
|
|
|
// These numbers are not accurate, but we have no real way to query these
|
|
|
|
m_gpuVirtualAddress.MaxGPUVirtualAddressBitsPerResource = 32;
|
|
|
|
m_gpuVirtualAddress.MaxGPUVirtualAddressBitsPerProcess = 40;
|
|
|
|
|
|
|
|
// Marker support only depends on the debug utils extension
|
|
|
|
m_marker.Profile = Instance->extensions().extDebugUtils;
|
|
|
|
|
|
|
|
// DXVK will keep all shaders in memory once created, and all Vulkan
|
|
|
|
// drivers that we know of that can run DXVK have an on-disk cache.
|
|
|
|
m_shaderCache.SupportFlags = D3D11_SHADER_CACHE_SUPPORT_AUTOMATIC_INPROC_CACHE
|
|
|
|
| D3D11_SHADER_CACHE_SUPPORT_AUTOMATIC_DISK_CACHE;
|
|
|
|
|
|
|
|
// DXVK does not support min precision
|
|
|
|
m_shaderMinPrecision.PixelShaderMinPrecision = 0;
|
|
|
|
m_shaderMinPrecision.AllOtherShaderStagesMinPrecision = 0;
|
|
|
|
|
|
|
|
// Report native support for command lists here so that we do not actually have
|
|
|
|
// to re-implement the UpdateSubresource bug from the D3D11 runtime, see MSDN:
|
|
|
|
// https://msdn.microsoft.com/en-us/library/windows/desktop/ff476486(v=vs.85).aspx)
|
|
|
|
m_threading.DriverConcurrentCreates = TRUE;
|
|
|
|
m_threading.DriverCommandLists = TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
D3D11DeviceFeatures::~D3D11DeviceFeatures() {
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
HRESULT D3D11DeviceFeatures::GetFeatureData(
|
|
|
|
D3D11_FEATURE Feature,
|
|
|
|
UINT FeatureDataSize,
|
|
|
|
void* pFeatureData) const {
|
|
|
|
switch (Feature) {
|
|
|
|
case D3D11_FEATURE_ARCHITECTURE_INFO:
|
|
|
|
return GetTypedFeatureData(FeatureDataSize, pFeatureData, &m_architectureInfo);
|
|
|
|
case D3D11_FEATURE_D3D9_OPTIONS:
|
|
|
|
return GetTypedFeatureData(FeatureDataSize, pFeatureData, &m_d3d9Options);
|
|
|
|
case D3D11_FEATURE_D3D9_OPTIONS1:
|
|
|
|
return GetTypedFeatureData(FeatureDataSize, pFeatureData, &m_d3d9Options1);
|
|
|
|
case D3D11_FEATURE_D3D9_SHADOW_SUPPORT:
|
|
|
|
return GetTypedFeatureData(FeatureDataSize, pFeatureData, &m_d3d9Shadow);
|
|
|
|
case D3D11_FEATURE_D3D9_SIMPLE_INSTANCING_SUPPORT:
|
|
|
|
return GetTypedFeatureData(FeatureDataSize, pFeatureData, &m_d3d9SimpleInstancing);
|
|
|
|
case D3D11_FEATURE_D3D10_X_HARDWARE_OPTIONS:
|
|
|
|
return GetTypedFeatureData(FeatureDataSize, pFeatureData, &m_d3d10Options);
|
|
|
|
case D3D11_FEATURE_D3D11_OPTIONS:
|
|
|
|
return GetTypedFeatureData(FeatureDataSize, pFeatureData, &m_d3d11Options);
|
|
|
|
case D3D11_FEATURE_D3D11_OPTIONS1:
|
|
|
|
return GetTypedFeatureData(FeatureDataSize, pFeatureData, &m_d3d11Options1);
|
|
|
|
case D3D11_FEATURE_D3D11_OPTIONS2:
|
|
|
|
return GetTypedFeatureData(FeatureDataSize, pFeatureData, &m_d3d11Options2);
|
|
|
|
case D3D11_FEATURE_D3D11_OPTIONS3:
|
|
|
|
return GetTypedFeatureData(FeatureDataSize, pFeatureData, &m_d3d11Options3);
|
|
|
|
case D3D11_FEATURE_D3D11_OPTIONS4:
|
|
|
|
return GetTypedFeatureData(FeatureDataSize, pFeatureData, &m_d3d11Options4);
|
|
|
|
case D3D11_FEATURE_D3D11_OPTIONS5:
|
|
|
|
return GetTypedFeatureData(FeatureDataSize, pFeatureData, &m_d3d11Options5);
|
|
|
|
case D3D11_FEATURE_DOUBLES:
|
|
|
|
return GetTypedFeatureData(FeatureDataSize, pFeatureData, &m_doubles);
|
|
|
|
case D3D11_FEATURE_GPU_VIRTUAL_ADDRESS_SUPPORT:
|
|
|
|
return GetTypedFeatureData(FeatureDataSize, pFeatureData, &m_gpuVirtualAddress);
|
|
|
|
case D3D11_FEATURE_MARKER_SUPPORT:
|
|
|
|
return GetTypedFeatureData(FeatureDataSize, pFeatureData, &m_marker);
|
|
|
|
case D3D11_FEATURE_SHADER_CACHE:
|
|
|
|
return GetTypedFeatureData(FeatureDataSize, pFeatureData, &m_shaderCache);
|
|
|
|
case D3D11_FEATURE_SHADER_MIN_PRECISION_SUPPORT:
|
|
|
|
return GetTypedFeatureData(FeatureDataSize, pFeatureData, &m_shaderMinPrecision);
|
|
|
|
case D3D11_FEATURE_THREADING:
|
|
|
|
return GetTypedFeatureData(FeatureDataSize, pFeatureData, &m_threading);
|
|
|
|
default:
|
|
|
|
Logger::err(str::format("D3D11: Unknown feature: ", Feature));
|
|
|
|
return E_INVALIDARG;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-09-03 23:39:51 +02:00
|
|
|
D3D_FEATURE_LEVEL D3D11DeviceFeatures::GetMaxFeatureLevel(
|
|
|
|
const Rc<DxvkInstance>& Instance,
|
|
|
|
const Rc<DxvkAdapter>& Adapter) {
|
|
|
|
D3D11DeviceFeatures features(Instance, Adapter, D3D_FEATURE_LEVEL_12_1);
|
|
|
|
return features.GetMaxFeatureLevel();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-09-03 22:45:58 +02:00
|
|
|
D3D11_CONSERVATIVE_RASTERIZATION_TIER D3D11DeviceFeatures::DetermineConservativeRasterizationTier(
|
|
|
|
D3D_FEATURE_LEVEL FeatureLevel) {
|
|
|
|
if (FeatureLevel < D3D_FEATURE_LEVEL_11_1
|
|
|
|
|| !m_features.extConservativeRasterization)
|
|
|
|
return D3D11_CONSERVATIVE_RASTERIZATION_NOT_SUPPORTED;
|
|
|
|
|
|
|
|
// We don't really have a way to query uncertainty regions,
|
|
|
|
// so just check degenerate triangle behaviour
|
|
|
|
if (!m_properties.extConservativeRasterization.degenerateTrianglesRasterized)
|
|
|
|
return D3D11_CONSERVATIVE_RASTERIZATION_TIER_1;
|
|
|
|
|
2022-09-05 07:27:00 +02:00
|
|
|
// Inner coverage is required for Tier 3 support
|
|
|
|
if (!m_properties.extConservativeRasterization.fullyCoveredFragmentShaderInputVariable)
|
|
|
|
return D3D11_CONSERVATIVE_RASTERIZATION_TIER_2;
|
|
|
|
|
|
|
|
return D3D11_CONSERVATIVE_RASTERIZATION_TIER_3;
|
2022-09-03 22:45:58 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
D3D11_SHARED_RESOURCE_TIER D3D11DeviceFeatures::DetermineSharedResourceTier(
|
2022-09-11 16:03:57 +02:00
|
|
|
const Rc<DxvkAdapter>& Adapter,
|
2022-09-03 22:45:58 +02:00
|
|
|
D3D_FEATURE_LEVEL FeatureLevel) {
|
2022-09-11 16:03:57 +02:00
|
|
|
static std::atomic<bool> s_errorShown = { false };
|
|
|
|
|
|
|
|
// Lie about supporting Tier 1 since that's the
|
|
|
|
// minimum required tier for Feature Level 11_1
|
|
|
|
if (!Adapter->features().khrExternalMemoryWin32) {
|
|
|
|
if (!s_errorShown.exchange(true))
|
|
|
|
Logger::warn("D3D11DeviceFeatures: External memory features not supported");
|
|
|
|
|
|
|
|
return D3D11_SHARED_RESOURCE_TIER_1;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Check support for extended formats. Ignore multi-plane
|
|
|
|
// formats here since driver support varies too much.
|
|
|
|
std::array<VkFormat, 30> requiredFormats = {{
|
|
|
|
VK_FORMAT_R16G16B16A16_SFLOAT,
|
|
|
|
VK_FORMAT_R32G32B32A32_SFLOAT,
|
|
|
|
VK_FORMAT_R32G32B32A32_UINT,
|
|
|
|
VK_FORMAT_R32G32B32A32_SINT,
|
|
|
|
VK_FORMAT_R16G16B16A16_SFLOAT,
|
|
|
|
VK_FORMAT_R16G16B16A16_UNORM,
|
|
|
|
VK_FORMAT_R16G16B16A16_UINT,
|
|
|
|
VK_FORMAT_R16G16B16A16_SNORM,
|
|
|
|
VK_FORMAT_R16G16B16A16_SINT,
|
|
|
|
VK_FORMAT_A2B10G10R10_UNORM_PACK32,
|
|
|
|
VK_FORMAT_A2B10G10R10_UINT_PACK32,
|
|
|
|
VK_FORMAT_R8G8B8A8_UNORM,
|
|
|
|
VK_FORMAT_R8G8B8A8_SRGB,
|
|
|
|
VK_FORMAT_R8G8B8A8_UINT,
|
|
|
|
VK_FORMAT_R8G8B8A8_SNORM,
|
|
|
|
VK_FORMAT_R8G8B8A8_SINT,
|
|
|
|
VK_FORMAT_B8G8R8A8_UNORM,
|
|
|
|
VK_FORMAT_B8G8R8A8_SRGB,
|
|
|
|
VK_FORMAT_R32_SFLOAT,
|
|
|
|
VK_FORMAT_R32_UINT,
|
|
|
|
VK_FORMAT_R32_SINT,
|
|
|
|
VK_FORMAT_R16_SFLOAT,
|
|
|
|
VK_FORMAT_R16_UNORM,
|
|
|
|
VK_FORMAT_R16_UINT,
|
|
|
|
VK_FORMAT_R16_SNORM,
|
|
|
|
VK_FORMAT_R16_SINT,
|
|
|
|
VK_FORMAT_R8_UNORM,
|
|
|
|
VK_FORMAT_R8_UINT,
|
|
|
|
VK_FORMAT_R8_SNORM,
|
|
|
|
VK_FORMAT_R8_SINT,
|
|
|
|
}};
|
|
|
|
|
|
|
|
bool allKmtHandlesSupported = true;
|
|
|
|
bool allNtHandlesSupported = true;
|
|
|
|
|
|
|
|
for (auto f : requiredFormats) {
|
|
|
|
allKmtHandlesSupported &= CheckFormatSharingSupport(Adapter, f, VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT);
|
|
|
|
allNtHandlesSupported &= CheckFormatSharingSupport(Adapter, f, VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Again, lie about at least tier 1 support
|
|
|
|
if (!allKmtHandlesSupported) {
|
|
|
|
if (!s_errorShown.exchange(true))
|
|
|
|
Logger::warn("D3D11DeviceFeatures: Some formats not supported for resource sharing");
|
|
|
|
return D3D11_SHARED_RESOURCE_TIER_1;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Tier 2 requires all the above formats to be shareable
|
|
|
|
// with NT handles in order to support D3D12 interop
|
|
|
|
if (!allNtHandlesSupported)
|
|
|
|
return D3D11_SHARED_RESOURCE_TIER_1;
|
|
|
|
|
|
|
|
// Tier 3 additionally requires R11G11B10 to be
|
|
|
|
// shareable with D3D12
|
|
|
|
if (!CheckFormatSharingSupport(Adapter, VK_FORMAT_B10G11R11_UFLOAT_PACK32, VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT))
|
|
|
|
return D3D11_SHARED_RESOURCE_TIER_2;
|
|
|
|
|
|
|
|
return D3D11_SHARED_RESOURCE_TIER_3;
|
2022-09-03 22:45:58 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
D3D11_TILED_RESOURCES_TIER D3D11DeviceFeatures::DetermineTiledResourcesTier(
|
|
|
|
D3D_FEATURE_LEVEL FeatureLevel) {
|
|
|
|
if (FeatureLevel < D3D_FEATURE_LEVEL_11_0
|
|
|
|
|| !m_features.core.features.sparseBinding
|
|
|
|
|| !m_features.core.features.sparseResidencyBuffer
|
|
|
|
|| !m_features.core.features.sparseResidencyImage2D
|
|
|
|
|| !m_features.core.features.sparseResidencyAliased
|
|
|
|
|| !m_properties.core.properties.sparseProperties.residencyStandard2DBlockShape)
|
|
|
|
return D3D11_TILED_RESOURCES_NOT_SUPPORTED;
|
|
|
|
|
|
|
|
if (FeatureLevel < D3D_FEATURE_LEVEL_11_1
|
|
|
|
|| !m_features.core.features.shaderResourceResidency
|
|
|
|
|| !m_features.core.features.shaderResourceMinLod
|
|
|
|
|| !m_features.vk12.samplerFilterMinmax
|
|
|
|
|| !m_properties.vk12.filterMinmaxSingleComponentFormats
|
|
|
|
|| !m_properties.core.properties.sparseProperties.residencyNonResidentStrict
|
|
|
|
|| m_properties.core.properties.sparseProperties.residencyAlignedMipSize)
|
|
|
|
return D3D11_TILED_RESOURCES_TIER_1;
|
|
|
|
|
2022-09-10 14:25:45 +02:00
|
|
|
if (!m_features.core.features.sparseResidencyImage3D
|
|
|
|
|| !m_properties.core.properties.sparseProperties.residencyStandard3DBlockShape)
|
|
|
|
return D3D11_TILED_RESOURCES_TIER_2;
|
|
|
|
|
|
|
|
return D3D11_TILED_RESOURCES_TIER_3;
|
2022-09-03 22:45:58 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
BOOL D3D11DeviceFeatures::DetermineUavExtendedTypedLoadSupport(
|
|
|
|
const Rc<DxvkAdapter>& Adapter,
|
|
|
|
D3D_FEATURE_LEVEL FeatureLevel) {
|
|
|
|
static const std::array<VkFormat, 18> s_formats = {{
|
|
|
|
VK_FORMAT_R32_SFLOAT,
|
|
|
|
VK_FORMAT_R32_UINT,
|
|
|
|
VK_FORMAT_R32_SINT,
|
|
|
|
VK_FORMAT_R32G32B32A32_SFLOAT,
|
|
|
|
VK_FORMAT_R32G32B32A32_UINT,
|
|
|
|
VK_FORMAT_R32G32B32A32_SINT,
|
|
|
|
VK_FORMAT_R16G16B16A16_SFLOAT,
|
|
|
|
VK_FORMAT_R16G16B16A16_UINT,
|
|
|
|
VK_FORMAT_R16G16B16A16_SINT,
|
|
|
|
VK_FORMAT_R8G8B8A8_UNORM,
|
|
|
|
VK_FORMAT_R8G8B8A8_UINT,
|
|
|
|
VK_FORMAT_R8G8B8A8_SINT,
|
|
|
|
VK_FORMAT_R16_SFLOAT,
|
|
|
|
VK_FORMAT_R16_UINT,
|
|
|
|
VK_FORMAT_R16_SINT,
|
|
|
|
VK_FORMAT_R8_UNORM,
|
|
|
|
VK_FORMAT_R8_UINT,
|
|
|
|
VK_FORMAT_R8_SINT,
|
|
|
|
}};
|
|
|
|
|
|
|
|
if (FeatureLevel < D3D_FEATURE_LEVEL_11_0)
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
for (auto f : s_formats) {
|
|
|
|
DxvkFormatFeatures features = Adapter->getFormatFeatures(f);
|
|
|
|
VkFormatFeatureFlags2 imgFeatures = features.optimal | features.linear;
|
|
|
|
|
|
|
|
if (!(imgFeatures & VK_FORMAT_FEATURE_2_STORAGE_READ_WITHOUT_FORMAT_BIT))
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
2022-09-03 23:39:51 +02:00
|
|
|
|
2022-09-11 16:03:57 +02:00
|
|
|
BOOL D3D11DeviceFeatures::CheckFormatSharingSupport(
|
|
|
|
const Rc<DxvkAdapter>& Adapter,
|
|
|
|
VkFormat Format,
|
|
|
|
VkExternalMemoryHandleTypeFlagBits HandleType) {
|
|
|
|
DxvkFormatQuery query = { };
|
|
|
|
query.format = Format;
|
|
|
|
query.type = VK_IMAGE_TYPE_2D;
|
|
|
|
query.tiling = VK_IMAGE_TILING_OPTIMAL;
|
|
|
|
query.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
|
|
|
|
query.handleType = HandleType;
|
|
|
|
|
|
|
|
constexpr VkExternalMemoryFeatureFlags featureMask
|
|
|
|
= VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT
|
|
|
|
| VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT;
|
|
|
|
|
|
|
|
auto limits = Adapter->getFormatLimits(query);
|
|
|
|
return limits && (limits->externalFeatures & featureMask);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-09-03 23:39:51 +02:00
|
|
|
D3D_FEATURE_LEVEL D3D11DeviceFeatures::GetMaxFeatureLevel() const {
|
|
|
|
// Check Feature Level 11_0 features
|
|
|
|
if (!m_features.core.features.drawIndirectFirstInstance
|
|
|
|
|| !m_features.core.features.fragmentStoresAndAtomics
|
|
|
|
|| !m_features.core.features.multiDrawIndirect
|
|
|
|
|| !m_features.core.features.tessellationShader)
|
|
|
|
return D3D_FEATURE_LEVEL_10_1;
|
|
|
|
|
|
|
|
// Check Feature Level 11_1 features
|
|
|
|
if (!m_d3d11Options.OutputMergerLogicOp
|
|
|
|
|| !m_features.core.features.vertexPipelineStoresAndAtomics)
|
|
|
|
return D3D_FEATURE_LEVEL_11_0;
|
|
|
|
|
|
|
|
// Check Feature Level 12_0 features
|
|
|
|
if (m_d3d11Options2.TiledResourcesTier < D3D11_TILED_RESOURCES_TIER_2
|
|
|
|
|| !m_d3d11Options2.TypedUAVLoadAdditionalFormats)
|
|
|
|
return D3D_FEATURE_LEVEL_11_1;
|
|
|
|
|
|
|
|
// Check Feature Level 12_1 features
|
|
|
|
if (!m_d3d11Options2.ConservativeRasterizationTier
|
|
|
|
|| !m_d3d11Options2.ROVsSupported)
|
|
|
|
return D3D_FEATURE_LEVEL_12_0;
|
|
|
|
|
|
|
|
return D3D_FEATURE_LEVEL_12_1;
|
|
|
|
}
|
|
|
|
|
2022-09-03 22:45:58 +02:00
|
|
|
}
|