diff --git a/src/dawn_native/Device.h b/src/dawn_native/Device.h index f089c76839..c4a49e1adf 100644 --- a/src/dawn_native/Device.h +++ b/src/dawn_native/Device.h @@ -249,6 +249,8 @@ namespace dawn_native { virtual uint32_t GetOptimalBytesPerRowAlignment() const = 0; virtual uint64_t GetOptimalBufferToTextureCopyOffsetAlignment() const = 0; + virtual float GetTimestampPeriodInNS() const = 0; + protected: void SetToggle(Toggle toggle, bool isEnabled); void ForceSetToggle(Toggle toggle, bool isEnabled); diff --git a/src/dawn_native/d3d12/DeviceD3D12.cpp b/src/dawn_native/d3d12/DeviceD3D12.cpp index d28767cb08..1d15eb58c1 100644 --- a/src/dawn_native/d3d12/DeviceD3D12.cpp +++ b/src/dawn_native/d3d12/DeviceD3D12.cpp @@ -77,6 +77,15 @@ namespace dawn_native { namespace d3d12 { CheckHRESULT(mD3d12Device->CreateCommandQueue(&queueDesc, IID_PPV_ARGS(&mCommandQueue)), "D3D12 create command queue")); + // Get GPU timestamp counter frequency (in ticks/second). This fails if the specified + // command queue doesn't support timestamps, D3D12_COMMAND_LIST_TYPE_DIRECT always support + // timestamps. + uint64_t frequency; + DAWN_TRY(CheckHRESULT(mCommandQueue->GetTimestampFrequency(&frequency), + "D3D12 get timestamp frequency")); + // Calculate the period in nanoseconds by the frequency. + mTimestampPeriod = static_cast(1e9) / frequency; + // If PIX is not attached, the QueryInterface fails. Hence, no need to check the return // value. mCommandQueue.As(&mD3d12SharingContract); @@ -655,4 +664,8 @@ namespace dawn_native { namespace d3d12 { return 1; } + float Device::GetTimestampPeriodInNS() const { + return mTimestampPeriod; + } + }} // namespace dawn_native::d3d12 diff --git a/src/dawn_native/d3d12/DeviceD3D12.h b/src/dawn_native/d3d12/DeviceD3D12.h index dc41448053..732e187986 100644 --- a/src/dawn_native/d3d12/DeviceD3D12.h +++ b/src/dawn_native/d3d12/DeviceD3D12.h @@ -141,6 +141,8 @@ namespace dawn_native { namespace d3d12 { uint32_t GetOptimalBytesPerRowAlignment() const override; uint64_t GetOptimalBufferToTextureCopyOffsetAlignment() const override; + float GetTimestampPeriodInNS() const override; + private: using DeviceBase::DeviceBase; @@ -236,6 +238,9 @@ namespace dawn_native { namespace d3d12 { // Sampler cache needs to be destroyed before the CPU sampler allocator to ensure the final // release is called. std::unique_ptr mSamplerHeapCache; + + // The number of nanoseconds required for a timestamp query to be incremented by 1 + float mTimestampPeriod = 1.0f; }; }} // namespace dawn_native::d3d12 diff --git a/src/dawn_native/metal/DeviceMTL.h b/src/dawn_native/metal/DeviceMTL.h index 53da499d77..f886fcd32d 100644 --- a/src/dawn_native/metal/DeviceMTL.h +++ b/src/dawn_native/metal/DeviceMTL.h @@ -71,6 +71,8 @@ namespace dawn_native { namespace metal { uint32_t GetOptimalBytesPerRowAlignment() const override; uint64_t GetOptimalBufferToTextureCopyOffsetAlignment() const override; + float GetTimestampPeriodInNS() const override; + private: Device(AdapterBase* adapter, NSPRef> mtlDevice, diff --git a/src/dawn_native/metal/DeviceMTL.mm b/src/dawn_native/metal/DeviceMTL.mm index 37df56a807..e570639ce0 100644 --- a/src/dawn_native/metal/DeviceMTL.mm +++ b/src/dawn_native/metal/DeviceMTL.mm @@ -402,4 +402,8 @@ namespace dawn_native { namespace metal { return 1; } + float Device::GetTimestampPeriodInNS() const { + return 1.0f; + } + }} // namespace dawn_native::metal diff --git a/src/dawn_native/null/DeviceNull.cpp b/src/dawn_native/null/DeviceNull.cpp index a821acfa5a..5f5a28304c 100644 --- a/src/dawn_native/null/DeviceNull.cpp +++ b/src/dawn_native/null/DeviceNull.cpp @@ -470,4 +470,8 @@ namespace dawn_native { namespace null { return 1; } + float Device::GetTimestampPeriodInNS() const { + return 1.0f; + } + }} // namespace dawn_native::null diff --git a/src/dawn_native/null/DeviceNull.h b/src/dawn_native/null/DeviceNull.h index 9a73a9b2f2..7cc08df949 100644 --- a/src/dawn_native/null/DeviceNull.h +++ b/src/dawn_native/null/DeviceNull.h @@ -116,6 +116,8 @@ namespace dawn_native { namespace null { uint32_t GetOptimalBytesPerRowAlignment() const override; uint64_t GetOptimalBufferToTextureCopyOffsetAlignment() const override; + float GetTimestampPeriodInNS() const override; + private: using DeviceBase::DeviceBase; diff --git a/src/dawn_native/opengl/DeviceGL.cpp b/src/dawn_native/opengl/DeviceGL.cpp index 5ae56b8784..1d81932bda 100644 --- a/src/dawn_native/opengl/DeviceGL.cpp +++ b/src/dawn_native/opengl/DeviceGL.cpp @@ -228,4 +228,8 @@ namespace dawn_native { namespace opengl { return 1; } + float Device::GetTimestampPeriodInNS() const { + return 1.0f; + } + }} // namespace dawn_native::opengl diff --git a/src/dawn_native/opengl/DeviceGL.h b/src/dawn_native/opengl/DeviceGL.h index 1d1f08719d..f463aff2aa 100644 --- a/src/dawn_native/opengl/DeviceGL.h +++ b/src/dawn_native/opengl/DeviceGL.h @@ -70,6 +70,8 @@ namespace dawn_native { namespace opengl { uint32_t GetOptimalBytesPerRowAlignment() const override; uint64_t GetOptimalBufferToTextureCopyOffsetAlignment() const override; + float GetTimestampPeriodInNS() const override; + private: Device(AdapterBase* adapter, const DeviceDescriptor* descriptor, diff --git a/src/dawn_native/vulkan/DeviceVk.cpp b/src/dawn_native/vulkan/DeviceVk.cpp index 398cc57575..3096ce4cd0 100644 --- a/src/dawn_native/vulkan/DeviceVk.cpp +++ b/src/dawn_native/vulkan/DeviceVk.cpp @@ -945,4 +945,8 @@ namespace dawn_native { namespace vulkan { return mDeviceInfo.properties.limits.optimalBufferCopyOffsetAlignment; } + float Device::GetTimestampPeriodInNS() const { + return mDeviceInfo.properties.limits.timestampPeriod; + } + }} // namespace dawn_native::vulkan diff --git a/src/dawn_native/vulkan/DeviceVk.h b/src/dawn_native/vulkan/DeviceVk.h index 40b11f7484..2a62779227 100644 --- a/src/dawn_native/vulkan/DeviceVk.h +++ b/src/dawn_native/vulkan/DeviceVk.h @@ -108,6 +108,8 @@ namespace dawn_native { namespace vulkan { uint32_t GetOptimalBytesPerRowAlignment() const override; uint64_t GetOptimalBufferToTextureCopyOffsetAlignment() const override; + float GetTimestampPeriodInNS() const override; + private: Device(Adapter* adapter, const DeviceDescriptor* descriptor);