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:
parent
6ced832d74
commit
4c32bd0b7d
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue