QRhiGraphicsPipeline create失败的一个奇怪原因

最近在学习Qt RHI图形渲染框架时遇到了一个奇怪的问题:QRhiGraphicsPipeline莫名其妙的create返回false!因为在出现这个问题的过程中,一直在调试fragment shader,并且是在研究HDR显示shader,期间频繁开关Windows的HDR显示开关,一度以为是系统出现了问题,于是尝试切换了SDR,也依然报错。

后来,花了一些时间revert修改,最后隔离出了问题所在。。。

首先,说明下程序框架基本抄自Qt官方文档中的例程:https://doc.qt.io/qt-6/qtgui-rhiwindow-example.html,重点标记下报错代码位置,在这里:

   m_colorTriSrb.reset(m_rhi->newShaderResourceBindings());
   static const QRhiShaderResourceBinding::StageFlags visibility =
           QRhiShaderResourceBinding::VertexStage | QRhiShaderResourceBinding::FragmentStage;
   m_colorTriSrb->setBindings({
           QRhiShaderResourceBinding::uniformBuffer(0, visibility, m_ubuf.get())
   });
   m_colorTriSrb->create();

   m_colorPipeline.reset(m_rhi->newGraphicsPipeline());
   // Enable depth testing; not quite needed for a simple triangle, but we
   // have a depth-stencil buffer so why not.
   m_colorPipeline->setDepthTest(true);
   m_colorPipeline->setDepthWrite(true);
   // Blend factors default to One, OneOneMinusSrcAlpha, which is convenient.
   QRhiGraphicsPipeline::TargetBlend premulAlphaBlend;
   premulAlphaBlend.enable = true;
   m_colorPipeline->setTargetBlends({ premulAlphaBlend });
   m_colorPipeline->setShaderStages({
       { QRhiShaderStage::Vertex, getShader(QLatin1String(":/color.vert.qsb")) },
       { QRhiShaderStage::Fragment, getShader(QLatin1String(":/color.frag.qsb")) }
   });
   QRhiVertexInputLayout inputLayout;
   inputLayout.setBindings({
       { 5 * sizeof(float) }
   });
   inputLayout.setAttributes({
       { 0, 0, QRhiVertexInputAttribute::Float2, 0 },
       { 0, 1, QRhiVertexInputAttribute::Float3, 2 * sizeof(float) }
   });
   m_colorPipeline->setVertexInputLayout(inputLayout);
   m_colorPipeline->setShaderResourceBindings(m_colorTriSrb.get());
   m_colorPipeline->setRenderPassDescriptor(m_rp.get());
   m_colorPipeline->create();

报错的就是最后的create,可以看到,这个pipeline其实还包含了shader部分的设置,而问题就出在了shader上,因为一直在改shader,其中一次在参考AI提供信息时,没有复制完全,改出了这样一段shader代码:

void render_10bit_hdr()
{
    vec3 rgb = decode_10bit_rgb_from_rg8();
    vec3 color;

    if (ubuf.color_transfer == 18) 
    {
        //color = hlgToLinear(rgb);
        color = BT2020toBT709(color);
        //color *= 2.5375 * 4.5;
    }
    else
    {
        color = PQToScRGB(rgb);
        color = BT2020toBT709(color);
        color *= 125.0;
    }
    //color = tonemapping(color);
    //color = hableMap(color);
    //color = LineartoGamma(color);

    fragColor = vec4(color, 1);
}

color = BT2020toBT709(color); 这行,为了调试,临时注掉了上面那行,导致了color其实没有初始化(估计底层是这个原因),而语法上,这段shader代码没有任何问题,Qt的qsb编译时也没有任何报错,但就是只要这个状态编出来的shader,就会导致m_colorPipeline的create返回false!

博主友情提示:

如您在评论中需要提及如QQ号、电子邮件地址或其他隐私敏感信息,欢迎使用>>博主专用加密工具v3<<处理后发布,原文只有博主可以看到。