Commit 8576659b authored by Laszlo Agocs's avatar Laszlo Agocs

Move over to do resolves per-pass instead of explicitly

parent 9b02b8fd
......@@ -112,7 +112,17 @@ void Window::customInit()
d.rb->build();
d.releasePool << d.rb;
d.rt = m_r->newTextureRenderTarget({ d.rb });
// the non-msaa texture that will be the destination in the resolve
d.tex = m_r->newTexture(QRhiTexture::RGBA8, d.rb->pixelSize());
d.releasePool << d.tex;
d.tex->build();
// rb is multisample, instead of writing out the msaa data into it,
// resolve into d.tex at the end of each render pass
QRhiTextureRenderTargetDescription rtDesc { d.rb };
rtDesc.colorAttachments[0].resolveTexture = d.tex;
d.rt = m_r->newTextureRenderTarget(rtDesc);
d.releasePool << d.rt;
d.rtRp = d.rt->newCompatibleRenderPassDescriptor();
d.releasePool << d.rtRp;
......@@ -150,11 +160,6 @@ void Window::customInit()
d.triPs->setRenderPassDescriptor(d.rtRp);
d.triPs->build();
// the non-msaa texture that will be the destination in the resolve
d.tex = m_r->newTexture(QRhiTexture::RGBA8, d.rb->pixelSize());
d.releasePool << d.tex;
d.tex->build();
d.sampler = m_r->newSampler(QRhiSampler::Linear, QRhiSampler::Linear, QRhiSampler::None,
QRhiSampler::ClampToEdge, QRhiSampler::ClampToEdge);
d.releasePool << d.sampler;
......@@ -235,11 +240,7 @@ void Window::customRender()
cb->setViewport({ 0, 0, float(d.rb->pixelSize().width()), float(d.rb->pixelSize().height()) });
cb->setVertexInput(0, { { d.vbuf, sizeof(vertexData) } });
cb->draw(3);
// add the resolve (msaa renderbuffer -> non-msaa texture)
u = m_r->nextResourceUpdateBatch();
u->resolveTexture(d.tex, { d.rb });
cb->endPass(u);
cb->endPass();
// onscreen (quad)
const QSize outputSizeInPixels = m_sc->currentPixelSize();
......
......@@ -459,11 +459,6 @@ void QRhiResourceUpdateBatch::copyTexture(QRhiTexture *dst, QRhiTexture *src, co
d->textureCopies.append({ dst, src, desc });
}
void QRhiResourceUpdateBatch::resolveTexture(QRhiTexture *dst, const QRhiTextureResolveDescription &desc)
{
d->textureResolves.append({ dst, desc });
}
void QRhiResourceUpdateBatch::readBackTexture(const QRhiReadbackDescription &rb, QRhiReadbackResult *result)
{
d->textureReadbacks.append({ rb, result });
......@@ -516,7 +511,6 @@ void QRhiResourceUpdateBatchPrivate::free()
staticBufferUploads.clear();
textureUploads.clear();
textureCopies.clear();
textureResolves.clear();
textureReadbacks.clear();
textureMipGens.clear();
texturePrepares.clear();
......@@ -531,7 +525,6 @@ void QRhiResourceUpdateBatchPrivate::merge(QRhiResourceUpdateBatchPrivate *other
staticBufferUploads += other->staticBufferUploads;
textureUploads += other->textureUploads;
textureCopies += other->textureCopies;
textureResolves += other->textureResolves;
textureReadbacks += other->textureReadbacks;
textureMipGens += other->textureMipGens;
texturePrepares += other->texturePrepares;
......
......@@ -241,8 +241,20 @@ struct Q_RHI_EXPORT QRhiTextureRenderTargetDescription
QRhiTexture *texture = nullptr;
QRhiRenderBuffer *renderBuffer = nullptr;
// for texture
int layer = 0; // face (0..5) for cubemaps
int level = 0;
int level = 0; // only when non-multisample
// When texture or renderBuffer is multisample. Optional. When set,
// samples are resolved into this non-multisample texture. Note that
// the msaa data may not be written out at all in this case. This is
// the only way to get a non-msaa texture from an msaa render target as
// we do not have an explicit resolve operation because it does not
// exist in some APIs and would not be efficient with tiled GPUs anyways.
QRhiTexture *resolveTexture = nullptr;
int resolveLayer = 0; // unused for now since cubemaps cannot be multisample
int resolveLevel = 0;
};
QRhiTextureRenderTargetDescription()
......@@ -323,30 +335,12 @@ struct Q_RHI_EXPORT QRhiTextureCopyDescription
Q_DECLARE_TYPEINFO(QRhiTextureCopyDescription, Q_MOVABLE_TYPE);
struct Q_RHI_EXPORT QRhiTextureResolveDescription
{
QRhiTextureResolveDescription() { }
QRhiTextureResolveDescription(QRhiTexture *src) : sourceTexture(src) { }
QRhiTextureResolveDescription(QRhiRenderBuffer *src) : sourceRenderBuffer(src) { }
// source is either a multisample texture or a multisample renderbuffer
QRhiTexture *sourceTexture = nullptr;
int sourceLayer = 0;
QRhiRenderBuffer *sourceRenderBuffer = nullptr;
int destinationLayer = 0;
int destinationLevel = 0;
};
Q_DECLARE_TYPEINFO(QRhiTextureResolveDescription, Q_MOVABLE_TYPE);
struct Q_RHI_EXPORT QRhiReadbackDescription
{
QRhiReadbackDescription() { } // source is the back buffer of the swapchain of the current frame (if the swapchain supports readback)
QRhiReadbackDescription(QRhiTexture *texture_) : texture(texture_) { } // source is the specified texture
// Note that reading back an msaa image is only supported for swapchains
// (by inserting an implicit resolve). For multisample textures, do an
// explicit resolve first.
// Note that reading back an msaa image is only supported for swapchains.
// Multisample textures cannot be read back.
QRhiTexture *texture = nullptr;
int layer = 0;
......@@ -416,7 +410,7 @@ public:
CubeMap = 1 << 2,
MipMapped = 1 << 3,
sRGB = 1 << 4,
UsedAsTransferSource = 1 << 5, // will (also) be used as the source of a readback or copy or resolve
UsedAsTransferSource = 1 << 5, // will (also) be used as the source of a copy or readback
UsedWithGenerateMips = 1 << 6
};
Q_DECLARE_FLAGS(Flags, Flag)
......@@ -923,7 +917,7 @@ public:
// Sometimes committing the updates is necessary without starting a render
// pass. Not often needed, updates should typically be passed to beginPass
// (or endPass, in case of readbacks or resolves) instead.
// (or endPass, in case of readbacks) instead.
void resourceUpdate(QRhiResourceUpdateBatch *resourceUpdates);
void beginPass(QRhiRenderTarget *rt,
......@@ -1033,7 +1027,6 @@ public:
void uploadTexture(QRhiTexture *tex, const QRhiTextureUploadDescription &desc);
void uploadTexture(QRhiTexture *tex, const QImage &image); // shortcut
void copyTexture(QRhiTexture *dst, QRhiTexture *src, const QRhiTextureCopyDescription &desc = QRhiTextureCopyDescription());
void resolveTexture(QRhiTexture *dst, const QRhiTextureResolveDescription &desc);
void readBackTexture(const QRhiReadbackDescription &rb, QRhiReadbackResult *result);
void generateMips(QRhiTexture *tex);
......@@ -1122,9 +1115,9 @@ public:
// depth-stencil buffer via the window surface).
//
// Color is also supported. With some gfx apis (GL) this is different from
// textures. (cannot be sampled, but can be rendered to and used in a
// multisample resolve) This becomes important when doing msaa offscreen
// and the gfx api has no multisample textures.
// textures. (cannot be sampled, but can be rendered to) This becomes
// important when doing msaa offscreen and the gfx api has no multisample
// textures.
QRhiRenderBuffer *newRenderBuffer(QRhiRenderBuffer::Type type,
const QSize &pixelSize,
int sampleCount = 1,
......
......@@ -184,16 +184,6 @@ struct QRhiResourceUpdateBatchPrivate
QRhiTextureCopyDescription desc;
};
struct TextureResolve {
TextureResolve() { }
TextureResolve(QRhiTexture *dst_, const QRhiTextureResolveDescription &desc_)
: dst(dst_), desc(desc_)
{ }
QRhiTexture *dst = nullptr;
QRhiTextureResolveDescription desc;
};
struct TextureRead {
TextureRead() { }
TextureRead(const QRhiReadbackDescription &rb_, QRhiReadbackResult *result_)
......@@ -226,7 +216,6 @@ struct QRhiResourceUpdateBatchPrivate
QVector<StaticBufferUpload> staticBufferUploads;
QVector<TextureUpload> textureUploads;
QVector<TextureCopy> textureCopies;
QVector<TextureResolve> textureResolves;
QVector<TextureRead> textureReadbacks;
QVector<TextureMipGen> textureMipGens;
QVector<TexturePrepare> texturePrepares;
......@@ -245,7 +234,6 @@ Q_DECLARE_TYPEINFO(QRhiResourceUpdateBatchPrivate::DynamicBufferUpdate, Q_MOVABL
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::TextureResolve, Q_MOVABLE_TYPE);
Q_DECLARE_TYPEINFO(QRhiResourceUpdateBatchPrivate::TextureRead, Q_MOVABLE_TYPE);
Q_DECLARE_TYPEINFO(QRhiResourceUpdateBatchPrivate::TextureMipGen, Q_MOVABLE_TYPE);
Q_DECLARE_TYPEINFO(QRhiResourceUpdateBatchPrivate::TexturePrepare, Q_MOVABLE_TYPE);
......
......@@ -821,52 +821,6 @@ void QRhiD3D11::enqueueResourceUpdates(QRhiCommandBuffer *cb, QRhiResourceUpdate
cbD->commands.append(cmd);
}
for (const QRhiResourceUpdateBatchPrivate::TextureResolve &u : ud->textureResolves) {
Q_ASSERT(u.dst);
Q_ASSERT(u.desc.sourceTexture || u.desc.sourceRenderBuffer);
QD3D11Texture *dstTexD = QRHI_RES(QD3D11Texture, u.dst);
if (dstTexD->sampleDesc.Count > 1) {
qWarning("Cannot resolve into a multisample texture");
continue;
}
QD3D11Texture *srcTexD = QRHI_RES(QD3D11Texture, u.desc.sourceTexture);
QD3D11RenderBuffer *srcRbD = QRHI_RES(QD3D11RenderBuffer, u.desc.sourceRenderBuffer);
QD3D11CommandBuffer::Command cmd;
cmd.cmd = QD3D11CommandBuffer::Command::ResolveSubRes;
cmd.args.resolveSubRes.dst = dstTexD->tex;
cmd.args.resolveSubRes.dstSubRes = D3D11CalcSubresource(u.desc.destinationLevel,
u.desc.destinationLayer,
dstTexD->mipLevelCount);
if (srcTexD) {
cmd.args.resolveSubRes.src = srcTexD->tex;
if (srcTexD->dxgiFormat != dstTexD->dxgiFormat) {
qWarning("Resolve source and destination formats do not match");
continue;
}
if (srcTexD->sampleDesc.Count <= 1) {
qWarning("Cannot resolve a non-multisample texture");
continue;
}
if (srcTexD->m_pixelSize != dstTexD->m_pixelSize) {
qWarning("Resolve source and destination sizes do not match");
continue;
}
} else {
cmd.args.resolveSubRes.src = srcRbD->tex;
if (srcRbD->dxgiFormat != dstTexD->dxgiFormat) {
qWarning("Resolve source and destination formats do not match");
continue;
}
if (srcRbD->m_pixelSize != dstTexD->m_pixelSize) {
qWarning("Resolve source and destination sizes do not match");
continue;
}
}
cmd.args.resolveSubRes.srcSubRes = D3D11CalcSubresource(0, u.desc.sourceLayer, 1);
cmd.args.resolveSubRes.format = dstTexD->dxgiFormat;
cbD->commands.append(cmd);
}
for (const QRhiResourceUpdateBatchPrivate::TextureRead &u : ud->textureReadbacks) {
ActiveReadback aRb;
aRb.desc = u.rb;
......@@ -1070,6 +1024,54 @@ void QRhiD3D11::endPass(QRhiCommandBuffer *cb, QRhiResourceUpdateBatch *resource
inPass = false;
QD3D11CommandBuffer *cbD = QRHI_RES(QD3D11CommandBuffer, cb);
if (cbD->currentTarget->type() == QRhiRenderTarget::RtTexture) {
QD3D11TextureRenderTarget *rtTex = QRHI_RES(QD3D11TextureRenderTarget, cbD->currentTarget);
for (int att = 0, attCount = rtTex->m_desc.colorAttachments.count(); att != attCount; ++att) {
const QRhiTextureRenderTargetDescription::ColorAttachment &colorAtt(rtTex->m_desc.colorAttachments[att]);
if (!colorAtt.resolveTexture)
continue;
QD3D11Texture *dstTexD = QRHI_RES(QD3D11Texture, colorAtt.resolveTexture);
QD3D11Texture *srcTexD = QRHI_RES(QD3D11Texture, colorAtt.texture);
QD3D11RenderBuffer *srcRbD = QRHI_RES(QD3D11RenderBuffer, colorAtt.renderBuffer);
Q_ASSERT(srcTexD || srcRbD);
QD3D11CommandBuffer::Command cmd;
cmd.cmd = QD3D11CommandBuffer::Command::ResolveSubRes;
cmd.args.resolveSubRes.dst = dstTexD->tex;
cmd.args.resolveSubRes.dstSubRes = D3D11CalcSubresource(colorAtt.resolveLevel,
colorAtt.resolveLayer,
dstTexD->mipLevelCount);
if (srcTexD) {
cmd.args.resolveSubRes.src = srcTexD->tex;
if (srcTexD->dxgiFormat != dstTexD->dxgiFormat) {
qWarning("Resolve source and destination formats do not match");
continue;
}
if (srcTexD->sampleDesc.Count <= 1) {
qWarning("Cannot resolve a non-multisample texture");
continue;
}
if (srcTexD->m_pixelSize != dstTexD->m_pixelSize) {
qWarning("Resolve source and destination sizes do not match");
continue;
}
} else {
cmd.args.resolveSubRes.src = srcRbD->tex;
if (srcRbD->dxgiFormat != dstTexD->dxgiFormat) {
qWarning("Resolve source and destination formats do not match");
continue;
}
if (srcRbD->m_pixelSize != dstTexD->m_pixelSize) {
qWarning("Resolve source and destination sizes do not match");
continue;
}
}
cmd.args.resolveSubRes.srcSubRes = D3D11CalcSubresource(0, colorAtt.layer, 1);
cmd.args.resolveSubRes.format = dstTexD->dxgiFormat;
cbD->commands.append(cmd);
}
}
cbD->currentTarget = nullptr;
if (resourceUpdates)
......
......@@ -702,30 +702,6 @@ void QRhiGles2::enqueueResourceUpdates(QRhiCommandBuffer *cb, QRhiResourceUpdate
cbD->commands.append(cmd);
}
for (const QRhiResourceUpdateBatchPrivate::TextureResolve &u : ud->textureResolves) {
Q_ASSERT(u.dst);
Q_ASSERT(u.desc.sourceTexture || u.desc.sourceRenderBuffer);
if (u.desc.sourceTexture) {
qWarning("Multisample textures not supported, skipping resolve");
continue;
}
QGles2Texture *dstTexD = QRHI_RES(QGles2Texture, u.dst);
QGles2RenderBuffer *srcRbD = QRHI_RES(QGles2RenderBuffer, u.desc.sourceRenderBuffer);
if (srcRbD->m_pixelSize != dstTexD->m_pixelSize) {
qWarning("Resolve source and destination sizes do not match");
continue;
}
QGles2CommandBuffer::Command cmd;
cmd.cmd = QGles2CommandBuffer::Command::BlitFromRenderbuffer;
cmd.args.blitFromRb.renderbuffer = srcRbD->renderbuffer;
cmd.args.blitFromRb.w = srcRbD->m_pixelSize.width();
cmd.args.blitFromRb.h = srcRbD->m_pixelSize.height();
cmd.args.blitFromRb.dst = dstTexD;
cmd.args.blitFromRb.dstLayer = u.desc.destinationLayer;
cmd.args.blitFromRb.dstLevel = u.desc.destinationLevel;
cbD->commands.append(cmd);
}
for (const QRhiResourceUpdateBatchPrivate::TextureRead &u : ud->textureReadbacks) {
QGles2CommandBuffer::Command cmd;
cmd.cmd = QGles2CommandBuffer::Command::ReadPixels;
......@@ -1453,6 +1429,30 @@ void QRhiGles2::endPass(QRhiCommandBuffer *cb, QRhiResourceUpdateBatch *resource
inPass = false;
QGles2CommandBuffer *cbD = QRHI_RES(QGles2CommandBuffer, cb);
if (cbD->currentTarget->type() == QRhiRenderTarget::RtTexture) {
QGles2TextureRenderTarget *rtTex = QRHI_RES(QGles2TextureRenderTarget, cbD->currentTarget);
// handle only 1 color attachment and only (msaa) renderbuffer
const QRhiTextureRenderTargetDescription::ColorAttachment &colorAtt(rtTex->m_desc.colorAttachments[0]);
if (colorAtt.resolveTexture) {
Q_ASSERT(colorAtt.renderBuffer);
QGles2RenderBuffer *rbD = QRHI_RES(QGles2RenderBuffer, colorAtt.renderBuffer);
const QSize size = colorAtt.resolveTexture->pixelSize();
if (rbD->pixelSize() != size) {
qWarning("Resolve source (%dx%d) and target (%dx%d) size does not match",
rbD->pixelSize().width(), rbD->pixelSize().height(), size.width(), size.height());
}
QGles2CommandBuffer::Command cmd;
cmd.cmd = QGles2CommandBuffer::Command::BlitFromRenderbuffer;
cmd.args.blitFromRb.renderbuffer = rbD->renderbuffer;
cmd.args.blitFromRb.w = size.width();
cmd.args.blitFromRb.h = size.height();
cmd.args.blitFromRb.dst = QRHI_RES(QGles2Texture, colorAtt.resolveTexture);
cmd.args.blitFromRb.dstLayer = colorAtt.resolveLayer;
cmd.args.blitFromRb.dstLevel = colorAtt.resolveLevel;
cbD->commands.append(cmd);
}
}
cbD->currentTarget = nullptr;
if (resourceUpdates)
......
......@@ -148,10 +148,12 @@ struct QMetalRenderTargetData
id<MTLTexture> tex = nil;
int layer = 0;
int level = 0;
id<MTLTexture> resolveTex = nil;
int resolveLayer = 0;
int resolveLevel = 0;
};
ColorAtt colorAtt[QMetalRenderPassDescriptor::MAX_COLOR_ATTACHMENTS];
id<MTLTexture> dsTex = nil;
id<MTLTexture> resolveTex = nil;
bool hasStencil = false;
} fb;
};
......@@ -566,9 +568,8 @@ QRhi::FrameOpResult QRhiMetal::beginFrame(QRhiSwapChain *swapChain)
scTex = swapChainD->d->msaaTex[currentFrameSlot];
}
swapChainD->rtWrapper.d->fb.colorAtt[0] = { scTex, 0, 0 };
swapChainD->rtWrapper.d->fb.colorAtt[0] = { scTex, 0, 0, resolveTex, 0, 0 };
swapChainD->rtWrapper.d->fb.dsTex = swapChainD->ds ? swapChainD->ds->d->tex : nil;
swapChainD->rtWrapper.d->fb.resolveTex = resolveTex;
swapChainD->rtWrapper.d->fb.hasStencil = swapChainD->ds ? true : false;
executeDeferredReleases();
......@@ -858,13 +859,12 @@ void QRhiMetal::beginPass(QRhiCommandBuffer *cb,
cbD->d->currentPassRpDesc.colorAttachments[i].texture = rtD->fb.colorAtt[i].tex;
cbD->d->currentPassRpDesc.colorAttachments[i].slice = rtD->fb.colorAtt[i].layer;
cbD->d->currentPassRpDesc.colorAttachments[i].level = rtD->fb.colorAtt[i].level;
}
// MSAA swapchains pass the multisample texture in colorTex and the
// non-multisample texture (from the drawable) in resolveTex.
if (rtD->fb.resolveTex) {
cbD->d->currentPassRpDesc.colorAttachments[0].storeAction = MTLStoreActionMultisampleResolve;
cbD->d->currentPassRpDesc.colorAttachments[0].resolveTexture = rtD->fb.resolveTex;
if (rtD->fb.colorAtt[i].resolveTex) {
cbD->d->currentPassRpDesc.colorAttachments[i].storeAction = MTLStoreActionMultisampleResolve;
cbD->d->currentPassRpDesc.colorAttachments[i].resolveTexture = rtD->fb.colorAtt[i].resolveTex;
cbD->d->currentPassRpDesc.colorAttachments[i].resolveSlice = rtD->fb.colorAtt[i].resolveLayer;
cbD->d->currentPassRpDesc.colorAttachments[i].resolveLevel = rtD->fb.colorAtt[i].resolveLevel;
}
}
if (rtD->dsAttCount) {
......@@ -1353,15 +1353,20 @@ bool QMetalTextureRenderTarget::build()
QMetalTexture *texD = QRHI_RES(QMetalTexture, m_desc.colorAttachments[i].texture);
QMetalRenderBuffer *rbD = QRHI_RES(QMetalRenderBuffer, m_desc.colorAttachments[i].renderBuffer);
Q_ASSERT(texD || rbD);
id<MTLTexture> dst;
if (texD) {
d->fb.colorAtt[i] = { texD->d->tex, m_desc.colorAttachments[i].layer, m_desc.colorAttachments[i].level };
dst = texD->d->tex;
if (i == 0)
d->pixelSize = texD->pixelSize();
} else {
d->fb.colorAtt[i] = { rbD->d->tex, m_desc.colorAttachments[i].layer, m_desc.colorAttachments[i].level };
dst = rbD->d->tex;
if (i == 0)
d->pixelSize = rbD->pixelSize();
}
QMetalTexture *resTexD = QRHI_RES(QMetalTexture, m_desc.colorAttachments[i].resolveTexture);
id<MTLTexture> resDst = resTexD ? resTexD->d->tex : nil;
d->fb.colorAtt[i] = { dst, m_desc.colorAttachments[i].layer, m_desc.colorAttachments[i].level,
resDst, m_desc.colorAttachments[i].resolveLayer, m_desc.colorAttachments[i].resolveLevel };
}
if (hasDepthStencil) {
......
......@@ -2129,67 +2129,6 @@ void QRhiVulkan::enqueueResourceUpdates(QRhiCommandBuffer *cb, QRhiResourceUpdat
finishTransferDest(cb, dstD);
}
for (const QRhiResourceUpdateBatchPrivate::TextureResolve &u : ud->textureResolves) {
Q_ASSERT(u.dst);
Q_ASSERT(u.desc.sourceTexture || u.desc.sourceRenderBuffer);
QVkTexture *dstTexD = QRHI_RES(QVkTexture, u.dst);
if (dstTexD->samples > VK_SAMPLE_COUNT_1_BIT) {
qWarning("Cannot resolve into a multisample texture");
continue;
}
VkImageResolve region;
memset(&region, 0, sizeof(region));
region.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
region.srcSubresource.baseArrayLayer = u.desc.sourceLayer;
region.srcSubresource.layerCount = 1;
region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
region.dstSubresource.mipLevel = u.desc.destinationLevel;
region.dstSubresource.baseArrayLayer = u.desc.destinationLayer;
region.dstSubresource.layerCount = 1;
region.extent.depth = 1;
QVkTexture *srcTexD = QRHI_RES(QVkTexture, u.desc.sourceTexture);
QVkRenderBuffer *srcRbD = QRHI_RES(QVkRenderBuffer, u.desc.sourceRenderBuffer);
QVkTexture *src;
if (srcTexD) {
if (srcTexD->vkformat != dstTexD->vkformat) {
qWarning("Resolve source and destination formats do not match");
continue;
}
if (srcTexD->samples == VK_SAMPLE_COUNT_1_BIT) {
qWarning("Cannot resolve a non-multisample texture");
continue;
}
if (srcTexD->m_pixelSize != dstTexD->m_pixelSize) {
qWarning("Resolve source and destination sizes do not match");
continue;
}
src = srcTexD;
} else {
if (srcRbD->vkformat != dstTexD->vkformat) {
qWarning("Resolve source and destination formats do not match");
continue;
}
if (srcRbD->m_pixelSize != dstTexD->m_pixelSize) {
qWarning("Resolve source and destination sizes do not match");
continue;
}
src = srcRbD->backingTexture;
}
region.extent.width = src->m_pixelSize.width();
region.extent.height = src->m_pixelSize.height();
prepareForTransferSrc(cb, src);
prepareForTransferDest(cb, dstTexD);
df->vkCmdResolveImage(cbD->cb, src->image, src->layout, dstTexD->image, dstTexD->layout, 1, &region);
finishTransferSrc(cb, src);
finishTransferDest(cb, dstTexD);
}
for (const QRhiResourceUpdateBatchPrivate::TextureRead &u : ud->textureReadbacks) {
ActiveReadback aRb;
aRb.activeFrameSlot = currentFrameSlot;
......
......@@ -2,7 +2,6 @@ mtl: rhi without a window, offscreen frame
mtl: readback (tex, backbuffer)
mtl: compressed textures
mtl: srgb (tex, swapchain buf)
mtl: resolveimage (color)
gl: tex formats (texture, readback)
gl: srgb
......@@ -50,13 +49,13 @@ multi mip/layer copy? (fewer barriers...)
multi-buffer (region) readback?
depth readback?
copy image depth?
depth resolve?
shadertools:
dxc for d3d as an alternative to fxc?
hlsl -> dxc -> spirv -> spirv-cross hmmm...
+++ done
change how resolve is done
mtl: color renderbuffer
targeting mip level in texrt
mtl: targeting cubemap faces
......
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