Details
-
Bug
-
Resolution: Invalid
-
P2: Important
-
None
-
6.2.0 RC2
-
None
-
Linux, Wayland
Description
I'm creating a custom QQuickItem with shaders built via qsb. The item doesn't do anything particularly special (it renders a colored triangle).
When running the program no shaders are found even though I'm positive they are included in the program correctly:
No rewriter-inserted attribute found, this should not happen. No GLSL shader code found (versions tried: QList(460, 450, 440, 430, 420, 410, 400, 330, 150, 140, 130, 120) ) in baked shader QShader(stage=0 shaders=QList(ShaderKey(1 Version(150 QFlags()) 0), ShaderKey(1 Ver sion(100 QFlags(0x1)) 0), ShaderKey(4 Version(12 QFlags()) 0), ShaderKey(1 Version(120 QFlags()) 0), ShaderKey(2 Version(50 QFlags()) 0), ShaderKey(0 Version(100 QFlags()) 0)) desc.isValid=true) Failed to build graphics pipeline state No GLSL shader code found (versions tried: QList(460, 450, 440, 430, 420, 410, 400, 330, 150, 140, 130, 120) ) in baked shader QShader(stage=0 shaders=QList(ShaderKey(1 Version(150 QFlags()) 0), ShaderKey(1 Ver sion(100 QFlags(0x1)) 0), ShaderKey(4 Version(12 QFlags()) 0), ShaderKey(1 Version(120 QFlags()) 0), ShaderKey(2 Version(50 QFlags()) 0), ShaderKey(0 Version(100 QFlags()) 0)) desc.isValid=true) Failed to build graphics pipeline state No GLSL shader code found (versions tried: QList(460, 450, 440, 430, 420, 410, 400, 330, 150, 140, 130, 120) ) in baked shader QShader(stage=0 shaders=QList(ShaderKey(1 Version(150 QFlags()) 0), ShaderKey(1 Ver sion(100 QFlags(0x1)) 0), ShaderKey(4 Version(12 QFlags()) 0), ShaderKey(1 Version(120 QFlags()) 0), ShaderKey(2 Version(50 QFlags()) 0), ShaderKey(0 Version(100 QFlags()) 0)) desc.isValid=true) Failed to build graphics pipeline state No GLSL shader code found (versions tried: QList(460, 450, 440, 430, 420, 410, 400, 330, 150, 140, 130, 120) ) in baked shader QShader(stage=0 shaders=QList(ShaderKey(1 Version(150 QFlags()) 0), ShaderKey(1 Ver sion(100 QFlags(0x1)) 0), ShaderKey(4 Version(12 QFlags()) 0), ShaderKey(1 Version(120 QFlags()) 0), ShaderKey(2 Version(50 QFlags()) 0), ShaderKey(0 Version(100 QFlags()) 0)) desc.isValid=true) Failed to build graphics pipeline state
Adding 'BATCHABLE' to the qt_add_shaders call makes the program work as expected
Source code below:
cmake_minimum_required(VERSION 3.16) find_package(Qt6 REQUIRED COMPONENTS Core Quick ShaderTools) set(CMAKE_AUTOMOC ON) set(CMAKE_AUTORCC ON) add_executable(myapp main.cpp myitem.cpp myapp.qrc) qt_add_shaders(myapp "myapp-shaders" BATCHABLE # Without this it fails PREFIX "/" FILES "shader.vert" "shader.frag" ) target_link_libraries(myapp PRIVATE Qt::Quick)
#include "myitem.h" #include <QSGGeometryNode> #include <QSGMaterial> #include <QSGMaterialShader> #include <QSGFlatColorMaterial> class MyMaterialShader : public QSGMaterialShader { public: MyMaterialShader() : QSGMaterialShader() { setShaderFileName(VertexStage, QLatin1String(":/shader.vert.qsb")); setShaderFileName(FragmentStage, QLatin1String(":/shader.frag.qsb")); } bool updateUniformData(RenderState &state, QSGMaterial *, QSGMaterial *) override { bool changed = false; QByteArray *buf = state.uniformData(); if (state.isMatrixDirty()) { const QMatrix4x4 m = state.combinedMatrix(); memcpy(buf->data(), m.constData(), 64); changed = true; } if (state.isOpacityDirty()) { const float opacity = state.opacity(); memcpy(buf->data() + 64, &opacity, 4); changed = true; } return changed; } }; static const QSGGeometry::AttributeSet &attributes() { static QSGGeometry::Attribute attr[] = { QSGGeometry::Attribute::create(0, 2, QSGGeometry::FloatType, true), QSGGeometry::Attribute::create(1, 1, QSGGeometry::FloatType) }; static QSGGeometry::AttributeSet set = { 2, 3 * sizeof(float), attr }; return set; } class MyItemMaterial : public QSGMaterial { public: MyItemMaterial() { } QSGMaterialType *type() const override { static QSGMaterialType typeId; return &typeId; } QSGMaterialShader *createShader(QSGRendererInterface::RenderMode renderMode) const override { Q_UNUSED(renderMode); return new MyMaterialShader; } int compare(const QSGMaterial *) const override { return 0; } }; class MyItemGeometryNode : public QSGGeometryNode { public: MyItemGeometryNode() { } void updateGeometry(const QSize size) { QSGGeometry *geometry = QSGGeometryNode::geometry(); if (geometry == nullptr) { geometry = new QSGGeometry(QSGGeometry::defaultAttributes_ColoredPoint2D(), 3); geometry->setDrawingMode(QSGGeometry::DrawTriangles); setGeometry(geometry); auto material = new MyItemMaterial; setMaterial(material); } QSGGeometry::ColoredPoint2D *points = geometry->vertexDataAsColoredPoint2D(); points[0].r = 255; points[0].g = 0; points[0].b = 0; points[0].a = 1; points[1] = points[0]; points[2] = points[0]; points[0].x = 0; points[0].y = 0; points[1].x = 0; points[1].y = size.height(); points[2].x = size.width(); points[2].y = size.height(); geometry->markVertexDataDirty(); markDirty(QSGNode::DirtyGeometry); } }; MyItem::MyItem(QQuickItem *parent) : QQuickItem(parent){ setFlag(QQuickItem::ItemHasContents, true); } QSGNode *MyItem::updatePaintNode(QSGNode *oldNode, QQuickItem::UpdatePaintNodeData *) { if (width() <= 0 || height() <= 0) { delete oldNode; return nullptr; } if (oldNode == nullptr) oldNode = new MyItemGeometryNode; auto geometryNode = static_cast<MyItemGeometryNode *>(oldNode); geometryNode->updateGeometry(QSize(width(), height())); return geometryNode; }