diff options
Diffstat (limited to 'src/gui/rhi/qrhimetal_p_p.h')
-rw-r--r-- | src/gui/rhi/qrhimetal_p_p.h | 460 |
1 files changed, 460 insertions, 0 deletions
diff --git a/src/gui/rhi/qrhimetal_p_p.h b/src/gui/rhi/qrhimetal_p_p.h new file mode 100644 index 0000000000..2be86db5c8 --- /dev/null +++ b/src/gui/rhi/qrhimetal_p_p.h @@ -0,0 +1,460 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Gui module +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QRHIMETAL_P_H +#define QRHIMETAL_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include "qrhimetal_p.h" +#include "qrhi_p_p.h" +#include <QWindow> + +QT_BEGIN_NAMESPACE + +static const int QMTL_FRAMES_IN_FLIGHT = 2; + +// have to hide the ObjC stuff, this header cannot contain MTL* at all +struct QMetalBufferData; + +struct QMetalBuffer : public QRhiBuffer +{ + QMetalBuffer(QRhiImplementation *rhi, Type type, UsageFlags usage, int size); + ~QMetalBuffer(); + void release() override; + bool build() override; + + QMetalBufferData *d; + uint generation = 0; + int lastActiveFrameSlot = -1; + friend class QRhiMetal; + friend struct QMetalShaderResourceBindings; +}; + +struct QMetalRenderBufferData; + +struct QMetalRenderBuffer : public QRhiRenderBuffer +{ + QMetalRenderBuffer(QRhiImplementation *rhi, Type type, const QSize &pixelSize, + int sampleCount, QRhiRenderBuffer::Flags flags); + ~QMetalRenderBuffer(); + void release() override; + bool build() override; + QRhiTexture::Format backingFormat() const override; + + QMetalRenderBufferData *d; + int samples = 1; + uint generation = 0; + int lastActiveFrameSlot = -1; + friend class QRhiMetal; +}; + +struct QMetalTextureData; + +struct QMetalTexture : public QRhiTexture +{ + QMetalTexture(QRhiImplementation *rhi, Format format, const QSize &pixelSize, + int sampleCount, Flags flags); + ~QMetalTexture(); + void release() override; + bool build() override; + bool buildFrom(const QRhiNativeHandles *src) override; + const QRhiNativeHandles *nativeHandles() override; + + bool prepareBuild(QSize *adjustedSize = nullptr); + + QMetalTextureData *d; + QRhiMetalTextureNativeHandles nativeHandlesStruct; + int mipLevelCount = 0; + int samples = 1; + uint generation = 0; + int lastActiveFrameSlot = -1; + friend class QRhiMetal; + friend struct QMetalShaderResourceBindings; + friend struct QMetalTextureData; +}; + +struct QMetalSamplerData; + +struct QMetalSampler : public QRhiSampler +{ + QMetalSampler(QRhiImplementation *rhi, Filter magFilter, Filter minFilter, Filter mipmapMode, + AddressMode u, AddressMode v); + ~QMetalSampler(); + void release() override; + bool build() override; + + QMetalSamplerData *d; + uint generation = 0; + int lastActiveFrameSlot = -1; + friend class QRhiMetal; + friend struct QMetalShaderResourceBindings; +}; + +struct QMetalRenderPassDescriptor : public QRhiRenderPassDescriptor +{ + QMetalRenderPassDescriptor(QRhiImplementation *rhi); + ~QMetalRenderPassDescriptor(); + void release() override; + + // there is no MTLRenderPassDescriptor here as one will be created for each pass in beginPass() + + // but the things needed for the render pipeline descriptor have to be provided + static const int MAX_COLOR_ATTACHMENTS = 8; + int colorAttachmentCount = 0; + bool hasDepthStencil = false; + int colorFormat[MAX_COLOR_ATTACHMENTS]; + int dsFormat; +}; + +struct QMetalRenderTargetData; + +struct QMetalReferenceRenderTarget : public QRhiRenderTarget +{ + QMetalReferenceRenderTarget(QRhiImplementation *rhi); + ~QMetalReferenceRenderTarget(); + void release() override; + + QSize pixelSize() const override; + float devicePixelRatio() const override; + int sampleCount() const override; + + QMetalRenderTargetData *d; +}; + +struct QMetalTextureRenderTarget : public QRhiTextureRenderTarget +{ + QMetalTextureRenderTarget(QRhiImplementation *rhi, const QRhiTextureRenderTargetDescription &desc, Flags flags); + ~QMetalTextureRenderTarget(); + void release() override; + + QSize pixelSize() const override; + float devicePixelRatio() const override; + int sampleCount() const override; + + QRhiRenderPassDescriptor *newCompatibleRenderPassDescriptor() override; + bool build() override; + + QMetalRenderTargetData *d; + friend class QRhiMetal; +}; + +struct QMetalShaderResourceBindings : public QRhiShaderResourceBindings +{ + QMetalShaderResourceBindings(QRhiImplementation *rhi); + ~QMetalShaderResourceBindings(); + void release() override; + bool build() override; + + QVarLengthArray<QRhiShaderResourceBinding, 8> sortedBindings; + int maxBinding = -1; + + struct BoundUniformBufferData { + quint64 id; + uint generation; + }; + struct BoundSampledTextureData { + quint64 texId; + uint texGeneration; + quint64 samplerId; + uint samplerGeneration; + }; + struct BoundStorageImageData { + quint64 id; + uint generation; + }; + struct BoundStorageBufferData { + quint64 id; + uint generation; + }; + struct BoundResourceData { + union { + BoundUniformBufferData ubuf; + BoundSampledTextureData stex; + BoundStorageImageData simage; + BoundStorageBufferData sbuf; + }; + }; + QVarLengthArray<BoundResourceData, 8> boundResourceData; + + uint generation = 0; + friend class QRhiMetal; +}; + +struct QMetalGraphicsPipelineData; + +struct QMetalGraphicsPipeline : public QRhiGraphicsPipeline +{ + QMetalGraphicsPipeline(QRhiImplementation *rhi); + ~QMetalGraphicsPipeline(); + void release() override; + bool build() override; + + QMetalGraphicsPipelineData *d; + uint generation = 0; + int lastActiveFrameSlot = -1; + friend class QRhiMetal; +}; + +struct QMetalComputePipelineData; + +struct QMetalComputePipeline : public QRhiComputePipeline +{ + QMetalComputePipeline(QRhiImplementation *rhi); + ~QMetalComputePipeline(); + void release() override; + bool build() override; + + QMetalComputePipelineData *d; + uint generation = 0; + int lastActiveFrameSlot = -1; + friend class QRhiMetal; +}; + +struct QMetalCommandBufferData; +struct QMetalSwapChain; + +struct QMetalCommandBuffer : public QRhiCommandBuffer +{ + QMetalCommandBuffer(QRhiImplementation *rhi); + ~QMetalCommandBuffer(); + void release() override; + + QMetalCommandBufferData *d = nullptr; + QRhiMetalCommandBufferNativeHandles nativeHandlesStruct; + + enum PassType { + NoPass, + RenderPass, + ComputePass + }; + + // per-pass (render or compute command encoder) persistent state + PassType recordingPass; + QRhiRenderTarget *currentTarget; + + // per-pass (render or compute command encoder) volatile (cached) state + QRhiGraphicsPipeline *currentGraphicsPipeline; + QRhiComputePipeline *currentComputePipeline; + uint currentPipelineGeneration; + QRhiShaderResourceBindings *currentGraphicsSrb; + QRhiShaderResourceBindings *currentComputeSrb; + uint currentSrbGeneration; + int currentResSlot; + QRhiBuffer *currentIndexBuffer; + quint32 currentIndexOffset; + QRhiCommandBuffer::IndexFormat currentIndexFormat; + int currentCullMode; + int currentFrontFaceWinding; + + const QRhiNativeHandles *nativeHandles(); + void resetState(); + void resetPerPassState(); + void resetPerPassCachedState(); +}; + +struct QMetalSwapChainData; + +struct QMetalSwapChain : public QRhiSwapChain +{ + QMetalSwapChain(QRhiImplementation *rhi); + ~QMetalSwapChain(); + void release() override; + + QRhiCommandBuffer *currentFrameCommandBuffer() override; + QRhiRenderTarget *currentFrameRenderTarget() override; + QSize surfacePixelSize() override; + + QRhiRenderPassDescriptor *newCompatibleRenderPassDescriptor() override; + + bool buildOrResize() override; + + void chooseFormats(); + + QWindow *window = nullptr; + QSize pixelSize; + int currentFrameSlot = 0; // 0..QMTL_FRAMES_IN_FLIGHT-1 + int frameCount = 0; + int samples = 1; + QMetalReferenceRenderTarget rtWrapper; + QMetalCommandBuffer cbWrapper; + QMetalRenderBuffer *ds = nullptr; + QMetalSwapChainData *d = nullptr; +}; + +struct QRhiMetalData; + +class QRhiMetal : public QRhiImplementation +{ +public: + QRhiMetal(QRhiMetalInitParams *params, QRhiMetalNativeHandles *importDevice = nullptr); + ~QRhiMetal(); + + bool create(QRhi::Flags flags) override; + void destroy() override; + + QRhiGraphicsPipeline *createGraphicsPipeline() override; + QRhiComputePipeline *createComputePipeline() override; + QRhiShaderResourceBindings *createShaderResourceBindings() override; + QRhiBuffer *createBuffer(QRhiBuffer::Type type, + QRhiBuffer::UsageFlags usage, + int size) override; + QRhiRenderBuffer *createRenderBuffer(QRhiRenderBuffer::Type type, + const QSize &pixelSize, + int sampleCount, + QRhiRenderBuffer::Flags flags) override; + QRhiTexture *createTexture(QRhiTexture::Format format, + const QSize &pixelSize, + int sampleCount, + QRhiTexture::Flags flags) override; + QRhiSampler *createSampler(QRhiSampler::Filter magFilter, QRhiSampler::Filter minFilter, + QRhiSampler::Filter mipmapMode, + QRhiSampler:: AddressMode u, QRhiSampler::AddressMode v) override; + + QRhiTextureRenderTarget *createTextureRenderTarget(const QRhiTextureRenderTargetDescription &desc, + QRhiTextureRenderTarget::Flags flags) override; + + QRhiSwapChain *createSwapChain() override; + QRhi::FrameOpResult beginFrame(QRhiSwapChain *swapChain, QRhi::BeginFrameFlags flags) override; + QRhi::FrameOpResult endFrame(QRhiSwapChain *swapChain, QRhi::EndFrameFlags flags) override; + QRhi::FrameOpResult beginOffscreenFrame(QRhiCommandBuffer **cb, QRhi::BeginFrameFlags flags) override; + QRhi::FrameOpResult endOffscreenFrame(QRhi::EndFrameFlags flags) override; + QRhi::FrameOpResult finish() override; + + void resourceUpdate(QRhiCommandBuffer *cb, QRhiResourceUpdateBatch *resourceUpdates) override; + + void beginPass(QRhiCommandBuffer *cb, + QRhiRenderTarget *rt, + const QColor &colorClearValue, + const QRhiDepthStencilClearValue &depthStencilClearValue, + QRhiResourceUpdateBatch *resourceUpdates) override; + void endPass(QRhiCommandBuffer *cb, QRhiResourceUpdateBatch *resourceUpdates) override; + + void setGraphicsPipeline(QRhiCommandBuffer *cb, + QRhiGraphicsPipeline *ps) override; + + void setShaderResources(QRhiCommandBuffer *cb, + QRhiShaderResourceBindings *srb, + int dynamicOffsetCount, + const QRhiCommandBuffer::DynamicOffset *dynamicOffsets) override; + + void setVertexInput(QRhiCommandBuffer *cb, + int startBinding, int bindingCount, const QRhiCommandBuffer::VertexInput *bindings, + QRhiBuffer *indexBuf, quint32 indexOffset, + QRhiCommandBuffer::IndexFormat indexFormat) override; + + void setViewport(QRhiCommandBuffer *cb, const QRhiViewport &viewport) override; + void setScissor(QRhiCommandBuffer *cb, const QRhiScissor &scissor) override; + void setBlendConstants(QRhiCommandBuffer *cb, const QColor &c) override; + void setStencilRef(QRhiCommandBuffer *cb, quint32 refValue) override; + + void draw(QRhiCommandBuffer *cb, quint32 vertexCount, + quint32 instanceCount, quint32 firstVertex, quint32 firstInstance) override; + + void drawIndexed(QRhiCommandBuffer *cb, quint32 indexCount, + quint32 instanceCount, quint32 firstIndex, + qint32 vertexOffset, quint32 firstInstance) override; + + void debugMarkBegin(QRhiCommandBuffer *cb, const QByteArray &name) override; + void debugMarkEnd(QRhiCommandBuffer *cb) override; + void debugMarkMsg(QRhiCommandBuffer *cb, const QByteArray &msg) override; + + void beginComputePass(QRhiCommandBuffer *cb, QRhiResourceUpdateBatch *resourceUpdates) override; + void endComputePass(QRhiCommandBuffer *cb, QRhiResourceUpdateBatch *resourceUpdates) override; + void setComputePipeline(QRhiCommandBuffer *cb, QRhiComputePipeline *ps) override; + void dispatch(QRhiCommandBuffer *cb, int x, int y, int z) override; + + const QRhiNativeHandles *nativeHandles(QRhiCommandBuffer *cb) override; + void beginExternal(QRhiCommandBuffer *cb) override; + void endExternal(QRhiCommandBuffer *cb) override; + + QVector<int> supportedSampleCounts() const override; + int ubufAlignment() const override; + bool isYUpInFramebuffer() const override; + bool isYUpInNDC() const override; + bool isClipDepthZeroToOne() const override; + QMatrix4x4 clipSpaceCorrMatrix() const override; + bool isTextureFormatSupported(QRhiTexture::Format format, QRhiTexture::Flags flags) const override; + bool isFeatureSupported(QRhi::Feature feature) const override; + int resourceLimit(QRhi::ResourceLimit limit) const override; + const QRhiNativeHandles *nativeHandles() override; + void sendVMemStatsToProfiler() override; + bool makeThreadLocalNativeContextCurrent() override; + void releaseCachedResources() override; + bool isDeviceLost() const override; + + void executeDeferredReleases(bool forced = false); + void finishActiveReadbacks(bool forced = false); + qsizetype subresUploadByteSize(const QRhiTextureSubresourceUploadDescription &subresDesc) const; + void enqueueSubresUpload(QMetalTexture *texD, void *mp, void *blitEncPtr, + int layer, int level, const QRhiTextureSubresourceUploadDescription &subresDesc, + qsizetype *curOfs); + void enqueueResourceUpdates(QRhiCommandBuffer *cb, QRhiResourceUpdateBatch *resourceUpdates); + void executeBufferHostWritesForCurrentFrame(QMetalBuffer *bufD); + static const int SUPPORTED_STAGES = 3; + void enqueueShaderResourceBindings(QMetalShaderResourceBindings *srbD, + QMetalCommandBuffer *cbD, + int dynamicOffsetCount, + const QRhiCommandBuffer::DynamicOffset *dynamicOffsets, + bool offsetOnlyChange, + const QShader::NativeResourceBindingMap *nativeResourceBindingMaps[SUPPORTED_STAGES]); + int effectiveSampleCount(int sampleCount) const; + + bool importedDevice = false; + bool importedCmdQueue = false; + QMetalSwapChain *currentSwapChain = nullptr; + QSet<QMetalSwapChain *> swapchains; + QRhiMetalNativeHandles nativeHandlesStruct; + + struct { + int maxTextureSize = 4096; + } caps; + + QRhiMetalData *d = nullptr; +}; + +QT_END_NAMESPACE + +#endif |