Commit db048497 authored by Laszlo Agocs's avatar Laszlo Agocs

Merge remote-tracking branch 'qvk6/master'

parents 241ff2a6 be2cb97c
load(qt_build_config)
# CONFIG += warning_clean
CONFIG += warning_clean
DEFINES += QT_NO_FOREACH
MODULE_VERSION = 5.12.0
......@@ -200,6 +200,7 @@ void Window::customRender()
cb->setGraphicsPipeline(d.ps);
cb->setViewport({ 0, 0, float(outputSizeInPixels.width()), float(outputSizeInPixels.height()) });
cb->setShaderResources();
cb->setVertexInput(0, { { d.vbuf, 0 }, { d.vbuf, 36 * 3 * sizeof(float) } });
cb->draw(36);
......
......@@ -216,6 +216,7 @@ void Window::customRender()
cb->setGraphicsPipeline(d.ps);
cb->setViewport({ 0, 0, float(outputSizeInPixels.width()), float(outputSizeInPixels.height()) });
cb->setShaderResources();
cb->setVertexInput(0, { { d.vbuf, 0 }, { d.vbuf, 36 * 3 * sizeof(float) } });
cb->draw(36);
......
......@@ -172,6 +172,7 @@ void Window::customRender()
cb->beginPass(m_sc->currentFrameRenderTarget(), { 0.4f, 0.7f, 0.0f, 1.0f }, { 1.0f, 0 }, u);
cb->setGraphicsPipeline(d.ps);
cb->setViewport(QRhiViewport(0, 0, outputSizeInPixels.width(), outputSizeInPixels.height()));
cb->setShaderResources();
cb->setVertexInput(0, { { d.vbuf, 0 } });
cb->draw(36);
cb->endPass();
......
......@@ -453,6 +453,7 @@ void Window::render()
cb->setGraphicsPipeline(m_ps);
cb->setViewport({ 0, 0, float(outputSizeInPixels.width()), float(outputSizeInPixels.height()) });
cb->setShaderResources();
cb->setVertexInput(0, { { m_vbuf, 0 } });
cb->draw(3);
......
......@@ -157,6 +157,7 @@ void Window::customRender()
cb->setGraphicsPipeline(d.ps);
cb->setViewport(QRhiViewport(0, 0, outputSizeInPixels.width(), outputSizeInPixels.height()));
cb->setShaderResources();
cb->setVertexInput(0, { { d.vbuf, 0 } });
cb->draw(3);
......
......@@ -271,7 +271,8 @@ void QRhiImgui::queueFrame(QRhiCommandBuffer *cb)
const QPointF scissorPixelBottomLeft = QPointF(cmd->ClipRect.x, d->lastOutputSize.height() - cmd->ClipRect.w);
const QSizeF scissorPixelSize = QSizeF(cmd->ClipRect.z - cmd->ClipRect.x, cmd->ClipRect.w - cmd->ClipRect.y);
const int textureIndex = int(reinterpret_cast<qintptr>(cmd->TextureId));
cb->setGraphicsPipeline(d->ps, d->textures[textureIndex].srb);
cb->setGraphicsPipeline(d->ps);
cb->setShaderResources(d->textures[textureIndex].srb);
cb->setScissor({ int(scissorPixelBottomLeft.x()), int(scissorPixelBottomLeft.y()),
int(scissorPixelSize.width()), int(scissorPixelSize.height()) });
cb->setVertexInput(0, vertexInput, d->ibuf, indexOffset, QRhiCommandBuffer::IndexUInt32);
......
......@@ -241,6 +241,7 @@ void Window::customRender()
cb->beginPass(d.rt, { 0.5f, 0.2f, 0, 1 }, { 1, 0 }, u);
cb->setGraphicsPipeline(d.triPs);
cb->setViewport({ 0, 0, float(d.rb->pixelSize().width()), float(d.rb->pixelSize().height()) });
cb->setShaderResources();
cb->setVertexInput(0, { { d.vbuf, sizeof(vertexData) } });
cb->draw(3);
cb->endPass();
......@@ -250,6 +251,7 @@ void Window::customRender()
cb->beginPass(m_sc->currentFrameRenderTarget(), { 0.4f, 0.7f, 0.0f, 1.0f }, { 1.0f, 0 });
cb->setGraphicsPipeline(d.ps);
cb->setViewport({ 0, 0, float(outputSizeInPixels.width()), float(outputSizeInPixels.height()) });
cb->setShaderResources();
cb->setVertexInput(0, { { d.vbuf, 0 } }, d.ibuf, 0, QRhiCommandBuffer::IndexUInt16);
cb->drawIndexed(6);
cb->endPass();
......
......@@ -299,6 +299,7 @@ void Window::customRender()
cb->beginPass(d.rt, { 0.5f, 0.2f, 0, 1 }, { 1, 0 });
cb->setGraphicsPipeline(d.triPs);
cb->setViewport({ 0, 0, float(d.msaaTex->pixelSize().width()), float(d.msaaTex->pixelSize().height()) });
cb->setShaderResources();
cb->setVertexInput(0, { { d.vbuf, sizeof(vertexData) } });
cb->draw(3);
cb->endPass();
......@@ -307,6 +308,7 @@ void Window::customRender()
cb->beginPass(d.msaaRt, { 0.5f, 0.2f, 0, 1 }, { 1, 0 });
cb->setGraphicsPipeline(d.msaaTriPs);
cb->setViewport({ 0, 0, float(d.msaaTex->pixelSize().width()), float(d.msaaTex->pixelSize().height()) });
cb->setShaderResources();
cb->setVertexInput(0, { { d.vbuf, sizeof(vertexData) } });
cb->draw(3);
cb->endPass();
......@@ -316,9 +318,11 @@ void Window::customRender()
cb->beginPass(m_sc->currentFrameRenderTarget(), { 0.4f, 0.7f, 0.0f, 1.0f }, { 1.0f, 0 });
cb->setGraphicsPipeline(d.psLeft); // showing the non-msaa version
cb->setViewport({ 0, 0, float(outputSizeInPixels.width()), float(outputSizeInPixels.height()) });
cb->setShaderResources();
cb->setVertexInput(0, { { d.vbuf, 0 } }, d.ibuf, 0, QRhiCommandBuffer::IndexUInt16);
cb->drawIndexed(6);
cb->setGraphicsPipeline(d.psRight); // showing the msaa version, resolved in the shader
cb->setShaderResources();
cb->drawIndexed(6);
cb->endPass();
}
......@@ -53,6 +53,7 @@
#include <QLabel>
#include <QPlainTextEdit>
#include <QPushButton>
#include <QCheckBox>
#include <QVBoxLayout>
#include <QCommandLineParser>
......@@ -277,7 +278,7 @@ void destroySharedResources()
class Window : public QWindow
{
public:
Window(const QString &title, const QColor &bgColor, int axis);
Window(const QString &title, const QColor &bgColor, int axis, bool noVSync);
~Window();
protected:
......@@ -291,7 +292,8 @@ protected:
bool event(QEvent *) override;
QColor m_bgColor;
int m_rotationAxis = 0;
int m_rotationAxis;
bool m_noVSync;
bool m_running = false;
bool m_notExposed = false;
......@@ -310,9 +312,10 @@ protected:
int m_opacityDir = -1;
};
Window::Window(const QString &title, const QColor &bgColor, int axis)
Window::Window(const QString &title, const QColor &bgColor, int axis, bool noVSync)
: m_bgColor(bgColor),
m_rotationAxis(axis)
m_rotationAxis(axis),
m_noVSync(noVSync)
{
switch (graphicsApi) {
case OpenGL:
......@@ -334,6 +337,12 @@ Window::Window(const QString &title, const QColor &bgColor, int axis)
break;
}
if (graphicsApi == OpenGL) {
QSurfaceFormat fmt = QSurfaceFormat::defaultFormat();
fmt.setSwapInterval(noVSync ? 0 : 1);
setFormat(fmt);
}
resize(800, 600);
setTitle(title);
}
......@@ -396,6 +405,9 @@ void Window::init()
m_releasePool << m_ds;
m_sc->setWindow(this);
m_sc->setDepthStencil(m_ds);
if (m_noVSync)
m_sc->setFlags(QRhiSwapChain::NoVSync);
m_rp = m_sc->newCompatibleRenderPassDescriptor();
m_releasePool << m_rp;
m_sc->setRenderPassDescriptor(m_rp);
......@@ -493,6 +505,7 @@ void Window::render()
cb->setGraphicsPipeline(d.ps);
cb->setViewport({ 0, 0, float(outputSizeInPixels.width()), float(outputSizeInPixels.height()) });
cb->setShaderResources();
cb->setVertexInput(0, { { d.vbuf, 0 } });
cb->draw(3);
......@@ -503,11 +516,11 @@ void Window::render()
requestUpdate();
}
void createWindow()
void createWindow(bool noVSync)
{
static QColor colors[] = { Qt::red, Qt::green, Qt::blue, Qt::yellow, Qt::cyan, Qt::gray };
const int n = d.windows.count();
d.windows.append(new Window(QString::asprintf("Window #%d", n), colors[n % 6], n % 3));
d.windows.append(new Window(QString::asprintf("Window #%d%s", n, noVSync ? " (no vsync)" : ""), colors[n % 6], n % 3, noVSync));
d.windows.last()->show();
}
......@@ -586,18 +599,25 @@ int main(int argc, char **argv)
QPlainTextEdit *info = new QPlainTextEdit(
QLatin1String("This application tests rendering with the same QRhi instance (and so the same Vulkan/Metal/D3D device or OpenGL context) "
"to multiple windows via multiple QRhiSwapChain objects, from the same one thread. Some resources are shared across all windows."
"\n\nNote that the behavior may differ depending on the underlying graphics API implementation and the number of windows.\n"
"to multiple windows via multiple QRhiSwapChain objects, from the same one thread. Some resources are shared across all windows.\n"
"\nNote that the behavior may differ depending on the underlying graphics API implementation and the number of windows. "
"One challenge here is the vsync throttling: with the default vsync/fifo presentation mode the behavior may differ between "
"platforms, drivers, and APIs as we present different swapchains' images in a row on the same thread. As a potential solution, "
"setting NoVSync on the second, third, and later window swapchains is offered as an option.\n"
"\n\nUsing API: ") + graphicsApiName());
info->setReadOnly(true);
layout->addWidget(info);
QLabel *label = new QLabel(QLatin1String("Window count: 0"));
layout->addWidget(label);
QCheckBox *vsCb = new QCheckBox(QLatin1String("Set NoVSync on all swapchains except the first"));
vsCb->setChecked(false);
layout->addWidget(vsCb);
QPushButton *btn = new QPushButton(QLatin1String("New window"));
QObject::connect(btn, &QPushButton::clicked, btn, [label, &winCount] {
QObject::connect(btn, &QPushButton::clicked, btn, [label, vsCb, &winCount] {
winCount += 1;
label->setText(QString::asprintf("Window count: %d", winCount));
createWindow();
const bool noVSync = vsCb->isChecked() && winCount > 1;
createWindow(noVSync);
});
layout->addWidget(btn);
btn = new QPushButton(QLatin1String("Close window"));
......
......@@ -629,6 +629,7 @@ void Renderer::render(bool newlyExposed, bool wakeBeforePresent)
cb->setGraphicsPipeline(m_ps);
cb->setViewport(QRhiViewport(0, 0, outputSize.width(), outputSize.height()));
cb->setShaderResources();
cb->setVertexInput(0, { { m_vbuf, 0 }, { m_vbuf, 36 * 3 * sizeof(float) } });
cb->draw(36);
......
......@@ -297,6 +297,7 @@ int main(int argc, char **argv)
cb->beginPass(rt, { 0, 1, 0, 1 }, { 1, 0 }, u);
cb->setGraphicsPipeline(ps);
cb->setViewport({ 0, 0, 1280, 720 });
cb->setShaderResources();
cb->setVertexInput(0, { { vbuf, 0 } });
cb->draw(3);
......
......@@ -124,6 +124,7 @@ QString graphicsApiName()
QRhi::Flags rhiFlags = QRhi::EnableDebugMarkers;
int sampleCount = 1;
QRhiSwapChain::Flags scFlags = 0;
QRhi::EndFrameFlags endFrameFlags = 0;
class Window : public QWindow
{
......@@ -413,7 +414,7 @@ void Window::render()
customRender();
m_r->endFrame(m_sc);
m_r->endFrame(m_sc, endFrameFlags);
#ifdef Q_OS_DARWIN
if (!scFlags.testFlag(QRhiSwapChain::NoVSync))
......@@ -482,6 +483,8 @@ int main(int argc, char **argv)
fmt.setSamples(sampleCount);
if (scFlags.testFlag(QRhiSwapChain::NoVSync))
fmt.setSwapInterval(0);
if (scFlags.testFlag(QRhiSwapChain::sRGB))
fmt.setColorSpace(QSurfaceFormat::sRGBColorSpace);
QSurfaceFormat::setDefaultFormat(fmt);
// Vulkan setup.
......
......@@ -481,6 +481,7 @@ void Window::render()
cb->setGraphicsPipeline(ps);
cb->setViewport({ 0, 0, float(outputSizeInPixels.width()), float(outputSizeInPixels.height()) });
cb->setShaderResources();
cb->setVertexInput(0, { { vbuf, 0 } }, ibuf, 0, QRhiCommandBuffer::IndexUInt16);
cb->drawIndexed(6);
......
......@@ -280,6 +280,7 @@ void Window::customRender()
cb->setGraphicsPipeline(d.ps);
cb->setViewport({ 0, 0, float(outputSizeInPixels.width()), float(outputSizeInPixels.height()) });
cb->setShaderResources();
cb->setVertexInput(0, { { d.vbuf, 0 }, { d.vbuf, 36 * 3 * sizeof(float) } });
cb->draw(36);
......
......@@ -147,8 +147,9 @@ void QuadRenderer::queueResourceUpdates(QRhiResourceUpdateBatch *resourceUpdates
void QuadRenderer::queueDraw(QRhiCommandBuffer *cb, const QSize &/*outputSizeInPixels*/)
{
cb->setGraphicsPipeline(m_ps, m_srb);
cb->setGraphicsPipeline(m_ps);
//cb->setViewport(QRhiViewport(0, 0, outputSizeInPixels.width(), outputSizeInPixels.height()));
cb->setShaderResources(m_srb);
cb->setVertexInput(0, { { m_vbuf, 0 } }, m_ibuf, 0, QRhiCommandBuffer::IndexUInt16);
cb->drawIndexed(6);
}
......@@ -227,6 +227,7 @@ void TexturedCubeRenderer::queueDraw(QRhiCommandBuffer *cb, const QSize &outputS
{
cb->setGraphicsPipeline(m_ps);
cb->setViewport(QRhiViewport(0, 0, outputSizeInPixels.width(), outputSizeInPixels.height()));
cb->setShaderResources();
cb->setVertexInput(0, { { m_vbuf, 0 }, { m_vbuf, 36 * 3 * sizeof(float) } });
cb->draw(36);
}
......@@ -304,6 +304,7 @@ void TriangleOnCubeRenderer::queueDraw(QRhiCommandBuffer *cb, const QSize &outpu
{
cb->setGraphicsPipeline(m_ps);
cb->setViewport(QRhiViewport(0, 0, outputSizeInPixels.width(), outputSizeInPixels.height()));
cb->setShaderResources();
cb->setVertexInput(0, { { m_vbuf, 0 }, { m_vbuf, 36 * 3 * sizeof(float) } });
cb->draw(36);
}
......@@ -167,7 +167,7 @@ void TriangleRenderer::queueResourceUpdates(QRhiResourceUpdateBatch *resourceUpd
#if 0
static int messWithBufferTrigger = 0;
// recreate the underlying VkBuffer every second frame
// to exercise setGraphicsPipeline's built-in smartness
// to exercise setShaderResources' built-in smartness
if (!(messWithBufferTrigger & 1)) {
m_ubuf->release();
m_ubuf->build();
......@@ -203,6 +203,7 @@ void TriangleRenderer::queueDraw(QRhiCommandBuffer *cb, const QSize &outputSizeI
{
cb->setGraphicsPipeline(m_ps);
cb->setViewport(QRhiViewport(0, 0, outputSizeInPixels.width(), outputSizeInPixels.height()));
cb->setShaderResources();
cb->setVertexInput(0, { { m_vbuf, 0 } });
cb->draw(3);
}
......@@ -65,6 +65,7 @@
#include <QRhiProfiler>
#define PROFILE_TO_FILE
//#define SKIP_PRESENT
//#define USE_MSAA
//#define USE_SRGB_SWAPCHAIN
//#define READBACK_SWAPCHAIN
......@@ -92,6 +93,10 @@ void preInit()
d.profOut.open(QIODevice::WriteOnly);
#endif
#ifdef SKIP_PRESENT
endFrameFlags |= QRhi::SkipPresent;
#endif
#ifdef USE_MSAA
sampleCount = 4; // enable 4x MSAA (except for the render-to-texture pass)
#endif
......@@ -156,6 +161,11 @@ void Window::customInit()
qDebug("isFeatureSupported(Instancing): %d", m_r->isFeatureSupported(QRhi::Instancing));
qDebug("isFeatureSupported(CustomInstanceStepRate): %d", m_r->isFeatureSupported(QRhi::CustomInstanceStepRate));
qDebug("isFeatureSupported(PrimitiveRestart): %d", m_r->isFeatureSupported(QRhi::PrimitiveRestart));
qDebug("isFeatureSupported(GeometryShaders): %d", m_r->isFeatureSupported(QRhi::GeometryShaders));
qDebug("isFeatureSupported(TessellationShaders): %d", m_r->isFeatureSupported(QRhi::TessellationShaders));
qDebug("isFeatureSupported(NonDynamicUniformBuffers): %d", m_r->isFeatureSupported(QRhi::NonDynamicUniformBuffers));
qDebug("isFeatureSupported(NonFourAlignedEffectiveIndexBufferOffset): %d", m_r->isFeatureSupported(QRhi::NonFourAlignedEffectiveIndexBufferOffset));
qDebug("isFeatureSupported(NPOTTextureRepeat): %d", m_r->isFeatureSupported(QRhi::NPOTTextureRepeat));
qDebug("Min 2D texture width/height: %d", m_r->resourceSizeLimit(QRhi::TextureSizeMin));
qDebug("Max 2D texture width/height: %d", m_r->resourceSizeLimit(QRhi::TextureSizeMax));
}
......
......@@ -171,6 +171,7 @@ void TriangleRenderer::queueDraw(QRhiCommandBuffer *cb, const QSize &outputSizeI
{
cb->setGraphicsPipeline(m_ps);
cb->setViewport(QRhiViewport(0, 0, outputSizeInPixels.width(), outputSizeInPixels.height()));
cb->setShaderResources();
cb->setVertexInput(0, { { m_vbuf, 0 } });
cb->draw(3);
}
INCLUDEPATH += $$PWD/VulkanMemoryAllocator
clang {
QMAKE_CFLAGS_WARN_ON += -Wno-unused-parameter -Wno-unused-variable -Wno-missing-field-initializers -Wno-tautological-compare
QMAKE_CXXFLAGS_WARN_ON = $$QMAKE_CFLAGS_WARN_ON
}
This diff is collapsed.
This diff is collapsed.
......@@ -46,20 +46,15 @@
#include "qrhiprofiler_p.h"
#include <QBitArray>
#include <QAtomicInt>
#include <QAtomicInteger>
QT_BEGIN_NAMESPACE
#define QRHI_RES(t, x) static_cast<t *>(x)
#define QRHI_RES_RHI(t) t *rhiD = static_cast<t *>(rhi)
#define QRHI_PROF QRhiProfilerPrivate *rhiP = rhi->profilerPrivateOrNull()
#define QRHI_RES_RHI(t) t *rhiD = static_cast<t *>(m_rhi)
#define QRHI_PROF QRhiProfilerPrivate *rhiP = m_rhi->profilerPrivateOrNull()
#define QRHI_PROF_F(f) for (bool qrhip_enabled = rhiP != nullptr; qrhip_enabled; qrhip_enabled = false) rhiP->f
class QRhiReferenceRenderTarget : public QRhiRenderTarget
{
protected:
QRhiReferenceRenderTarget(QRhiImplementation *rhi);
};
class QRhiImplementation
{
public:
......@@ -89,8 +84,8 @@ public:
QRhiTextureRenderTarget::Flags flags) = 0;
virtual QRhiSwapChain *createSwapChain() = 0;
virtual QRhi::FrameOpResult beginFrame(QRhiSwapChain *swapChain) = 0;
virtual QRhi::FrameOpResult endFrame(QRhiSwapChain *swapChain) = 0;
virtual QRhi::FrameOpResult beginFrame(QRhiSwapChain *swapChain, QRhi::BeginFrameFlags flags) = 0;
virtual QRhi::FrameOpResult endFrame(QRhiSwapChain *swapChain, QRhi::EndFrameFlags flags) = 0;
virtual QRhi::FrameOpResult beginOffscreenFrame(QRhiCommandBuffer **cb) = 0;
virtual QRhi::FrameOpResult endOffscreenFrame() = 0;
virtual QRhi::FrameOpResult finish() = 0;
......@@ -105,8 +100,11 @@ public:
virtual void endPass(QRhiCommandBuffer *cb, QRhiResourceUpdateBatch *resourceUpdates) = 0;
virtual void setGraphicsPipeline(QRhiCommandBuffer *cb,
QRhiGraphicsPipeline *ps,
QRhiShaderResourceBindings *srb = nullptr) = 0;
QRhiGraphicsPipeline *ps) = 0;
virtual void setShaderResources(QRhiCommandBuffer *cb,
QRhiShaderResourceBindings *srb,
const QVector<QRhiCommandBuffer::DynamicOffset> &dynamicOffsets) = 0;
virtual void setVertexInput(QRhiCommandBuffer *cb,
int startBinding, const QVector<QRhiCommandBuffer::VertexInput> &bindings,
......@@ -131,6 +129,7 @@ public:
virtual QVector<int> supportedSampleCounts() const = 0;
virtual int ubufAlignment() const = 0;
virtual bool isYUpInFramebuffer() const = 0;
virtual bool isYUpInNDC() const = 0;
virtual QMatrix4x4 clipSpaceCorrMatrix() const = 0;
virtual bool isTextureFormatSupported(QRhiTexture::Format format, QRhiTexture::Flags flags) const = 0;
virtual bool isFeatureSupported(QRhi::Feature feature) const = 0;
......@@ -158,7 +157,7 @@ public:
// only really care about resources that own native graphics resources underneath
void registerResource(QRhiResource *res)
{
res->orphanedWithRsh = nullptr;
res->m_orphanedWithRsh = nullptr;
resources.insert(res);
}
......@@ -174,23 +173,37 @@ public:
static bool orphanCheck(QRhiResource *res)
{
if (res->orphanedWithRsh) {
if (res->m_orphanedWithRsh) {
qWarning("Attempted to perform something on an orphaned QRhiResource %p (%s). This is invalid.",
res, res->objectName.constData());
(void *) res, res->m_objectName.constData());
return false;
}
return true;
}
void addReleaseAndDestroyLater(QRhiResource *res)
{
if (inFrame)
pendingReleaseAndDestroyResources.insert(res);
else
res->releaseAndDestroy();
}
QRhi *q;
protected:
QRhiResourceSharingHostPrivate *rsh = nullptr;
bool debugMarkers = false;
private:
QRhi::Implementation implType;
QThread *implThread;
QRhiProfiler profiler;
QVector<QRhiResourceUpdateBatch *> resUpdPool;
QBitArray resUpdPoolMap;
QRhiProfiler profiler;
bool debugMarkers = false;
QSet<QRhiResource *> resources;
QSet<QRhiResource *> pendingReleaseAndDestroyResources;
bool inFrame = false;
friend class QRhi;
friend class QRhiResourceUpdateBatchPrivate;
......@@ -221,51 +234,71 @@ public:
QByteArray data;
};
struct TextureUpload {
TextureUpload() { }
TextureUpload(QRhiTexture *tex_, const QRhiTextureUploadDescription &desc_)
: tex(tex_), desc(desc_)
{ }
QRhiTexture *tex = nullptr;
QRhiTextureUploadDescription desc;
};
struct TextureCopy {
TextureCopy() { }
TextureCopy(QRhiTexture *dst_, QRhiTexture *src_, const QRhiTextureCopyDescription &desc_)
: dst(dst_), src(src_), desc(desc_)
{ }
QRhiTexture *dst = nullptr;
QRhiTexture *src = nullptr;
QRhiTextureCopyDescription desc;
};
struct TextureRead {
TextureRead() { }
TextureRead(const QRhiReadbackDescription &rb_, QRhiReadbackResult *result_)
: rb(rb_), result(result_)
{ }
struct TextureOp {
enum Type {
TexUpload,
TexCopy,
TexRead,
TexMipGen
};
Type type;
struct Upload {
QRhiTexture *tex = nullptr;
QRhiTextureUploadDescription desc;
} upload;
struct Copy {
QRhiTexture *dst = nullptr;
QRhiTexture *src = nullptr;
QRhiTextureCopyDescription desc;
} copy;
struct Read {
QRhiReadbackDescription rb;
QRhiReadbackResult *result;
} read;
struct MipGen {
QRhiTexture *tex = nullptr;
} mipgen;
static TextureOp textureUpload(QRhiTexture *tex, const QRhiTextureUploadDescription &desc)
{
TextureOp op;
op.type = TexUpload;
op.upload.tex = tex;
op.upload.desc = desc;
return op;
}
QRhiReadbackDescription rb;
QRhiReadbackResult *result;
};
static TextureOp textureCopy(QRhiTexture *dst, QRhiTexture *src, const QRhiTextureCopyDescription &desc)
{
TextureOp op;
op.type = TexCopy;
op.copy.dst = dst;
op.copy.src = src;
op.copy.desc = desc;
return op;
}
struct TextureMipGen {
TextureMipGen() { }
TextureMipGen(QRhiTexture *tex_) : tex(tex_)
{ }
static TextureOp textureRead(const QRhiReadbackDescription &rb, QRhiReadbackResult *result)
{
TextureOp op;
op.type = TexRead;
op.read.rb = rb;
op.read.result = result;
return op;
}
QRhiTexture *tex = nullptr;
static TextureOp textureMipGen(QRhiTexture *tex)
{
TextureOp op;
op.type = TexMipGen;
op.mipgen.tex = tex;
return op;
}
};
QVector<DynamicBufferUpdate> dynamicBufferUpdates;
QVector<StaticBufferUpload> staticBufferUploads;
QVector<TextureUpload> textureUploads;
QVector<TextureCopy> textureCopies;
QVector<TextureRead> textureReadbacks;
QVector<TextureMipGen> textureMipGens;
QVector<TextureOp> textureOps;
QRhiResourceUpdateBatch *q = nullptr;
QRhiImplementation *rhi = nullptr;
......@@ -279,10 +312,7 @@ public:
Q_DECLARE_TYPEINFO(QRhiResourceUpdateBatchPrivate::DynamicBufferUpdate, Q_MOVABLE_TYPE);
Q_DECLARE_TYPEINFO(QRhiResourceUpdateBatchPrivate::StaticBufferUpload, Q_MOVABLE_TYPE);
Q_DECLARE_TYPEINFO(QRhiResourceUpdateBatchPrivate::TextureUpload, Q_MOVABLE_TYPE);
Q_DECLARE_TYPEINFO(QRhiResourceUpdateBatchPrivate::TextureCopy, Q_MOVABLE_TYPE);
Q_DECLARE_TYPEINFO(QRhiResourceUpdateBatchPrivate::TextureRead, Q_MOVABLE_TYPE);
Q_DECLARE_TYPEINFO(QRhiResourceUpdateBatchPrivate::TextureMipGen, Q_MOVABLE_TYPE);
Q_DECLARE_TYPEINFO(QRhiResourceUpdateBatchPrivate::TextureOp, Q_MOVABLE_TYPE);
class Q_RHI_PRIVATE_EXPORT QRhiShaderResourceBindingPrivate
{
......@@ -312,6 +342,7 @@ public:
QRhiBuffer *buf;
int offset;
int maybeSize;
bool hasDynamicOffset;
};
struct SampledTextureData {
QRhiTexture *tex;
......@@ -382,6 +413,20 @@ private:
int curBinding = -1;
};
class QRhiGlobalObjectIdGenerator
{
public:
#ifdef Q_ATOMIC_INT64_IS_SUPPORTED
using Type = quint64;
#else
using Type = quint32;
#endif
static Type newId();
private:
QAtomicInteger<Type> counter;
};
QT_END_NAMESPACE
#endif
This diff is collapsed.
......@@ -146,7 +146,7 @@ struct QD3D11RenderTargetData
ID3D11DepthStencilView *dsv = nullptr;
};
struct QD3D11ReferenceRenderTarget : public QRhiReferenceRenderTarget
struct QD3D11ReferenceRenderTarget : public QRhiRenderTarget
{
QD3D11ReferenceRenderTarget(QRhiImplementation *rhi);
void release() override;
......@@ -189,10 +189,13 @@ struct QD3D11ShaderResourceBindings : public QRhiShaderResourceBindings
// Keep track of the generation number of each referenced QRhi* to be able
// to detect that the batched bindings are out of date.
struct BoundUniformBufferData {
quint64 id;
uint generation;
};
struct BoundSampledTextureData {
quint64 texId;
uint texGeneration;
quint64 samplerId;
uint samplerGeneration;
};
struct BoundResourceData {
......@@ -246,9 +249,6 @@ struct QD3D11CommandBuffer : public QRhiCommandBuffer
QD3D11CommandBuffer(QRhiImplementation *rhi);
void release() override;
// Technically it's not like we really need to queue up the commands, but
// have it this way since it helps keeping things concise and may become
// essential if "command buffers" become application creatable some day.
struct Command {
enum Cmd {
SetRenderTarget,
......@@ -258,6 +258,7 @@ struct QD3D11CommandBuffer : public QRhiCommandBuffer
BindVertexBuffers,
BindIndexBuffer,
BindGraphicsPipeline,
BindShaderResources,
StencilRef,
BlendConstants,
Draw,
......@@ -272,6 +273,11 @@ struct QD3D11CommandBuffer : public QRhiCommandBuffer
};
enum ClearFlag { Color = 1, Depth = 2, Stencil = 4 };
Cmd cmd;
static const int MAX_UBUF_BINDINGS = 32; // should be D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT but 128 is a waste of space for our purposes
// QRhi*/QD3D11* references should be kept at minimum (so no
// QRhiTexture/Buffer/etc. pointers).
union {
struct {
QRhiRenderTarget *rt;
......@@ -304,9 +310,13 @@ struct QD3D11CommandBuffer : public QRhiCommandBuffer
} bindIndexBuffer;
struct {
QD3D11GraphicsPipeline *ps;
QD3D11ShaderResourceBindings *srb;
bool srbOnlyChange;
} bindGraphicsPipeline;
struct {
QD3D11ShaderResourceBindings *srb;
bool offsetOnlyChange;
int dynamicOffsetCount;
uint dynamicOffsetPairs[MAX_UBUF_BINDINGS * 2]; // binding, offsetInConstants
} bindShaderResources;
struct {
QD3D11GraphicsPipeline *ps;
quint32 ref;
......@@ -356,7 +366,7 @@ struct QD3D11CommandBuffer : public QRhiCommandBuffer
DXGI_FORMAT format;
} resolveSubRes;
struct {
QD3D11Texture *tex;
ID3D11ShaderResourceView *srv;
} genMip;