Improving D3D12 backend validation messages.

Improves validation messages in various D3D12 backend files:

 - CommandBufferD3D12.cpp
 - ShaderModuleD3D12.cpp
 - SwapChainD3D12.cpp
 - TextureD3D12.cpp

Bug: dawn:563
Change-Id: I00607012f5bec81780c419993fc32dc0984dad27
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/67143
Commit-Queue: Brandon Jones <bajones@chromium.org>
Commit-Queue: Austin Eng <enga@chromium.org>
Auto-Submit: Brandon Jones <bajones@chromium.org>
Reviewed-by: Austin Eng <enga@chromium.org>
This commit is contained in:
Brandon Jones 2021-10-21 20:21:54 +00:00 committed by Dawn LUCI CQ
parent 0cd8edc31b
commit 1d55306255
5 changed files with 60 additions and 69 deletions

View File

@ -1068,11 +1068,10 @@ namespace dawn_native { namespace d3d12 {
DispatchIndirectCmd* dispatch = mCommands.NextCommand<DispatchIndirectCmd>(); DispatchIndirectCmd* dispatch = mCommands.NextCommand<DispatchIndirectCmd>();
// TODO(dawn:839): support [[num_workgroups]] for DispatchIndirect calls // TODO(dawn:839): support [[num_workgroups]] for DispatchIndirect calls
if (lastPipeline->UsesNumWorkgroups()) { DAWN_INVALID_IF(lastPipeline->UsesNumWorkgroups(),
return DAWN_VALIDATION_ERROR( "Using %s with [[num_workgroups]] in a DispatchIndirect call "
"Using a compute pipeline with [[num_workgroups]] in a " "is not implemented.",
"DispatchIndirect call is not implemented"); lastPipeline);
}
Buffer* buffer = ToBackend(dispatch->indirectBuffer.Get()); Buffer* buffer = ToBackend(dispatch->indirectBuffer.Get());

View File

@ -138,7 +138,9 @@ namespace dawn_native { namespace d3d12 {
} }
if (backendDevice->ConsumedError( if (backendDevice->ConsumedError(
ValidateTextureDescriptorCanBeWrapped(textureDescriptor))) { ValidateTextureDescriptorCanBeWrapped(textureDescriptor),
"validating that a D3D12 external image can be wrapped with %s",
textureDescriptor)) {
return nullptr; return nullptr;
} }

View File

@ -341,9 +341,8 @@ namespace dawn_native { namespace d3d12 {
ComPtr<IDxcBlobEncoding> errors; ComPtr<IDxcBlobEncoding> errors;
DAWN_TRY(CheckHRESULT(result->GetErrorBuffer(&errors), "DXC get error buffer")); DAWN_TRY(CheckHRESULT(result->GetErrorBuffer(&errors), "DXC get error buffer"));
std::string message = std::string("DXC compile failed with ") + return DAWN_FORMAT_VALIDATION_ERROR("DXC compile failed with: %s",
static_cast<char*>(errors->GetBufferPointer()); static_cast<char*>(errors->GetBufferPointer()));
return DAWN_VALIDATION_ERROR(message);
} }
ComPtr<IDxcBlob> compiledShader; ComPtr<IDxcBlob> compiledShader;
@ -370,14 +369,12 @@ namespace dawn_native { namespace d3d12 {
ComPtr<ID3DBlob> compiledShader; ComPtr<ID3DBlob> compiledShader;
ComPtr<ID3DBlob> errors; ComPtr<ID3DBlob> errors;
if (FAILED(functions->d3dCompile(hlslSource.c_str(), hlslSource.length(), nullptr, DAWN_INVALID_IF(FAILED(functions->d3dCompile(
nullptr, nullptr, request.entryPointName, hlslSource.c_str(), hlslSource.length(), nullptr, nullptr, nullptr,
targetProfile, request.compileFlags, 0, request.entryPointName, targetProfile, request.compileFlags, 0,
&compiledShader, &errors))) { &compiledShader, &errors)),
std::string message = std::string("D3D compile failed with ") + "D3D compile failed with: %s",
static_cast<char*>(errors->GetBufferPointer()); static_cast<char*>(errors->GetBufferPointer()));
return DAWN_VALIDATION_ERROR(message);
}
return std::move(compiledShader); return std::move(compiledShader);
} }
@ -421,15 +418,13 @@ namespace dawn_native { namespace d3d12 {
if (it != data->remappings.end()) { if (it != data->remappings.end()) {
*remappedEntryPointName = it->second; *remappedEntryPointName = it->second;
} else { } else {
if (request.disableSymbolRenaming) { DAWN_INVALID_IF(!request.disableSymbolRenaming,
*remappedEntryPointName = request.entryPointName; "Could not find remapped name for entry point.");
} else {
return DAWN_VALIDATION_ERROR( *remappedEntryPointName = request.entryPointName;
"Could not find remapped name for entry point.");
}
} }
} else { } else {
return DAWN_VALIDATION_ERROR("Transform output missing renamer data."); return DAWN_FORMAT_VALIDATION_ERROR("Transform output missing renamer data.");
} }
tint::writer::hlsl::Options options; tint::writer::hlsl::Options options;
@ -439,10 +434,8 @@ namespace dawn_native { namespace d3d12 {
options.root_constant_binding_point.binding = request.numWorkgroupsShaderRegister; options.root_constant_binding_point.binding = request.numWorkgroupsShaderRegister;
} }
auto result = tint::writer::hlsl::Generate(&transformedProgram, options); auto result = tint::writer::hlsl::Generate(&transformedProgram, options);
if (!result.success) { DAWN_INVALID_IF(!result.success, "An error occured while generating HLSL: %s",
errorStream << "Generator: " << result.error << std::endl; result.error);
return DAWN_VALIDATION_ERROR(errorStream.str().c_str());
}
return std::move(result.hlsl); return std::move(result.hlsl);
} }

