qrhimetal_p.h 10.8 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65
/****************************************************************************
**
** Copyright (C) 2018 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
** This file is part of the Qt RHI module
**
** $QT_BEGIN_LICENSE:GPL$
** 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 https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 or (at your option) any later version
** approved by the KDE Free Qt Foundation. The licenses are as published by
** the Free Software Foundation and appearing in the file LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.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.h"
#include "qrhi_p.h"
#include <QShaderDescription>
#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;
Laszlo Agocs's avatar
Laszlo Agocs committed
66
    friend class QRhiMetal;
67 68
};

Laszlo Agocs's avatar
Laszlo Agocs committed
69 70
struct QMetalRenderBufferData;

71 72 73
struct QMetalRenderBuffer : public QRhiRenderBuffer
{
    QMetalRenderBuffer(QRhiImplementation *rhi, Type type, const QSize &pixelSize,
Laszlo Agocs's avatar
Laszlo Agocs committed
74
                       int sampleCount, QRhiRenderBuffer::Flags flags);
Laszlo Agocs's avatar
Laszlo Agocs committed
75
    ~QMetalRenderBuffer();
76 77
    void release() override;
    bool build() override;
Laszlo Agocs's avatar
Laszlo Agocs committed
78

Laszlo Agocs's avatar
Laszlo Agocs committed
79 80 81
    QMetalRenderBufferData *d;
    uint generation = 0;
    int lastActiveFrameSlot = -1;
Laszlo Agocs's avatar
Laszlo Agocs committed
82
    friend class QRhiMetal;
83 84
};

Laszlo Agocs's avatar
Laszlo Agocs committed
85 86
struct QMetalTextureData;

87 88
struct QMetalTexture : public QRhiTexture
{
Laszlo Agocs's avatar
Laszlo Agocs committed
89 90
    QMetalTexture(QRhiImplementation *rhi, Format format, const QSize &pixelSize,
                  int sampleCount, Flags flags);
Laszlo Agocs's avatar
Laszlo Agocs committed
91
    ~QMetalTexture();
92 93 94
    void release() override;
    bool build() override;

Laszlo Agocs's avatar
Laszlo Agocs committed
95
    QMetalTextureData *d;
Laszlo Agocs's avatar
Laszlo Agocs committed
96
    int mipLevelCount = 0;
97 98
    uint generation = 0;
    int lastActiveFrameSlot = -1;
Laszlo Agocs's avatar
Laszlo Agocs committed
99
    friend class QRhiMetal;
100 101
};

Laszlo Agocs's avatar
Laszlo Agocs committed
102 103
struct QMetalSamplerData;

104 105 106 107
struct QMetalSampler : public QRhiSampler
{
    QMetalSampler(QRhiImplementation *rhi, Filter magFilter, Filter minFilter, Filter mipmapMode,
                  AddressMode u, AddressMode v, AddressMode w);
Laszlo Agocs's avatar
Laszlo Agocs committed
108
    ~QMetalSampler();
109 110 111
    void release() override;
    bool build() override;

Laszlo Agocs's avatar
Laszlo Agocs committed
112
    QMetalSamplerData *d;
113 114
    uint generation = 0;
    int lastActiveFrameSlot = -1;
Laszlo Agocs's avatar
Laszlo Agocs committed
115
    friend class QRhiMetal;
116 117
};

Laszlo Agocs's avatar
Laszlo Agocs committed
118
struct QMetalRenderPassDescriptor : public QRhiRenderPassDescriptor
119
{
Laszlo Agocs's avatar
Laszlo Agocs committed
120
    QMetalRenderPassDescriptor(QRhiImplementation *rhi);
121 122 123
    void release() override;

    // there is no MTLRenderPassDescriptor here as one will be created for each pass in beginPass()
124

125
    // but the things needed for the render pipeline descriptor have to be provided
Laszlo Agocs's avatar
Laszlo Agocs committed
126
    static const int MAX_COLOR_ATTACHMENTS = 8;
Laszlo Agocs's avatar
Laszlo Agocs committed
127
    int colorAttachmentCount = 0;
128
    bool hasDepthStencil = false;
Laszlo Agocs's avatar
Laszlo Agocs committed
129
    int colorFormat[MAX_COLOR_ATTACHMENTS];
130
    int dsFormat;
131 132
};

133
struct QMetalRenderTargetData;
134 135 136 137

struct QMetalReferenceRenderTarget : public QRhiReferenceRenderTarget
{
    QMetalReferenceRenderTarget(QRhiImplementation *rhi);
138
    ~QMetalReferenceRenderTarget();
139
    void release() override;
140

141 142 143
    Type type() const override;
    QSize sizeInPixels() const override;

144
    QMetalRenderTargetData *d;
145 146 147 148 149
};

struct QMetalTextureRenderTarget : public QRhiTextureRenderTarget
{
    QMetalTextureRenderTarget(QRhiImplementation *rhi, const QRhiTextureRenderTargetDescription &desc, Flags flags);
150
    ~QMetalTextureRenderTarget();
151
    void release() override;
Laszlo Agocs's avatar
Laszlo Agocs committed
152

153 154 155
    Type type() const override;
    QSize sizeInPixels() const override;

Laszlo Agocs's avatar
Laszlo Agocs committed
156
    QRhiRenderPassDescriptor *newCompatibleRenderPassDescriptor() override;
Laszlo Agocs's avatar
Laszlo Agocs committed
157 158
    bool build() override;

159
    QMetalRenderTargetData *d;
Laszlo Agocs's avatar
Laszlo Agocs committed
160
    friend class QRhiMetal;
161 162 163 164 165 166 167 168
};

struct QMetalShaderResourceBindings : public QRhiShaderResourceBindings
{
    QMetalShaderResourceBindings(QRhiImplementation *rhi);
    void release() override;
    bool build() override;

169
    QVector<QRhiShaderResourceBinding> sortedBindings;
170 171
    int maxBinding = -1;
    uint generation = 0;
Laszlo Agocs's avatar
Laszlo Agocs committed
172
    friend class QRhiMetal;
173 174 175 176 177 178 179 180 181 182 183 184 185 186
};

struct QMetalGraphicsPipelineData;

struct QMetalGraphicsPipeline : public QRhiGraphicsPipeline
{
    QMetalGraphicsPipeline(QRhiImplementation *rhi);
    ~QMetalGraphicsPipeline();
    void release() override;
    bool build() override;

    QMetalGraphicsPipelineData *d;
    uint generation = 0;
    int lastActiveFrameSlot = -1;
Laszlo Agocs's avatar
Laszlo Agocs committed
187
    friend class QRhiMetal;
188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205
};

struct QMetalCommandBufferData;
struct QMetalSwapChain;

struct QMetalCommandBuffer : public QRhiCommandBuffer
{
    QMetalCommandBuffer(QRhiImplementation *rhi);
    ~QMetalCommandBuffer();
    void release() override;

    QMetalCommandBufferData *d = nullptr;

    QRhiRenderTarget *currentTarget;
    QRhiGraphicsPipeline *currentPipeline;
    uint currentPipelineGeneration;
    QRhiShaderResourceBindings *currentSrb;
    uint currentSrbGeneration;
Laszlo Agocs's avatar
Laszlo Agocs committed
206 207 208
    QRhiBuffer *currentIndexBuffer;
    quint32 currentIndexOffset;
    QRhi::IndexFormat currentIndexFormat;
209

210
    void resetState();
211 212 213 214 215 216 217 218 219 220 221 222
};

struct QMetalSwapChainData;

struct QMetalSwapChain : public QRhiSwapChain
{
    QMetalSwapChain(QRhiImplementation *rhi);
    ~QMetalSwapChain();
    void release() override;

    QRhiCommandBuffer *currentFrameCommandBuffer() override;
    QRhiRenderTarget *currentFrameRenderTarget() override;
223
    QSize effectivePixelSize() const override;
224

Laszlo Agocs's avatar
Laszlo Agocs committed
225
    QRhiRenderPassDescriptor *newCompatibleRenderPassDescriptor() override;
Laszlo Agocs's avatar
Laszlo Agocs committed
226

Laszlo Agocs's avatar
Laszlo Agocs committed
227
    bool buildOrResize() override;
228

Laszlo Agocs's avatar
Laszlo Agocs committed
229
    QSize pixelSize;
230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252
    int currentFrame = 0; // 0..QMTL_FRAMES_IN_FLIGHT-1
    QMetalReferenceRenderTarget rtWrapper;
    QMetalCommandBuffer cbWrapper;
    QMetalRenderBuffer *ds = nullptr;
    QMetalSwapChainData *d = nullptr;
};

struct QRhiMetalData;

class QRhiMetal : public QRhiImplementation
{
public:
    QRhiMetal(QRhiInitParams *params);
    ~QRhiMetal();

    QRhiGraphicsPipeline *createGraphicsPipeline() 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,
Laszlo Agocs's avatar
Laszlo Agocs committed
253
                                         QRhiRenderBuffer::Flags flags) override;
254 255
    QRhiTexture *createTexture(QRhiTexture::Format format,
                               const QSize &pixelSize,
Laszlo Agocs's avatar
Laszlo Agocs committed
256
                               int sampleCount,
257 258 259 260 261 262 263 264 265 266 267
                               QRhiTexture::Flags flags) override;
    QRhiSampler *createSampler(QRhiSampler::Filter magFilter, QRhiSampler::Filter minFilter,
                               QRhiSampler::Filter mipmapMode,
                               QRhiSampler:: AddressMode u, QRhiSampler::AddressMode v, QRhiSampler::AddressMode w) override;

    QRhiTextureRenderTarget *createTextureRenderTarget(const QRhiTextureRenderTargetDescription &desc,
                                                       QRhiTextureRenderTarget::Flags flags) override;

    QRhiSwapChain *createSwapChain() override;
    QRhi::FrameOpResult beginFrame(QRhiSwapChain *swapChain) override;
    QRhi::FrameOpResult endFrame(QRhiSwapChain *swapChain) override;
268
    QRhi::FrameOpResult beginOffscreenFrame(QRhiCommandBuffer **cb) override;
269 270
    QRhi::FrameOpResult endOffscreenFrame() override;
    QRhi::FrameOpResult finish() override;
271

272 273 274 275
    void resourceUpdate(QRhiCommandBuffer *cb, QRhiResourceUpdateBatch *resourceUpdates) override;

    void beginPass(QRhiCommandBuffer *cb,
                   QRhiRenderTarget *rt,
276 277 278
                   const QRhiColorClearValue &colorClearValue,
                   const QRhiDepthStencilClearValue &depthStencilClearValue,
                   QRhiResourceUpdateBatch *resourceUpdates) override;
279
    void endPass(QRhiCommandBuffer *cb, QRhiResourceUpdateBatch *resourceUpdates) override;
280 281 282 283 284 285

    void setGraphicsPipeline(QRhiCommandBuffer *cb,
                             QRhiGraphicsPipeline *ps,
                             QRhiShaderResourceBindings *srb) override;

    void setVertexInput(QRhiCommandBuffer *cb,
286
                        int startBinding, const QVector<QRhiCommandBuffer::VertexInput> &bindings,
287
                        QRhiBuffer *indexBuf, quint32 indexOffset,
288
                        QRhiCommandBuffer::IndexFormat indexFormat) override;
289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305

    void setViewport(QRhiCommandBuffer *cb, const QRhiViewport &viewport) override;
    void setScissor(QRhiCommandBuffer *cb, const QRhiScissor &scissor) override;
    void setBlendConstants(QRhiCommandBuffer *cb, const QVector4D &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;

    QVector<int> supportedSampleCounts() const override;
    int ubufAlignment() const override;
    bool isYUpInFramebuffer() const override;
    QMatrix4x4 clipSpaceCorrMatrix() const override;
306
    bool isTextureFormatSupported(QRhiTexture::Format format, QRhiTexture::Flags flags) const override;
307 308 309 310

    void create();
    void destroy();
    void executeDeferredReleases(bool forced = false);
311
    void enqueueResourceUpdates(QRhiCommandBuffer *cb, QRhiResourceUpdateBatch *resourceUpdates);
312 313 314 315 316 317 318 319 320 321 322 323 324 325
    void executeBufferHostWritesForCurrentFrame(QMetalBuffer *bufD);

    bool importedDevice = false;
    bool inFrame = false;
    int currentFrameSlot = 0;
    int finishedFrameCount = 0;
    bool inPass = false;

    QRhiMetalData *d = nullptr;
};

QT_END_NAMESPACE

#endif