Some games, e.g. Hitman 2, do not check for success, and if the feature
check is unimplemented they will use uninitialised data for the result.
Signed-off-by: Conor McCarthy <cmccarthy(a)codeweavers.com>
---
v3: Report FALSE for Native16BitShaderOpsSupported.
Supersedes 174444.
---
include/vkd3d_d3d12.idl | 141 +++++++++++++++++++
libs/vkd3d/device.c | 279 +++++++++++++++++++++++++++++++++++++
libs/vkd3d/vkd3d_private.h | 5 +
3 files changed, 425 insertions(+)
diff --git a/include/vkd3d_d3d12.idl b/include/vkd3d_d3d12.idl
index ec8b83d..e4d5454 100644
--- a/include/vkd3d_d3d12.idl
+++ b/include/vkd3d_d3d12.idl
@@ -1608,6 +1608,141 @@ typedef struct D3D12_FEATURE_DATA_SHADER_MODEL
D3D_SHADER_MODEL HighestShaderModel;
} D3D12_FEATURE_DATA_SHADER_MODEL;
+typedef struct D3D12_FEATURE_DATA_D3D12_OPTIONS1
+{
+ BOOL WaveOps;
+ UINT WaveLaneCountMin;
+ UINT WaveLaneCountMax;
+ UINT TotalLaneCount;
+ BOOL ExpandedComputeResourceStates;
+ BOOL Int64ShaderOps;
+} D3D12_FEATURE_DATA_D3D12_OPTIONS1;
+
+typedef enum D3D12_PROGRAMMABLE_SAMPLE_POSITIONS_TIER
+{
+ D3D12_PROGRAMMABLE_SAMPLE_POSITIONS_TIER_NOT_SUPPORTED = 0,
+ D3D12_PROGRAMMABLE_SAMPLE_POSITIONS_TIER_1 = 1,
+ D3D12_PROGRAMMABLE_SAMPLE_POSITIONS_TIER_2 = 2,
+} D3D12_PROGRAMMABLE_SAMPLE_POSITIONS_TIER;
+
+typedef struct D3D12_FEATURE_DATA_D3D12_OPTIONS2
+{
+ BOOL DepthBoundsTestSupported;
+ D3D12_PROGRAMMABLE_SAMPLE_POSITIONS_TIER ProgrammableSamplePositionsTier;
+} D3D12_FEATURE_DATA_D3D12_OPTIONS2;
+
+typedef enum D3D12_SHADER_CACHE_SUPPORT_FLAGS
+{
+ D3D12_SHADER_CACHE_SUPPORT_NONE = 0x0,
+ D3D12_SHADER_CACHE_SUPPORT_SINGLE_PSO = 0x1,
+ D3D12_SHADER_CACHE_SUPPORT_LIBRARY = 0x2,
+ D3D12_SHADER_CACHE_SUPPORT_AUTOMATIC_INPROC_CACHE = 0x4,
+ D3D12_SHADER_CACHE_SUPPORT_AUTOMATIC_DISK_CACHE = 0x8,
+} D3D12_SHADER_CACHE_SUPPORT_FLAGS;
+
+typedef struct D3D12_FEATURE_DATA_SHADER_CACHE
+{
+ D3D12_SHADER_CACHE_SUPPORT_FLAGS SupportFlags;
+} D3D12_FEATURE_DATA_SHADER_CACHE;
+
+typedef struct D3D12_FEATURE_DATA_COMMAND_QUEUE_PRIORITY
+{
+ D3D12_COMMAND_LIST_TYPE CommandListType;
+ UINT Priority;
+ BOOL PriorityForTypeIsSupported;
+} D3D12_FEATURE_DATA_COMMAND_QUEUE_PRIORITY;
+
+typedef struct D3D12_FEATURE_DATA_ARCHITECTURE1
+{
+ UINT NodeIndex;
+ BOOL TileBasedRenderer;
+ BOOL UMA;
+ BOOL CacheCoherentUMA;
+ BOOL IsolatedMMU;
+} D3D12_FEATURE_DATA_ARCHITECTURE1;
+
+typedef enum D3D12_COMMAND_LIST_SUPPORT_FLAGS
+{
+ D3D12_COMMAND_LIST_SUPPORT_FLAG_NONE = 0x0,
+ D3D12_COMMAND_LIST_SUPPORT_FLAG_DIRECT = 0x1,
+ D3D12_COMMAND_LIST_SUPPORT_FLAG_BUNDLE = 0x2,
+ D3D12_COMMAND_LIST_SUPPORT_FLAG_COMPUTE = 0x4,
+ D3D12_COMMAND_LIST_SUPPORT_FLAG_COPY = 0x8,
+} D3D12_COMMAND_LIST_SUPPORT_FLAGS;
+
+typedef enum D3D12_VIEW_INSTANCING_TIER
+{
+ D3D12_VIEW_INSTANCING_TIER_NOT_SUPPORTED = 0,
+ D3D12_VIEW_INSTANCING_TIER_1 = 1,
+ D3D12_VIEW_INSTANCING_TIER_2 = 2,
+ D3D12_VIEW_INSTANCING_TIER_3 = 3,
+} D3D12_VIEW_INSTANCING_TIER;
+
+typedef struct D3D12_FEATURE_DATA_D3D12_OPTIONS3
+{
+ BOOL CopyQueueTimestampQueriesSupported;
+ BOOL CastingFullyTypedFormatSupported;
+ D3D12_COMMAND_LIST_SUPPORT_FLAGS WriteBufferImmediateSupportFlags;
+ D3D12_VIEW_INSTANCING_TIER ViewInstancingTier;
+ BOOL BarycentricsSupported;
+} D3D12_FEATURE_DATA_D3D12_OPTIONS3;
+
+typedef struct D3D12_FEATURE_DATA_EXISTING_HEAPS
+{
+ BOOL Supported;
+} D3D12_FEATURE_DATA_EXISTING_HEAPS;
+
+typedef enum D3D12_SHARED_RESOURCE_COMPATIBILITY_TIER
+{
+ D3D12_SHARED_RESOURCE_COMPATIBILITY_TIER_0 = 0,
+ D3D12_SHARED_RESOURCE_COMPATIBILITY_TIER_1 = 1,
+} D3D12_SHARED_RESOURCE_COMPATIBILITY_TIER;
+
+typedef struct D3D12_FEATURE_DATA_D3D12_OPTIONS4
+{
+ BOOL MSAA64KBAlignedTextureSupported;
+ D3D12_SHARED_RESOURCE_COMPATIBILITY_TIER SharedResourceCompatibilityTier;
+ BOOL Native16BitShaderOpsSupported;
+} D3D12_FEATURE_DATA_D3D12_OPTIONS4;
+
+typedef enum D3D12_HEAP_SERIALIZATION_TIER
+{
+ D3D12_HEAP_SERIALIZATION_TIER_0 = 0,
+ D3D12_HEAP_SERIALIZATION_TIER_10 = 10,
+} D3D12_HEAP_SERIALIZATION_TIER;
+
+typedef struct D3D12_FEATURE_DATA_SERIALIZATION
+{
+ UINT NodeIndex;
+ D3D12_HEAP_SERIALIZATION_TIER HeapSerializationTier;
+} D3D12_FEATURE_DATA_SERIALIZATION;
+
+typedef struct D3D12_FEATURE_DATA_CROSS_NODE
+{
+ D3D12_CROSS_NODE_SHARING_TIER SharingTier;
+ BOOL AtomicShaderInstructions;
+} D3D12_FEATURE_DATA_CROSS_NODE;
+
+typedef enum D3D12_RENDER_PASS_TIER
+{
+ D3D12_RENDER_PASS_TIER_0 = 0,
+ D3D12_RENDER_PASS_TIER_1 = 1,
+ D3D12_RENDER_PASS_TIER_2 = 2,
+} D3D12_RENDER_PASS_TIER;
+
+typedef enum D3D12_RAYTRACING_TIER
+{
+ D3D12_RAYTRACING_TIER_NOT_SUPPORTED = 0,
+ D3D12_RAYTRACING_TIER_1_0 = 10,
+} D3D12_RAYTRACING_TIER;
+
+typedef struct D3D12_FEATURE_DATA_D3D12_OPTIONS5
+{
+ BOOL SRVOnlyTiledResourceTier3;
+ D3D12_RENDER_PASS_TIER RenderPassesTier;
+ D3D12_RAYTRACING_TIER RaytracingTier;
+} D3D12_FEATURE_DATA_D3D12_OPTIONS5;
+
typedef enum D3D12_FEATURE
{
D3D12_FEATURE_D3D12_OPTIONS = 0,
@@ -1624,6 +1759,12 @@ typedef enum D3D12_FEATURE
D3D12_FEATURE_D3D12_OPTIONS2 = 18,
D3D12_FEATURE_SHADER_CACHE = 19,
D3D12_FEATURE_COMMAND_QUEUE_PRIORITY = 20,
+ D3D12_FEATURE_D3D12_OPTIONS3 = 21,
+ D3D12_FEATURE_EXISTING_HEAPS = 22,
+ D3D12_FEATURE_D3D12_OPTIONS4 = 23,
+ D3D12_FEATURE_SERIALIZATION = 24,
+ D3D12_FEATURE_CROSS_NODE = 25,
+ D3D12_FEATURE_D3D12_OPTIONS5 = 27,
} D3D12_FEATURE;
typedef struct D3D12_MEMCPY_DEST
diff --git a/libs/vkd3d/device.c b/libs/vkd3d/device.c
index e3bb2aa..ae1c4c9 100644
--- a/libs/vkd3d/device.c
+++ b/libs/vkd3d/device.c
@@ -1336,6 +1336,34 @@ static HRESULT vkd3d_init_device_caps(struct d3d12_device *device,
device->feature_options.VPAndRTArrayIndexFromAnyShaderFeedingRasterizerSupportedWithoutGSEmulation = FALSE;
device->feature_options.ResourceHeapTier = D3D12_RESOURCE_HEAP_TIER_2;
+ device->feature_options1.WaveOps = FALSE;
+ device->feature_options1.WaveLaneCountMin = 0;
+ device->feature_options1.WaveLaneCountMax = 0;
+ device->feature_options1.TotalLaneCount = 0;
+ device->feature_options1.ExpandedComputeResourceStates = TRUE;
+ device->feature_options1.Int64ShaderOps = features->shaderInt64;
+
+ /* Depth bounds test is enabled in D3D12_DEPTH_STENCIL_DESC1, which is not supported. */
+ device->feature_options2.DepthBoundsTestSupported = FALSE;
+ /* d3d12_command_list_SetSamplePositions() is not implemented. */
+ device->feature_options2.ProgrammableSamplePositionsTier = D3D12_PROGRAMMABLE_SAMPLE_POSITIONS_TIER_NOT_SUPPORTED;
+
+ device->feature_options3.CopyQueueTimestampQueriesSupported = FALSE;
+ device->feature_options3.CastingFullyTypedFormatSupported = FALSE;
+ device->feature_options3.WriteBufferImmediateSupportFlags = D3D12_COMMAND_LIST_SUPPORT_FLAG_NONE;
+ device->feature_options3.ViewInstancingTier = D3D12_VIEW_INSTANCING_TIER_NOT_SUPPORTED;
+ device->feature_options3.BarycentricsSupported = FALSE;
+
+ /* Alignment support can be tested later. */
+ device->feature_options4.MSAA64KBAlignedTextureSupported = FALSE;
+ device->feature_options4.SharedResourceCompatibilityTier = D3D12_SHARED_RESOURCE_COMPATIBILITY_TIER_0;
+ /* An SM 6.2 feature. This would require features->shaderInt16 and VK_KHR_shader_float16_int8. */
+ device->feature_options4.Native16BitShaderOpsSupported = FALSE;
+
+ device->feature_options5.SRVOnlyTiledResourceTier3 = FALSE;
+ device->feature_options5.RenderPassesTier = D3D12_RENDER_PASS_TIER_0;
+ device->feature_options5.RaytracingTier = D3D12_RAYTRACING_TIER_NOT_SUPPORTED;
+
if ((vr = VK_CALL(vkEnumerateDeviceExtensionProperties(physical_device, NULL, &count, NULL))) < 0)
{
ERR("Failed to enumerate device extensions, vr %d.\n", vr);
@@ -1590,6 +1618,8 @@ static HRESULT d3d12_device_create_vkd3d_queues(struct d3d12_device *device,
else
goto out_destroy_queues;
+ device->feature_options3.CopyQueueTimestampQueriesSupported = !!device->copy_queue->timestamp_bits;
+
return S_OK;
out_destroy_queues:
@@ -2418,6 +2448,29 @@ bool d3d12_device_is_uma(struct d3d12_device *device, bool *coherent)
return true;
}
+/* The 4MB alignment requirement for MSAA was lowered to 64KB on hardware that supports it.
+ * This is distinct from the small MSAA requirement which applies to a total size of 4MB or less. */
+static bool d3d12_is_64k_msaa_supported(struct d3d12_device *device)
+{
+ D3D12_RESOURCE_ALLOCATION_INFO info;
+ D3D12_RESOURCE_DESC resource_desc;
+
+ memset(&resource_desc, 0, sizeof(resource_desc));
+ resource_desc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D;
+ resource_desc.Width = 1024;
+ resource_desc.Height = 1025;
+ resource_desc.DepthOrArraySize = 1;
+ resource_desc.MipLevels = 1;
+ resource_desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
+ resource_desc.SampleDesc.Count = 4;
+ resource_desc.Flags = D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET;
+
+ /* FIXME: in some cases Vulkan requires 0x20000 or more for non-MSAA resources, which must have
+ * 0x10000 in their description, so we might resonably return true here for 0x20000 or 0x40000. */
+ return SUCCEEDED(vkd3d_get_image_allocation_info(device, &resource_desc, &info))
+ && info.Alignment <= 0x10000;
+}
+
static HRESULT STDMETHODCALLTYPE d3d12_device_CheckFeatureSupport(ID3D12Device *iface,
D3D12_FEATURE feature, void *feature_data, UINT feature_data_size)
{
@@ -2668,6 +2721,27 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CheckFeatureSupport(ID3D12Device *
return S_OK;
}
+ case D3D12_FEATURE_D3D12_OPTIONS1:
+ {
+ D3D12_FEATURE_DATA_D3D12_OPTIONS1 *data = feature_data;
+
+ if (feature_data_size != sizeof(*data))
+ {
+ WARN("Invalid size %u.\n", feature_data_size);
+ return E_INVALIDARG;
+ }
+
+ *data = device->feature_options1;
+
+ TRACE("Wave ops %#x.\n", data->WaveOps);
+ TRACE("Min wave lane count %#x.\n", data->WaveLaneCountMin);
+ TRACE("Max wave lane count %#x.\n", data->WaveLaneCountMax);
+ TRACE("Total lane count %#x.\n", data->TotalLaneCount);
+ TRACE("Expanded compute resource states %#x.\n", data->ExpandedComputeResourceStates);
+ TRACE("Int64 shader ops %#x.\n", data->Int64ShaderOps);
+ return S_OK;
+ }
+
case D3D12_FEATURE_ROOT_SIGNATURE:
{
D3D12_FEATURE_DATA_ROOT_SIGNATURE *data = feature_data;
@@ -2685,6 +2759,211 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CheckFeatureSupport(ID3D12Device *
return S_OK;
}
+ case D3D12_FEATURE_ARCHITECTURE1:
+ {
+ D3D12_FEATURE_DATA_ARCHITECTURE1 *data = feature_data;
+ bool coherent;
+
+ if (feature_data_size != sizeof(*data))
+ {
+ WARN("Invalid size %u.\n", feature_data_size);
+ return E_INVALIDARG;
+ }
+
+ if (data->NodeIndex)
+ {
+ FIXME("Multi-adapter not supported.\n");
+ return E_INVALIDARG;
+ }
+
+ WARN("Assuming device does not support tile based rendering.\n");
+ data->TileBasedRenderer = FALSE;
+
+ data->UMA = d3d12_device_is_uma(device, &coherent);
+ data->CacheCoherentUMA = data->UMA ? coherent : FALSE;
+
+ WARN("Assuming device does not have an isolated memory management unit.\n");
+ data->IsolatedMMU = FALSE;
+
+ TRACE("Tile based renderer %#x, UMA %#x, cache coherent UMA %#x, isolated MMU %#x.\n",
+ data->TileBasedRenderer, data->UMA, data->CacheCoherentUMA, data->IsolatedMMU);
+ return S_OK;
+ }
+
+ case D3D12_FEATURE_D3D12_OPTIONS2:
+ {
+ D3D12_FEATURE_DATA_D3D12_OPTIONS2 *data = feature_data;
+
+ if (feature_data_size != sizeof(*data))
+ {
+ WARN("Invalid size %u.\n", feature_data_size);
+ return E_INVALIDARG;
+ }
+
+ *data = device->feature_options2;
+
+ TRACE("Depth bounds test %#x.\n", data->DepthBoundsTestSupported);
+ TRACE("Programmable sample positions tier %#x.\n", data->ProgrammableSamplePositionsTier);
+ return S_OK;
+ }
+
+ case D3D12_FEATURE_SHADER_CACHE:
+ {
+ D3D12_FEATURE_DATA_SHADER_CACHE *data = feature_data;
+
+ if (feature_data_size != sizeof(*data))
+ {
+ WARN("Invalid size %u.\n", feature_data_size);
+ return E_INVALIDARG;
+ }
+
+ /* FIXME: The D3D12 documentation states that D3D12_SHADER_CACHE_SUPPORT_SINGLE_PSO is
+ * always supported, but the CachedPSO field of D3D12_GRAPHICS_PIPELINE_STATE_DESC is
+ * ignored and GetCachedBlob() is a stub. */
+ data->SupportFlags = D3D12_SHADER_CACHE_SUPPORT_NONE;
+
+ TRACE("Shader cache support %#x.\n", data->SupportFlags);
+ return S_OK;
+ }
+
+ case D3D12_FEATURE_COMMAND_QUEUE_PRIORITY:
+ {
+ D3D12_FEATURE_DATA_COMMAND_QUEUE_PRIORITY *data = feature_data;
+
+ if (feature_data_size != sizeof(*data))
+ {
+ WARN("Invalid size %u.\n", feature_data_size);
+ return E_INVALIDARG;
+ }
+
+ switch (data->CommandListType)
+ {
+ case D3D12_COMMAND_LIST_TYPE_DIRECT:
+ case D3D12_COMMAND_LIST_TYPE_COMPUTE:
+ case D3D12_COMMAND_LIST_TYPE_COPY:
+ data->PriorityForTypeIsSupported = FALSE;
+ TRACE("Command list type %#x, priority %u, supported %#x.\n",
+ data->CommandListType, data->Priority, data->PriorityForTypeIsSupported);
+ return S_OK;
+
+ default:
+ FIXME("Unhandled command list type %#x.\n", data->CommandListType);
+ return E_INVALIDARG;
+ }
+ }
+
+ case D3D12_FEATURE_D3D12_OPTIONS3:
+ {
+ D3D12_FEATURE_DATA_D3D12_OPTIONS3 *data = feature_data;
+
+ if (feature_data_size != sizeof(*data))
+ {
+ WARN("Invalid size %u.\n", feature_data_size);
+ return E_INVALIDARG;
+ }
+
+ *data = device->feature_options3;
+
+ TRACE("Copy queue timestamp queries %#x.\n", data->CopyQueueTimestampQueriesSupported);
+ TRACE("Casting fully typed format %#x.\n", data->CastingFullyTypedFormatSupported);
+ TRACE("Write buffer immediate %#x.\n", data->WriteBufferImmediateSupportFlags);
+ TRACE("View instancing tier %#x.\n", data->ViewInstancingTier);
+ TRACE("Barycentrics %#x.\n", data->BarycentricsSupported);
+ return S_OK;
+ }
+
+ case D3D12_FEATURE_EXISTING_HEAPS:
+ {
+ D3D12_FEATURE_DATA_EXISTING_HEAPS *data = feature_data;
+
+ if (feature_data_size != sizeof(*data))
+ {
+ WARN("Invalid size %u.\n", feature_data_size);
+ return E_INVALIDARG;
+ }
+
+ data->Supported = FALSE;
+
+ TRACE("Existing heaps %#x.\n", data->Supported);
+ return S_OK;
+ }
+
+ case D3D12_FEATURE_D3D12_OPTIONS4:
+ {
+ D3D12_FEATURE_DATA_D3D12_OPTIONS4 *data = feature_data;
+
+ if (feature_data_size != sizeof(*data))
+ {
+ WARN("Invalid size %u.\n", feature_data_size);
+ return E_INVALIDARG;
+ }
+
+ *data = device->feature_options4;
+ data->MSAA64KBAlignedTextureSupported = d3d12_is_64k_msaa_supported(device);
+
+ TRACE("64KB aligned MSAA textures %#x.\n", data->MSAA64KBAlignedTextureSupported);
+ TRACE("Shared resource compatibility tier %#x.\n", data->SharedResourceCompatibilityTier);
+ TRACE("Native 16-bit shader ops %#x.\n", data->Native16BitShaderOpsSupported);
+ return S_OK;
+ }
+
+ case D3D12_FEATURE_SERIALIZATION:
+ {
+ D3D12_FEATURE_DATA_SERIALIZATION *data = feature_data;
+
+ if (feature_data_size != sizeof(*data))
+ {
+ WARN("Invalid size %u.\n", feature_data_size);
+ return E_INVALIDARG;
+ }
+ if (data->NodeIndex)
+ {
+ FIXME("Multi-adapter not supported.\n");
+ return E_INVALIDARG;
+ }
+
+ data->HeapSerializationTier = D3D12_HEAP_SERIALIZATION_TIER_0;
+
+ TRACE("Heap serialization tier %#x.\n", data->HeapSerializationTier);
+ return S_OK;
+ }
+
+ case D3D12_FEATURE_CROSS_NODE:
+ {
+ D3D12_FEATURE_DATA_CROSS_NODE *data = feature_data;
+
+ if (feature_data_size != sizeof(*data))
+ {
+ WARN("Invalid size %u.\n", feature_data_size);
+ return E_INVALIDARG;
+ }
+
+ data->SharingTier = D3D12_CROSS_NODE_SHARING_TIER_NOT_SUPPORTED;
+ data->AtomicShaderInstructions = FALSE;
+
+ TRACE("Cross node sharing tier %#x.\n", data->SharingTier);
+ TRACE("Cross node shader atomics %#x.\n", data->AtomicShaderInstructions);
+ return S_OK;
+ }
+
+ case D3D12_FEATURE_D3D12_OPTIONS5:
+ {
+ D3D12_FEATURE_DATA_D3D12_OPTIONS5 *data = feature_data;
+
+ if (feature_data_size != sizeof(*data))
+ {
+ WARN("Invalid size %u.\n", feature_data_size);
+ return E_INVALIDARG;
+ }
+
+ *data = device->feature_options5;
+
+ TRACE("SRV tiled resource tier 3 only %#x.\n", data->SRVOnlyTiledResourceTier3);
+ TRACE("Render pass tier %#x.\n", data->RenderPassesTier);
+ TRACE("Ray tracing tier %#x.\n", data->RaytracingTier);
+ return S_OK;
+ }
+
default:
FIXME("Unhandled feature %#x.\n", feature);
return E_NOTIMPL;
diff --git a/libs/vkd3d/vkd3d_private.h b/libs/vkd3d/vkd3d_private.h
index 9ff6bba..d18fba1 100644
--- a/libs/vkd3d/vkd3d_private.h
+++ b/libs/vkd3d/vkd3d_private.h
@@ -1131,6 +1131,11 @@ struct d3d12_device
VkPhysicalDeviceMemoryProperties memory_properties;
D3D12_FEATURE_DATA_D3D12_OPTIONS feature_options;
+ D3D12_FEATURE_DATA_D3D12_OPTIONS1 feature_options1;
+ D3D12_FEATURE_DATA_D3D12_OPTIONS2 feature_options2;
+ D3D12_FEATURE_DATA_D3D12_OPTIONS3 feature_options3;
+ D3D12_FEATURE_DATA_D3D12_OPTIONS4 feature_options4;
+ D3D12_FEATURE_DATA_D3D12_OPTIONS5 feature_options5;
struct vkd3d_vulkan_info vk_info;
--
2.24.0