qrhimetal_p.h 12 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
    QRhiTexture::Format backingFormat() const override;
Laszlo Agocs's avatar
Laszlo Agocs committed
79

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

Laszlo Agocs's avatar
Laszlo Agocs committed
87
88
struct QMetalTextureData;

89
90
struct QMetalTexture : public QRhiTexture
{
Laszlo Agocs's avatar
Laszlo Agocs committed
91
92
    QMetalTexture(QRhiImplementation *rhi, Format format, const QSize &pixelSize,
                  int sampleCount, Flags flags);
Laszlo Agocs's avatar
Laszlo Agocs committed
93
    ~QMetalTexture();
94
95
    void release() override;
    bool build() override;
96
97
    bool buildFrom(const QRhiNativeHandles *src) override;
    const QRhiNativeHandles *nativeHandles() override;
Laszlo Agocs's avatar
Laszlo Agocs committed
98
99

    bool prepareBuild(QSize *adjustedSize = nullptr);
100

Laszlo Agocs's avatar
Laszlo Agocs committed
101
    QMetalTextureData *d;
102
    QRhiMetalTextureNativeHandles nativeHandlesStruct;
Laszlo Agocs's avatar
Laszlo Agocs committed
103
    int mipLevelCount = 0;
104
    int samples = 1;
105
106
    uint generation = 0;
    int lastActiveFrameSlot = -1;
Laszlo Agocs's avatar
Laszlo Agocs committed
107
    friend class QRhiMetal;
108
109
};

Laszlo Agocs's avatar
Laszlo Agocs committed
110
111
struct QMetalSamplerData;

112
113
114
115
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
116
    ~QMetalSampler();
117
118
119
    void release() override;
    bool build() override;

Laszlo Agocs's avatar
Laszlo Agocs committed
120
    QMetalSamplerData *d;
121
122
    uint generation = 0;
    int lastActiveFrameSlot = -1;
Laszlo Agocs's avatar
Laszlo Agocs committed
123
    friend class QRhiMetal;
124
125
};

Laszlo Agocs's avatar
Laszlo Agocs committed
126
struct QMetalRenderPassDescriptor : public QRhiRenderPassDescriptor
127
{
Laszlo Agocs's avatar
Laszlo Agocs committed
128
    QMetalRenderPassDescriptor(QRhiImplementation *rhi);
129
130
131
    void release() override;

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

133
    // but the things needed for the render pipeline descriptor have to be provided
Laszlo Agocs's avatar
Laszlo Agocs committed
134
    static const int MAX_COLOR_ATTACHMENTS = 8;
Laszlo Agocs's avatar
Laszlo Agocs committed
135
    int colorAttachmentCount = 0;
136
    bool hasDepthStencil = false;
Laszlo Agocs's avatar
Laszlo Agocs committed
137
    int colorFormat[MAX_COLOR_ATTACHMENTS];
138
    int dsFormat;
139
140
};

141
struct QMetalRenderTargetData;
142
143
144
145

struct QMetalReferenceRenderTarget : public QRhiReferenceRenderTarget
{
    QMetalReferenceRenderTarget(QRhiImplementation *rhi);
146
    ~QMetalReferenceRenderTarget();
147
    void release() override;
148

149
150
    Type type() const override;
    QSize sizeInPixels() const override;
Laszlo Agocs's avatar
Laszlo Agocs committed
151
    float devicePixelRatio() const override;
152

153
    QMetalRenderTargetData *d;
154
155
156
157
158
};

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

162
163
    Type type() const override;
    QSize sizeInPixels() const override;
Laszlo Agocs's avatar
Laszlo Agocs committed
164
    float devicePixelRatio() const override;
165

Laszlo Agocs's avatar
Laszlo Agocs committed
166
    QRhiRenderPassDescriptor *newCompatibleRenderPassDescriptor() override;
Laszlo Agocs's avatar
Laszlo Agocs committed
167
168
    bool build() override;

169
    QMetalRenderTargetData *d;
Laszlo Agocs's avatar
Laszlo Agocs committed
170
    friend class QRhiMetal;
171
172
173
174
175
176
177
178
};

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

179
    QVector<QRhiShaderResourceBinding> sortedBindings;
180
181
    int maxBinding = -1;
    uint generation = 0;
Laszlo Agocs's avatar
Laszlo Agocs committed
182
    friend class QRhiMetal;
183
184
185
186
187
188
189
190
191
192
193
194
195
196
};

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
197
    friend class QRhiMetal;
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
};

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
216
217
    QRhiBuffer *currentIndexBuffer;
    quint32 currentIndexOffset;
Laszlo Agocs's avatar
Laszlo Agocs committed
218
    QRhiCommandBuffer::IndexFormat currentIndexFormat;
219

220
    void resetState();
221
222
223
224
225
226
227
228
229
230
231
232
};