View File

@ -166,9 +166,9 @@ namespace dawn_native { namespace d3d12 {
// TODO(crbug.com/dawn/269): figure out what should happen when surfaces are used by // TODO(crbug.com/dawn/269): figure out what should happen when surfaces are used by
// multiple backends one after the other. It probably needs to block until the backend // multiple backends one after the other. It probably needs to block until the backend
// and GPU are completely finished with the previous swapchain. // and GPU are completely finished with the previous swapchain.
if (previousSwapChain->GetBackendType() != wgpu::BackendType::D3D12) { DAWN_INVALID_IF(previousSwapChain->GetBackendType() != wgpu::BackendType::D3D12,
return DAWN_VALIDATION_ERROR("d3d12::SwapChain cannot switch between APIs"); "D3D12 SwapChain cannot switch backend types from %s to %s.",
} previousSwapChain->GetBackendType(), wgpu::BackendType::D3D12);
// TODO(crbug.com/dawn/269): use ToBackend once OldSwapChainBase is removed. // TODO(crbug.com/dawn/269): use ToBackend once OldSwapChainBase is removed.
SwapChain* previousD3D12SwapChain = static_cast<SwapChain*>(previousSwapChain); SwapChain* previousD3D12SwapChain = static_cast<SwapChain*>(previousSwapChain);
@ -176,9 +176,8 @@ namespace dawn_native { namespace d3d12 {
// TODO(crbug.com/dawn/269): Figure out switching an HWND between devices, it might // TODO(crbug.com/dawn/269): Figure out switching an HWND between devices, it might
// require just losing the reference to the swapchain, but might also need to wait for // require just losing the reference to the swapchain, but might also need to wait for
// all previous operations to complete. // all previous operations to complete.
if (GetDevice() != previousSwapChain->GetDevice()) { DAWN_INVALID_IF(GetDevice() != previousSwapChain->GetDevice(),
return DAWN_VALIDATION_ERROR("d3d12::SwapChain cannot switch between devices"); "D3D12 SwapChain cannot switch between D3D Devices");
}
// The previous swapchain is on the same device so we want to reuse it but it is still not // The previous swapchain is on the same device so we want to reuse it but it is still not
// always possible. Because DXGI requires that a new swapchain be created if the // always possible. Because DXGI requires that a new swapchain be created if the

View File

@ -423,21 +423,18 @@ namespace dawn_native { namespace d3d12 {
} }
MaybeError ValidateTextureDescriptorCanBeWrapped(const TextureDescriptor* descriptor) { MaybeError ValidateTextureDescriptorCanBeWrapped(const TextureDescriptor* descriptor) {
if (descriptor->dimension != wgpu::TextureDimension::e2D) { DAWN_INVALID_IF(descriptor->dimension != wgpu::TextureDimension::e2D,
return DAWN_VALIDATION_ERROR("Texture must be 2D"); "Texture dimension (%s) is not %s.", descriptor->dimension,
} wgpu::TextureDimension::e2D);
if (descriptor->mipLevelCount != 1) { DAWN_INVALID_IF(descriptor->mipLevelCount != 1, "Mip level count (%u) is not 1.",
return DAWN_VALIDATION_ERROR("Mip level count must be 1"); descriptor->mipLevelCount);
}
if (descriptor->size.depthOrArrayLayers != 1) { DAWN_INVALID_IF(descriptor->size.depthOrArrayLayers != 1,
return DAWN_VALIDATION_ERROR("Depth must be 1"); "Array layer count (%u) is not 1.", descriptor->size.depthOrArrayLayers);
}
if (descriptor->sampleCount != 1) { DAWN_INVALID_IF(descriptor->sampleCount != 1, "Sample count (%u) is not 1.",
return DAWN_VALIDATION_ERROR("Sample count must be 1"); descriptor->sampleCount);
}
return {}; return {};
} }
@ -445,25 +442,27 @@ namespace dawn_native { namespace d3d12 {
MaybeError ValidateD3D12TextureCanBeWrapped(ID3D12Resource* d3d12Resource, MaybeError ValidateD3D12TextureCanBeWrapped(ID3D12Resource* d3d12Resource,
const TextureDescriptor* dawnDescriptor) { const TextureDescriptor* dawnDescriptor) {
const D3D12_RESOURCE_DESC d3dDescriptor = d3d12Resource->GetDesc(); const D3D12_RESOURCE_DESC d3dDescriptor = d3d12Resource->GetDesc();
if ((dawnDescriptor->size.width != d3dDescriptor.Width) || DAWN_INVALID_IF(
(dawnDescriptor->size.height != d3dDescriptor.Height) || (dawnDescriptor->size.width != d3dDescriptor.Width) ||
(dawnDescriptor->size.depthOrArrayLayers != 1)) { (dawnDescriptor->size.height != d3dDescriptor.Height) ||
return DAWN_VALIDATION_ERROR("D3D12 texture size doesn't match descriptor"); (dawnDescriptor->size.depthOrArrayLayers != 1),
} "D3D12 texture size (Width: %u, Height: %u, DepthOrArraySize: 1) doesn't match Dawn "
"descriptor size (width: %u, height: %u, depthOrArrayLayers: %u).",
d3dDescriptor.Width, d3dDescriptor.Height, dawnDescriptor->size.width,
dawnDescriptor->size.height, dawnDescriptor->size.depthOrArrayLayers);
const DXGI_FORMAT dxgiFormatFromDescriptor = D3D12TextureFormat(dawnDescriptor->format); const DXGI_FORMAT dxgiFormatFromDescriptor = D3D12TextureFormat(dawnDescriptor->format);
if (dxgiFormatFromDescriptor != d3dDescriptor.Format) { DAWN_INVALID_IF(
return DAWN_VALIDATION_ERROR( dxgiFormatFromDescriptor != d3dDescriptor.Format,
"D3D12 texture format must be compatible with descriptor format."); "D3D12 texture format (%x) is not compatible with Dawn descriptor format (%s).",
} d3dDescriptor.Format, dawnDescriptor->format);
if (d3dDescriptor.MipLevels != 1) { DAWN_INVALID_IF(d3dDescriptor.MipLevels != 1,
return DAWN_VALIDATION_ERROR("D3D12 texture number of miplevels must be 1."); "D3D12 texture number of miplevels (%u) is not 1.",
} d3dDescriptor.MipLevels);
if (d3dDescriptor.DepthOrArraySize != 1) { DAWN_INVALID_IF(d3dDescriptor.DepthOrArraySize != 1,
return DAWN_VALIDATION_ERROR("D3D12 texture array size must be 1."); "D3D12 texture array size (%u) is not 1.", d3dDescriptor.DepthOrArraySize);
}
// Shared textures cannot be multi-sample so no need to check those. // Shared textures cannot be multi-sample so no need to check those.
ASSERT(d3dDescriptor.SampleDesc.Count == 1); ASSERT(d3dDescriptor.SampleDesc.Count == 1);
@ -487,7 +486,7 @@ namespace dawn_native { namespace d3d12 {
break; break;
} }
return DAWN_VALIDATION_ERROR("DXGI format does not support cross-API sharing."); return DAWN_FORMAT_VALIDATION_ERROR("DXGI format does not support cross-API sharing.");
} }
// static // static
@ -496,9 +495,8 @@ namespace dawn_native { namespace d3d12 {
Ref<Texture> dawnTexture = Ref<Texture> dawnTexture =
AcquireRef(new Texture(device, descriptor, TextureState::OwnedInternal)); AcquireRef(new Texture(device, descriptor, TextureState::OwnedInternal));
if (dawnTexture->GetFormat().IsMultiPlanar()) { DAWN_INVALID_IF(dawnTexture->GetFormat().IsMultiPlanar(),
return DAWN_VALIDATION_ERROR("Cannot create a multi-planar formatted texture directly"); "Cannot create a multi-planar formatted texture directly");
}
DAWN_TRY(dawnTexture->InitializeAsInternalTexture()); DAWN_TRY(dawnTexture->InitializeAsInternalTexture());
return std::move(dawnTexture); return std::move(dawnTexture);
@ -522,10 +520,10 @@ namespace dawn_native { namespace d3d12 {
// Importing a multi-planar format must be initialized. This is required because // Importing a multi-planar format must be initialized. This is required because
// a shared multi-planar format cannot be initialized by Dawn. // a shared multi-planar format cannot be initialized by Dawn.
if (!isInitialized && dawnTexture->GetFormat().IsMultiPlanar()) { DAWN_INVALID_IF(
return DAWN_VALIDATION_ERROR( !isInitialized && dawnTexture->GetFormat().IsMultiPlanar(),
"Cannot create a multi-planar formatted texture without being initialized"); "Cannot create a texture with a multi-planar format (%s) with uninitialized data.",
} dawnTexture->GetFormat().format);
dawnTexture->SetIsSubresourceContentInitialized(isInitialized, dawnTexture->SetIsSubresourceContentInitialized(isInitialized,
dawnTexture->GetAllSubresources()); dawnTexture->GetAllSubresources());