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@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;
Implemented on top of VK_EXT_calibrated_timestamps.
Signed-off-by: Conor McCarthy cmccarthy@codeweavers.com --- Supersedes 174445. --- 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 75af27d..3f42981 100644 --- a/libs/vkd3d/command.c +++ b/libs/vkd3d/command.c @@ -6097,10 +6097,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 ae1c4c9..5d43ddb 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 d18fba1..4df0a26 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)
On Wed, 27 Nov 2019 at 18:35, Conor McCarthy cmccarthy@codeweavers.com wrote:
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@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(+)
It's probably best to split this into separate patches for each option, both to keep things reviewable, and for the purpose of bisects.
In terms of style, the existing file isn't entirely consistent about it, but we tend to put enums together at the top, and the structures using them together below that. Enum element values should generally by in hexadecimal, since that's how we print them in debug messages.