dawn-cmake/src/dawn_native/metal/DeviceMTL.h

131 lines
5.6 KiB
C
Raw Normal View History

// 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.
#ifndef DAWNNATIVE_METAL_DEVICEMTL_H_
#define DAWNNATIVE_METAL_DEVICEMTL_H_
#include "dawn_native/dawn_platform.h"
#include "dawn_native/Commands.h"
2018-07-24 11:53:51 +00:00
#include "dawn_native/Device.h"
#include "dawn_native/metal/CommandRecordingContext.h"
2018-07-24 11:53:51 +00:00
#include "dawn_native/metal/Forward.h"
#import <IOSurface/IOSurfaceRef.h>
#import <Metal/Metal.h>
#import <QuartzCore/QuartzCore.h>
#include <atomic>
#include <memory>
#include <mutex>
namespace dawn_native { namespace metal {
class Device : public DeviceBase {
2017-11-24 19:12:44 +00:00
public:
static ResultOrError<Device*> Create(AdapterBase* adapter,
NSPRef<id<MTLDevice>> mtlDevice,
const DeviceDescriptor* descriptor);
~Device() override;
2017-11-24 19:12:44 +00:00
MaybeError Initialize();
CommandBufferBase* CreateCommandBuffer(CommandEncoder* encoder,
const CommandBufferDescriptor* descriptor) override;
2017-11-24 19:12:44 +00:00
MaybeError TickImpl() override;
2017-11-24 19:12:44 +00:00
id<MTLDevice> GetMTLDevice();
id<MTLCommandQueue> GetMTLQueue();
2017-11-24 19:12:44 +00:00
CommandRecordingContext* GetPendingCommandContext();
2017-11-24 19:12:44 +00:00
void SubmitPendingCommandBuffer();
TextureBase* CreateTextureWrappingIOSurface(const ExternalImageDescriptor* descriptor,
IOSurfaceRef ioSurface,
uint32_t plane);
void WaitForCommandsToBeScheduled();
ResultOrError<std::unique_ptr<StagingBufferBase>> CreateStagingBuffer(size_t size) override;
MaybeError CopyFromStagingToBuffer(StagingBufferBase* source,
uint64_t sourceOffset,
BufferBase* destination,
uint64_t destinationOffset,
uint64_t size) override;
MaybeError CopyFromStagingToTexture(const StagingBufferBase* source,
const TextureDataLayout& dataLayout,
TextureCopy* dst,
const Extent3D& copySizePixels) override;
uint32_t GetOptimalBytesPerRowAlignment() const override;
uint64_t GetOptimalBufferToTextureCopyOffsetAlignment() const override;
2017-11-24 19:12:44 +00:00
private:
Device(AdapterBase* adapter,
NSPRef<id<MTLDevice>> mtlDevice,
const DeviceDescriptor* descriptor);
ResultOrError<BindGroupBase*> CreateBindGroupImpl(
const BindGroupDescriptor* descriptor) override;
ResultOrError<BindGroupLayoutBase*> CreateBindGroupLayoutImpl(
const BindGroupLayoutDescriptor* descriptor) override;
ResultOrError<Ref<BufferBase>> CreateBufferImpl(
const BufferDescriptor* descriptor) override;
ResultOrError<ComputePipelineBase*> CreateComputePipelineImpl(
const ComputePipelineDescriptor* descriptor) override;
ResultOrError<PipelineLayoutBase*> CreatePipelineLayoutImpl(
const PipelineLayoutDescriptor* descriptor) override;
ResultOrError<QuerySetBase*> CreateQuerySetImpl(
const QuerySetDescriptor* descriptor) override;
ResultOrError<RenderPipelineBase*> CreateRenderPipelineImpl(
const RenderPipelineDescriptor* descriptor) override;
ResultOrError<SamplerBase*> CreateSamplerImpl(const SamplerDescriptor* descriptor) override;
ResultOrError<ShaderModuleBase*> CreateShaderModuleImpl(
const ShaderModuleDescriptor* descriptor) override;
ResultOrError<SwapChainBase*> CreateSwapChainImpl(
const SwapChainDescriptor* descriptor) override;
ResultOrError<NewSwapChainBase*> CreateSwapChainImpl(
Surface* surface,
NewSwapChainBase* previousSwapChain,
const SwapChainDescriptor* descriptor) override;
ResultOrError<Ref<TextureBase>> CreateTextureImpl(
const TextureDescriptor* descriptor) override;
ResultOrError<TextureViewBase*> CreateTextureViewImpl(
TextureBase* texture,
const TextureViewDescriptor* descriptor) override;
void InitTogglesFromDriver();
Simplify the device lifecycle. What was previously the Device's loss status is now a state that also contains the "being created" state. Its transitions are entirely handled in the frontend which enforces somewhat uniform lifecycles between backends. The backend devices' ShutDownImpl() function is now guaranteed to be called only during the destructor, which leads to further simplification. Previously Destroy() could also be called when the device was first lost. This require complications because, for example, a WGPUBuffer could still exist, and would want to call some resource allocator service after the call to Destroy(). Now destruction of the device's backing API objects is deferred to the destructor. (that's ok as long as the application can't submit any more work). WaitForCompletion is now guaranteed to be called before ShutDownImpl() iff the call to DeviceBase::Initialize was succesful and the backing device not lost. The idea is that after DeviceBase::Initialize, the GPU can have some work enqueued and we need to wait for it to complete before deleting backing API objects. In the future we might also have backend be reentrant, using WebGPU itself to implement parts of the backend. Reentrant calls would only be allowed after DeviceBase::Initialize. Also the DynamicUploader that was special-cased in all backends is now handled entirely by the frontend. Bug: dawn:373 Change-Id: I985417d67727ea3bc11849c999c5ef0e02403223 Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/18801 Commit-Queue: Corentin Wallez <cwallez@chromium.org> Reviewed-by: Austin Eng <enga@chromium.org>
2020-04-07 16:19:47 +00:00
void ShutDownImpl() override;
MaybeError WaitForIdleForDestruction() override;
ExecutionSerial CheckAndUpdateCompletedSerials() override;
NSPRef<id<MTLDevice>> mMtlDevice;
NSPRef<id<MTLCommandQueue>> mCommandQueue;
2017-11-24 19:12:44 +00:00
CommandRecordingContext mCommandContext;
// The completed serial is updated in a Metal completion handler that can be fired on a
// different thread, so it needs to be atomic.
std::atomic<uint64_t> mCompletedSerial;
// mLastSubmittedCommands will be accessed in a Metal schedule handler that can be fired on
// a different thread so we guard access to it with a mutex.
std::mutex mLastSubmittedCommandsMutex;
NSPRef<id<MTLCommandBuffer>> mLastSubmittedCommands;
};
}} // namespace dawn_native::metal
#endif // DAWNNATIVE_METAL_DEVICEMTL_H_