Handle failed calls to ID3D12CommandQueue::GetTimestampFrequency

ID2D12CommandQueue::GetTimestampFrequency returns an error HRESULT
when there are bugs in Windows container and vGPU implementations.

To workaround, we check the return value during adapter creation
and disable the timestamp query extension upon failure.

Device creation is still allowed to succeed when the method returns
failure.

Change-Id: Ie71f8712fc9f4f50e4ce26ecfec929b5b1a126d4
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/63225
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Commit-Queue: Rafael Cintron <rafael.cintron@microsoft.com>
This commit is contained in:
Rafael Cintron 2021-09-03 17:29:20 +00:00 committed by Dawn LUCI CQ
parent 10b9cce816
commit 0376ebe3df
3 changed files with 37 additions and 9 deletions

View File

@ -109,10 +109,33 @@ namespace dawn_native { namespace d3d12 {
return {};
}
bool Adapter::AreTimestampQueriesSupported() const {
D3D12_COMMAND_QUEUE_DESC queueDesc = {};
queueDesc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE;
queueDesc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT;
ComPtr<ID3D12CommandQueue> d3d12CommandQueue;
HRESULT hr = mD3d12Device->CreateCommandQueue(&queueDesc, IID_PPV_ARGS(&d3d12CommandQueue));
if (FAILED(hr)) {
return false;
}
// GetTimestampFrequency returns an error HRESULT when there are bugs in Windows container
// and vGPU implementations.
uint64_t timeStampFrequency;
hr = d3d12CommandQueue->GetTimestampFrequency(&timeStampFrequency);
if (FAILED(hr)) {
return false;
}
return true;
}
void Adapter::InitializeSupportedExtensions() {
if (AreTimestampQueriesSupported()) {
mSupportedExtensions.EnableExtension(Extension::TimestampQuery);
}
mSupportedExtensions.EnableExtension(Extension::TextureCompressionBC);
mSupportedExtensions.EnableExtension(Extension::PipelineStatisticsQuery);
mSupportedExtensions.EnableExtension(Extension::TimestampQuery);
mSupportedExtensions.EnableExtension(Extension::MultiPlanarFormats);
}

View File

@ -45,6 +45,8 @@ namespace dawn_native { namespace d3d12 {
ResultOrError<DeviceBase*> CreateDeviceImpl(const DeviceDescriptor* descriptor) override;
MaybeError ResetInternalDeviceForTestingImpl() override;
bool AreTimestampQueriesSupported() const;
void InitializeSupportedExtensions();
MaybeError InitializeDebugLayerFilters();
void CleanUpDebugLayerFilters();

View File

@ -73,14 +73,17 @@ namespace dawn_native { namespace d3d12 {
CheckHRESULT(mD3d12Device->CreateCommandQueue(&queueDesc, IID_PPV_ARGS(&mCommandQueue)),
"D3D12 create command queue"));
if (IsExtensionEnabled(Extension::TimestampQuery)) {
// 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.
// command queue doesn't support timestamps. D3D12_COMMAND_LIST_TYPE_DIRECT queues
// always support timestamps except where there are bugs in Windows container and vGPU
// implementations.
uint64_t frequency;
DAWN_TRY(CheckHRESULT(mCommandQueue->GetTimestampFrequency(&frequency),
"D3D12 get timestamp frequency"));
// Calculate the period in nanoseconds by the frequency.
mTimestampPeriod = static_cast<float>(1e9) / frequency;
}
// If PIX is not attached, the QueryInterface fails. Hence, no need to check the return
// value.