• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2018 The Dawn Authors
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include "dawn_native/Adapter.h"
16 
17 #include "common/Constants.h"
18 #include "dawn_native/Instance.h"
19 
20 namespace dawn_native {
21 
AdapterBase(InstanceBase * instance,wgpu::BackendType backend)22     AdapterBase::AdapterBase(InstanceBase* instance, wgpu::BackendType backend)
23         : mInstance(instance), mBackend(backend) {
24         mSupportedFeatures.EnableFeature(Feature::DawnInternalUsages);
25     }
26 
Initialize()27     MaybeError AdapterBase::Initialize() {
28         DAWN_TRY_CONTEXT(InitializeImpl(), "initializing adapter (backend=%s)", mBackend);
29         DAWN_TRY_CONTEXT(
30             InitializeSupportedFeaturesImpl(),
31             "gathering supported features for \"%s\" - \"%s\" (vendorId=%#06x deviceId=%#06x "
32             "backend=%s type=%s)",
33             mPCIInfo.name, mDriverDescription, mPCIInfo.vendorId, mPCIInfo.deviceId, mBackend,
34             mAdapterType);
35         DAWN_TRY_CONTEXT(
36             InitializeSupportedLimitsImpl(&mLimits),
37             "gathering supported limits for \"%s\" - \"%s\" (vendorId=%#06x deviceId=%#06x "
38             "backend=%s type=%s)",
39             mPCIInfo.name, mDriverDescription, mPCIInfo.vendorId, mPCIInfo.deviceId, mBackend,
40             mAdapterType);
41 
42         // Enforce internal Dawn constants.
43         mLimits.v1.maxVertexBufferArrayStride =
44             std::min(mLimits.v1.maxVertexBufferArrayStride, kMaxVertexBufferArrayStride);
45         mLimits.v1.maxBindGroups = std::min(mLimits.v1.maxBindGroups, kMaxBindGroups);
46         mLimits.v1.maxVertexAttributes =
47             std::min(mLimits.v1.maxVertexAttributes, uint32_t(kMaxVertexAttributes));
48         mLimits.v1.maxVertexBuffers =
49             std::min(mLimits.v1.maxVertexBuffers, uint32_t(kMaxVertexBuffers));
50         mLimits.v1.maxInterStageShaderComponents =
51             std::min(mLimits.v1.maxInterStageShaderComponents, kMaxInterStageShaderComponents);
52         mLimits.v1.maxSampledTexturesPerShaderStage = std::min(
53             mLimits.v1.maxSampledTexturesPerShaderStage, kMaxSampledTexturesPerShaderStage);
54         mLimits.v1.maxSamplersPerShaderStage =
55             std::min(mLimits.v1.maxSamplersPerShaderStage, kMaxSamplersPerShaderStage);
56         mLimits.v1.maxStorageBuffersPerShaderStage =
57             std::min(mLimits.v1.maxStorageBuffersPerShaderStage, kMaxStorageBuffersPerShaderStage);
58         mLimits.v1.maxStorageTexturesPerShaderStage = std::min(
59             mLimits.v1.maxStorageTexturesPerShaderStage, kMaxStorageTexturesPerShaderStage);
60         mLimits.v1.maxUniformBuffersPerShaderStage =
61             std::min(mLimits.v1.maxUniformBuffersPerShaderStage, kMaxUniformBuffersPerShaderStage);
62         mLimits.v1.maxDynamicUniformBuffersPerPipelineLayout =
63             std::min(mLimits.v1.maxDynamicUniformBuffersPerPipelineLayout,
64                      kMaxDynamicUniformBuffersPerPipelineLayout);
65         mLimits.v1.maxDynamicStorageBuffersPerPipelineLayout =
66             std::min(mLimits.v1.maxDynamicStorageBuffersPerPipelineLayout,
67                      kMaxDynamicStorageBuffersPerPipelineLayout);
68 
69         return {};
70     }
71 
GetBackendType() const72     wgpu::BackendType AdapterBase::GetBackendType() const {
73         return mBackend;
74     }
75 
GetAdapterType() const76     wgpu::AdapterType AdapterBase::GetAdapterType() const {
77         return mAdapterType;
78     }
79 
GetDriverDescription() const80     const std::string& AdapterBase::GetDriverDescription() const {
81         return mDriverDescription;
82     }
83 
GetPCIInfo() const84     const PCIInfo& AdapterBase::GetPCIInfo() const {
85         return mPCIInfo;
86     }
87 
GetInstance() const88     InstanceBase* AdapterBase::GetInstance() const {
89         return mInstance;
90     }
91 
GetSupportedFeatures() const92     FeaturesSet AdapterBase::GetSupportedFeatures() const {
93         return mSupportedFeatures;
94     }
95 
SupportsAllRequestedFeatures(const std::vector<const char * > & requestedFeatures) const96     bool AdapterBase::SupportsAllRequestedFeatures(
97         const std::vector<const char*>& requestedFeatures) const {
98         for (const char* featureStr : requestedFeatures) {
99             Feature featureEnum = mInstance->FeatureNameToEnum(featureStr);
100             if (featureEnum == Feature::InvalidEnum) {
101                 return false;
102             }
103             if (!mSupportedFeatures.IsEnabled(featureEnum)) {
104                 return false;
105             }
106         }
107         return true;
108     }
109 
GetAdapterProperties() const110     WGPUDeviceProperties AdapterBase::GetAdapterProperties() const {
111         WGPUDeviceProperties adapterProperties = {};
112         adapterProperties.deviceID = mPCIInfo.deviceId;
113         adapterProperties.vendorID = mPCIInfo.vendorId;
114         adapterProperties.adapterType = static_cast<WGPUAdapterType>(mAdapterType);
115 
116         mSupportedFeatures.InitializeDeviceProperties(&adapterProperties);
117         // This is OK for now because there are no limit feature structs.
118         // If we add additional structs, the caller will need to provide memory
119         // to store them (ex. by calling GetLimits directly instead). Currently,
120         // we keep this function as it's only used internally in Chromium to
121         // send the adapter properties across the wire.
122         GetLimits(FromAPI(&adapterProperties.limits));
123         return adapterProperties;
124     }
125 
GetLimits(SupportedLimits * limits) const126     bool AdapterBase::GetLimits(SupportedLimits* limits) const {
127         ASSERT(limits != nullptr);
128         if (limits->nextInChain != nullptr) {
129             return false;
130         }
131         if (mUseTieredLimits) {
132             limits->limits = ApplyLimitTiers(mLimits.v1);
133         } else {
134             limits->limits = mLimits.v1;
135         }
136         return true;
137     }
138 
CreateDevice(const DawnDeviceDescriptor * descriptor)139     DeviceBase* AdapterBase::CreateDevice(const DawnDeviceDescriptor* descriptor) {
140         DeviceBase* result = nullptr;
141 
142         if (mInstance->ConsumedError(CreateDeviceInternal(&result, descriptor))) {
143             return nullptr;
144         }
145 
146         return result;
147     }
148 
RequestDevice(const DawnDeviceDescriptor * descriptor,WGPURequestDeviceCallback callback,void * userdata)149     void AdapterBase::RequestDevice(const DawnDeviceDescriptor* descriptor,
150                                     WGPURequestDeviceCallback callback,
151                                     void* userdata) {
152         DeviceBase* device = nullptr;
153         MaybeError err = CreateDeviceInternal(&device, descriptor);
154 
155         if (err.IsError()) {
156             std::unique_ptr<ErrorData> errorData = err.AcquireError();
157             callback(WGPURequestDeviceStatus_Error, ToAPI(device),
158                      errorData->GetFormattedMessage().c_str(), userdata);
159             return;
160         }
161         WGPURequestDeviceStatus status =
162             device == nullptr ? WGPURequestDeviceStatus_Unknown : WGPURequestDeviceStatus_Success;
163         callback(status, ToAPI(device), nullptr, userdata);
164     }
165 
CreateDeviceInternal(DeviceBase ** result,const DawnDeviceDescriptor * descriptor)166     MaybeError AdapterBase::CreateDeviceInternal(DeviceBase** result,
167                                                  const DawnDeviceDescriptor* descriptor) {
168         if (descriptor != nullptr) {
169             for (const char* featureStr : descriptor->requiredFeatures) {
170                 Feature featureEnum = mInstance->FeatureNameToEnum(featureStr);
171                 DAWN_INVALID_IF(featureEnum == Feature::InvalidEnum,
172                                 "Requested feature %s is unknown.", featureStr);
173                 DAWN_INVALID_IF(!mSupportedFeatures.IsEnabled(featureEnum),
174                                 "Requested feature %s is disabled.", featureStr);
175             }
176         }
177 
178         if (descriptor != nullptr && descriptor->requiredLimits != nullptr) {
179             DAWN_TRY_CONTEXT(
180                 ValidateLimits(mUseTieredLimits ? ApplyLimitTiers(mLimits.v1) : mLimits.v1,
181                                FromAPI(descriptor->requiredLimits)->limits),
182                 "validating required limits");
183 
184             DAWN_INVALID_IF(descriptor->requiredLimits->nextInChain != nullptr,
185                             "nextInChain is not nullptr.");
186         }
187 
188         DAWN_TRY_ASSIGN(*result, CreateDeviceImpl(descriptor));
189         return {};
190     }
191 
SetUseTieredLimits(bool useTieredLimits)192     void AdapterBase::SetUseTieredLimits(bool useTieredLimits) {
193         mUseTieredLimits = useTieredLimits;
194     }
195 
ResetInternalDeviceForTesting()196     void AdapterBase::ResetInternalDeviceForTesting() {
197         mInstance->ConsumedError(ResetInternalDeviceForTestingImpl());
198     }
199 
ResetInternalDeviceForTestingImpl()200     MaybeError AdapterBase::ResetInternalDeviceForTestingImpl() {
201         return DAWN_INTERNAL_ERROR(
202             "ResetInternalDeviceForTesting should only be used with the D3D12 backend.");
203     }
204 
205 }  // namespace dawn_native
206