mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-01-18 11:52:12 +01:00
[d3d11] Introduce D3D11DeviceFeatures
This commit is contained in:
parent
5490aa936b
commit
71d6e8f849
268
src/d3d11/d3d11_features.cpp
Normal file
268
src/d3d11/d3d11_features.cpp
Normal file
@ -0,0 +1,268 @@
|
||||
#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.
|
||||
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;
|
||||
m_d3d11Options.ExtendedResourceSharing = TRUE;
|
||||
|
||||
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
|
||||
m_d3d11Options4.ExtendedNV12SharedTextureSupported = TRUE;
|
||||
|
||||
// More D3D11.4 options
|
||||
m_d3d11Options5.SharedResourceTier = DetermineSharedResourceTier(FeatureLevel);
|
||||
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
|
||||
return D3D11_CONSERVATIVE_RASTERIZATION_TIER_2;
|
||||
}
|
||||
|
||||
|
||||
D3D11_SHARED_RESOURCE_TIER D3D11DeviceFeatures::DetermineSharedResourceTier(
|
||||
D3D_FEATURE_LEVEL FeatureLevel) {
|
||||
// Shared resources are all sorts of wonky for obvious
|
||||
// reasons, so don't over-promise things here for now
|
||||
return D3D11_SHARED_RESOURCE_TIER_1;
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
|
||||
if (!m_features.core.features.sparseResidencyImage3D
|
||||
|| !m_properties.core.properties.sparseProperties.residencyStandard3DBlockShape)
|
||||
return D3D11_TILED_RESOURCES_TIER_2;
|
||||
|
||||
return D3D11_TILED_RESOURCES_TIER_3;
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
89
src/d3d11/d3d11_features.h
Normal file
89
src/d3d11/d3d11_features.h
Normal file
@ -0,0 +1,89 @@
|
||||
#pragma once
|
||||
|
||||
#include "d3d11_include.h"
|
||||
|
||||
#include "../dxvk/dxvk_adapter.h"
|
||||
#include "../dxvk/dxvk_instance.h"
|
||||
|
||||
namespace dxvk {
|
||||
|
||||
/**
|
||||
* \brief Device features
|
||||
*
|
||||
* Stores D3D device feature structs.
|
||||
*/
|
||||
class D3D11DeviceFeatures {
|
||||
|
||||
public:
|
||||
|
||||
D3D11DeviceFeatures();
|
||||
|
||||
D3D11DeviceFeatures(
|
||||
const Rc<DxvkInstance>& Instance,
|
||||
const Rc<DxvkAdapter>& Adapter,
|
||||
D3D_FEATURE_LEVEL FeatureLevel);
|
||||
|
||||
~D3D11DeviceFeatures();
|
||||
|
||||
/**
|
||||
* \brief Retrieves feature support data
|
||||
*
|
||||
* \param [in] Feature D3D feature to query
|
||||
* \param [in] FeatureDataSize Data size, in bytes
|
||||
* \param [out] pFeatureData Data
|
||||
* \returns Status of the operation
|
||||
*/
|
||||
HRESULT GetFeatureData(
|
||||
D3D11_FEATURE Feature,
|
||||
UINT FeatureDataSize,
|
||||
void* pFeatureData) const;
|
||||
|
||||
private:
|
||||
|
||||
DxvkDeviceFeatures m_features;
|
||||
DxvkDeviceInfo m_properties;
|
||||
|
||||
D3D11_FEATURE_DATA_ARCHITECTURE_INFO m_architectureInfo = { };
|
||||
D3D11_FEATURE_DATA_D3D9_OPTIONS m_d3d9Options = { };
|
||||
D3D11_FEATURE_DATA_D3D9_OPTIONS1 m_d3d9Options1 = { };
|
||||
D3D11_FEATURE_DATA_D3D9_SHADOW_SUPPORT m_d3d9Shadow = { };
|
||||
D3D11_FEATURE_DATA_D3D9_SIMPLE_INSTANCING_SUPPORT m_d3d9SimpleInstancing = { };
|
||||
D3D11_FEATURE_DATA_D3D10_X_HARDWARE_OPTIONS m_d3d10Options = { };
|
||||
D3D11_FEATURE_DATA_D3D11_OPTIONS m_d3d11Options = { };
|
||||
D3D11_FEATURE_DATA_D3D11_OPTIONS1 m_d3d11Options1 = { };
|
||||
D3D11_FEATURE_DATA_D3D11_OPTIONS2 m_d3d11Options2 = { };
|
||||
D3D11_FEATURE_DATA_D3D11_OPTIONS3 m_d3d11Options3 = { };
|
||||
D3D11_FEATURE_DATA_D3D11_OPTIONS4 m_d3d11Options4 = { };
|
||||
D3D11_FEATURE_DATA_D3D11_OPTIONS5 m_d3d11Options5 = { };
|
||||
D3D11_FEATURE_DATA_DOUBLES m_doubles = { };
|
||||
D3D11_FEATURE_DATA_GPU_VIRTUAL_ADDRESS_SUPPORT m_gpuVirtualAddress = { };
|
||||
D3D11_FEATURE_DATA_MARKER_SUPPORT m_marker = { };
|
||||
D3D11_FEATURE_DATA_SHADER_CACHE m_shaderCache = { };
|
||||
D3D11_FEATURE_DATA_SHADER_MIN_PRECISION_SUPPORT m_shaderMinPrecision = { };
|
||||
D3D11_FEATURE_DATA_THREADING m_threading = { };
|
||||
|
||||
template<typename T>
|
||||
static HRESULT GetTypedFeatureData(UINT Size, void* pDstData, const T* pSrcData) {
|
||||
if (Size != sizeof(T))
|
||||
return E_INVALIDARG;
|
||||
|
||||
*(reinterpret_cast<T*>(pDstData)) = *pSrcData;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
D3D11_CONSERVATIVE_RASTERIZATION_TIER DetermineConservativeRasterizationTier(
|
||||
D3D_FEATURE_LEVEL FeatureLevel);
|
||||
|
||||
D3D11_SHARED_RESOURCE_TIER DetermineSharedResourceTier(
|
||||
D3D_FEATURE_LEVEL FeatureLevel);
|
||||
|
||||
D3D11_TILED_RESOURCES_TIER DetermineTiledResourcesTier(
|
||||
D3D_FEATURE_LEVEL FeatureLevel);
|
||||
|
||||
BOOL DetermineUavExtendedTypedLoadSupport(
|
||||
const Rc<DxvkAdapter>& Adapter,
|
||||
D3D_FEATURE_LEVEL FeatureLevel);
|
||||
|
||||
};
|
||||
|
||||
}
|
@ -37,6 +37,7 @@ d3d11_src = [
|
||||
'd3d11_depth_stencil.cpp',
|
||||
'd3d11_device.cpp',
|
||||
'd3d11_enums.cpp',
|
||||
'd3d11_features.cpp',
|
||||
'd3d11_fence.cpp',
|
||||
'd3d11_gdi.cpp',
|
||||
'd3d11_initializer.cpp',
|
||||
|
Loading…
x
Reference in New Issue
Block a user