#include "dawn/native/Device.h"
#include <webgpu/webgpu.h>
#include <algorithm>
#include <array>
#include <mutex>
#include <utility>
#include "absl/container/flat_hash_set.h"
#include "absl/strings/str_format.h"
#include "dawn/common/Log.h"
#include "dawn/common/Ref.h"
#include "dawn/common/Version_autogen.h"
#include "dawn/native/AsyncTask.h"
#include "dawn/native/AttachmentState.h"
#include "dawn/native/BindGroup.h"
#include "dawn/native/BindGroupLayout.h"
#include "dawn/native/BlitBufferToDepthStencil.h"
#include "dawn/native/BlobCache.h"
#include "dawn/native/Buffer.h"
#include "dawn/native/ChainUtils.h"
#include "dawn/native/CommandBuffer.h"
#include "dawn/native/CommandEncoder.h"
#include "dawn/native/CompilationMessages.h"
#include "dawn/native/CreatePipelineAsyncEvent.h"
#include "dawn/native/DawnNative.h"
#include "dawn/native/DynamicUploader.h"
#include "dawn/native/Error.h"
#include "dawn/native/ErrorData.h"
#include "dawn/native/ErrorInjector.h"
#include "dawn/native/ErrorScope.h"
#include "dawn/native/ExternalTexture.h"
#include "dawn/native/Instance.h"
#include "dawn/native/InternalPipelineStore.h"
#include "dawn/native/ObjectType_autogen.h"
#include "dawn/native/PhysicalDevice.h"
#include "dawn/native/PipelineCache.h"
#include "dawn/native/QuerySet.h"
#include "dawn/native/Queue.h"
#include "dawn/native/RenderBundleEncoder.h"
#include "dawn/native/RenderPipeline.h"
#include "dawn/native/Sampler.h"
#include "dawn/native/SharedBufferMemory.h"
#include "dawn/native/SharedFence.h"
#include "dawn/native/SharedTextureMemory.h"
#include "dawn/native/Surface.h"
#include "dawn/native/SwapChain.h"
#include "dawn/native/Texture.h"
#include "dawn/native/ValidationUtils_autogen.h"
#include "dawn/native/utils/WGPUHelpers.h"
#include "dawn/platform/DawnPlatform.h"
#include "dawn/platform/metrics/HistogramMacros.h"
#include "dawn/platform/tracing/TraceEvent.h"
#include "partition_alloc/pointers/raw_ptr.h"
namespace dawn::native {
struct DeviceBase::Caches { … };
template <typename RefCountedT, typename CreateFn>
auto GetOrCreate(ContentLessObjectCache<RefCountedT>& cache,
RefCountedT* blueprint,
CreateFn createFn) { … }
namespace {
struct LoggingCallbackTask : CallbackTask { … };
void LegacyDeviceLostCallback(WGPUDevice const* device,
WGPUDeviceLostReason reason,
char const* message,
void* callback,
void* userdata) { … }
void LegacyDeviceLostCallback2(WGPUDevice const* device,
WGPUDeviceLostReason reason,
char const* message,
void* callback,
void* userdata) { … }
void LegacyUncapturedErrorCallback(WGPUDevice const* device,
WGPUErrorType type,
const char* message,
void* callback,
void* userdata) { … }
static constexpr WGPUUncapturedErrorCallbackInfo2 kEmptyUncapturedErrorCallbackInfo = …;
}
DeviceBase::DeviceLostEvent::DeviceLostEvent(const WGPUDeviceLostCallbackInfo2& callbackInfo)
: … { … }
DeviceBase::DeviceLostEvent::~DeviceLostEvent() { … }
Ref<DeviceBase::DeviceLostEvent> DeviceBase::DeviceLostEvent::Create(
const DeviceDescriptor* descriptor) { … }
void DeviceBase::DeviceLostEvent::Complete(EventCompletionType completionType) { … }
ResultOrError<Ref<PipelineLayoutBase>> ValidateLayoutAndGetComputePipelineDescriptorWithDefaults(
DeviceBase* device,
const ComputePipelineDescriptor& descriptor,
ComputePipelineDescriptor* outDescriptor) { … }
ResultOrError<Ref<PipelineLayoutBase>> ValidateLayoutAndGetRenderPipelineDescriptorWithDefaults(
DeviceBase* device,
const RenderPipelineDescriptor& descriptor,
RenderPipelineDescriptor* outDescriptor,
bool allowInternalBinding) { … }
DeviceBase::DeviceBase(AdapterBase* adapter,
const UnpackedPtr<DeviceDescriptor>& descriptor,
const TogglesState& deviceToggles,
Ref<DeviceLostEvent>&& lostEvent)
: … { … }
DeviceBase::DeviceBase() : … { … }
DeviceBase::~DeviceBase() { … }
MaybeError DeviceBase::Initialize(Ref<QueueBase> defaultQueue) { … }
void DeviceBase::WillDropLastExternalRef() { … }
void DeviceBase::DestroyObjects() { … }
void DeviceBase::Destroy() { … }
void DeviceBase::APIDestroy() { … }
void DeviceBase::HandleError(std::unique_ptr<ErrorData> error,
InternalErrorType additionalAllowedErrors,
WGPUDeviceLostReason lostReason) { … }
void DeviceBase::ConsumeError(std::unique_ptr<ErrorData> error,
InternalErrorType additionalAllowedErrors) { … }
void DeviceBase::APISetLoggingCallback(wgpu::LoggingCallback callback, void* userdata) { … }
void DeviceBase::APISetUncapturedErrorCallback(wgpu::ErrorCallback callback, void* userdata) { … }
void DeviceBase::APISetDeviceLostCallback(wgpu::DeviceLostCallback callback, void* userdata) { … }
void DeviceBase::APIPushErrorScope(wgpu::ErrorFilter filter) { … }
void DeviceBase::APIPopErrorScope(wgpu::ErrorCallback callback, void* userdata) { … }
Future DeviceBase::APIPopErrorScopeF(const PopErrorScopeCallbackInfo& callbackInfo) { … }
Future DeviceBase::APIPopErrorScope2(const WGPUPopErrorScopeCallbackInfo2& callbackInfo) { … }
BlobCache* DeviceBase::GetBlobCache() const { … }
Blob DeviceBase::LoadCachedBlob(const CacheKey& key) { … }
void DeviceBase::StoreCachedBlob(const CacheKey& key, const Blob& blob) { … }
MaybeError DeviceBase::ValidateObject(const ApiObjectBase* object) const { … }
MaybeError DeviceBase::ValidateIsAlive() const { … }
void DeviceBase::APIForceLoss2(wgpu::DeviceLostReason reason, std::string_view message) { … }
DeviceBase::State DeviceBase::GetState() const { … }
bool DeviceBase::IsLost() const { … }
ApiObjectList* DeviceBase::GetObjectTrackingList(ObjectType type) { … }
const ApiObjectList* DeviceBase::GetObjectTrackingList(ObjectType type) const { … }
InstanceBase* DeviceBase::GetInstance() const { … }
AdapterBase* DeviceBase::GetAdapter() const { … }
PhysicalDeviceBase* DeviceBase::GetPhysicalDevice() const { … }
dawn::platform::Platform* DeviceBase::GetPlatform() const { … }
InternalPipelineStore* DeviceBase::GetInternalPipelineStore() { … }
bool DeviceBase::HasPendingTasks() { … }
bool DeviceBase::IsDeviceIdle() { … }
ResultOrError<const Format*> DeviceBase::GetInternalFormat(wgpu::TextureFormat format) const { … }
const Format& DeviceBase::GetValidInternalFormat(wgpu::TextureFormat format) const { … }
const Format& DeviceBase::GetValidInternalFormat(FormatIndex index) const { … }
std::vector<const Format*> DeviceBase::GetCompatibleViewFormats(const Format& format) const { … }
ResultOrError<Ref<BindGroupLayoutBase>> DeviceBase::GetOrCreateBindGroupLayout(
const BindGroupLayoutDescriptor* descriptor,
PipelineCompatibilityToken pipelineCompatibilityToken) { … }
ResultOrError<Ref<BindGroupLayoutBase>> DeviceBase::CreateEmptyBindGroupLayout() { … }
ResultOrError<Ref<PipelineLayoutBase>> DeviceBase::CreateEmptyPipelineLayout() { … }
BindGroupLayoutBase* DeviceBase::GetEmptyBindGroupLayout() { … }
PipelineLayoutBase* DeviceBase::GetEmptyPipelineLayout() { … }
Ref<ComputePipelineBase> DeviceBase::GetCachedComputePipeline(
ComputePipelineBase* uninitializedComputePipeline) { … }
Ref<RenderPipelineBase> DeviceBase::GetCachedRenderPipeline(
RenderPipelineBase* uninitializedRenderPipeline) { … }
Ref<ComputePipelineBase> DeviceBase::AddOrGetCachedComputePipeline(
Ref<ComputePipelineBase> computePipeline) { … }
Ref<RenderPipelineBase> DeviceBase::AddOrGetCachedRenderPipeline(
Ref<RenderPipelineBase> renderPipeline) { … }
ResultOrError<Ref<TextureViewBase>>
DeviceBase::GetOrCreatePlaceholderTextureViewForExternalTexture() { … }
ResultOrError<Ref<PipelineLayoutBase>> DeviceBase::GetOrCreatePipelineLayout(
const UnpackedPtr<PipelineLayoutDescriptor>& descriptor) { … }
ResultOrError<Ref<SamplerBase>> DeviceBase::GetOrCreateSampler(
const SamplerDescriptor* descriptor) { … }
ResultOrError<Ref<ShaderModuleBase>> DeviceBase::GetOrCreateShaderModule(
const UnpackedPtr<ShaderModuleDescriptor>& descriptor,
const std::vector<tint::wgsl::Extension>& internalExtensions,
ShaderModuleParseResult* parseResult,
std::unique_ptr<OwnedCompilationMessages>* compilationMessages) { … }
Ref<AttachmentState> DeviceBase::GetOrCreateAttachmentState(AttachmentState* blueprint) { … }
Ref<AttachmentState> DeviceBase::GetOrCreateAttachmentState(
const RenderBundleEncoderDescriptor* descriptor) { … }
Ref<AttachmentState> DeviceBase::GetOrCreateAttachmentState(
const UnpackedPtr<RenderPipelineDescriptor>& descriptor,
const PipelineLayoutBase* layout) { … }
Ref<AttachmentState> DeviceBase::GetOrCreateAttachmentState(
const UnpackedPtr<RenderPassDescriptor>& descriptor) { … }
Ref<PipelineCacheBase> DeviceBase::GetOrCreatePipelineCache(const CacheKey& key) { … }
BindGroupBase* DeviceBase::APICreateBindGroup(const BindGroupDescriptor* descriptor) { … }
BindGroupLayoutBase* DeviceBase::APICreateBindGroupLayout(
const BindGroupLayoutDescriptor* descriptor) { … }
BufferBase* DeviceBase::APICreateBuffer(const BufferDescriptor* descriptor) { … }
CommandEncoder* DeviceBase::APICreateCommandEncoder(const CommandEncoderDescriptor* descriptor) { … }
ComputePipelineBase* DeviceBase::APICreateComputePipeline(
const ComputePipelineDescriptor* descriptor) { … }
void DeviceBase::APICreateComputePipelineAsync(const ComputePipelineDescriptor* descriptor,
WGPUCreateComputePipelineAsyncCallback callback,
void* userdata) { … }
Future DeviceBase::APICreateComputePipelineAsyncF(
const ComputePipelineDescriptor* descriptor,
const CreateComputePipelineAsyncCallbackInfo& callbackInfo) { … }
Future DeviceBase::APICreateComputePipelineAsync2(
const ComputePipelineDescriptor* descriptor,
const WGPUCreateComputePipelineAsyncCallbackInfo2& callbackInfo) { … }
PipelineLayoutBase* DeviceBase::APICreatePipelineLayout(
const PipelineLayoutDescriptor* descriptor) { … }
QuerySetBase* DeviceBase::APICreateQuerySet(const QuerySetDescriptor* descriptor) { … }
SamplerBase* DeviceBase::APICreateSampler(const SamplerDescriptor* descriptor) { … }
void DeviceBase::APICreateRenderPipelineAsync(const RenderPipelineDescriptor* descriptor,
WGPUCreateRenderPipelineAsyncCallback callback,
void* userdata) { … }
Future DeviceBase::APICreateRenderPipelineAsyncF(
const RenderPipelineDescriptor* descriptor,
const CreateRenderPipelineAsyncCallbackInfo& callbackInfo) { … }
Future DeviceBase::APICreateRenderPipelineAsync2(
const RenderPipelineDescriptor* descriptor,
const WGPUCreateRenderPipelineAsyncCallbackInfo2& callbackInfo) { … }
RenderBundleEncoder* DeviceBase::APICreateRenderBundleEncoder(
const RenderBundleEncoderDescriptor* descriptor) { … }
RenderPipelineBase* DeviceBase::APICreateRenderPipeline(
const RenderPipelineDescriptor* descriptor) { … }
ShaderModuleBase* DeviceBase::APICreateShaderModule(const ShaderModuleDescriptor* descriptor) { … }
ShaderModuleBase* DeviceBase::APICreateErrorShaderModule2(const ShaderModuleDescriptor* descriptor,
std::string_view errorMessage) { … }
SwapChainBase* DeviceBase::APICreateSwapChain(Surface* surface,
const SwapChainDescriptor* descriptor) { … }
TextureBase* DeviceBase::APICreateTexture(const TextureDescriptor* descriptor) { … }
wgpu::TextureUsage DeviceBase::APIGetSupportedSurfaceUsage(Surface* surface) { … }
BufferBase* DeviceBase::APICreateErrorBuffer(const BufferDescriptor* desc) { … }
ExternalTextureBase* DeviceBase::APICreateErrorExternalTexture() { … }
TextureBase* DeviceBase::APICreateErrorTexture(const TextureDescriptor* desc) { … }
bool DeviceBase::APITick() { … }
MaybeError DeviceBase::Tick() { … }
AdapterBase* DeviceBase::APIGetAdapter() { … }
QueueBase* DeviceBase::APIGetQueue() { … }
ExternalTextureBase* DeviceBase::APICreateExternalTexture(
const ExternalTextureDescriptor* descriptor) { … }
SharedBufferMemoryBase* DeviceBase::APIImportSharedBufferMemory(
const SharedBufferMemoryDescriptor* descriptor) { … }
ResultOrError<Ref<SharedBufferMemoryBase>> DeviceBase::ImportSharedBufferMemoryImpl(
const SharedBufferMemoryDescriptor* descriptor) { … }
SharedTextureMemoryBase* DeviceBase::APIImportSharedTextureMemory(
const SharedTextureMemoryDescriptor* descriptor) { … }
ResultOrError<Ref<SharedTextureMemoryBase>> DeviceBase::ImportSharedTextureMemoryImpl(
const SharedTextureMemoryDescriptor* descriptor) { … }
SharedFenceBase* DeviceBase::APIImportSharedFence(const SharedFenceDescriptor* descriptor) { … }
ResultOrError<Ref<SharedFenceBase>> DeviceBase::ImportSharedFenceImpl(
const SharedFenceDescriptor* descriptor) { … }
void DeviceBase::ApplyFeatures(const UnpackedPtr<DeviceDescriptor>& deviceDescriptor) { … }
bool DeviceBase::HasFeature(Feature feature) const { … }
void DeviceBase::SetWGSLExtensionAllowList() { … }
const tint::wgsl::AllowedFeatures& DeviceBase::GetWGSLAllowedFeatures() const { … }
bool DeviceBase::IsValidationEnabled() const { … }
bool DeviceBase::IsRobustnessEnabled() const { … }
bool DeviceBase::IsCompatibilityMode() const { … }
bool DeviceBase::IsImmediateErrorHandlingEnabled() const { … }
size_t DeviceBase::GetLazyClearCountForTesting() { … }
void DeviceBase::IncrementLazyClearCountForTesting() { … }
void DeviceBase::EmitWarningOnce(const std::string& message) { … }
void DeviceBase::EmitCompilationLog(const ShaderModuleBase* module) { … }
void DeviceBase::EmitLog(const char* message) { … }
void DeviceBase::EmitLog(WGPULoggingType loggingType, const char* message) { … }
wgpu::Status DeviceBase::APIGetAHardwareBufferProperties(void* handle,
AHardwareBufferProperties* properties) { … }
wgpu::Status DeviceBase::APIGetLimits(SupportedLimits* limits) const { … }
bool DeviceBase::APIHasFeature(wgpu::FeatureName feature) const { … }
size_t DeviceBase::APIEnumerateFeatures(wgpu::FeatureName* features) const { … }
void DeviceBase::APIInjectError2(wgpu::ErrorType type, std::string_view message) { … }
void DeviceBase::APIValidateTextureDescriptor(const TextureDescriptor* descriptorOrig) { … }
QueueBase* DeviceBase::GetQueue() const { … }
ResultOrError<Ref<BindGroupBase>> DeviceBase::CreateBindGroup(const BindGroupDescriptor* descriptor,
UsageValidationMode mode) { … }
ResultOrError<Ref<BindGroupLayoutBase>> DeviceBase::CreateBindGroupLayout(
const BindGroupLayoutDescriptor* descriptor,
bool allowInternalBinding) { … }
ResultOrError<Ref<BufferBase>> DeviceBase::CreateBuffer(const BufferDescriptor* rawDescriptor) { … }
ResultOrError<Ref<ComputePipelineBase>> DeviceBase::CreateComputePipeline(
const ComputePipelineDescriptor* descriptor) { … }
ResultOrError<Ref<CommandEncoder>> DeviceBase::CreateCommandEncoder(
const CommandEncoderDescriptor* descriptor) { … }
Ref<PipelineCacheBase> DeviceBase::GetOrCreatePipelineCacheImpl(const CacheKey& key) { … }
ResultOrError<Ref<ComputePipelineBase>> DeviceBase::CreateUninitializedComputePipeline(
const ComputePipelineDescriptor* descriptor) { … }
void DeviceBase::InitializeComputePipelineAsyncImpl(Ref<CreateComputePipelineAsyncEvent> event) { … }
void DeviceBase::InitializeRenderPipelineAsyncImpl(Ref<CreateRenderPipelineAsyncEvent> event) { … }
ResultOrError<Ref<PipelineLayoutBase>> DeviceBase::CreatePipelineLayout(
const PipelineLayoutDescriptor* descriptor,
PipelineCompatibilityToken pipelineCompatibilityToken) { … }
ResultOrError<Ref<ExternalTextureBase>> DeviceBase::CreateExternalTextureImpl(
const ExternalTextureDescriptor* descriptor) { … }
ResultOrError<Ref<QuerySetBase>> DeviceBase::CreateQuerySet(const QuerySetDescriptor* descriptor) { … }
ResultOrError<Ref<RenderBundleEncoder>> DeviceBase::CreateRenderBundleEncoder(
const RenderBundleEncoderDescriptor* descriptor) { … }
ResultOrError<Ref<RenderPipelineBase>> DeviceBase::CreateRenderPipeline(
const RenderPipelineDescriptor* descriptor,
bool allowInternalBinding) { … }
ResultOrError<Ref<RenderPipelineBase>> DeviceBase::CreateUninitializedRenderPipeline(
const RenderPipelineDescriptor* descriptor,
bool allowInternalBinding) { … }
ResultOrError<Ref<SamplerBase>> DeviceBase::CreateSampler(const SamplerDescriptor* descriptorOrig) { … }
ResultOrError<Ref<ShaderModuleBase>> DeviceBase::CreateShaderModule(
const ShaderModuleDescriptor* descriptor,
const std::vector<tint::wgsl::Extension>& internalExtensions,
std::unique_ptr<OwnedCompilationMessages>* compilationMessages) { … }
ResultOrError<Ref<SwapChainBase>> DeviceBase::CreateSwapChain(
Surface* surface,
const SwapChainDescriptor* descriptor) { … }
ResultOrError<Ref<SwapChainBase>> DeviceBase::CreateSwapChain(Surface* surface,
SwapChainBase* previousSwapChain,
const SurfaceConfiguration* config) { … }
ResultOrError<Ref<TextureBase>> DeviceBase::CreateTexture(const TextureDescriptor* descriptorOrig) { … }
ResultOrError<Ref<TextureViewBase>> DeviceBase::CreateTextureView(
TextureBase* texture,
const TextureViewDescriptor* descriptorOrig) { … }
ResultOrError<wgpu::TextureUsage> DeviceBase::GetSupportedSurfaceUsage(
const Surface* surface) const { … }
DynamicUploader* DeviceBase::GetDynamicUploader() const { … }
std::vector<const char*> DeviceBase::GetTogglesUsed() const { … }
bool DeviceBase::IsToggleEnabled(Toggle toggle) const { … }
const TogglesState& DeviceBase::GetTogglesState() const { … }
void DeviceBase::ForceEnableFeatureForTesting(Feature feature) { … }
void DeviceBase::FlushCallbackTaskQueue() { … }
const CombinedLimits& DeviceBase::GetLimits() const { … }
AsyncTaskManager* DeviceBase::GetAsyncTaskManager() const { … }
CallbackTaskManager* DeviceBase::GetCallbackTaskManager() const { … }
dawn::platform::WorkerTaskPool* DeviceBase::GetWorkerTaskPool() const { … }
PipelineCompatibilityToken DeviceBase::GetNextPipelineCompatibilityToken() { … }
const CacheKey& DeviceBase::GetCacheKey() const { … }
const std::string& DeviceBase::GetLabel() const { … }
void DeviceBase::APISetLabel(const char* label) { … }
void DeviceBase::APISetLabel2(std::optional<std::string_view> label) { … }
void DeviceBase::SetLabelImpl() { … }
bool DeviceBase::ShouldDuplicateNumWorkgroupsForDispatchIndirect(
ComputePipelineBase* computePipeline) const { … }
bool DeviceBase::MayRequireDuplicationOfIndirectParameters() const { … }
bool DeviceBase::ShouldDuplicateParametersForDrawIndirect(
const RenderPipelineBase* renderPipelineBase) const { … }
bool DeviceBase::ShouldApplyIndexBufferOffsetToFirstIndex() const { … }
bool DeviceBase::CanTextureLoadResolveTargetInTheSameRenderpass() const { … }
bool DeviceBase::PreferNotUsingMappableOrUniformBufferAsStorage() const { … }
uint64_t DeviceBase::GetBufferCopyOffsetAlignmentForDepthStencil() const { … }
MaybeError DeviceBase::CopyFromStagingToBuffer(BufferBase* source,
uint64_t sourceOffset,
BufferBase* destination,
uint64_t destinationOffset,
uint64_t size) { … }
MaybeError DeviceBase::CopyFromStagingToTexture(BufferBase* source,
const TextureDataLayout& src,
const TextureCopy& dst,
const Extent3D& copySizePixels) { … }
Mutex::AutoLockAndHoldRef DeviceBase::GetScopedLockSafeForDelete() { … }
Mutex::AutoLock DeviceBase::GetScopedLock() { … }
bool DeviceBase::IsLockedByCurrentThreadIfNeeded() const { … }
void DeviceBase::DumpMemoryStatistics(dawn::native::MemoryDump* dump) const { … }
uint64_t DeviceBase::ComputeEstimatedMemoryUsage() const { … }
void DeviceBase::ReduceMemoryUsage() { … }
ResultOrError<Ref<BufferBase>> DeviceBase::GetOrCreateTemporaryUniformBuffer(size_t size) { … }
IgnoreLazyClearCountScope::IgnoreLazyClearCountScope(DeviceBase* device)
: … { … }
IgnoreLazyClearCountScope::~IgnoreLazyClearCountScope() { … }
}