mirror of
https://github.com/encounter/dawn-cmake.git
synced 2025-09-01 16:28:39 +00:00
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>
197 lines
7.9 KiB
C++
197 lines
7.9 KiB
C++
// Copyright 2018 The Dawn Authors
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
#include "dawn_native/Adapter.h"
|
|
|
|
#include "common/Constants.h"
|
|
#include "dawn_native/Instance.h"
|
|
|
|
namespace dawn_native {
|
|
|
|
AdapterBase::AdapterBase(InstanceBase* instance, wgpu::BackendType backend)
|
|
: mInstance(instance), mBackend(backend) {
|
|
mSupportedFeatures.EnableFeature(Feature::DawnInternalUsages);
|
|
}
|
|
|
|
MaybeError AdapterBase::Initialize() {
|
|
DAWN_TRY(InitializeImpl());
|
|
DAWN_TRY(InitializeSupportedFeaturesImpl());
|
|
DAWN_TRY(InitializeSupportedLimitsImpl(&mLimits));
|
|
|
|
// Enforce internal Dawn constants.
|
|
mLimits.v1.maxVertexBufferArrayStride =
|
|
std::min(mLimits.v1.maxVertexBufferArrayStride, kMaxVertexBufferArrayStride);
|
|
mLimits.v1.maxBindGroups = std::min(mLimits.v1.maxBindGroups, kMaxBindGroups);
|
|
mLimits.v1.maxVertexAttributes =
|
|
std::min(mLimits.v1.maxVertexAttributes, uint32_t(kMaxVertexAttributes));
|
|
mLimits.v1.maxVertexBuffers =
|
|
std::min(mLimits.v1.maxVertexBuffers, uint32_t(kMaxVertexBuffers));
|
|
mLimits.v1.maxInterStageShaderComponents =
|
|
std::min(mLimits.v1.maxInterStageShaderComponents, kMaxInterStageShaderComponents);
|
|
mLimits.v1.maxSampledTexturesPerShaderStage = std::min(
|
|
mLimits.v1.maxSampledTexturesPerShaderStage, kMaxSampledTexturesPerShaderStage);
|
|
mLimits.v1.maxSamplersPerShaderStage =
|
|
std::min(mLimits.v1.maxSamplersPerShaderStage, kMaxSamplersPerShaderStage);
|
|
mLimits.v1.maxStorageBuffersPerShaderStage =
|
|
std::min(mLimits.v1.maxStorageBuffersPerShaderStage, kMaxStorageBuffersPerShaderStage);
|
|
mLimits.v1.maxStorageTexturesPerShaderStage = std::min(
|
|
mLimits.v1.maxStorageTexturesPerShaderStage, kMaxStorageTexturesPerShaderStage);
|
|
mLimits.v1.maxUniformBuffersPerShaderStage =
|
|
std::min(mLimits.v1.maxUniformBuffersPerShaderStage, kMaxUniformBuffersPerShaderStage);
|
|
mLimits.v1.maxDynamicUniformBuffersPerPipelineLayout =
|
|
std::min(mLimits.v1.maxDynamicUniformBuffersPerPipelineLayout,
|
|
kMaxDynamicUniformBuffersPerPipelineLayout);
|
|
mLimits.v1.maxDynamicStorageBuffersPerPipelineLayout =
|
|
std::min(mLimits.v1.maxDynamicStorageBuffersPerPipelineLayout,
|
|
kMaxDynamicStorageBuffersPerPipelineLayout);
|
|
|
|
return {};
|
|
}
|
|
|
|
wgpu::BackendType AdapterBase::GetBackendType() const {
|
|
return mBackend;
|
|
}
|
|
|
|
wgpu::AdapterType AdapterBase::GetAdapterType() const {
|
|
return mAdapterType;
|
|
}
|
|
|
|
const std::string& AdapterBase::GetDriverDescription() const {
|
|
return mDriverDescription;
|
|
}
|
|
|
|
const PCIInfo& AdapterBase::GetPCIInfo() const {
|
|
return mPCIInfo;
|
|
}
|
|
|
|
InstanceBase* AdapterBase::GetInstance() const {
|
|
return mInstance;
|
|
}
|
|
|
|
FeaturesSet AdapterBase::GetSupportedFeatures() const {
|
|
return mSupportedFeatures;
|
|
}
|
|
|
|
bool AdapterBase::SupportsAllRequestedFeatures(
|
|
const std::vector<const char*>& requestedFeatures) const {
|
|
for (const char* featureStr : requestedFeatures) {
|
|
Feature featureEnum = mInstance->FeatureNameToEnum(featureStr);
|
|
if (featureEnum == Feature::InvalidEnum) {
|
|
return false;
|
|
}
|
|
if (!mSupportedFeatures.IsEnabled(featureEnum)) {
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
WGPUDeviceProperties AdapterBase::GetAdapterProperties() const {
|
|
WGPUDeviceProperties adapterProperties = {};
|
|
adapterProperties.deviceID = mPCIInfo.deviceId;
|
|
adapterProperties.vendorID = mPCIInfo.vendorId;
|
|
|
|
mSupportedFeatures.InitializeDeviceProperties(&adapterProperties);
|
|
// This is OK for now because there are no limit feature structs.
|
|
// If we add additional structs, the caller will need to provide memory
|
|
// to store them (ex. by calling GetLimits directly instead). Currently,
|
|
// we keep this function as it's only used internally in Chromium to
|
|
// send the adapter properties across the wire.
|
|
GetLimits(reinterpret_cast<SupportedLimits*>(&adapterProperties.limits));
|
|
return adapterProperties;
|
|
}
|
|
|
|
bool AdapterBase::GetLimits(SupportedLimits* limits) const {
|
|
ASSERT(limits != nullptr);
|
|
if (limits->nextInChain != nullptr) {
|
|
return false;
|
|
}
|
|
if (mUseTieredLimits) {
|
|
limits->limits = ApplyLimitTiers(mLimits.v1);
|
|
} else {
|
|
limits->limits = mLimits.v1;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
DeviceBase* AdapterBase::CreateDevice(const DeviceDescriptor* descriptor) {
|
|
DeviceBase* result = nullptr;
|
|
|
|
if (mInstance->ConsumedError(CreateDeviceInternal(&result, descriptor))) {
|
|
return nullptr;
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
void AdapterBase::RequestDevice(const DeviceDescriptor* descriptor,
|
|
WGPURequestDeviceCallback callback,
|
|
void* userdata) {
|
|
DeviceBase* result = nullptr;
|
|
MaybeError err = CreateDeviceInternal(&result, descriptor);
|
|
WGPUDevice device = reinterpret_cast<WGPUDevice>(result);
|
|
|
|
if (err.IsError()) {
|
|
std::unique_ptr<ErrorData> errorData = err.AcquireError();
|
|
callback(WGPURequestDeviceStatus_Error, device,
|
|
errorData->GetFormattedMessage().c_str(), userdata);
|
|
return;
|
|
}
|
|
WGPURequestDeviceStatus status =
|
|
device == nullptr ? WGPURequestDeviceStatus_Unknown : WGPURequestDeviceStatus_Success;
|
|
callback(status, device, nullptr, userdata);
|
|
}
|
|
|
|
MaybeError AdapterBase::CreateDeviceInternal(DeviceBase** result,
|
|
const DeviceDescriptor* descriptor) {
|
|
if (descriptor != nullptr) {
|
|
for (const char* featureStr : descriptor->requiredFeatures) {
|
|
Feature featureEnum = mInstance->FeatureNameToEnum(featureStr);
|
|
DAWN_INVALID_IF(featureEnum == Feature::InvalidEnum,
|
|
"Requested feature %s is unknown.", featureStr);
|
|
DAWN_INVALID_IF(!mSupportedFeatures.IsEnabled(featureEnum),
|
|
"Requested feature %s is disabled.", featureStr);
|
|
}
|
|
}
|
|
|
|
if (descriptor != nullptr && descriptor->requiredLimits != nullptr) {
|
|
DAWN_TRY_CONTEXT(
|
|
ValidateLimits(
|
|
mUseTieredLimits ? ApplyLimitTiers(mLimits.v1) : mLimits.v1,
|
|
reinterpret_cast<const RequiredLimits*>(descriptor->requiredLimits)->limits),
|
|
"validating required limits");
|
|
|
|
DAWN_INVALID_IF(descriptor->requiredLimits->nextInChain != nullptr,
|
|
"nextInChain is not nullptr.");
|
|
}
|
|
|
|
DAWN_TRY_ASSIGN(*result, CreateDeviceImpl(descriptor));
|
|
return {};
|
|
}
|
|
|
|
void AdapterBase::SetUseTieredLimits(bool useTieredLimits) {
|
|
mUseTieredLimits = useTieredLimits;
|
|
}
|
|
|
|
void AdapterBase::ResetInternalDeviceForTesting() {
|
|
mInstance->ConsumedError(ResetInternalDeviceForTestingImpl());
|
|
}
|
|
|
|
MaybeError AdapterBase::ResetInternalDeviceForTestingImpl() {
|
|
return DAWN_INTERNAL_ERROR(
|
|
"ResetInternalDeviceForTesting should only be used with the D3D12 backend.");
|
|
}
|
|
|
|
} // namespace dawn_native
|