You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
339 lines
13 KiB
339 lines
13 KiB
/****************************************************************************
|
|
Copyright (c) 2019-2023 Xiamen Yaji Software Co., Ltd.
|
|
|
|
http://www.cocos.com
|
|
|
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
of this software and associated documentation files (the "Software"), to deal
|
|
in the Software without restriction, including without limitation the rights to
|
|
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
|
of the Software, and to permit persons to whom the Software is furnished to do so,
|
|
subject to the following conditions:
|
|
|
|
The above copyright notice and this permission notice shall be included in
|
|
all copies or substantial portions of the Software.
|
|
|
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
THE SOFTWARE.
|
|
****************************************************************************/
|
|
|
|
#pragma once
|
|
|
|
#include "GFXBuffer.h"
|
|
#include "GFXCommandBuffer.h"
|
|
#include "GFXDescriptorSet.h"
|
|
#include "GFXDescriptorSetLayout.h"
|
|
#include "GFXFramebuffer.h"
|
|
#include "GFXInputAssembler.h"
|
|
#include "GFXObject.h"
|
|
#include "GFXPipelineLayout.h"
|
|
#include "GFXPipelineState.h"
|
|
#include "GFXQueryPool.h"
|
|
#include "GFXQueue.h"
|
|
#include "GFXRenderPass.h"
|
|
#include "GFXShader.h"
|
|
#include "GFXSwapchain.h"
|
|
#include "GFXTexture.h"
|
|
#include "base/RefCounted.h"
|
|
#include "base/std/container/array.h"
|
|
#include "states/GFXBufferBarrier.h"
|
|
#include "states/GFXGeneralBarrier.h"
|
|
#include "states/GFXSampler.h"
|
|
#include "states/GFXTextureBarrier.h"
|
|
|
|
namespace cc {
|
|
namespace gfx {
|
|
|
|
class CC_DLL Device : public RefCounted {
|
|
public:
|
|
static Device *getInstance();
|
|
|
|
~Device() override;
|
|
|
|
bool initialize(const DeviceInfo &info);
|
|
void destroy();
|
|
|
|
// aim to ensure waiting for work on gpu done when cpu encodes ahead of gpu certain frame(s).
|
|
virtual void frameSync() = 0;
|
|
|
|
virtual void acquire(Swapchain *const *swapchains, uint32_t count) = 0;
|
|
virtual void present() = 0;
|
|
|
|
virtual void flushCommands(CommandBuffer *const *cmdBuffs, uint32_t count) {}
|
|
|
|
virtual MemoryStatus &getMemoryStatus() { return _memoryStatus; }
|
|
virtual uint32_t getNumDrawCalls() const { return _numDrawCalls; }
|
|
virtual uint32_t getNumInstances() const { return _numInstances; }
|
|
virtual uint32_t getNumTris() const { return _numTriangles; }
|
|
|
|
inline CommandBuffer *createCommandBuffer(const CommandBufferInfo &info);
|
|
inline Queue *createQueue(const QueueInfo &info);
|
|
inline QueryPool *createQueryPool(const QueryPoolInfo &info);
|
|
inline Swapchain *createSwapchain(const SwapchainInfo &info);
|
|
inline const ccstd::vector<Swapchain *> &getSwapchains() const { return _swapchains; }
|
|
inline Buffer *createBuffer(const BufferInfo &info);
|
|
inline Buffer *createBuffer(const BufferViewInfo &info);
|
|
inline Texture *createTexture(const TextureInfo &info);
|
|
inline Texture *createTexture(const TextureViewInfo &info);
|
|
inline Shader *createShader(const ShaderInfo &info);
|
|
inline InputAssembler *createInputAssembler(const InputAssemblerInfo &info);
|
|
inline RenderPass *createRenderPass(const RenderPassInfo &info);
|
|
inline Framebuffer *createFramebuffer(const FramebufferInfo &info);
|
|
inline DescriptorSet *createDescriptorSet(const DescriptorSetInfo &info);
|
|
inline DescriptorSetLayout *createDescriptorSetLayout(const DescriptorSetLayoutInfo &info);
|
|
inline PipelineLayout *createPipelineLayout(const PipelineLayoutInfo &info);
|
|
inline PipelineState *createPipelineState(const PipelineStateInfo &info);
|
|
|
|
virtual Sampler *getSampler(const SamplerInfo &info);
|
|
virtual GeneralBarrier *getGeneralBarrier(const GeneralBarrierInfo &info);
|
|
virtual TextureBarrier *getTextureBarrier(const TextureBarrierInfo &info);
|
|
virtual BufferBarrier *getBufferBarrier(const BufferBarrierInfo &info);
|
|
|
|
virtual void copyBuffersToTexture(const uint8_t *const *buffers, Texture *dst, const BufferTextureCopy *regions, uint32_t count) = 0;
|
|
virtual void copyTextureToBuffers(Texture *src, uint8_t *const *buffers, const BufferTextureCopy *region, uint32_t count) = 0;
|
|
virtual void getQueryPoolResults(QueryPool *queryPool) = 0;
|
|
|
|
inline void copyTextureToBuffers(Texture *src, BufferSrcList &buffers, const BufferTextureCopyList ®ions);
|
|
inline void copyBuffersToTexture(const BufferDataList &buffers, Texture *dst, const BufferTextureCopyList ®ions);
|
|
inline void flushCommands(const ccstd::vector<CommandBuffer *> &cmdBuffs);
|
|
inline void acquire(const ccstd::vector<Swapchain *> &swapchains);
|
|
|
|
inline Queue *getQueue() const { return _queue; }
|
|
inline QueryPool *getQueryPool() const { return _queryPool; }
|
|
inline CommandBuffer *getCommandBuffer() const { return _cmdBuff; }
|
|
inline const DeviceCaps &getCapabilities() const { return _caps; }
|
|
inline API getGfxAPI() const { return _api; }
|
|
inline const ccstd::string &getDeviceName() const { return _deviceName; }
|
|
inline const ccstd::string &getRenderer() const { return _renderer; }
|
|
inline const ccstd::string &getVendor() const { return _vendor; }
|
|
inline bool hasFeature(Feature feature) const { return _features[toNumber(feature)]; }
|
|
inline FormatFeature getFormatFeatures(Format format) const { return _formatFeatures[toNumber(format)]; }
|
|
|
|
inline const BindingMappingInfo &bindingMappingInfo() const { return _bindingMappingInfo; }
|
|
|
|
// for external update operations which has to be performed on the device thread.
|
|
// AR camera texture update, etc.
|
|
template <typename ExecuteMethod>
|
|
void registerOnAcquireCallback(ExecuteMethod &&execute);
|
|
|
|
virtual void enableAutoBarrier(bool en) { _options.enableBarrierDeduce = en; }
|
|
virtual SampleCount getMaxSampleCount(Format format, TextureUsage usage, TextureFlags flags) const {
|
|
std::ignore = format;
|
|
std::ignore = usage;
|
|
std::ignore = flags;
|
|
return SampleCount::X1;
|
|
};
|
|
|
|
protected:
|
|
static Device *instance;
|
|
static bool isSupportDetachDeviceThread;
|
|
|
|
friend class DeviceAgent;
|
|
friend class DeviceValidator;
|
|
friend class DeviceManager;
|
|
|
|
Device();
|
|
|
|
virtual bool doInit(const DeviceInfo &info) = 0;
|
|
virtual void doDestroy() = 0;
|
|
|
|
virtual CommandBuffer *createCommandBuffer(const CommandBufferInfo &info, bool hasAgent) = 0;
|
|
virtual Queue *createQueue() = 0;
|
|
virtual QueryPool *createQueryPool() = 0;
|
|
virtual Swapchain *createSwapchain() = 0;
|
|
virtual Buffer *createBuffer() = 0;
|
|
virtual Texture *createTexture() = 0;
|
|
virtual Shader *createShader() = 0;
|
|
virtual InputAssembler *createInputAssembler() = 0;
|
|
virtual RenderPass *createRenderPass() = 0;
|
|
virtual Framebuffer *createFramebuffer() = 0;
|
|
virtual DescriptorSet *createDescriptorSet() = 0;
|
|
virtual DescriptorSetLayout *createDescriptorSetLayout() = 0;
|
|
virtual PipelineLayout *createPipelineLayout() = 0;
|
|
virtual PipelineState *createPipelineState() = 0;
|
|
|
|
virtual Sampler *createSampler(const SamplerInfo &info) { return ccnew Sampler(info); }
|
|
virtual GeneralBarrier *createGeneralBarrier(const GeneralBarrierInfo &info) { return ccnew GeneralBarrier(info); }
|
|
virtual TextureBarrier *createTextureBarrier(const TextureBarrierInfo &info) { return ccnew TextureBarrier(info); }
|
|
virtual BufferBarrier *createBufferBarrier(const BufferBarrierInfo &info) { return ccnew BufferBarrier(info); }
|
|
|
|
// For context switching between threads
|
|
virtual void bindContext(bool bound) {}
|
|
|
|
ccstd::string _deviceName;
|
|
ccstd::string _renderer;
|
|
ccstd::string _vendor;
|
|
ccstd::string _version;
|
|
API _api{API::UNKNOWN};
|
|
DeviceCaps _caps;
|
|
BindingMappingInfo _bindingMappingInfo;
|
|
DeviceOptions _options;
|
|
|
|
bool _multithreadedCommandRecording{true};
|
|
|
|
ccstd::array<bool, static_cast<size_t>(Feature::COUNT)> _features;
|
|
ccstd::array<FormatFeature, static_cast<size_t>(Format::COUNT)> _formatFeatures;
|
|
|
|
Queue *_queue{nullptr};
|
|
QueryPool *_queryPool{nullptr};
|
|
CommandBuffer *_cmdBuff{nullptr};
|
|
Executable *_onAcquire{nullptr};
|
|
|
|
uint32_t _numDrawCalls{0U};
|
|
uint32_t _numInstances{0U};
|
|
uint32_t _numTriangles{0U};
|
|
MemoryStatus _memoryStatus;
|
|
|
|
ccstd::unordered_map<SamplerInfo, Sampler *, Hasher<SamplerInfo>> _samplers;
|
|
ccstd::unordered_map<GeneralBarrierInfo, GeneralBarrier *, Hasher<GeneralBarrierInfo>> _generalBarriers;
|
|
ccstd::unordered_map<TextureBarrierInfo, TextureBarrier *, Hasher<TextureBarrierInfo>> _textureBarriers;
|
|
ccstd::unordered_map<BufferBarrierInfo, BufferBarrier *, Hasher<BufferBarrierInfo>> _bufferBarriers;
|
|
|
|
private:
|
|
ccstd::vector<Swapchain *> _swapchains; // weak reference
|
|
};
|
|
|
|
class DefaultResource {
|
|
public:
|
|
explicit DefaultResource(Device *device);
|
|
|
|
~DefaultResource() = default;
|
|
|
|
Texture *getTexture(TextureType type) const;
|
|
Buffer *getBuffer() const;
|
|
|
|
private:
|
|
IntrusivePtr<Texture> _texture2D;
|
|
IntrusivePtr<Texture> _texture2DArray;
|
|
IntrusivePtr<Texture> _textureCube;
|
|
IntrusivePtr<Texture> _texture3D;
|
|
IntrusivePtr<Buffer> _buffer;
|
|
};
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
CommandBuffer *Device::createCommandBuffer(const CommandBufferInfo &info) {
|
|
CommandBuffer *res = createCommandBuffer(info, false);
|
|
res->initialize(info);
|
|
return res;
|
|
}
|
|
|
|
Queue *Device::createQueue(const QueueInfo &info) {
|
|
Queue *res = createQueue();
|
|
res->initialize(info);
|
|
return res;
|
|
}
|
|
|
|
QueryPool *Device::createQueryPool(const QueryPoolInfo &info) {
|
|
QueryPool *res = createQueryPool();
|
|
res->initialize(info);
|
|
return res;
|
|
}
|
|
|
|
Swapchain *Device::createSwapchain(const SwapchainInfo &info) {
|
|
Swapchain *res = createSwapchain();
|
|
res->initialize(info);
|
|
_swapchains.push_back(res);
|
|
return res;
|
|
}
|
|
|
|
Buffer *Device::createBuffer(const BufferInfo &info) {
|
|
Buffer *res = createBuffer();
|
|
res->initialize(info);
|
|
return res;
|
|
}
|
|
|
|
Buffer *Device::createBuffer(const BufferViewInfo &info) {
|
|
Buffer *res = createBuffer();
|
|
res->initialize(info);
|
|
return res;
|
|
}
|
|
|
|
Texture *Device::createTexture(const TextureInfo &info) {
|
|
Texture *res = createTexture();
|
|
res->initialize(info);
|
|
return res;
|
|
}
|
|
|
|
Texture *Device::createTexture(const TextureViewInfo &info) {
|
|
Texture *res = createTexture();
|
|
res->initialize(info);
|
|
return res;
|
|
}
|
|
|
|
Shader *Device::createShader(const ShaderInfo &info) {
|
|
Shader *res = createShader();
|
|
res->initialize(info);
|
|
return res;
|
|
}
|
|
|
|
InputAssembler *Device::createInputAssembler(const InputAssemblerInfo &info) {
|
|
InputAssembler *res = createInputAssembler();
|
|
res->initialize(info);
|
|
return res;
|
|
}
|
|
|
|
RenderPass *Device::createRenderPass(const RenderPassInfo &info) {
|
|
RenderPass *res = createRenderPass();
|
|
res->initialize(info);
|
|
return res;
|
|
}
|
|
|
|
Framebuffer *Device::createFramebuffer(const FramebufferInfo &info) {
|
|
Framebuffer *res = createFramebuffer();
|
|
res->initialize(info);
|
|
return res;
|
|
}
|
|
|
|
DescriptorSet *Device::createDescriptorSet(const DescriptorSetInfo &info) {
|
|
DescriptorSet *res = createDescriptorSet();
|
|
res->initialize(info);
|
|
return res;
|
|
}
|
|
|
|
DescriptorSetLayout *Device::createDescriptorSetLayout(const DescriptorSetLayoutInfo &info) {
|
|
DescriptorSetLayout *res = createDescriptorSetLayout();
|
|
res->initialize(info);
|
|
return res;
|
|
}
|
|
|
|
PipelineLayout *Device::createPipelineLayout(const PipelineLayoutInfo &info) {
|
|
PipelineLayout *res = createPipelineLayout();
|
|
res->initialize(info);
|
|
return res;
|
|
}
|
|
|
|
PipelineState *Device::createPipelineState(const PipelineStateInfo &info) {
|
|
PipelineState *res = createPipelineState();
|
|
res->initialize(info);
|
|
return res;
|
|
}
|
|
|
|
void Device::copyBuffersToTexture(const BufferDataList &buffers, Texture *dst, const BufferTextureCopyList ®ions) {
|
|
copyBuffersToTexture(buffers.data(), dst, regions.data(), utils::toUint(regions.size()));
|
|
}
|
|
|
|
void Device::copyTextureToBuffers(Texture *src, BufferSrcList &buffers, const BufferTextureCopyList ®ions) {
|
|
copyTextureToBuffers(src, buffers.data(), regions.data(), utils::toUint(regions.size()));
|
|
}
|
|
|
|
void Device::flushCommands(const ccstd::vector<CommandBuffer *> &cmdBuffs) {
|
|
flushCommands(cmdBuffs.data(), utils::toUint(cmdBuffs.size()));
|
|
}
|
|
|
|
void Device::acquire(const ccstd::vector<Swapchain *> &swapchains) {
|
|
acquire(swapchains.data(), utils::toUint(swapchains.size()));
|
|
}
|
|
|
|
template <typename ExecuteMethod>
|
|
void Device::registerOnAcquireCallback(ExecuteMethod &&execute) {
|
|
_onAcquire = ccnew CallbackExecutable<ExecuteMethod>(std::forward<ExecuteMethod>(execute));
|
|
}
|
|
|
|
} // namespace gfx
|
|
} // namespace cc
|
|
|