Various validation error improvements
A grab bag of validation error message improvements in the following files: - Adapter.cpp - BackendConnection.cpp - BindGroup.cpp - CommandBuffer.cpp - CommandBufferStateTracker.cpp - ComputePipeline.cpp - Device.cpp - Instance.cpp - Limits.cpp - Queue.cpp Bug: dawn:563 Change-Id: Ied9f660fc22302d3fd5af4796de32efec529ca05 Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/67001 Commit-Queue: Brandon Jones <bajones@chromium.org> Reviewed-by: Austin Eng <enga@chromium.org>
This commit is contained in:
parent
6ec86e0411
commit
520539f8f9
|
@ -144,8 +144,8 @@ namespace dawn_native {
|
||||||
|
|
||||||
if (err.IsError()) {
|
if (err.IsError()) {
|
||||||
std::unique_ptr<ErrorData> errorData = err.AcquireError();
|
std::unique_ptr<ErrorData> errorData = err.AcquireError();
|
||||||
callback(WGPURequestDeviceStatus_Error, device, errorData->GetMessage().c_str(),
|
callback(WGPURequestDeviceStatus_Error, device,
|
||||||
userdata);
|
errorData->GetFormattedMessage().c_str(), userdata);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
WGPURequestDeviceStatus status =
|
WGPURequestDeviceStatus status =
|
||||||
|
@ -166,9 +166,11 @@ namespace dawn_native {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (descriptor != nullptr && descriptor->requiredLimits != nullptr) {
|
if (descriptor != nullptr && descriptor->requiredLimits != nullptr) {
|
||||||
DAWN_TRY(ValidateLimits(
|
DAWN_TRY_CONTEXT(
|
||||||
mUseTieredLimits ? ApplyLimitTiers(mLimits.v1) : mLimits.v1,
|
ValidateLimits(
|
||||||
reinterpret_cast<const RequiredLimits*>(descriptor->requiredLimits)->limits));
|
mUseTieredLimits ? ApplyLimitTiers(mLimits.v1) : mLimits.v1,
|
||||||
|
reinterpret_cast<const RequiredLimits*>(descriptor->requiredLimits)->limits),
|
||||||
|
"validating required limits");
|
||||||
|
|
||||||
DAWN_INVALID_IF(descriptor->requiredLimits->nextInChain != nullptr,
|
DAWN_INVALID_IF(descriptor->requiredLimits->nextInChain != nullptr,
|
||||||
"nextInChain is not nullptr.");
|
"nextInChain is not nullptr.");
|
||||||
|
|
|
@ -30,7 +30,7 @@ namespace dawn_native {
|
||||||
|
|
||||||
ResultOrError<std::vector<std::unique_ptr<AdapterBase>>> BackendConnection::DiscoverAdapters(
|
ResultOrError<std::vector<std::unique_ptr<AdapterBase>>> BackendConnection::DiscoverAdapters(
|
||||||
const AdapterDiscoveryOptionsBase* options) {
|
const AdapterDiscoveryOptionsBase* options) {
|
||||||
return DAWN_VALIDATION_ERROR("DiscoverAdapters not implemented for this backend.");
|
return DAWN_FORMAT_VALIDATION_ERROR("DiscoverAdapters not implemented for this backend.");
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace dawn_native
|
} // namespace dawn_native
|
||||||
|
|
|
@ -36,10 +36,13 @@ namespace dawn_native {
|
||||||
MaybeError ValidateBufferBinding(const DeviceBase* device,
|
MaybeError ValidateBufferBinding(const DeviceBase* device,
|
||||||
const BindGroupEntry& entry,
|
const BindGroupEntry& entry,
|
||||||
const BindingInfo& bindingInfo) {
|
const BindingInfo& bindingInfo) {
|
||||||
if (entry.buffer == nullptr || entry.sampler != nullptr ||
|
DAWN_INVALID_IF(entry.buffer == nullptr, "Binding entry buffer not set.");
|
||||||
entry.textureView != nullptr || entry.nextInChain != nullptr) {
|
|
||||||
return DAWN_VALIDATION_ERROR("Expected buffer binding");
|
DAWN_INVALID_IF(entry.sampler != nullptr || entry.textureView != nullptr,
|
||||||
}
|
"Expected only buffer to be set for binding entry.");
|
||||||
|
|
||||||
|
DAWN_INVALID_IF(entry.nextInChain != nullptr, "nextInChain must be nullptr.");
|
||||||
|
|
||||||
DAWN_TRY(device->ValidateObject(entry.buffer));
|
DAWN_TRY(device->ValidateObject(entry.buffer));
|
||||||
|
|
||||||
ASSERT(bindingInfo.bindingType == BindingInfoType::Buffer);
|
ASSERT(bindingInfo.bindingType == BindingInfoType::Buffer);
|
||||||
|
@ -116,10 +119,13 @@ namespace dawn_native {
|
||||||
MaybeError ValidateTextureBinding(DeviceBase* device,
|
MaybeError ValidateTextureBinding(DeviceBase* device,
|
||||||
const BindGroupEntry& entry,
|
const BindGroupEntry& entry,
|
||||||
const BindingInfo& bindingInfo) {
|
const BindingInfo& bindingInfo) {
|
||||||
if (entry.textureView == nullptr || entry.sampler != nullptr ||
|
DAWN_INVALID_IF(entry.textureView == nullptr, "Binding entry textureView not set.");
|
||||||
entry.buffer != nullptr || entry.nextInChain != nullptr) {
|
|
||||||
return DAWN_VALIDATION_ERROR("Expected texture binding");
|
DAWN_INVALID_IF(entry.sampler != nullptr || entry.buffer != nullptr,
|
||||||
}
|
"Expected only textureView to be set for binding entry.");
|
||||||
|
|
||||||
|
DAWN_INVALID_IF(entry.nextInChain != nullptr, "nextInChain must be nullptr.");
|
||||||
|
|
||||||
DAWN_TRY(device->ValidateObject(entry.textureView));
|
DAWN_TRY(device->ValidateObject(entry.textureView));
|
||||||
|
|
||||||
TextureViewBase* view = entry.textureView;
|
TextureViewBase* view = entry.textureView;
|
||||||
|
@ -189,10 +195,13 @@ namespace dawn_native {
|
||||||
MaybeError ValidateSamplerBinding(const DeviceBase* device,
|
MaybeError ValidateSamplerBinding(const DeviceBase* device,
|
||||||
const BindGroupEntry& entry,
|
const BindGroupEntry& entry,
|
||||||
const BindingInfo& bindingInfo) {
|
const BindingInfo& bindingInfo) {
|
||||||
if (entry.sampler == nullptr || entry.textureView != nullptr ||
|
DAWN_INVALID_IF(entry.sampler == nullptr, "Binding entry sampler not set.");
|
||||||
entry.buffer != nullptr || entry.nextInChain != nullptr) {
|
|
||||||
return DAWN_VALIDATION_ERROR("Expected sampler binding");
|
DAWN_INVALID_IF(entry.textureView != nullptr || entry.buffer != nullptr,
|
||||||
}
|
"Expected only sampler to be set for binding entry.");
|
||||||
|
|
||||||
|
DAWN_INVALID_IF(entry.nextInChain != nullptr, "nextInChain must be nullptr.");
|
||||||
|
|
||||||
DAWN_TRY(device->ValidateObject(entry.sampler));
|
DAWN_TRY(device->ValidateObject(entry.sampler));
|
||||||
|
|
||||||
ASSERT(bindingInfo.bindingType == BindingInfoType::Sampler);
|
ASSERT(bindingInfo.bindingType == BindingInfoType::Sampler);
|
||||||
|
@ -233,10 +242,12 @@ namespace dawn_native {
|
||||||
const ExternalTextureBindingEntry* externalTextureBindingEntry = nullptr;
|
const ExternalTextureBindingEntry* externalTextureBindingEntry = nullptr;
|
||||||
FindInChain(entry.nextInChain, &externalTextureBindingEntry);
|
FindInChain(entry.nextInChain, &externalTextureBindingEntry);
|
||||||
|
|
||||||
if (entry.sampler != nullptr || entry.textureView != nullptr ||
|
DAWN_INVALID_IF(externalTextureBindingEntry == nullptr,
|
||||||
entry.buffer != nullptr || externalTextureBindingEntry == nullptr) {
|
"Binding entry external texture not set.");
|
||||||
return DAWN_VALIDATION_ERROR("Expected external texture binding");
|
|
||||||
}
|
DAWN_INVALID_IF(
|
||||||
|
entry.sampler != nullptr || entry.textureView != nullptr || entry.buffer != nullptr,
|
||||||
|
"Expected only external texture to be set for binding entry.");
|
||||||
|
|
||||||
DAWN_TRY(ValidateSingleSType(externalTextureBindingEntry->nextInChain,
|
DAWN_TRY(ValidateSingleSType(externalTextureBindingEntry->nextInChain,
|
||||||
wgpu::SType::ExternalTextureBindingEntry));
|
wgpu::SType::ExternalTextureBindingEntry));
|
||||||
|
@ -250,9 +261,7 @@ namespace dawn_native {
|
||||||
|
|
||||||
MaybeError ValidateBindGroupDescriptor(DeviceBase* device,
|
MaybeError ValidateBindGroupDescriptor(DeviceBase* device,
|
||||||
const BindGroupDescriptor* descriptor) {
|
const BindGroupDescriptor* descriptor) {
|
||||||
if (descriptor->nextInChain != nullptr) {
|
DAWN_INVALID_IF(descriptor->nextInChain != nullptr, "nextInChain must be nullptr.");
|
||||||
return DAWN_VALIDATION_ERROR("nextInChain must be nullptr");
|
|
||||||
}
|
|
||||||
|
|
||||||
DAWN_TRY(device->ValidateObject(descriptor->layout));
|
DAWN_TRY(device->ValidateObject(descriptor->layout));
|
||||||
|
|
||||||
|
|
|
@ -59,9 +59,7 @@ namespace dawn_native {
|
||||||
MaybeError CommandBufferBase::ValidateCanUseInSubmitNow() const {
|
MaybeError CommandBufferBase::ValidateCanUseInSubmitNow() const {
|
||||||
ASSERT(!IsError());
|
ASSERT(!IsError());
|
||||||
|
|
||||||
if (mDestroyed) {
|
DAWN_INVALID_IF(mDestroyed, "%s cannot be submitted more than once.", this);
|
||||||
return DAWN_VALIDATION_ERROR("Command buffer reused in submit");
|
|
||||||
}
|
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -246,7 +246,7 @@ namespace dawn_native {
|
||||||
// because to have invalid aspects one of the above conditions must have failed earlier.
|
// because to have invalid aspects one of the above conditions must have failed earlier.
|
||||||
// If this is reached, make sure lazy aspects and the error checks above are consistent.
|
// If this is reached, make sure lazy aspects and the error checks above are consistent.
|
||||||
UNREACHABLE();
|
UNREACHABLE();
|
||||||
return DAWN_VALIDATION_ERROR("Index buffer invalid");
|
return DAWN_FORMAT_VALIDATION_ERROR("Index buffer is invalid.");
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(dawn:563): Indicate which slots were not set.
|
// TODO(dawn:563): Indicate which slots were not set.
|
||||||
|
@ -277,7 +277,7 @@ namespace dawn_native {
|
||||||
// because to have invalid aspects one of the above conditions must have failed earlier.
|
// because to have invalid aspects one of the above conditions must have failed earlier.
|
||||||
// If this is reached, make sure lazy aspects and the error checks above are consistent.
|
// If this is reached, make sure lazy aspects and the error checks above are consistent.
|
||||||
UNREACHABLE();
|
UNREACHABLE();
|
||||||
return DAWN_VALIDATION_ERROR("Bind groups invalid");
|
return DAWN_FORMAT_VALIDATION_ERROR("Bind groups are invalid.");
|
||||||
}
|
}
|
||||||
|
|
||||||
DAWN_INVALID_IF(aspects[VALIDATION_ASPECT_PIPELINE], "No pipeline set.");
|
DAWN_INVALID_IF(aspects[VALIDATION_ASPECT_PIPELINE], "No pipeline set.");
|
||||||
|
|
|
@ -23,7 +23,7 @@ namespace dawn_native {
|
||||||
MaybeError ValidateComputePipelineDescriptor(DeviceBase* device,
|
MaybeError ValidateComputePipelineDescriptor(DeviceBase* device,
|
||||||
const ComputePipelineDescriptor* descriptor) {
|
const ComputePipelineDescriptor* descriptor) {
|
||||||
if (descriptor->nextInChain != nullptr) {
|
if (descriptor->nextInChain != nullptr) {
|
||||||
return DAWN_VALIDATION_ERROR("nextInChain must be nullptr");
|
return DAWN_FORMAT_VALIDATION_ERROR("nextInChain must be nullptr.");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (descriptor->layout != nullptr) {
|
if (descriptor->layout != nullptr) {
|
||||||
|
|
|
@ -507,10 +507,8 @@ namespace dawn_native {
|
||||||
}
|
}
|
||||||
|
|
||||||
MaybeError DeviceBase::ValidateIsAlive() const {
|
MaybeError DeviceBase::ValidateIsAlive() const {
|
||||||
if (DAWN_LIKELY(mState == State::Alive)) {
|
DAWN_INVALID_IF(mState != State::Alive, "%s is lost.", this);
|
||||||
return {};
|
return {};
|
||||||
}
|
|
||||||
return DAWN_VALIDATION_ERROR("Device is lost");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DeviceBase::APILoseForTesting() {
|
void DeviceBase::APILoseForTesting() {
|
||||||
|
@ -615,14 +613,10 @@ namespace dawn_native {
|
||||||
|
|
||||||
ResultOrError<const Format*> DeviceBase::GetInternalFormat(wgpu::TextureFormat format) const {
|
ResultOrError<const Format*> DeviceBase::GetInternalFormat(wgpu::TextureFormat format) const {
|
||||||
size_t index = ComputeFormatIndex(format);
|
size_t index = ComputeFormatIndex(format);
|
||||||
if (index >= mFormatTable.size()) {
|
DAWN_INVALID_IF(index >= mFormatTable.size(), "Unknown texture format %s.", format);
|
||||||
return DAWN_VALIDATION_ERROR("Unknown texture format");
|
|
||||||
}
|
|
||||||
|
|
||||||
const Format* internalFormat = &mFormatTable[index];
|
const Format* internalFormat = &mFormatTable[index];
|
||||||
if (!internalFormat->isSupported) {
|
DAWN_INVALID_IF(!internalFormat->isSupported, "Unsupported texture format %s.", format);
|
||||||
return DAWN_VALIDATION_ERROR("Unsupported texture format");
|
|
||||||
}
|
|
||||||
|
|
||||||
return internalFormat;
|
return internalFormat;
|
||||||
}
|
}
|
||||||
|
|
|
@ -185,9 +185,7 @@ namespace dawn_native {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!foundBackend) {
|
DAWN_INVALID_IF(!foundBackend, "No matching backend found.");
|
||||||
return DAWN_VALIDATION_ERROR("Backend isn't present.");
|
|
||||||
}
|
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -98,9 +98,9 @@ namespace dawn_native {
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
static MaybeError Validate(T supported, T required) {
|
static MaybeError Validate(T supported, T required) {
|
||||||
if (IsBetter(required, supported)) {
|
DAWN_INVALID_IF(IsBetter(required, supported),
|
||||||
return DAWN_VALIDATION_ERROR("requiredLimit lower than supported limit");
|
"Required limit (%u) is lower than the supported limit (%u).",
|
||||||
}
|
required, supported);
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -114,9 +114,9 @@ namespace dawn_native {
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
static MaybeError Validate(T supported, T required) {
|
static MaybeError Validate(T supported, T required) {
|
||||||
if (IsBetter(required, supported)) {
|
DAWN_INVALID_IF(IsBetter(required, supported),
|
||||||
return DAWN_VALIDATION_ERROR("requiredLimit greater than supported limit");
|
"Required limit (%u) is greater than the supported limit (%u).",
|
||||||
}
|
required, supported);
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -163,10 +163,11 @@ namespace dawn_native {
|
||||||
}
|
}
|
||||||
|
|
||||||
MaybeError ValidateLimits(const Limits& supportedLimits, const Limits& requiredLimits) {
|
MaybeError ValidateLimits(const Limits& supportedLimits, const Limits& requiredLimits) {
|
||||||
#define X(Better, limitName, ...) \
|
#define X(Better, limitName, ...) \
|
||||||
if (!IsLimitUndefined(requiredLimits.limitName)) { \
|
if (!IsLimitUndefined(requiredLimits.limitName)) { \
|
||||||
DAWN_TRY(CheckLimit<LimitBetterDirection::Better>::Validate(supportedLimits.limitName, \
|
DAWN_TRY_CONTEXT(CheckLimit<LimitBetterDirection::Better>::Validate( \
|
||||||
requiredLimits.limitName)); \
|
supportedLimits.limitName, requiredLimits.limitName), \
|
||||||
|
"validating " #limitName); \
|
||||||
}
|
}
|
||||||
LIMITS(X)
|
LIMITS(X)
|
||||||
#undef X
|
#undef X
|
||||||
|
|
|
@ -434,9 +434,7 @@ namespace dawn_native {
|
||||||
*status = WGPUQueueWorkDoneStatus_Error;
|
*status = WGPUQueueWorkDoneStatus_Error;
|
||||||
DAWN_TRY(GetDevice()->ValidateObject(this));
|
DAWN_TRY(GetDevice()->ValidateObject(this));
|
||||||
|
|
||||||
if (signalValue != 0) {
|
DAWN_INVALID_IF(signalValue != 0, "SignalValue (%u) is not 0.", signalValue);
|
||||||
return DAWN_VALIDATION_ERROR("SignalValue must currently be 0.");
|
|
||||||
}
|
|
||||||
|
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
@ -451,17 +449,17 @@ namespace dawn_native {
|
||||||
|
|
||||||
DAWN_TRY(ValidateImageCopyTexture(GetDevice(), *destination, *writeSize));
|
DAWN_TRY(ValidateImageCopyTexture(GetDevice(), *destination, *writeSize));
|
||||||
|
|
||||||
if (dataLayout.offset > dataSize) {
|
DAWN_INVALID_IF(dataLayout.offset > dataSize,
|
||||||
return DAWN_VALIDATION_ERROR("Queue::WriteTexture out of range");
|
"Data offset (%u) is greater than the data size (%u).", dataLayout.offset,
|
||||||
}
|
dataSize);
|
||||||
|
|
||||||
if (!(destination->texture->GetUsage() & wgpu::TextureUsage::CopyDst)) {
|
DAWN_INVALID_IF(!(destination->texture->GetUsage() & wgpu::TextureUsage::CopyDst),
|
||||||
return DAWN_VALIDATION_ERROR("Texture needs the CopyDst usage bit");
|
"Usage (%s) of %s does not include %s.", destination->texture->GetUsage(),
|
||||||
}
|
destination->texture, wgpu::TextureUsage::CopyDst);
|
||||||
|
|
||||||
if (destination->texture->GetSampleCount() > 1) {
|
DAWN_INVALID_IF(destination->texture->GetSampleCount() > 1,
|
||||||
return DAWN_VALIDATION_ERROR("The sample count of textures must be 1");
|
"Sample count (%u) of %s is not 1", destination->texture->GetSampleCount(),
|
||||||
}
|
destination->texture);
|
||||||
|
|
||||||
DAWN_TRY(ValidateLinearToDepthStencilCopyRestrictions(*destination));
|
DAWN_TRY(ValidateLinearToDepthStencilCopyRestrictions(*destination));
|
||||||
// We validate texture copy range before validating linear texture data,
|
// We validate texture copy range before validating linear texture data,
|
||||||
|
|
Loading…
Reference in New Issue