struct QMetalSwapChainData;

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

    QRhiCommandBuffer *currentFrameCommandBuffer() override;
    QRhiRenderTarget *currentFrameRenderTarget() override;
233
    QSize surfacePixelSize() override;
234

Laszlo Agocs's avatar
Laszlo Agocs committed
235
    QRhiRenderPassDescriptor *newCompatibleRenderPassDescriptor() override;
Laszlo Agocs's avatar
Laszlo Agocs committed
236

Laszlo Agocs's avatar
Laszlo Agocs committed
237
    bool buildOrResize() override;
238

239
240
    void chooseFormats();

241
    QWindow *window = nullptr;
Laszlo Agocs's avatar
Laszlo Agocs committed
242
    QSize pixelSize;
243
    int currentFrame = 0; // 0..QMTL_FRAMES_IN_FLIGHT-1
244
    int samples = 1;
245
246
247
248
249
250
251
252
253
254
255
256
257
258
    QMetalReferenceRenderTarget rtWrapper;
    QMetalCommandBuffer cbWrapper;
    QMetalRenderBuffer *ds = nullptr;
    QMetalSwapChainData *d = nullptr;
};

struct QRhiMetalData;

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

259
    bool create(QRhi::Flags flags) override;
260
261
    void destroy() override;

262
263
264
265
266
267
268
269
    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
270
                                         QRhiRenderBuffer::Flags flags) override;
271
272
    QRhiTexture *createTexture(QRhiTexture::Format format,
                               const QSize &pixelSize,
Laszlo Agocs's avatar
Laszlo Agocs committed
273
                               int sampleCount,
274
275
276
277
278
279
280
281
282
283
284
                               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;
285
    QRhi::FrameOpResult beginOffscreenFrame(QRhiCommandBuffer **cb) override;
286
287
    QRhi::FrameOpResult endOffscreenFrame() override;
    QRhi::FrameOpResult finish() override;
288

289
290
291
292
    void resourceUpdate(QRhiCommandBuffer *cb, QRhiResourceUpdateBatch *resourceUpdates) override;

    void beginPass(QRhiCommandBuffer *cb,
                   QRhiRenderTarget *rt,
293
294
295
                   const QRhiColorClearValue &colorClearValue,
                   const QRhiDepthStencilClearValue &depthStencilClearValue,
                   QRhiResourceUpdateBatch *resourceUpdates) override;
296
    void endPass(QRhiCommandBuffer *cb, QRhiResourceUpdateBatch *resourceUpdates) override;
297
298
299
300
301
302

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

    void setVertexInput(QRhiCommandBuffer *cb,
303
                        int startBinding, const QVector<QRhiCommandBuffer::VertexInput> &bindings,
304
                        QRhiBuffer *indexBuf, quint32 indexOffset,
305
                        QRhiCommandBuffer::IndexFormat indexFormat) override;
306
307
308
309
310
311
312
313
314
315
316
317
318

    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;

319
320
321
322
    void debugMarkBegin(QRhiCommandBuffer *cb, const QByteArray &name) override;
    void debugMarkEnd(QRhiCommandBuffer *cb) override;
    void debugMarkMsg(QRhiCommandBuffer *cb, const QByteArray &msg) override;

323
324
325
326
    QVector<int> supportedSampleCounts() const override;
    int ubufAlignment() const override;
    bool isYUpInFramebuffer() const override;
    QMatrix4x4 clipSpaceCorrMatrix() const override;
327
    bool isTextureFormatSupported(QRhiTexture::Format format, QRhiTexture::Flags flags) const override;
Laszlo Agocs's avatar
Laszlo Agocs committed
328
    bool isFeatureSupported(QRhi::Feature feature) const override;
329
    int resourceSizeLimit(QRhi::ResourceSizeLimit limit) const override;
330
    const QRhiNativeHandles *nativeHandles() override;
331
332

    void executeDeferredReleases(bool forced = false);
333
    void finishActiveReadbacks(bool forced = false);
334
    void enqueueResourceUpdates(QRhiCommandBuffer *cb, QRhiResourceUpdateBatch *resourceUpdates);
335
    void executeBufferHostWritesForCurrentFrame(QMetalBuffer *bufD);
336
    int effectiveSampleCount(int sampleCount) const;
337
338
339
340
341
342

    bool importedDevice = false;
    bool inFrame = false;
    int currentFrameSlot = 0;
    int finishedFrameCount = 0;
    bool inPass = false;
343
    QMetalSwapChain *currentSwapChain = nullptr;
Laszlo Agocs's avatar
Laszlo Agocs committed
344
    QSet<QMetalSwapChain *> swapchains;
345
    QRhiMetalNativeHandles nativeHandlesStruct;
346

347
348
349
350
    struct {
        int maxTextureSize = 4096;
    } caps;

351
352
353
354
355
356
    QRhiMetalData *d = nullptr;
};

QT_END_NAMESPACE

#endif