D3D12: Silence known debug layer warnings

This will help remove noise in debug layer output. This patch also
 promotes warnings and higher to Dawn errors.

BUG: dawn:363, dawn:418, dawn:419, dawn:421

Change-Id: I3112c94aff71fc7e76dff48c82bafe9e051ed3b4
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/21702
Commit-Queue: Corentin Wallez <cwallez@chromium.org>
Reviewed-by: Bryan Bernhart <bryan.bernhart@intel.com>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
This commit is contained in:
Enrico Galli 2020-05-29 08:29:58 +00:00 committed by Commit Bot service account
parent 6ced832d74
commit 4c32bd0b7d
4 changed files with 149 additions and 1 deletions

View File

@ -15,7 +15,9 @@
#include "dawn_native/d3d12/AdapterD3D12.h"
#include "common/Constants.h"
#include "dawn_native/Instance.h"
#include "dawn_native/d3d12/BackendD3D12.h"
#include "dawn_native/d3d12/D3D12Error.h"
#include "dawn_native/d3d12/DeviceD3D12.h"
#include "dawn_native/d3d12/PlatformFunctions.h"
@ -40,6 +42,10 @@ namespace dawn_native { namespace d3d12 {
mBackend(backend) {
}
Adapter::~Adapter() {
CleanUpDebugLayerFilters();
}
const D3D12DeviceInfo& Adapter::GetDeviceInfo() const {
return mDeviceInfo;
}
@ -66,6 +72,8 @@ namespace dawn_native { namespace d3d12 {
return DAWN_INTERNAL_ERROR("D3D12CreateDevice failed");
}
DAWN_TRY(InitializeDebugLayerFilters());
DXGI_ADAPTER_DESC1 adapterDesc;
mHardwareAdapter->GetDesc1(&adapterDesc);
@ -96,6 +104,89 @@ namespace dawn_native { namespace d3d12 {
mSupportedExtensions.EnableExtension(Extension::TimestampQuery);
}
MaybeError Adapter::InitializeDebugLayerFilters() {
if (!GetInstance()->IsBackendValidationEnabled()) {
return {};
}
ComPtr<ID3D12InfoQueue> infoQueue;
ASSERT_SUCCESS(mD3d12Device.As(&infoQueue));
// We create storage filter with a deny list to deny specific messages from getting
// written to the queue. The filter will silence them in the debug output.
D3D12_INFO_QUEUE_FILTER storageFilter = {};
D3D12_MESSAGE_ID denyIds[] = {
//
// Permanent IDs: list of warnings that are not applicable
//
// Resource sub-allocation partially maps pre-allocated heaps. This means the
// entire physical addresses space may have no resources or have many resources
// assigned the same heap.
D3D12_MESSAGE_ID_HEAP_ADDRESS_RANGE_HAS_NO_RESOURCE,
D3D12_MESSAGE_ID_HEAP_ADDRESS_RANGE_INTERSECTS_MULTIPLE_BUFFERS,
// The debug layer validates pipeline objects when they are created. Dawn validates
// them when them when they are set. Therefore, since the issue is caught at a later
// time, we can silence this warnings.
D3D12_MESSAGE_ID_CREATEGRAPHICSPIPELINESTATE_RENDERTARGETVIEW_NOT_SET,
// Adding a clear color during resource creation would require heuristics or delayed
// creation.
// https://crbug.com/dawn/418
D3D12_MESSAGE_ID_CLEARRENDERTARGETVIEW_MISMATCHINGCLEARVALUE,
D3D12_MESSAGE_ID_CLEARDEPTHSTENCILVIEW_MISMATCHINGCLEARVALUE,
// Dawn enforces proper Unmaps at a later time.
// https://crbug.com/dawn/422
D3D12_MESSAGE_ID_EXECUTECOMMANDLISTS_GPU_WRITTEN_READBACK_RESOURCE_MAPPED,
//
// Temporary IDs: list of warnings that should be fixed or promoted
//
// Remove after warning have been addressed
// https://crbug.com/dawn/419
D3D12_MESSAGE_ID_UNMAP_RANGE_NOT_EMPTY,
// Remove after warning have been addressed
// https://crbug.com/dawn/421
D3D12_MESSAGE_ID_GPU_BASED_VALIDATION_INCOMPATIBLE_RESOURCE_STATE,
};
storageFilter.DenyList.NumIDs = ARRAYSIZE(denyIds);
storageFilter.DenyList.pIDList = denyIds;
DAWN_TRY(CheckHRESULT(infoQueue->PushStorageFilter(&storageFilter),
"ID3D12InfoQueue::PushStorageFilter"));
// We create a retrieval filter with an allow list to select which messages we are
// allowed to be read back from the queue. If any messages are read back, they are
// converted to Dawn errors.
D3D12_INFO_QUEUE_FILTER retrievalFilter{};
// We will only create errors from warnings or worse. This ignores info and message.
D3D12_MESSAGE_SEVERITY severities[] = {
D3D12_MESSAGE_SEVERITY_ERROR,
D3D12_MESSAGE_SEVERITY_WARNING,
D3D12_MESSAGE_SEVERITY_CORRUPTION,
};
retrievalFilter.AllowList.NumSeverities = ARRAYSIZE(severities);
retrievalFilter.AllowList.pSeverityList = severities;
DAWN_TRY(CheckHRESULT(infoQueue->PushRetrievalFilter(&retrievalFilter),
"ID3D12InfoQueue::PushRetrievalFilter"));
return {};
}
void Adapter::CleanUpDebugLayerFilters() {
if (!GetInstance()->IsBackendValidationEnabled()) {
return;
}
ComPtr<ID3D12InfoQueue> infoQueue;
ASSERT_SUCCESS(mD3d12Device.As(&infoQueue));
infoQueue->PopRetrievalFilter();
infoQueue->PopStorageFilter();
}
ResultOrError<DeviceBase*> Adapter::CreateDeviceImpl(const DeviceDescriptor* descriptor) {
return Device::Create(this, descriptor);
}

View File

@ -27,7 +27,7 @@ namespace dawn_native { namespace d3d12 {
class Adapter : public AdapterBase {
public:
Adapter(Backend* backend, ComPtr<IDXGIAdapter3> hardwareAdapter);
~Adapter() override = default;
~Adapter() override;
const D3D12DeviceInfo& GetDeviceInfo() const;
IDXGIAdapter3* GetHardwareAdapter() const;
@ -39,6 +39,8 @@ namespace dawn_native { namespace d3d12 {
private:
ResultOrError<DeviceBase*> CreateDeviceImpl(const DeviceDescriptor* descriptor) override;
void InitializeSupportedExtensions();
MaybeError InitializeDebugLayerFilters();
void CleanUpDebugLayerFilters();
ComPtr<IDXGIAdapter3> mHardwareAdapter;
ComPtr<ID3D12Device> mD3d12Device;

View File

@ -17,6 +17,7 @@
#include "common/Assert.h"
#include "dawn_native/BackendConnection.h"
#include "dawn_native/ErrorData.h"
#include "dawn_native/Instance.h"
#include "dawn_native/d3d12/AdapterD3D12.h"
#include "dawn_native/d3d12/BackendD3D12.h"
#include "dawn_native/d3d12/BindGroupD3D12.h"
@ -41,12 +42,16 @@
#include "dawn_native/d3d12/SwapChainD3D12.h"
#include "dawn_native/d3d12/TextureD3D12.h"
#include <sstream>
namespace dawn_native { namespace d3d12 {
// TODO(dawn:155): Figure out these values.
static constexpr uint16_t kShaderVisibleDescriptorHeapSize = 1024;
static constexpr uint8_t kAttachmentDescriptorHeapSize = 64;
static constexpr uint64_t kMaxDebugMessagesToPrint = 5;
// static
ResultOrError<Device*> Device::Create(Adapter* adapter, const DeviceDescriptor* descriptor) {
Ref<Device> device = AcquireRef(new Device(adapter, descriptor));
@ -221,6 +226,9 @@ namespace dawn_native { namespace d3d12 {
mUsedComObjectRefs.ClearUpTo(completedSerial);
DAWN_TRY(ExecutePendingCommandContext());
DAWN_TRY(NextSerial());
DAWN_TRY(CheckDebugLayerAndGenerateErrors());
return {};
}
@ -460,6 +468,51 @@ namespace dawn_native { namespace d3d12 {
return {};
}
MaybeError Device::CheckDebugLayerAndGenerateErrors() {
if (!GetAdapter()->GetInstance()->IsBackendValidationEnabled()) {
return {};
}
ComPtr<ID3D12InfoQueue> infoQueue;
ASSERT_SUCCESS(mD3d12Device.As(&infoQueue));
uint64_t totalErrors = infoQueue->GetNumStoredMessagesAllowedByRetrievalFilter();
// Check if any errors have occurred otherwise we would be creating an empty error. Note
// that we use GetNumStoredMessagesAllowedByRetrievalFilter instead of GetNumStoredMessages
// because we only convert WARNINGS or higher messages to dawn errors.
if (totalErrors == 0) {
return {};
}
std::ostringstream messages;
uint64_t errorsToPrint = std::min(kMaxDebugMessagesToPrint, totalErrors);
for (uint64_t i = 0; i < errorsToPrint; ++i) {
SIZE_T messageLength = 0;
HRESULT hr = infoQueue->GetMessageW(i, nullptr, &messageLength);
if (FAILED(hr)) {
messages << " ID3D12InfoQueue::GetMessageW failed with " << hr << '\n';
continue;
}
std::unique_ptr<uint8_t[]> messageData(new uint8_t[messageLength]);
D3D12_MESSAGE* message = reinterpret_cast<D3D12_MESSAGE*>(messageData.get());
hr = infoQueue->GetMessageW(i, message, &messageLength);
if (FAILED(hr)) {
messages << " ID3D12InfoQueue::GetMessageW failed with " << hr << '\n';
continue;
}
messages << message->pDescription << " (" << message->ID << ")\n";
}
if (errorsToPrint < totalErrors) {
messages << (totalErrors - errorsToPrint) << " messages silenced\n";
}
// We only print up to the first kMaxDebugMessagesToPrint errors
infoQueue->ClearStoredMessages();
return DAWN_INTERNAL_ERROR(messages.str());
}
void Device::ShutDownImpl() {
ASSERT(GetState() == State::Disconnected);

View File

@ -156,6 +156,8 @@ namespace dawn_native { namespace d3d12 {
void ShutDownImpl() override;
MaybeError WaitForIdleForDestruction() override;
MaybeError CheckDebugLayerAndGenerateErrors();
ComPtr<ID3D12Fence> mFence;
HANDLE mFenceEvent = nullptr;
Serial CheckAndUpdateCompletedSerials() override;