gfx icon indicating copy to clipboard operation
gfx copied to clipboard

Putting in place plumbing to expose timestamp query related details. Is timestamp querying supported by the device? What is the tick period?

Open bzm3r opened this issue 4 years ago • 4 comments

Problem

Currently, gfx-hal exposes a way to generate timestamp queries, there is no way to check whether timestamp queries are supported by the device, or get the period of the ticks returned by the query.

Getting this information

Using Vulkan: this information is stored within the VkPhysicalDeviceLimits info structure. See timestampComputeAndGraphics and timestampPeriod fields.

Using DX12: this information is obtained by calling ID3D12CommandQueue::GetTimestampFrequency method, which is a method on ID3D12CommandQueue. If the HRESULT of the get is an error, then the device?/command queue? does not support timestamp querying.

Note that an ID3D12CommandQueue is created by calling the ID3D12Device::CreateCommandQueue method on ID3D12Device.

Using DX11/Metal/OpenGL: I don't know what the situation is for these backends, so I hope others can provide information.

Solution

First, let us examine the Vulkan case.

Vulkan. In my understanding, a PhysicalDevice is publicly accessible as a field on an Adapter object. PhysicalDevice has the properties field of type vk::PhysicalDeviceProperties, which in turn has a field called limits containing the information we need to expose.

Therefore, we need a method on PhysicalDevice which returns the relevant information stored in its properties field. Suppose we call this method get_timestamp_query_info, for the purposes of the discussion (actual name left up to discussion). The PhysicalDevice trait should specify such a method.

DX12. To implement get_timestamp_query_info for DX12, one runs into an issue because unlike in the Vulkan case where the info is associated with a physical device, it seems that in the DX12 case, this information is associated with a logical device, ID3D12Device, which can be obtained by calling the as_raw method implemented for a (logical) Device by the DX12 backend.

This means that we have to call adapter.physical_device.open to get Gpu object which stores a logical device, and then the get_timestamp_query should be called on this device. This suggests that the gfx-hal trait which should specify the get_timestamp_query method is Device, and not PhysicalDevice as we concluded when examining the Vulkan case. However, I think we would prefer to keep with what the Vulkan case demands.

In order to keep with the Vulkan case, maybe the DX12 impl of get_timestamp_query for PhysicalDevice should create a raw logical device much like what is done in the impl for open. However, the this logical device is temporary, and only used to create a raw command queue, which can be called to get timestamp information, which is then returned to the user.


Conclusion

Can the gfx-hal API designers discuss what is the best way to approach the above problem? I will be happy to implement their recommended solution for the Vulkan and DX12 backends, but will have to leave the implementation for other backends to someone else.

bzm3r avatar Feb 20 '20 21:02 bzm3r

Thanks for filing such a detailed issue!

First observation: we need to get that info when there is only a physical device available, just like Vulkan does. Otherwise, piping gfx-portability will be difficult.

Second observation: D3D12 has to create a logical device when enumerating adapters, so it's already available to us. The only thing we need extra is the queue. One of the ways to proceed would be having enumerate_adapters to create queues for each adapter on D3D12 and querying the timestamp resolution.

Now, you also suggested to make the query a function. I really like this idea for making the cost of query optional, while still allowing gfx-portability to gather all the data. I think it's a good direction to take, possibly with other exposed limits and capabilities as well.

kvark avatar Feb 21 '20 14:02 kvark

Your suggestions make sense to me :)

PR is in progress.

bzm3r avatar Feb 26 '20 07:02 bzm3r

@msiglreith why are the timing related queries specific to command queues in DX12? Can the time period for a measured tick be different based on the queue's properties (priority, type, etc.)?

bzm3r avatar Feb 27 '20 00:02 bzm3r

hmm, I guess queue type is the only interesting property. I suggest to just check for direct and compute and take the value. In the best case, all queues report the same property (hopefully). Worst case, compute or copy differ. Then we can also just say that these queues don't support timestamp queries for vk portability.

msiglreith avatar Feb 29 '20 12:02 msiglreith