QRhi rendering question
Unsolved
Game Development
-
Hi, I managed to have a perfectly working rendering code with QRhi (offline rendering), fully functional with Metal, DX11 and OpenGL, but unfortunately I can't use it in debug mode because it turns out I'm doing something forbidden, a cb->resourceUpdate() during a cb->beginPass() and cb->endPass() in the SpectralChannel::render() method below.
Do you know how I can fix my code to move or remove that unwanted resourceUpdate() and still get all the proper resources refresh ? Here's how it goes (simplified):
void SpectralChannel::paintEvent(QPaintEvent *event) { QRhiCommandBuffer *cb; m_rhi->beginOffscreenFrame(&cb); render(cb); m_rhi->endOffscreenFrame(); QImage image(reinterpret_cast<const uchar *>(readbackResult.data.constData()), readbackResult.pixelSize.width(), readbackResult.pixelSize.height(), QImage::Format_RGBA8888_Premultiplied); if (m_rhi->isYUpInFramebuffer()) image = image.mirrored(); image.setDevicePixelRatio(devicePixelRatio()); QPainter painter(this); painter.drawImage(0,0,image); } QRhiResourceUpdateBatch* SpectralChannel::updateFrameBuffer() { QRhiResourceUpdateBatch* updateBatch = resourceUpdateBatch(true); updateBatch->readBackTexture({ texTarget.get() }, &readbackResult); return updateBatch; } QRhiResourceUpdateBatch* SpectralChannel::resourceUpdateBatch(bool renewBatch) { if(!m_resourceUpdateBatch) m_resourceUpdateBatch=rhi()->nextResourceUpdateBatch(); if(renewBatch) { QRhiResourceUpdateBatch* currentBatch=m_resourceUpdateBatch; m_resourceUpdateBatch=rhi()->nextResourceUpdateBatch(); return currentBatch; } else return m_resourceUpdateBatch; } void SpectralChannel::render(QRhiCommandBuffer *cb) { updateTextures(); //bunch of textures update/creation (several textures are destroyed and rebuilt due to changing sizes) resourceUpdateBatch()->updateDynamicBuffer(uniformCommonBuf.get(),0,sizeof(float)*4*4,scaledDisplayMatrix.constData()); //start drawing commands cb->beginPass(renderTarget(), Qt::black, { 1.0f, 0 }, resourceUpdateBatch(true)); cb->setViewport({ 0, 0, float(width()*devicePixelRatio()), float(height()*devicePixelRatio()) }); for(QHash<LayerPtr, SpectralTextureMeta2>::iterator tex = textureList.begin(); tex != textureList.end(); tex++) { cb->setGraphicsPipeline(tex.value().spectralPipeline.get()); resourceUpdateBatch()->updateDynamicBuffer(...); ... resourceUpdateBatch()->updateDynamicBuffer(...); cb->resourceUpdate(resourceUpdateBatch(true)); //this resourceUpdate is forbidden in debug mode ! cb->setShaderResources(); const QRhiCommandBuffer::VertexInput vbufBinding(...); cb->setVertexInput(0, 1, &vbufBinding); cb->draw(4); } cb->endPass(updateFrameBuffer()); }
-
FWIW, the fixed code (thanks to github copilot)
void SpectralChannel::render(QRhiCommandBuffer *cb) { //update resources first updateTextures(); Area scaledDisplayArea=convert.toScaled(displayArea); scaledDisplayArea.moveLeft(0.); QMatrix4x4 scaledDisplayMatrix=scaledDisplayArea.toMatrix(); resourceUpdateBatch()->updateDynamicBuffer(...); for(QHash<LayerPtr, SpectralTextureMeta2>::iterator tex = textureList.begin(); tex != textureList.end(); tex++) { resourceUpdateBatch()->updateDynamicBuffer(...); ... } cb->resourceUpdate(resourceUpdateBatch(true)); //start drawing commands cb->beginPass(renderTarget(), Qt::black, { 1.0f, 0 }, resourceUpdateBatch(true)); cb->setViewport({ 0, 0, float(width()*devicePixelRatio()), float(height()*devicePixelRatio()) }); for(QHash<LayerPtr, SpectralTextureMeta2>::iterator tex = textureList.begin(); tex != textureList.end(); tex++) { cb->setGraphicsPipeline(tex.value().spectralPipeline.get()); const QRhiCommandBuffer::VertexInput vbufBinding(tex.value().vertexBuf.get(), 0); cb->setVertexInput(0, 1, &vbufBinding); cb->setShaderResources(); cb->draw(4); } cb->endPass(updateFrameBuffer()); }