V-EZ icon indicating copy to clipboard operation
V-EZ copied to clipboard

Incompatible render passes

Open SilvanVR opened this issue 7 years ago • 5 comments

When using my stereo rendering pipeline i get the following error: error Trying to investigate and give some more information.

SilvanVR avatar Sep 26 '18 16:09 SilvanVR

Okay, so for now i know it is related somehow to rendering two full-screen quads with the same shader:

// This causes the error above with the incompatible render pass.
// I also checked renderdoc, it reports the second pass again as depth only
cam->addComponent<PostProcess>(ASSETS.getMaterial("/materials/post processing/gaussian_blur_horizontal.material"));
cam->addComponent<PostProcess>(ASSETS.getMaterial("/materials/post processing/gaussian_blur_vertical.material"));

Changing one of the post processing effects to another one or even add another post processing effect between those two and the error is gone. The source of this error must be somehow caused by rendering two full-screen quads with the same shader successively. Maybe you have an quick idea, before i will investigate tomorrow deeper. :-)

SilvanVR avatar Sep 30 '18 22:09 SilvanVR

Not sure if it has to do with this issue, but why there are two commented lines? (StreamEncoder.cpp 942) That looks suspicious.

switch (dsWrite.descriptorType)
{
case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
    //imageInfo.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
    //m_pipelineBarriers.ImageAccess(m_stream.TellP(), bindingInfo.pImageView->GetImage(), &bindingInfo.pImageView->GetSubresourceRange(), imageInfo.imageLayout, accessMask, stageMask);
    break;

case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
    imageInfo.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
    break;

case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
    imageInfo.imageLayout = VK_IMAGE_LAYOUT_GENERAL;
    m_pipelineBarriers.ImageAccess(m_stream.TellP(), bindingInfo.pImageView->GetImage(), &bindingInfo.pImageView->GetSubresourceRange(), imageInfo.imageLayout, accessMask, stageMask);
    break;

default:
    continue;
}

SilvanVR avatar Oct 01 '18 11:10 SilvanVR

Okay i know now where is the bug. It starts all with StreamEncoder.cpp Line 1009:

// No need to re-create if graphics state is not dirty.
if (!m_graphicsState.IsDirty())
    return;

Because two of the same shaders get binded subsequently, the graphics pipeline is of course not dirty, because nothing changed. This causes the statement above to return. However, that should not happen because the subsequent draw rely on the code being executed after that return statement. Specifically (StreamEncoder.cpp 1033) will not be executed.:

// Add output location to subpass's outputAttachments array.
subpass.outputAttachments.emplace(resource.location);

This on the other hand causes the next render pass to fail finding the correct outputAttachment: (RenderPassCache.cpp line 258)

// Determine whether attachment was written to in current subpass and fill in attachment reference appropriately.
allColorAttachments.push_back({ VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL });
if (pDesc->subpasses[i].outputAttachments.find(k) != pDesc->subpasses[i].outputAttachments.end())
    allColorAttachments.back().attachment = k; // THIS WILL NOT BE EXECUTED

And that is the reason why the pass is reported as depth-only. Solution? Mark the pipeline as dirty when a new render pass begins. I tested it and it works.

SilvanVR avatar Oct 01 '18 12:10 SilvanVR

Where did you make your change at? In GraphicsState.cpp line 258, the dirty flag is already being set if the pipeline changes.

soconne avatar Oct 03 '18 17:10 soconne

Yes, but that is the problem. The pipeline does not change when the same shader was bound two times. What i did is adding a function in GraphicsState.h:

void SetDirty() { m_dirty = true; }

and call it in StreamEncoder.cpp:

void StreamEncoder::CmdBeginRenderPass(const VezRenderPassBeginInfo* pBeginInfo)
{
    // Mark the beginning of the renderpass.
    m_inRenderPass = true;

   // ADDED THE FUNCTION HERE
   m_graphicsState.SetDirty();
   ....
}

SilvanVR avatar Oct 03 '18 18:10 SilvanVR