Move away from CBOR in QShaderDescription serialization
...but keep support for deserializing for all older versions in order to play nice with existing .qsb files. The usage of binary JSON and then CBOR is a historical artifact: relying on the QJsonDocument (which we generate for purposes unrelated to binary serialization) was a convenient shortcut. However, writing to and reading from a QDataStream instead (which QShader already does) is trivial. In order not to be limited by potential CBOR requirements in the future, take it all into our own hands. Extend the qshader autotest accordingly. Task-number: QTBUG-81298 Change-Id: If0047b659bd6601ca47b5bbbce1b719630cde01e Reviewed-by: Paul Olav Tvete <paul.tvete@qt.io>
This commit is contained in:
parent
9a0ab41f28
commit
7e2cef0f15
@ -367,7 +367,7 @@ QByteArray QShader::serialized() const
|
||||
|
||||
ds << QShaderPrivate::QSB_VERSION;
|
||||
ds << int(d->stage);
|
||||
ds << d->desc.toCbor();
|
||||
d->desc.serialize(&ds);
|
||||
ds << d->shaders.count();
|
||||
for (auto it = d->shaders.cbegin(), itEnd = d->shaders.cend(); it != itEnd; ++it) {
|
||||
const QShaderKey &k(it.key());
|
||||
@ -428,6 +428,7 @@ QShader QShader::fromSerialized(const QByteArray &data)
|
||||
ds >> intVal;
|
||||
d->qsbVersion = intVal;
|
||||
if (d->qsbVersion != QShaderPrivate::QSB_VERSION
|
||||
&& d->qsbVersion != QShaderPrivate::QSB_VERSION_WITH_CBOR
|
||||
&& d->qsbVersion != QShaderPrivate::QSB_VERSION_WITH_BINARY_JSON
|
||||
&& d->qsbVersion != QShaderPrivate::QSB_VERSION_WITHOUT_BINDINGS)
|
||||
{
|
||||
@ -437,14 +438,18 @@ QShader QShader::fromSerialized(const QByteArray &data)
|
||||
|
||||
ds >> intVal;
|
||||
d->stage = Stage(intVal);
|
||||
QByteArray descBin;
|
||||
ds >> descBin;
|
||||
if (d->qsbVersion > QShaderPrivate::QSB_VERSION_WITH_BINARY_JSON) {
|
||||
if (d->qsbVersion > QShaderPrivate::QSB_VERSION_WITH_CBOR) {
|
||||
d->desc = QShaderDescription::deserialize(&ds);
|
||||
} else if (d->qsbVersion > QShaderPrivate::QSB_VERSION_WITH_BINARY_JSON) {
|
||||
QByteArray descBin;
|
||||
ds >> descBin;
|
||||
d->desc = QShaderDescription::fromCbor(descBin);
|
||||
} else {
|
||||
#if QT_CONFIG(binaryjson) && QT_DEPRECATED_SINCE(5, 15)
|
||||
QT_WARNING_PUSH
|
||||
QT_WARNING_DISABLE_DEPRECATED
|
||||
QByteArray descBin;
|
||||
ds >> descBin;
|
||||
d->desc = QShaderDescription::fromBinaryJson(descBin);
|
||||
QT_WARNING_POP
|
||||
#else
|
||||
|
@ -57,7 +57,8 @@ QT_BEGIN_NAMESPACE
|
||||
|
||||
struct Q_GUI_EXPORT QShaderPrivate
|
||||
{
|
||||
static const int QSB_VERSION = 3;
|
||||
static const int QSB_VERSION = 4;
|
||||
static const int QSB_VERSION_WITH_CBOR = 3;
|
||||
static const int QSB_VERSION_WITH_BINARY_JSON = 2;
|
||||
static const int QSB_VERSION_WITHOUT_BINDINGS = 1;
|
||||
|
||||
|
@ -36,6 +36,7 @@
|
||||
|
||||
#include "qshaderdescription_p_p.h"
|
||||
#include <QDebug>
|
||||
#include <QDataStream>
|
||||
#include <QJsonObject>
|
||||
#include <QJsonArray>
|
||||
#include <QCborValue>
|
||||
@ -358,6 +359,11 @@ QByteArray QShaderDescription::toJson() const
|
||||
return d->makeDoc().toJson();
|
||||
}
|
||||
|
||||
void QShaderDescription::serialize(QDataStream *stream) const
|
||||
{
|
||||
d->writeToStream(stream);
|
||||
}
|
||||
|
||||
#if QT_CONFIG(binaryjson) && QT_DEPRECATED_SINCE(5, 15)
|
||||
/*!
|
||||
\deprecated
|
||||
@ -396,6 +402,13 @@ QShaderDescription QShaderDescription::fromCbor(const QByteArray &data)
|
||||
return desc;
|
||||
}
|
||||
|
||||
QShaderDescription QShaderDescription::deserialize(QDataStream *stream)
|
||||
{
|
||||
QShaderDescription desc;
|
||||
QShaderDescriptionPrivate::get(&desc)->loadFromStream(stream);
|
||||
return desc;
|
||||
}
|
||||
|
||||
/*!
|
||||
\return the list of input variables. This includes vertex inputs (sometimes
|
||||
called attributes) for the vertex stage, and inputs for other stages
|
||||
@ -867,6 +880,15 @@ static void addDeco(QJsonObject *obj, const QShaderDescription::InOutVariable &v
|
||||
(*obj)[imageFlagsKey] = int(v.imageFlags);
|
||||
}
|
||||
|
||||
static void serializeDecorations(QDataStream *stream, const QShaderDescription::InOutVariable &v)
|
||||
{
|
||||
(*stream) << v.location;
|
||||
(*stream) << v.binding;
|
||||
(*stream) << v.descriptorSet;
|
||||
(*stream) << int(v.imageFormat);
|
||||
(*stream) << int(v.imageFlags);
|
||||
}
|
||||
|
||||
static QJsonObject inOutObject(const QShaderDescription::InOutVariable &v)
|
||||
{
|
||||
QJsonObject obj;
|
||||
@ -876,6 +898,13 @@ static QJsonObject inOutObject(const QShaderDescription::InOutVariable &v)
|
||||
return obj;
|
||||
}
|
||||
|
||||
static void serializeInOutVar(QDataStream *stream, const QShaderDescription::InOutVariable &v)
|
||||
{
|
||||
(*stream) << v.name;
|
||||
(*stream) << int(v.type);
|
||||
serializeDecorations(stream, v);
|
||||
}
|
||||
|
||||
static QJsonObject blockMemberObject(const QShaderDescription::BlockVariable &v)
|
||||
{
|
||||
QJsonObject obj;
|
||||
@ -904,6 +933,23 @@ static QJsonObject blockMemberObject(const QShaderDescription::BlockVariable &v)
|
||||
return obj;
|
||||
}
|
||||
|
||||
static void serializeBlockMemberVar(QDataStream *stream, const QShaderDescription::BlockVariable &v)
|
||||
{
|
||||
(*stream) << v.name;
|
||||
(*stream) << int(v.type);
|
||||
(*stream) << v.offset;
|
||||
(*stream) << v.size;
|
||||
(*stream) << v.arrayDims.count();
|
||||
for (int dim : v.arrayDims)
|
||||
(*stream) << dim;
|
||||
(*stream) << v.arrayStride;
|
||||
(*stream) << v.matrixStride;
|
||||
(*stream) << v.matrixIsRowMajor;
|
||||
(*stream) << v.structMembers.count();
|
||||
for (const QShaderDescription::BlockVariable &sv : v.structMembers)
|
||||
serializeBlockMemberVar(stream, sv);
|
||||
}
|
||||
|
||||
QJsonDocument QShaderDescriptionPrivate::makeDoc()
|
||||
{
|
||||
QJsonObject root;
|
||||
@ -1002,6 +1048,67 @@ QJsonDocument QShaderDescriptionPrivate::makeDoc()
|
||||
return QJsonDocument(root);
|
||||
}
|
||||
|
||||
void QShaderDescriptionPrivate::writeToStream(QDataStream *stream)
|
||||
{
|
||||
(*stream) << inVars.count();
|
||||
for (const QShaderDescription::InOutVariable &v : qAsConst(inVars))
|
||||
serializeInOutVar(stream, v);
|
||||
|
||||
(*stream) << outVars.count();
|
||||
for (const QShaderDescription::InOutVariable &v : qAsConst(outVars))
|
||||
serializeInOutVar(stream, v);
|
||||
|
||||
(*stream) << uniformBlocks.count();
|
||||
for (const QShaderDescription::UniformBlock &b : uniformBlocks) {
|
||||
(*stream) << b.blockName;
|
||||
(*stream) << b.structName;
|
||||
(*stream) << b.size;
|
||||
(*stream) << b.binding;
|
||||
(*stream) << b.descriptorSet;
|
||||
(*stream) << b.members.count();
|
||||
for (const QShaderDescription::BlockVariable &v : b.members)
|
||||
serializeBlockMemberVar(stream, v);
|
||||
}
|
||||
|
||||
(*stream) << pushConstantBlocks.count();
|
||||
for (const QShaderDescription::PushConstantBlock &b : pushConstantBlocks) {
|
||||
(*stream) << b.name;
|
||||
(*stream) << b.size;
|
||||
(*stream) << b.members.count();
|
||||
for (const QShaderDescription::BlockVariable &v : b.members)
|
||||
serializeBlockMemberVar(stream, v);
|
||||
}
|
||||
|
||||
(*stream) << storageBlocks.count();
|
||||
for (const QShaderDescription::StorageBlock &b : storageBlocks) {
|
||||
(*stream) << b.blockName;
|
||||
(*stream) << b.instanceName;
|
||||
(*stream) << b.knownSize;
|
||||
(*stream) << b.binding;
|
||||
(*stream) << b.descriptorSet;
|
||||
(*stream) << b.members.count();
|
||||
for (const QShaderDescription::BlockVariable &v : b.members)
|
||||
serializeBlockMemberVar(stream, v);
|
||||
}
|
||||
|
||||
(*stream) << combinedImageSamplers.count();
|
||||
for (const QShaderDescription::InOutVariable &v : qAsConst(combinedImageSamplers)) {
|
||||
(*stream) << v.name;
|
||||
(*stream) << int(v.type);
|
||||
serializeDecorations(stream, v);
|
||||
}
|
||||
|
||||
(*stream) << storageImages.count();
|
||||
for (const QShaderDescription::InOutVariable &v : qAsConst(storageImages)) {
|
||||
(*stream) << v.name;
|
||||
(*stream) << int(v.type);
|
||||
serializeDecorations(stream, v);
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < 3; ++i)
|
||||
(*stream) << localSize[i];
|
||||
}
|
||||
|
||||
static QShaderDescription::InOutVariable inOutVar(const QJsonObject &obj)
|
||||
{
|
||||
QShaderDescription::InOutVariable var;
|
||||
@ -1020,6 +1127,29 @@ static QShaderDescription::InOutVariable inOutVar(const QJsonObject &obj)
|
||||
return var;
|
||||
}
|
||||
|
||||
static void deserializeDecorations(QDataStream *stream, QShaderDescription::InOutVariable *v)
|
||||
{
|
||||
(*stream) >> v->location;
|
||||
(*stream) >> v->binding;
|
||||
(*stream) >> v->descriptorSet;
|
||||
int f;
|
||||
(*stream) >> f;
|
||||
v->imageFormat = QShaderDescription::ImageFormat(f);
|
||||
(*stream) >> f;
|
||||
v->imageFlags = QShaderDescription::ImageFlags(f);
|
||||
}
|
||||
|
||||
static QShaderDescription::InOutVariable deserializeInOutVar(QDataStream *stream)
|
||||
{
|
||||
QShaderDescription::InOutVariable var;
|
||||
(*stream) >> var.name;
|
||||
int t;
|
||||
(*stream) >> t;
|
||||
var.type = QShaderDescription::VariableType(t);
|
||||
deserializeDecorations(stream, &var);
|
||||
return var;
|
||||
}
|
||||
|
||||
static QShaderDescription::BlockVariable blockVar(const QJsonObject &obj)
|
||||
{
|
||||
QShaderDescription::BlockVariable var;
|
||||
@ -1046,6 +1176,30 @@ static QShaderDescription::BlockVariable blockVar(const QJsonObject &obj)
|
||||
return var;
|
||||
}
|
||||
|
||||
static QShaderDescription::BlockVariable deserializeBlockMemberVar(QDataStream *stream)
|
||||
{
|
||||
QShaderDescription::BlockVariable var;
|
||||
(*stream) >> var.name;
|
||||
int t;
|
||||
(*stream) >> t;
|
||||
var.type = QShaderDescription::VariableType(t);
|
||||
(*stream) >> var.offset;
|
||||
(*stream) >> var.size;
|
||||
int count;
|
||||
(*stream) >> count;
|
||||
var.arrayDims.resize(count);
|
||||
for (int i = 0; i < count; ++i)
|
||||
(*stream) >> var.arrayDims[i];
|
||||
(*stream) >> var.arrayStride;
|
||||
(*stream) >> var.matrixStride;
|
||||
(*stream) >> var.matrixIsRowMajor;
|
||||
(*stream) >> count;
|
||||
var.structMembers.resize(count);
|
||||
for (int i = 0; i < count; ++i)
|
||||
var.structMembers[i] = deserializeBlockMemberVar(stream);
|
||||
return var;
|
||||
}
|
||||
|
||||
void QShaderDescriptionPrivate::loadDoc(const QJsonDocument &doc)
|
||||
{
|
||||
if (doc.isNull()) {
|
||||
@ -1150,6 +1304,87 @@ void QShaderDescriptionPrivate::loadDoc(const QJsonDocument &doc)
|
||||
}
|
||||
}
|
||||
|
||||
void QShaderDescriptionPrivate::loadFromStream(QDataStream *stream)
|
||||
{
|
||||
Q_ASSERT(ref.loadRelaxed() == 1); // must be detached
|
||||
|
||||
int count;
|
||||
(*stream) >> count;
|
||||
inVars.resize(count);
|
||||
for (int i = 0; i < count; ++i)
|
||||
inVars[i] = deserializeInOutVar(stream);
|
||||
|
||||
(*stream) >> count;
|
||||
outVars.resize(count);
|
||||
for (int i = 0; i < count; ++i)
|
||||
outVars[i] = deserializeInOutVar(stream);
|
||||
|
||||
(*stream) >> count;
|
||||
uniformBlocks.resize(count);
|
||||
for (int i = 0; i < count; ++i) {
|
||||
(*stream) >> uniformBlocks[i].blockName;
|
||||
(*stream) >> uniformBlocks[i].structName;
|
||||
(*stream) >> uniformBlocks[i].size;
|
||||
(*stream) >> uniformBlocks[i].binding;
|
||||
(*stream) >> uniformBlocks[i].descriptorSet;
|
||||
int memberCount;
|
||||
(*stream) >> memberCount;
|
||||
uniformBlocks[i].members.resize(memberCount);
|
||||
for (int memberIdx = 0; memberIdx < memberCount; ++memberIdx)
|
||||
uniformBlocks[i].members[memberIdx] = deserializeBlockMemberVar(stream);
|
||||
}
|
||||
|
||||
(*stream) >> count;
|
||||
pushConstantBlocks.resize(count);
|
||||
for (int i = 0; i < count; ++i) {
|
||||
(*stream) >> pushConstantBlocks[i].name;
|
||||
(*stream) >> pushConstantBlocks[i].size;
|
||||
int memberCount;
|
||||
(*stream) >> memberCount;
|
||||
pushConstantBlocks[i].members.resize(memberCount);
|
||||
for (int memberIdx = 0; memberIdx < memberCount; ++memberIdx)
|
||||
pushConstantBlocks[i].members[memberIdx] = deserializeBlockMemberVar(stream);
|
||||
}
|
||||
|
||||
(*stream) >> count;
|
||||
storageBlocks.resize(count);
|
||||
for (int i = 0; i < count; ++i) {
|
||||
(*stream) >> storageBlocks[i].blockName;
|
||||
(*stream) >> storageBlocks[i].instanceName;
|
||||
(*stream) >> storageBlocks[i].knownSize;
|
||||
(*stream) >> storageBlocks[i].binding;
|
||||
(*stream) >> storageBlocks[i].descriptorSet;
|
||||
int memberCount;
|
||||
(*stream) >> memberCount;
|
||||
storageBlocks[i].members.resize(memberCount);
|
||||
for (int memberIdx = 0; memberIdx < memberCount; ++memberIdx)
|
||||
storageBlocks[i].members[memberIdx] = deserializeBlockMemberVar(stream);
|
||||
}
|
||||
|
||||
(*stream) >> count;
|
||||
combinedImageSamplers.resize(count);
|
||||
for (int i = 0; i < count; ++i) {
|
||||
(*stream) >> combinedImageSamplers[i].name;
|
||||
int t;
|
||||
(*stream) >> t;
|
||||
combinedImageSamplers[i].type = QShaderDescription::VariableType(t);
|
||||
deserializeDecorations(stream, &combinedImageSamplers[i]);
|
||||
}
|
||||
|
||||
(*stream) >> count;
|
||||
storageImages.resize(count);
|
||||
for (int i = 0; i < count; ++i) {
|
||||
(*stream) >> storageImages[i].name;
|
||||
int t;
|
||||
(*stream) >> t;
|
||||
storageImages[i].type = QShaderDescription::VariableType(t);
|
||||
deserializeDecorations(stream, &storageImages[i]);
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < 3; ++i)
|
||||
(*stream) >> localSize[i];
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns \c true if the two QShaderDescription objects \a lhs and \a rhs are
|
||||
equal.
|
||||
|
@ -56,6 +56,7 @@
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
struct QShaderDescriptionPrivate;
|
||||
class QDataStream;
|
||||
|
||||
class Q_GUI_EXPORT QShaderDescription
|
||||
{
|
||||
@ -69,6 +70,7 @@ public:
|
||||
bool isValid() const;
|
||||
|
||||
QByteArray toCbor() const;
|
||||
void serialize(QDataStream *stream) const;
|
||||
QByteArray toJson() const;
|
||||
|
||||
#if QT_CONFIG(binaryjson) && QT_DEPRECATED_SINCE(5, 15)
|
||||
@ -76,6 +78,7 @@ public:
|
||||
static QShaderDescription fromBinaryJson(const QByteArray &data);
|
||||
#endif
|
||||
static QShaderDescription fromCbor(const QByteArray &data);
|
||||
static QShaderDescription deserialize(QDataStream *stream);
|
||||
|
||||
enum VariableType {
|
||||
Unknown = 0,
|
||||
|
@ -80,7 +80,9 @@ struct Q_GUI_EXPORT QShaderDescriptionPrivate
|
||||
static const QShaderDescriptionPrivate *get(const QShaderDescription *desc) { return desc->d; }
|
||||
|
||||
QJsonDocument makeDoc();
|
||||
void writeToStream(QDataStream *stream);
|
||||
void loadDoc(const QJsonDocument &doc);
|
||||
void loadFromStream(QDataStream *stream);
|
||||
|
||||
QAtomicInt ref;
|
||||
QVector<QShaderDescription::InOutVariable> inVars;
|
||||
|
BIN
tests/auto/gui/rhi/qshader/data/texture_all_v4.frag.qsb
Normal file
BIN
tests/auto/gui/rhi/qshader/data/texture_all_v4.frag.qsb
Normal file
Binary file not shown.
@ -43,6 +43,8 @@ private slots:
|
||||
void mslResourceMapping();
|
||||
void loadV3();
|
||||
void serializeShaderDesc();
|
||||
void comparison();
|
||||
void loadV4();
|
||||
};
|
||||
|
||||
static QShader getShader(const QString &name)
|
||||
@ -353,21 +355,38 @@ void tst_QShader::serializeShaderDesc()
|
||||
QShaderDescription desc;
|
||||
QVERIFY(!desc.isValid());
|
||||
|
||||
const QByteArray data = desc.toCbor();
|
||||
QByteArray data;
|
||||
{
|
||||
QBuffer buf(&data);
|
||||
QDataStream ds(&buf);
|
||||
QVERIFY(buf.open(QIODevice::WriteOnly));
|
||||
desc.serialize(&ds);
|
||||
}
|
||||
QVERIFY(!data.isEmpty());
|
||||
|
||||
QShaderDescription desc2 = QShaderDescription::fromCbor(data);
|
||||
QVERIFY(!desc2.isValid());
|
||||
{
|
||||
QBuffer buf(&data);
|
||||
QDataStream ds(&buf);
|
||||
QVERIFY(buf.open(QIODevice::ReadOnly));
|
||||
QShaderDescription desc2 = QShaderDescription::deserialize(&ds);
|
||||
QVERIFY(!desc2.isValid());
|
||||
}
|
||||
}
|
||||
|
||||
// a QShaderDescription with inputs, outputs, uniform block and combined image sampler
|
||||
{
|
||||
QShader s = getShader(QLatin1String(":/data/texture_all_v3.frag.qsb"));
|
||||
QShader s = getShader(QLatin1String(":/data/texture_all_v4.frag.qsb"));
|
||||
QVERIFY(s.isValid());
|
||||
const QShaderDescription desc = s.description();
|
||||
QVERIFY(desc.isValid());
|
||||
|
||||
const QByteArray data = desc.toCbor();
|
||||
QByteArray data;
|
||||
{
|
||||
QBuffer buf(&data);
|
||||
QDataStream ds(&buf);
|
||||
QVERIFY(buf.open(QIODevice::WriteOnly));
|
||||
desc.serialize(&ds);
|
||||
}
|
||||
QVERIFY(!data.isEmpty());
|
||||
|
||||
QShaderDescription desc2;
|
||||
@ -375,14 +394,22 @@ void tst_QShader::serializeShaderDesc()
|
||||
QVERIFY(!(desc == desc2));
|
||||
QVERIFY(desc != desc2);
|
||||
|
||||
desc2 = QShaderDescription::fromCbor(data);
|
||||
QVERIFY(desc2.isValid());
|
||||
QCOMPARE(desc, desc2);
|
||||
{
|
||||
QBuffer buf(&data);
|
||||
QDataStream ds(&buf);
|
||||
QVERIFY(buf.open(QIODevice::ReadOnly));
|
||||
QShaderDescription desc2 = QShaderDescription::deserialize(&ds);
|
||||
QVERIFY(desc2.isValid());
|
||||
QCOMPARE(desc, desc2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QShader::comparison()
|
||||
{
|
||||
// exercise QShader and QShaderDescription comparisons
|
||||
{
|
||||
QShader s1 = getShader(QLatin1String(":/data/texture_all_v3.frag.qsb"));
|
||||
QShader s1 = getShader(QLatin1String(":/data/texture_all_v4.frag.qsb"));
|
||||
QVERIFY(s1.isValid());
|
||||
QShader s2 = getShader(QLatin1String(":/data/color_all_v1.vert.qsb"));
|
||||
QVERIFY(s2.isValid());
|
||||
@ -393,6 +420,93 @@ void tst_QShader::serializeShaderDesc()
|
||||
QVERIFY(s1 != s2);
|
||||
QVERIFY(s1.description() != s2.description());
|
||||
}
|
||||
|
||||
{
|
||||
QShader s1 = getShader(QLatin1String(":/data/texture_all_v4.frag.qsb"));
|
||||
QVERIFY(s1.isValid());
|
||||
QShader s2 = getShader(QLatin1String(":/data/texture_all_v4.frag.qsb"));
|
||||
QVERIFY(s2.isValid());
|
||||
|
||||
QVERIFY(s1.description().isValid());
|
||||
QVERIFY(s2.description().isValid());
|
||||
|
||||
QVERIFY(s1 == s2);
|
||||
QVERIFY(s1.description() == s2.description());
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QShader::loadV4()
|
||||
{
|
||||
// qsb version 4: QShaderDescription is serialized via QDataStream. Ensure the deserialized data is as expected.
|
||||
QShader s = getShader(QLatin1String(":/data/texture_all_v4.frag.qsb"));
|
||||
QVERIFY(s.isValid());
|
||||
QCOMPARE(QShaderPrivate::get(&s)->qsbVersion, 4);
|
||||
|
||||
const QVector<QShaderKey> availableShaders = s.availableShaders();
|
||||
QCOMPARE(availableShaders.count(), 7);
|
||||
QVERIFY(availableShaders.contains(QShaderKey(QShader::SpirvShader, QShaderVersion(100))));
|
||||
QVERIFY(availableShaders.contains(QShaderKey(QShader::MslShader, QShaderVersion(12))));
|
||||
QVERIFY(availableShaders.contains(QShaderKey(QShader::HlslShader, QShaderVersion(50))));
|
||||
QVERIFY(availableShaders.contains(QShaderKey(QShader::GlslShader, QShaderVersion(100, QShaderVersion::GlslEs))));
|
||||
QVERIFY(availableShaders.contains(QShaderKey(QShader::GlslShader, QShaderVersion(120))));
|
||||
QVERIFY(availableShaders.contains(QShaderKey(QShader::GlslShader, QShaderVersion(150))));
|
||||
QVERIFY(availableShaders.contains(QShaderKey(QShader::GlslShader, QShaderVersion(330))));
|
||||
|
||||
const QShaderDescription desc = s.description();
|
||||
QVERIFY(desc.isValid());
|
||||
QCOMPARE(desc.inputVariables().count(), 1);
|
||||
for (const QShaderDescription::InOutVariable &v : desc.inputVariables()) {
|
||||
switch (v.location) {
|
||||
case 0:
|
||||
QCOMPARE(v.name, QLatin1String("qt_TexCoord"));
|
||||
QCOMPARE(v.type, QShaderDescription::Vec2);
|
||||
break;
|
||||
default:
|
||||
QVERIFY(false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
QCOMPARE(desc.outputVariables().count(), 1);
|
||||
for (const QShaderDescription::InOutVariable &v : desc.outputVariables()) {
|
||||
switch (v.location) {
|
||||
case 0:
|
||||
QCOMPARE(v.name, QLatin1String("fragColor"));
|
||||
QCOMPARE(v.type, QShaderDescription::Vec4);
|
||||
break;
|
||||
default:
|
||||
QVERIFY(false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
QCOMPARE(desc.uniformBlocks().count(), 1);
|
||||
const QShaderDescription::UniformBlock blk = desc.uniformBlocks().first();
|
||||
QCOMPARE(blk.blockName, QLatin1String("buf"));
|
||||
QCOMPARE(blk.structName, QLatin1String("ubuf"));
|
||||
QCOMPARE(blk.size, 68);
|
||||
QCOMPARE(blk.binding, 0);
|
||||
QCOMPARE(blk.descriptorSet, 0);
|
||||
QCOMPARE(blk.members.count(), 2);
|
||||
for (int i = 0; i < blk.members.count(); ++i) {
|
||||
const QShaderDescription::BlockVariable v = blk.members[i];
|
||||
switch (i) {
|
||||
case 0:
|
||||
QCOMPARE(v.offset, 0);
|
||||
QCOMPARE(v.size, 64);
|
||||
QCOMPARE(v.name, QLatin1String("qt_Matrix"));
|
||||
QCOMPARE(v.type, QShaderDescription::Mat4);
|
||||
QCOMPARE(v.matrixStride, 16);
|
||||
break;
|
||||
case 1:
|
||||
QCOMPARE(v.offset, 64);
|
||||
QCOMPARE(v.size, 4);
|
||||
QCOMPARE(v.name, QLatin1String("opacity"));
|
||||
QCOMPARE(v.type, QShaderDescription::Float);
|
||||
break;
|
||||
default:
|
||||
QVERIFY(false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#include <tst_qshader.moc>
|
||||
|
Loading…
Reference in New Issue
Block a user