Commit 728c8fa9 authored by Laszlo Agocs's avatar Laszlo Agocs

Revamp swapchain api

...and add the - for now - unused buildCompatibleRenderPass functions.
parent 2ee3c17d
......@@ -354,7 +354,12 @@ void Window::recreateSwapChain()
}
m_ds->build();
m_hasSwapChain = m_sc->build(this, outputSize, 0, m_ds, 1);
m_sc->setWindow(this);
m_sc->setRequestedPixelSize(outputSize);
m_sc->setDepthStencil(m_ds);
m_hasSwapChain = m_sc->buildOrResize();
m_swapChainChanged = true;
m_elapsedMs = 0;
......@@ -423,7 +428,7 @@ void Window::render()
// If the window got resized or got newly exposed, recreate the swapchain.
// (the newly-exposed case is not actually required by some
// platforms/backends, but f.ex. Vulkan on Windows seems to need it)
if (m_sc->requestedSizeInPixels() != size() * devicePixelRatio() || m_newlyExposed) {
if (m_sc->requestedPixelSize() != size() * devicePixelRatio() || m_newlyExposed) {
recreateSwapChain();
if (!m_hasSwapChain)
return;
......
......@@ -174,7 +174,13 @@ void ExampleWindow::recreateSwapChain()
m_ds->build();
m_hasSwapChain = m_sc->build(this, outputSize, 0, m_ds, m_triRenderer.sampleCount());
m_sc->setWindow(this);
m_sc->setRequestedPixelSize(outputSize);
m_sc->setDepthStencil(m_ds);
m_sc->setSampleCount(m_triRenderer.sampleCount());
m_hasSwapChain = m_sc->buildOrResize();
m_swapChainChanged = true;
}
......@@ -195,7 +201,7 @@ void ExampleWindow::render()
if (!m_hasSwapChain || m_notExposed)
return;
if (m_sc->requestedSizeInPixels() != size() * devicePixelRatio() || m_newlyExposed) {
if (m_sc->requestedPixelSize() != size() * devicePixelRatio() || m_newlyExposed) {
recreateSwapChain();
if (!m_hasSwapChain)
return;
......
......@@ -80,7 +80,8 @@ void Renderer::initResources()
void Renderer::initSwapChainResources()
{
m_sc->build(m_window); // this just wraps the window's swapchain
m_sc->setTarget(m_window); // note: very different from setWindow(m_window)
m_sc->buildOrResize(); // this just wraps the qvulkanwindow's swapchain
m_triRenderer.initOutputDependentResources(m_sc->defaultRenderPass(), m_sc->effectiveSizeInPixels());
}
......
......@@ -479,6 +479,9 @@ public:
Flags flags() const { return m_flags; }
void setFlags(Flags f) { m_flags = f; }
// to be called before build() with description and flags set
virtual QRhiRenderPass *buildCompatibleRenderPass() = 0;
// as usual, textures in desc must be built before calling build() on the rt
virtual bool build() = 0;
......@@ -710,6 +713,26 @@ public:
};
Q_DECLARE_FLAGS(SurfaceImportFlags, SurfaceImportFlag)
QWindow *window() const { return m_window; }
void setWindow(QWindow *window) { m_window = window; }
QSize requestedPixelSize() const { return m_requestedPixelSize; }
void setRequestedPixelSize(const QSize &size) { m_requestedPixelSize = size; }
SurfaceImportFlags flags() const { return m_flags; }
void setFlags(SurfaceImportFlags f) { m_flags = f; }
QRhiRenderBuffer *depthStencil() const { return m_depthStencil; }
void setDepthStencil(QRhiRenderBuffer *ds) { m_depthStencil = ds; }
int sampleCount() const { return m_sampleCount; }
void setSampleCount(int samples) { m_sampleCount = samples; }
// Alternatively, integrate with an existing swapchain, f.ex.
// QVulkanWindow. Other settings have no effect when this is set.
QObject *target() const { return m_target; }
void setTarget(QObject *obj) { m_target = obj; }
virtual QRhiCommandBuffer *currentFrameCommandBuffer() = 0;
virtual QRhiRenderTarget *currentFrameRenderTarget() = 0;
virtual const QRhiRenderPass *defaultRenderPass() const = 0;
......@@ -717,18 +740,21 @@ public:
// Some backends use the requested size, others ignore it and get the actual
// size on their own. Keep track of both - application logic will need the
// requested size (to do their "if qwindow->size() * dpr != req.size then
// rebuild_swapchain" logic) and the actual size as well (for all graphics
// resize_swapchain" logic) and the actual size as well (for all graphics
// calculations like viewport).
virtual QSize requestedSizeInPixels() const = 0;
virtual QSize effectiveSizeInPixels() const = 0;
virtual bool build(QWindow *window, const QSize &requestedPixelSize, SurfaceImportFlags flags,
QRhiRenderBuffer *depthStencil, int sampleCount) = 0;
virtual bool build(QObject *target) = 0; // integrate with an existing swapchain, f.ex. QVulkanWindow
virtual QRhiRenderPass *buildCompatibleRenderPass() = 0;
virtual bool buildOrResize() = 0;
protected:
QRhiSwapChain(QRhiImplementation *rhi);
QWindow *m_window = nullptr;
QSize m_requestedPixelSize;
SurfaceImportFlags m_flags;
QRhiRenderBuffer *m_depthStencil = nullptr;
int m_sampleCount = 1;
QObject *m_target = nullptr;
void *m_reserved;
};
......
......@@ -1170,6 +1170,7 @@ bool QD3D11Sampler::build()
return true;
}
// dummy, no Vulkan-style RenderPass+Framebuffer concept here
QD3D11RenderPass::QD3D11RenderPass(QRhiImplementation *rhi)
: QRhiRenderPass(rhi)
{
......@@ -1235,6 +1236,11 @@ void QD3D11TextureRenderTarget::release()
}
}
QRhiRenderPass *QD3D11TextureRenderTarget::buildCompatibleRenderPass()
{
return new QD3D11RenderPass(rhi);
}
bool QD3D11TextureRenderTarget::build()
{
if (rtv[0] || dsv)
......@@ -1821,29 +1827,26 @@ const QRhiRenderPass *QD3D11SwapChain::defaultRenderPass() const
return rt.renderPass();
}
QSize QD3D11SwapChain::requestedSizeInPixels() const
QSize QD3D11SwapChain::effectiveSizeInPixels() const
{
return pixelSize;
}
QSize QD3D11SwapChain::effectiveSizeInPixels() const
QRhiRenderPass *QD3D11SwapChain::buildCompatibleRenderPass()
{
return pixelSize;
return new QD3D11RenderPass(rhi);
}
bool QD3D11SwapChain::build(QWindow *window_, const QSize &requestedPixelSize, SurfaceImportFlags flags,
QRhiRenderBuffer *depthStencil, int sampleCount)
bool QD3D11SwapChain::buildOrResize()
{
// Can be called multiple times due to window resizes - that is not the
// same as a simple release+build (as with other resources). Just need to
// resize the buffers then.
Q_ASSERT(!swapChain || window == window_);
Q_ASSERT(!swapChain || window == m_window);
Q_UNUSED(sampleCount); // ### MSAA
window = window_;
pixelSize = requestedPixelSize;
window = m_window;
pixelSize = m_requestedPixelSize;
QRHI_RES_RHI(QRhiD3D11);
......@@ -1868,9 +1871,9 @@ bool QD3D11SwapChain::build(QWindow *window_, const QSize &requestedPixelSize, S
desc.BufferCount = BUFFER_COUNT;
desc.Scaling = DXGI_SCALING_STRETCH;
desc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD;
if (flags.testFlag(SurfaceHasPreMulAlpha))
if (m_flags.testFlag(SurfaceHasPreMulAlpha))
desc.AlphaMode = DXGI_ALPHA_MODE_PREMULTIPLIED;
else if (flags.testFlag(SurfaceHasNonPreMulAlpha))
else if (m_flags.testFlag(SurfaceHasNonPreMulAlpha))
desc.AlphaMode = DXGI_ALPHA_MODE_STRAIGHT;
desc.Flags = swapChainFlags;
......@@ -1911,20 +1914,14 @@ bool QD3D11SwapChain::build(QWindow *window_, const QSize &requestedPixelSize, S
}
currentFrame = 0;
ds = depthStencil ? QRHI_RES(QD3D11RenderBuffer, depthStencil) : nullptr;
ds = m_depthStencil ? QRHI_RES(QD3D11RenderBuffer, m_depthStencil) : nullptr;
QD3D11ReferenceRenderTarget *rtD = QRHI_RES(QD3D11ReferenceRenderTarget, &rt);
rtD->d.pixelSize = pixelSize;
rtD->d.colorAttCount = 1;
rtD->d.dsAttCount = depthStencil ? 1 : 0;
rtD->d.dsAttCount = m_depthStencil ? 1 : 0;
return true;
}
bool QD3D11SwapChain::build(QObject *target)
{
Q_UNUSED(target);
return false;
}
QT_END_NAMESPACE
......@@ -140,11 +140,14 @@ struct QD3D11TextureRenderTarget : public QRhiTextureRenderTarget
{
QD3D11TextureRenderTarget(QRhiImplementation *rhi, const QRhiTextureRenderTargetDescription &desc, Flags flags);
void release() override;
Type type() const override;
bool build() override;
QSize sizeInPixels() const override;
const QRhiRenderPass *renderPass() const override;
QRhiRenderPass *buildCompatibleRenderPass() override;
bool build() override;
QD3D11BasicRenderTargetData d;
ID3D11RenderTargetView *rtv[QD3D11BasicRenderTargetData::MAX_COLOR_ATTACHMENTS];
bool ownsDsv = false;
......@@ -360,13 +363,10 @@ struct QD3D11SwapChain : public QRhiSwapChain
QRhiCommandBuffer *currentFrameCommandBuffer() override;
QRhiRenderTarget *currentFrameRenderTarget() override;
const QRhiRenderPass *defaultRenderPass() const override;
QSize requestedSizeInPixels() const override;
QSize effectiveSizeInPixels() const override;
bool build(QWindow *window, const QSize &requestedPixelSize, SurfaceImportFlags flags,
QRhiRenderBuffer *depthStencil, int sampleCount) override;
bool build(QObject *target) override;
QRhiRenderPass *buildCompatibleRenderPass() override;
bool buildOrResize();
QWindow *window = nullptr;
QSize pixelSize;
......
......@@ -1225,6 +1225,7 @@ bool QGles2Sampler::build()
return true;
}
// dummy, no Vulkan-style RenderPass+Framebuffer concept here
QGles2RenderPass::QGles2RenderPass(QRhiImplementation *rhi)
: QRhiRenderPass(rhi)
{
......@@ -1285,6 +1286,11 @@ void QGles2TextureRenderTarget::release()
rhiD->releaseQueue.append(e);
}
QRhiRenderPass *QGles2TextureRenderTarget::buildCompatibleRenderPass()
{
return new QGles2RenderPass(rhi);
}
bool QGles2TextureRenderTarget::build()
{
QRHI_RES_RHI(QRhiGles2);
......@@ -1544,36 +1550,25 @@ const QRhiRenderPass *QGles2SwapChain::defaultRenderPass() const
return rt.renderPass();
}
QSize QGles2SwapChain::requestedSizeInPixels() const
QSize QGles2SwapChain::effectiveSizeInPixels() const
{
return pixelSize;
}
QSize QGles2SwapChain::effectiveSizeInPixels() const
QRhiRenderPass *QGles2SwapChain::buildCompatibleRenderPass()
{
return pixelSize;
return new QGles2RenderPass(rhi);
}
bool QGles2SwapChain::build(QWindow *window, const QSize &requestedPixelSize, SurfaceImportFlags flags,
QRhiRenderBuffer *depthStencil, int sampleCount)
bool QGles2SwapChain::buildOrResize()
{
Q_UNUSED(flags);
Q_UNUSED(sampleCount);
surface = window;
pixelSize = requestedPixelSize;
surface = m_window;
pixelSize = m_requestedPixelSize;
rt.d.pixelSize = pixelSize;
rt.d.attCount = depthStencil ? 2 : 1;
rt.d.attCount = m_depthStencil ? 2 : 1;
return true;
}
bool QGles2SwapChain::build(QObject *target)
{
// ### some day this could support QOpenGLWindow, OpenGLWidget, ...
Q_UNUSED(target);
return false;
}
QT_END_NAMESPACE
......@@ -139,11 +139,14 @@ struct QGles2TextureRenderTarget : public QRhiTextureRenderTarget
{
QGles2TextureRenderTarget(QRhiImplementation *rhi, const QRhiTextureRenderTargetDescription &desc, Flags flags);
void release() override;
Type type() const override;
bool build() override;
QSize sizeInPixels() const override;
const QRhiRenderPass *renderPass() const override;
QRhiRenderPass *buildCompatibleRenderPass() override;
bool build() override;
QGles2BasicRenderTargetData d;
GLuint framebuffer = 0;
friend class QRhiGles2;
......@@ -292,13 +295,10 @@ struct QGles2SwapChain : public QRhiSwapChain
QRhiCommandBuffer *currentFrameCommandBuffer() override;
QRhiRenderTarget *currentFrameRenderTarget() override;
const QRhiRenderPass *defaultRenderPass() const override;
QSize requestedSizeInPixels() const override;
QSize effectiveSizeInPixels() const override;
bool build(QWindow *window, const QSize &requestedPixelSize, SurfaceImportFlags flags,
QRhiRenderBuffer *depthStencil, int sampleCount) override;
bool build(QObject *target) override;
QRhiRenderPass *buildCompatibleRenderPass() override;
bool buildOrResize() override;
QSurface *surface = nullptr;
QSize pixelSize;
......
......@@ -682,6 +682,8 @@ bool QMetalSampler::build()
return true;
}
// dummy, no Vulkan-style RenderPass+Framebuffer concept here.
// We do have MTLRenderPassDescriptor of course, but it will be created on the fly for each pass.
QMetalRenderPass::QMetalRenderPass(QRhiImplementation *rhi)
: QRhiRenderPass(rhi)
{
......@@ -730,6 +732,11 @@ void QMetalTextureRenderTarget::release()
{
}
QRhiRenderPass *QMetalTextureRenderTarget::buildCompatibleRenderPass()
{
return new QMetalRenderPass(rhi);
}
bool QMetalTextureRenderTarget::build()
{
return true;
......
......@@ -131,11 +131,14 @@ struct QMetalTextureRenderTarget : public QRhiTextureRenderTarget
{
QMetalTextureRenderTarget(QRhiImplementation *rhi, const QRhiTextureRenderTargetDescription &desc, Flags flags);
void release() override;
Type type() const override;
bool build() override;
QSize sizeInPixels() const override;
const QRhiRenderPass *renderPass() const override;
QRhiRenderPass *buildCompatibleRenderPass() override;
bool build() override;
QMetalBasicRenderTargetData d;
friend class QRhiMetal;
};
......@@ -209,6 +212,8 @@ struct QMetalSwapChain : public QRhiSwapChain
QSize requestedSizeInPixels() const override;
QSize effectiveSizeInPixels() const override;
QRhiRenderPass *buildCompatibleRenderPass() override;
bool build(QWindow *window, const QSize &requestedPixelSize, SurfaceImportFlags flags,
QRhiRenderBuffer *depthStencil, int sampleCount) override;
......
......@@ -764,9 +764,6 @@ bool QRhiVulkan::recreateSwapChain(VkSurfaceKHR surface, const QSize &pixelSize,
df->vkDeviceWaitIdle(dev);
QVkSwapChain *swapChainD = QRHI_RES(QVkSwapChain, swapChain);
swapChainD->requestedPixelSize = pixelSize;
if (!vkCreateSwapchainKHR) {
vkCreateSwapchainKHR = reinterpret_cast<PFN_vkCreateSwapchainKHR>(f->vkGetDeviceProcAddr(dev, "vkCreateSwapchainKHR"));
vkDestroySwapchainKHR = reinterpret_cast<PFN_vkDestroySwapchainKHR>(f->vkGetDeviceProcAddr(dev, "vkDestroySwapchainKHR"));
......@@ -779,17 +776,19 @@ bool QRhiVulkan::recreateSwapChain(VkSurfaceKHR surface, const QSize &pixelSize,
}
}
VkSurfaceCapabilitiesKHR surfaceCaps;
vkGetPhysicalDeviceSurfaceCapabilitiesKHR(physDev, surface, &surfaceCaps);
quint32 reqBufferCount = QVkSwapChain::DEFAULT_BUFFER_COUNT;
if (surfaceCaps.maxImageCount)
reqBufferCount = qBound(surfaceCaps.minImageCount, reqBufferCount, surfaceCaps.maxImageCount);
QVkSwapChain *swapChainD = QRHI_RES(QVkSwapChain, swapChain);
VkExtent2D bufferSize = surfaceCaps.currentExtent;
if (bufferSize.width == quint32(-1)) {
Q_ASSERT(bufferSize.height == quint32(-1));
bufferSize.width = swapChainD->requestedPixelSize.width();
bufferSize.height = swapChainD->requestedPixelSize.height();
bufferSize.width = swapChainD->m_requestedPixelSize.width();
bufferSize.height = swapChainD->m_requestedPixelSize.height();
}
swapChainD->effectivePixelSize = QSize(bufferSize.width, bufferSize.height);
......@@ -1061,7 +1060,7 @@ QRhi::FrameOpResult QRhiVulkan::beginWrapperFrame(QRhiSwapChain *swapChain)
swapChainD->cbWrapper.cb = w->currentCommandBuffer();
swapChainD->rtWrapper.d.fb = w->currentFramebuffer();
swapChainD->requestedPixelSize = swapChainD->effectivePixelSize = swapChainD->rtWrapper.d.pixelSize = w->swapChainImageSize();
swapChainD->m_requestedPixelSize = swapChainD->effectivePixelSize = swapChainD->rtWrapper.d.pixelSize = w->swapChainImageSize();
currentFrameSlot = w->currentFrame();
......@@ -2809,6 +2808,25 @@ void QVkTextureRenderTarget::release()
rhiD->releaseQueue.append(e);
}
QRhiRenderPass *QVkTextureRenderTarget::buildCompatibleRenderPass()
{
QRHI_RES_RHI(QRhiVulkan);
QVkRenderPass *rp = new QVkRenderPass(rhi);
const VkFormat dsFormat = m_desc.depthTexture ? toVkTextureFormat(m_desc.depthTexture->format())
: rhiD->optimalDepthStencilFormat();
if (!rhiD->createOffscreenRenderPass(&rp->rp,
m_desc.colorAttachments,
m_flags.testFlag(QRhiTextureRenderTarget::PreserveColorContents),
d.dsAttCount > 0,
dsFormat,
m_desc.depthTexture != nullptr))
{
delete rp;
return nullptr;
}
return rp;
}
bool QVkTextureRenderTarget::build()
{
if (d.fb)
......@@ -3239,24 +3257,45 @@ const QRhiRenderPass *QVkSwapChain::defaultRenderPass() const
return rtWrapper.renderPass();
}
QSize QVkSwapChain::requestedSizeInPixels() const
{
return requestedPixelSize;
}
QSize QVkSwapChain::effectiveSizeInPixels() const
{
return effectivePixelSize;
}
bool QVkSwapChain::build(QWindow *window, const QSize &requestedPixelSize_, SurfaceImportFlags flags,
QRhiRenderBuffer *depthStencil, int sampleCount_)
QRhiRenderPass *QVkSwapChain::buildCompatibleRenderPass()
{
QRHI_RES_RHI(QRhiVulkan);
QVkRenderPass *rp = new QVkRenderPass(rhi);
if (!rhiD->createDefaultRenderPass(&rp->rp, m_depthStencil != nullptr, sampleCount, colorFormat)) {
delete rp;
return nullptr;
}
return rp;
}
bool QVkSwapChain::buildOrResize()
{
if (m_target) {
if (sc)
release();
QVulkanWindow *vkw = qobject_cast<QVulkanWindow *>(m_target);
if (vkw) {
rtWrapper.d.rp.rp = vkw->defaultRenderPass();
m_requestedPixelSize = effectivePixelSize = rtWrapper.d.pixelSize = vkw->swapChainImageSize();
rtWrapper.d.colorAttCount = 1;
rtWrapper.d.dsAttCount = 1;
rtWrapper.d.msaaAttCount = vkw->sampleCountFlagBits() > VK_SAMPLE_COUNT_1_BIT ? 1 : 0;
wrapWindow = vkw;
return true;
}
return false;
}
// Can be called multiple times due to window resizes - that is not the
// same as a simple release+build (as with other resources). Thus no
// release() here. See recreateSwapChain() below.
VkSurfaceKHR surface = QVulkanInstance::surfaceForWindow(window);
VkSurfaceKHR surface = QVulkanInstance::surfaceForWindow(m_window);
if (!surface) {
qWarning("Failed to get surface for window");
return false;
......@@ -3286,24 +3325,24 @@ bool QVkSwapChain::build(QWindow *window, const QSize &requestedPixelSize_, Surf
colorSpace = formats[0].colorSpace;
}
sampleCount = rhiD->effectiveSampleCount(sampleCount_);
if (depthStencil && depthStencil->sampleCount() != sampleCount) {
sampleCount = rhiD->effectiveSampleCount(m_sampleCount);
if (m_depthStencil && m_depthStencil->sampleCount() != m_sampleCount) {
qWarning("Depth-stencil buffer's sampleCount (%d) does not match color buffers' sample count (%d). Expect problems.",
depthStencil->sampleCount(), sampleCount);
m_depthStencil->sampleCount(), m_sampleCount);
}
if (!rhiD->recreateSwapChain(surface, requestedPixelSize_, flags, this))
if (!rhiD->recreateSwapChain(surface, m_requestedPixelSize, m_flags, this))
return false;
if (!rhiD->createDefaultRenderPass(&rp, depthStencil != nullptr, sampleCount, colorFormat))
if (!rhiD->createDefaultRenderPass(&rp, m_depthStencil != nullptr, sampleCount, colorFormat))
return false;
rtWrapper.d.rp.rp = rp;
rtWrapper.d.pixelSize = effectivePixelSize;
rtWrapper.d.colorAttCount = 1;
if (depthStencil) {
if (m_depthStencil) {
rtWrapper.d.dsAttCount = 1;
ds = QRHI_RES(QVkRenderBuffer, depthStencil);
ds = QRHI_RES(QVkRenderBuffer, m_depthStencil);
} else {
rtWrapper.d.dsAttCount = 0;
ds = nullptr;
......@@ -3341,23 +3380,4 @@ bool QVkSwapChain::build(QWindow *window, const QSize &requestedPixelSize_, Surf
return true;
}
bool QVkSwapChain::build(QObject *target)
{
if (sc)
release();
QVulkanWindow *vkw = qobject_cast<QVulkanWindow *>(target);
if (vkw) {
rtWrapper.d.rp.rp = vkw->defaultRenderPass();
requestedPixelSize = effectivePixelSize = rtWrapper.d.pixelSize = vkw->swapChainImageSize();
rtWrapper.d.colorAttCount = 1;
rtWrapper.d.dsAttCount = 1;
rtWrapper.d.msaaAttCount = vkw->sampleCountFlagBits() > VK_SAMPLE_COUNT_1_BIT ? 1 : 0;
wrapWindow = vkw;
return true;
}
return false;
}
QT_END_NAMESPACE
......@@ -158,11 +158,14 @@ struct QVkTextureRenderTarget : public QRhiTextureRenderTarget
{
QVkTextureRenderTarget(QRhiImplementation *rhi, const QRhiTextureRenderTargetDescription &desc, Flags flags);
void release() override;
Type type() const override;
bool build() override;
QSize sizeInPixels() const override;
const QRhiRenderPass *renderPass() const override;
QRhiRenderPass *buildCompatibleRenderPass() override;
bool build() override;
QVkBasicRenderTargetData d;
VkImageView cubeFaceView[6];
int lastActiveFrameSlot = -1;
......@@ -236,6 +239,8 @@ struct QVkCommandBuffer : public QRhiCommandBuffer
uint currentPipelineGeneration;
QRhiShaderResourceBindings *currentSrb;
uint currentSrbGeneration;
friend class QRhiVulkan;
};
struct QVkSwapChain : public QRhiSwapChain
......@@ -246,19 +251,15 @@ struct QVkSwapChain : public QRhiSwapChain
QRhiCommandBuffer *currentFrameCommandBuffer() override;
QRhiRenderTarget *currentFrameRenderTarget() override;
const QRhiRenderPass *defaultRenderPass() const override;
QSize requestedSizeInPixels() const override;
QSize effectiveSizeInPixels() const override;
bool build(QWindow *window, const QSize &requestedPixelSize, SurfaceImportFlags flags,
QRhiRenderBuffer *depthStencil, int sampleCount) override;
bool build(QObject *target) override;
QRhiRenderPass *buildCompatibleRenderPass() override;
bool buildOrResize() override;
static const int DEFAULT_BUFFER_COUNT = 2;
static const int MAX_BUFFER_COUNT = 3;
QVulkanWindow *wrapWindow = nullptr;
QSize requestedPixelSize;
QSize effectivePixelSize;
bool supportsReadback = false;
VkSwapchainKHR sc = VK_NULL_HANDLE;
......@@ -294,6 +295,8 @@ struct QVkSwapChain : public QRhiSwapChain
quint32 currentImage = 0; // index in imageRes
quint32 currentFrame = 0; // index in frameRes
friend class QRhiVulkan;
};
class QRhiVulkan : public QRhiImplementation
......
make rp dep in ps less invasive (rethink how QRhiRenderPass is handled)
review swapchain param handling
rename res pattern to new-build-release (from create-build-release)?
figure out what's up with instance step rate
mtl: buffer logic is borked
mtl: fix Dynamic for non-uniform buffers
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment