[PATCH vkd3d v2 1/2] vkd3d: Add more features to CheckFeatureSupport().
Some games, e.g. Hitman 2, do not check for success, and if the feature check is unimplemented they will use uninitialised data as the result. Signed-off-by: Conor McCarthy <cmccarthy(a)codeweavers.com> --- v2: Fix corrupt patch. Supersedes 174442. --- include/vkd3d_d3d12.idl | 141 +++++++++++++++++++ libs/vkd3d/device.c | 276 +++++++++++++++++++++++++++++++++++++ libs/vkd3d/vkd3d_private.h | 5 + 3 files changed, 422 insertions(+) diff --git a/include/vkd3d_d3d12.idl b/include/vkd3d_d3d12.idl index 8246424..3747c8e 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 7ff567d..cd850c9 100644 --- a/libs/vkd3d/device.c +++ b/libs/vkd3d/device.c @@ -1336,6 +1336,33 @@ 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; + device->feature_options4.Native16BitShaderOpsSupported = features->shaderInt16; + + 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 +1617,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: @@ -2433,6 +2462,27 @@ bool d3d12_device_is_uma(struct d3d12_device *device, bool *coherent) return true; } +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 = 1024; + 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: is 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) { @@ -2683,6 +2733,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; @@ -2700,6 +2771,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 9edf96e..7ba1db4 100644 --- a/libs/vkd3d/vkd3d_private.h +++ b/libs/vkd3d/vkd3d_private.h @@ -1086,6 +1086,11 @@ struct d3d12_device PFN_vkd3d_memory_usage_callback pfn_memory_usage_callback; 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
Implemented on top of VK_EXT_calibrated_timestamps. Signed-off-by: Conor McCarthy <cmccarthy(a)codeweavers.com> --- Supersedes 174443. --- libs/vkd3d/command.c | 64 ++++++++++++++++++++++++++++++++++++-- libs/vkd3d/device.c | 1 + libs/vkd3d/vkd3d_private.h | 1 + libs/vkd3d/vulkan_procs.h | 3 ++ 4 files changed, 67 insertions(+), 2 deletions(-) diff --git a/libs/vkd3d/command.c b/libs/vkd3d/command.c index 1686f0e..bb85bf3 100644 --- a/libs/vkd3d/command.c +++ b/libs/vkd3d/command.c @@ -5962,10 +5962,70 @@ static HRESULT STDMETHODCALLTYPE d3d12_command_queue_GetTimestampFrequency(ID3D1 static HRESULT STDMETHODCALLTYPE d3d12_command_queue_GetClockCalibration(ID3D12CommandQueue *iface, UINT64 *gpu_timestamp, UINT64 *cpu_timestamp) { - FIXME("iface %p, gpu_timestamp %p, cpu_timestamp %p stub!\n", + struct d3d12_command_queue *command_queue = impl_from_ID3D12CommandQueue(iface); + const struct vkd3d_vk_device_procs *vk_procs = &command_queue->device->vk_procs; + const struct vkd3d_vulkan_info *vk_info = &command_queue->device->vk_info; + VkCalibratedTimestampInfoEXT infos[4]; + uint64_t timestamps[4]; + uint64_t deviations[4]; + VkResult vr; + size_t i; + + TRACE("iface %p, gpu_timestamp %p, cpu_timestamp %p.\n", iface, gpu_timestamp, cpu_timestamp); - return E_NOTIMPL; + if (!command_queue->vkd3d_queue->timestamp_bits) + { + WARN("Timestamp queries not supported.\n"); + return E_FAIL; + } + + if (!gpu_timestamp || !cpu_timestamp) + return E_INVALIDARG; + + if (!vk_info->EXT_calibrated_timestamps) + { + FIXME("VK_EXT_calibrated_timestamps was not found. Calibrated timestamps are not available.\n"); + return E_NOTIMPL; + } + + /* vkGetPhysicalDeviceCalibrateableTimeDomainsEXT() is missing from RADV. */ + infos[0].sType = VK_STRUCTURE_TYPE_CALIBRATED_TIMESTAMP_INFO_EXT; + infos[0].pNext = NULL; + infos[0].timeDomain = VK_TIME_DOMAIN_DEVICE_EXT; + infos[1].sType = VK_STRUCTURE_TYPE_CALIBRATED_TIMESTAMP_INFO_EXT; + infos[1].pNext = NULL; + infos[1].timeDomain = VK_TIME_DOMAIN_CLOCK_MONOTONIC_RAW_EXT; + infos[2].sType = VK_STRUCTURE_TYPE_CALIBRATED_TIMESTAMP_INFO_EXT; + infos[2].pNext = NULL; + infos[2].timeDomain = VK_TIME_DOMAIN_CLOCK_MONOTONIC_EXT; + infos[3].sType = VK_STRUCTURE_TYPE_CALIBRATED_TIMESTAMP_INFO_EXT; + infos[3].pNext = NULL; + infos[3].timeDomain = VK_TIME_DOMAIN_QUERY_PERFORMANCE_COUNTER_EXT; + + memset(timestamps, 0, sizeof(timestamps)); + if ((vr = VK_CALL(vkGetCalibratedTimestampsEXT(command_queue->device->vk_device, + ARRAY_SIZE(infos), infos, timestamps, deviations))) < 0) + { + WARN("Failed to get calibrated timestamps, vr %d.\n", vr); + return E_FAIL; + } + /* Convert monotonic clock to Windows ticks. */ + timestamps[1] /= 100; + timestamps[2] /= 100; + + for (i = 1; i < ARRAY_SIZE(infos) && !timestamps[i]; ++i) + ; + if (i == ARRAY_SIZE(infos)) + { + WARN("Failed to get CPU timestamp.\n"); + return E_FAIL; + } + + *gpu_timestamp = timestamps[0]; + *cpu_timestamp = timestamps[i]; + + return S_OK; } static D3D12_COMMAND_QUEUE_DESC * STDMETHODCALLTYPE d3d12_command_queue_GetDesc(ID3D12CommandQueue *iface, diff --git a/libs/vkd3d/device.c b/libs/vkd3d/device.c index cd850c9..5fb0ca7 100644 --- a/libs/vkd3d/device.c +++ b/libs/vkd3d/device.c @@ -128,6 +128,7 @@ static const struct vkd3d_optional_extension_info optional_device_extensions[] = VK_EXTENSION(KHR_MAINTENANCE3, KHR_maintenance3), VK_EXTENSION(KHR_PUSH_DESCRIPTOR, KHR_push_descriptor), /* EXT extensions */ + VK_EXTENSION(EXT_CALIBRATED_TIMESTAMPS, EXT_calibrated_timestamps), VK_EXTENSION(EXT_CONDITIONAL_RENDERING, EXT_conditional_rendering), VK_EXTENSION(EXT_DEBUG_MARKER, EXT_debug_marker), VK_EXTENSION(EXT_DEPTH_CLIP_ENABLE, EXT_depth_clip_enable), diff --git a/libs/vkd3d/vkd3d_private.h b/libs/vkd3d/vkd3d_private.h index 7ba1db4..d1861ce 100644 --- a/libs/vkd3d/vkd3d_private.h +++ b/libs/vkd3d/vkd3d_private.h @@ -101,6 +101,7 @@ struct vkd3d_vulkan_info bool KHR_maintenance3; bool KHR_push_descriptor; /* EXT device extensions */ + bool EXT_calibrated_timestamps; bool EXT_conditional_rendering; bool EXT_debug_marker; bool EXT_depth_clip_enable; diff --git a/libs/vkd3d/vulkan_procs.h b/libs/vkd3d/vulkan_procs.h index ec29eb4..77ceb71 100644 --- a/libs/vkd3d/vulkan_procs.h +++ b/libs/vkd3d/vulkan_procs.h @@ -192,6 +192,9 @@ VK_DEVICE_EXT_PFN(vkGetDescriptorSetLayoutSupportKHR) /* VK_KHR_push_descriptor */ VK_DEVICE_EXT_PFN(vkCmdPushDescriptorSetKHR) +/* VK_EXT_calibrated_timestamps */ +VK_DEVICE_EXT_PFN(vkGetCalibratedTimestampsEXT) + /* VK_EXT_conditional_rendering */ VK_DEVICE_EXT_PFN(vkCmdBeginConditionalRenderingEXT) VK_DEVICE_EXT_PFN(vkCmdEndConditionalRenderingEXT) -- 2.24.0
participants (1)
-
Conor McCarthy