mirror of https://github.com/qt/qt3d.git
Shader: record standard uniform at loading time
Avoids having to check for each uniform (for each frame, each geometry) whether it is a standard uniform or a user defined one. Change-Id: I76cff7869aacc1343a9acf991f8035b8118581ed Reviewed-by: Mike Krus <mike.krus@kdab.com>
This commit is contained in:
parent
9a417bcb92
commit
3019497559
|
|
@ -50,10 +50,19 @@ namespace Render {
|
|||
|
||||
namespace {
|
||||
|
||||
struct StringToIntCache
|
||||
{
|
||||
QReadWriteLock lock;
|
||||
QHash<QString, int> map = QHash<QString, int>();
|
||||
QVector<QString> reverseMap = QVector<QString>();
|
||||
|
||||
static StringToIntCache& instance()
|
||||
{
|
||||
static StringToIntCache c;
|
||||
return c;
|
||||
}
|
||||
};
|
||||
|
||||
} // anonymous
|
||||
|
||||
int StringToInt::lookupId(QLatin1String str)
|
||||
|
|
@ -64,20 +73,21 @@ int StringToInt::lookupId(QLatin1String str)
|
|||
|
||||
int StringToInt::lookupId(const QString &str)
|
||||
{
|
||||
auto& cache = StringToIntCache::instance();
|
||||
int idx;
|
||||
{
|
||||
QReadLocker readLocker(&lock);
|
||||
idx = map.value(str, -1);
|
||||
QReadLocker readLocker(&cache.lock);
|
||||
idx = cache.map.value(str, -1);
|
||||
}
|
||||
|
||||
if (Q_UNLIKELY(idx < 0)) {
|
||||
QWriteLocker writeLocker(&lock);
|
||||
idx = map.value(str, -1);
|
||||
QWriteLocker writeLocker(&cache.lock);
|
||||
idx = cache.map.value(str, -1);
|
||||
if (idx < 0) {
|
||||
idx = reverseMap.size();
|
||||
Q_ASSERT(map.size() == reverseMap.size());
|
||||
map.insert(str, idx);
|
||||
reverseMap.append(str);
|
||||
idx = cache.reverseMap.size();
|
||||
Q_ASSERT(cache.map.size() == cache.reverseMap.size());
|
||||
cache.map.insert(str, idx);
|
||||
cache.reverseMap.append(str);
|
||||
}
|
||||
}
|
||||
return idx;
|
||||
|
|
@ -85,9 +95,10 @@ int StringToInt::lookupId(const QString &str)
|
|||
|
||||
QString StringToInt::lookupString(int idx)
|
||||
{
|
||||
QReadLocker readLocker(&lock);
|
||||
if (Q_LIKELY(reverseMap.size() > idx))
|
||||
return reverseMap.at(idx);
|
||||
auto& cache = StringToIntCache::instance();
|
||||
QReadLocker readLocker(&cache.lock);
|
||||
if (Q_LIKELY(cache.reverseMap.size() > idx))
|
||||
return cache.reverseMap.at(idx);
|
||||
|
||||
return QString();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -57,6 +57,29 @@ using namespace Qt3DCore;
|
|||
|
||||
namespace Qt3DRender {
|
||||
namespace Render {
|
||||
const int Shader::modelMatrixNameId = StringToInt::lookupId(QLatin1String("modelMatrix"));
|
||||
const int Shader::viewMatrixNameId = StringToInt::lookupId(QLatin1String("viewMatrix"));
|
||||
const int Shader::projectionMatrixNameId = StringToInt::lookupId(QLatin1String("projectionMatrix"));
|
||||
const int Shader::modelViewMatrixNameId = StringToInt::lookupId(QLatin1String("modelView"));
|
||||
const int Shader::viewProjectionMatrixNameId = StringToInt::lookupId(QLatin1String("viewProjectionMatrix"));
|
||||
const int Shader::modelViewProjectionNameId = StringToInt::lookupId(QLatin1String("modelViewProjection"));
|
||||
const int Shader::mvpNameId = StringToInt::lookupId(QLatin1String("mvp"));
|
||||
const int Shader::inverseModelMatrixNameId = StringToInt::lookupId(QLatin1String("inverseModelMatrix"));
|
||||
const int Shader::inverseViewMatrixNameId = StringToInt::lookupId(QLatin1String("inverseViewMatrix"));
|
||||
const int Shader::inverseProjectionMatrixNameId = StringToInt::lookupId(QLatin1String("inverseProjectionMatrix"));
|
||||
const int Shader::inverseModelViewNameId = StringToInt::lookupId(QLatin1String("inverseModelView"));
|
||||
const int Shader::inverseViewProjectionMatrixNameId = StringToInt::lookupId(QLatin1String("inverseViewProjectionMatrix"));
|
||||
const int Shader::inverseModelViewProjectionNameId = StringToInt::lookupId(QLatin1String("inverseModelViewProjection"));
|
||||
const int Shader::modelNormalMatrixNameId = StringToInt::lookupId(QLatin1String("modelNormalMatrix"));
|
||||
const int Shader::modelViewNormalNameId = StringToInt::lookupId(QLatin1String("modelViewNormal"));
|
||||
const int Shader::viewportMatrixNameId = StringToInt::lookupId(QLatin1String("viewportMatrix"));
|
||||
const int Shader::inverseViewportMatrixNameId = StringToInt::lookupId(QLatin1String("inverseViewportMatrix"));
|
||||
const int Shader::aspectRatioNameId = StringToInt::lookupId(QLatin1String("aspectRatio"));
|
||||
const int Shader::exposureNameId = StringToInt::lookupId(QLatin1String("exposure"));
|
||||
const int Shader::gammaNameId = StringToInt::lookupId(QLatin1String("gamma"));
|
||||
const int Shader::timeNameId = StringToInt::lookupId(QLatin1String("time"));
|
||||
const int Shader::eyePositionNameId = StringToInt::lookupId(QLatin1String("eyePosition"));
|
||||
const int Shader::skinningPaletteNameId = StringToInt::lookupId(QLatin1String("skinningPalette[0]"));
|
||||
|
||||
Shader::Shader()
|
||||
: BackendNode(ReadWrite)
|
||||
|
|
@ -308,13 +331,47 @@ void Shader::initializeUniforms(const QVector<ShaderUniform> &uniformsDescriptio
|
|||
{
|
||||
m_uniforms = uniformsDescription;
|
||||
m_uniformsNames.resize(uniformsDescription.size());
|
||||
m_uniformsNamesIds.resize(uniformsDescription.size());
|
||||
m_uniformsNamesIds.reserve(uniformsDescription.size());
|
||||
m_standardUniformNamesIds.reserve(5);
|
||||
QHash<QString, ShaderUniform> activeUniformsInDefaultBlock;
|
||||
|
||||
static const QVector<int> standardUniformNameIds = {
|
||||
modelMatrixNameId,
|
||||
viewMatrixNameId,
|
||||
projectionMatrixNameId,
|
||||
modelViewMatrixNameId,
|
||||
viewProjectionMatrixNameId,
|
||||
modelViewProjectionNameId,
|
||||
mvpNameId,
|
||||
inverseModelMatrixNameId,
|
||||
inverseViewMatrixNameId,
|
||||
inverseProjectionMatrixNameId,
|
||||
inverseModelViewNameId,
|
||||
inverseViewProjectionMatrixNameId,
|
||||
inverseModelViewProjectionNameId,
|
||||
modelNormalMatrixNameId,
|
||||
modelViewNormalNameId,
|
||||
viewportMatrixNameId,
|
||||
inverseViewportMatrixNameId,
|
||||
aspectRatioNameId,
|
||||
exposureNameId,
|
||||
gammaNameId,
|
||||
timeNameId,
|
||||
eyePositionNameId,
|
||||
skinningPaletteNameId,
|
||||
};
|
||||
|
||||
for (int i = 0, m = uniformsDescription.size(); i < m; i++) {
|
||||
m_uniformsNames[i] = m_uniforms[i].m_name;
|
||||
m_uniforms[i].m_nameId = StringToInt::lookupId(m_uniformsNames[i]);
|
||||
m_uniformsNamesIds[i] = m_uniforms[i].m_nameId;
|
||||
const int nameId = StringToInt::lookupId(m_uniformsNames[i]);
|
||||
m_uniforms[i].m_nameId = nameId;
|
||||
|
||||
// Is the uniform a Qt3D "Standard" uniform or a user defined one?
|
||||
if (standardUniformNameIds.contains(nameId))
|
||||
m_standardUniformNamesIds.push_back(nameId);
|
||||
else
|
||||
m_uniformsNamesIds.push_back(nameId);
|
||||
|
||||
if (uniformsDescription[i].m_blockIndex == -1) { // Uniform is in default block
|
||||
qCDebug(Shaders) << "Active Uniform in Default Block " << uniformsDescription[i].m_name << uniformsDescription[i].m_blockIndex;
|
||||
activeUniformsInDefaultBlock.insert(uniformsDescription[i].m_name, uniformsDescription[i]);
|
||||
|
|
@ -394,6 +451,7 @@ void Shader::initializeFromReference(const Shader &other)
|
|||
{
|
||||
Q_ASSERT(m_dna == other.m_dna);
|
||||
m_uniformsNamesIds = other.m_uniformsNamesIds;
|
||||
m_standardUniformNamesIds = other.m_standardUniformNamesIds;
|
||||
m_uniformsNames = other.m_uniformsNames;
|
||||
m_uniforms = other.m_uniforms;
|
||||
m_attributesNames = other.m_attributesNames;
|
||||
|
|
|
|||
|
|
@ -75,6 +75,30 @@ typedef uint ProgramDNA;
|
|||
class Q_AUTOTEST_EXPORT Shader : public BackendNode
|
||||
{
|
||||
public:
|
||||
static const int modelMatrixNameId;
|
||||
static const int viewMatrixNameId;
|
||||
static const int projectionMatrixNameId;
|
||||
static const int modelViewMatrixNameId;
|
||||
static const int viewProjectionMatrixNameId;
|
||||
static const int modelViewProjectionNameId;
|
||||
static const int mvpNameId;
|
||||
static const int inverseModelMatrixNameId;
|
||||
static const int inverseViewMatrixNameId;
|
||||
static const int inverseProjectionMatrixNameId;
|
||||
static const int inverseModelViewNameId;
|
||||
static const int inverseViewProjectionMatrixNameId;
|
||||
static const int inverseModelViewProjectionNameId;
|
||||
static const int modelNormalMatrixNameId;
|
||||
static const int modelViewNormalNameId;
|
||||
static const int viewportMatrixNameId;
|
||||
static const int inverseViewportMatrixNameId;
|
||||
static const int aspectRatioNameId;
|
||||
static const int exposureNameId;
|
||||
static const int gammaNameId;
|
||||
static const int timeNameId;
|
||||
static const int eyePositionNameId;
|
||||
static const int skinningPaletteNameId;
|
||||
|
||||
Shader();
|
||||
~Shader();
|
||||
|
||||
|
|
@ -88,6 +112,7 @@ public:
|
|||
const QHash<QString, int> fragOutputs() const;
|
||||
|
||||
inline QVector<int> uniformsNamesIds() const { return m_uniformsNamesIds; }
|
||||
inline QVector<int> standardUniformNameIds() const { return m_standardUniformNamesIds; }
|
||||
inline QVector<int> uniformBlockNamesIds() const { return m_uniformBlockNamesIds; }
|
||||
inline QVector<int> storageBlockNamesIds() const { return m_shaderStorageBlockNamesIds; }
|
||||
inline QVector<int> attributeNamesIds() const { return m_attributeNamesIds; }
|
||||
|
|
@ -128,6 +153,7 @@ public:
|
|||
private:
|
||||
QVector<QString> m_uniformsNames;
|
||||
QVector<int> m_uniformsNamesIds;
|
||||
QVector<int> m_standardUniformNamesIds;
|
||||
QVector<ShaderUniform> m_uniforms;
|
||||
|
||||
QVector<QString> m_attributesNames;
|
||||
|
|
|
|||
|
|
@ -119,29 +119,29 @@ RenderView::StandardUniformsNameToTypeHash RenderView::initializeStandardUniform
|
|||
{
|
||||
RenderView::StandardUniformsNameToTypeHash setters;
|
||||
|
||||
setters.insert(StringToInt::lookupId(QLatin1String("modelMatrix")), ModelMatrix);
|
||||
setters.insert(StringToInt::lookupId(QLatin1String("viewMatrix")), ViewMatrix);
|
||||
setters.insert(StringToInt::lookupId(QLatin1String("projectionMatrix")), ProjectionMatrix);
|
||||
setters.insert(StringToInt::lookupId(QLatin1String("modelView")), ModelViewMatrix);
|
||||
setters.insert(StringToInt::lookupId(QLatin1String("viewProjectionMatrix")), ViewProjectionMatrix);
|
||||
setters.insert(StringToInt::lookupId(QLatin1String("modelViewProjection")), ModelViewProjectionMatrix);
|
||||
setters.insert(StringToInt::lookupId(QLatin1String("mvp")), ModelViewProjectionMatrix);
|
||||
setters.insert(StringToInt::lookupId(QLatin1String("inverseModelMatrix")), InverseModelMatrix);
|
||||
setters.insert(StringToInt::lookupId(QLatin1String("inverseViewMatrix")), InverseViewMatrix);
|
||||
setters.insert(StringToInt::lookupId(QLatin1String("inverseProjectionMatrix")), InverseProjectionMatrix);
|
||||
setters.insert(StringToInt::lookupId(QLatin1String("inverseModelView")), InverseModelViewMatrix);
|
||||
setters.insert(StringToInt::lookupId(QLatin1String("inverseViewProjectionMatrix")), InverseViewProjectionMatrix);
|
||||
setters.insert(StringToInt::lookupId(QLatin1String("inverseModelViewProjection")), InverseModelViewProjectionMatrix);
|
||||
setters.insert(StringToInt::lookupId(QLatin1String("modelNormalMatrix")), ModelNormalMatrix);
|
||||
setters.insert(StringToInt::lookupId(QLatin1String("modelViewNormal")), ModelViewNormalMatrix);
|
||||
setters.insert(StringToInt::lookupId(QLatin1String("viewportMatrix")), ViewportMatrix);
|
||||
setters.insert(StringToInt::lookupId(QLatin1String("inverseViewportMatrix")), InverseViewportMatrix);
|
||||
setters.insert(StringToInt::lookupId(QLatin1String("aspectRatio")), AspectRatio);
|
||||
setters.insert(StringToInt::lookupId(QLatin1String("exposure")), Exposure);
|
||||
setters.insert(StringToInt::lookupId(QLatin1String("gamma")), Gamma);
|
||||
setters.insert(StringToInt::lookupId(QLatin1String("time")), Time);
|
||||
setters.insert(StringToInt::lookupId(QLatin1String("eyePosition")), EyePosition);
|
||||
setters.insert(StringToInt::lookupId(QLatin1String("skinningPalette[0]")), SkinningPalette);
|
||||
setters.insert(Shader::modelMatrixNameId, ModelMatrix);
|
||||
setters.insert(Shader::viewMatrixNameId, ViewMatrix);
|
||||
setters.insert(Shader::projectionMatrixNameId, ProjectionMatrix);
|
||||
setters.insert(Shader::modelViewMatrixNameId, ModelViewMatrix);
|
||||
setters.insert(Shader::viewProjectionMatrixNameId, ViewProjectionMatrix);
|
||||
setters.insert(Shader::modelViewProjectionNameId, ModelViewProjectionMatrix);
|
||||
setters.insert(Shader::mvpNameId, ModelViewProjectionMatrix);
|
||||
setters.insert(Shader::inverseModelMatrixNameId, InverseModelMatrix);
|
||||
setters.insert(Shader::inverseViewMatrixNameId, InverseViewMatrix);
|
||||
setters.insert(Shader::inverseProjectionMatrixNameId, InverseProjectionMatrix);
|
||||
setters.insert(Shader::inverseModelViewNameId, InverseModelViewMatrix);
|
||||
setters.insert(Shader::inverseViewProjectionMatrixNameId, InverseViewProjectionMatrix);
|
||||
setters.insert(Shader::inverseModelViewProjectionNameId, InverseModelViewProjectionMatrix);
|
||||
setters.insert(Shader::modelNormalMatrixNameId, ModelNormalMatrix);
|
||||
setters.insert(Shader::modelViewNormalNameId, ModelViewNormalMatrix);
|
||||
setters.insert(Shader::viewportMatrixNameId, ViewportMatrix);
|
||||
setters.insert(Shader::inverseViewportMatrixNameId, InverseViewportMatrix);
|
||||
setters.insert(Shader::aspectRatioNameId, AspectRatio);
|
||||
setters.insert(Shader::exposureNameId, Exposure);
|
||||
setters.insert(Shader::gammaNameId, Gamma);
|
||||
setters.insert(Shader::timeNameId, Time);
|
||||
setters.insert(Shader::eyePositionNameId, EyePosition);
|
||||
setters.insert(Shader::skinningPaletteNameId, SkinningPalette);
|
||||
|
||||
return setters;
|
||||
}
|
||||
|
|
@ -1023,6 +1023,7 @@ void RenderView::setShaderAndUniforms(RenderCommand *command,
|
|||
// If a parameter is defined and not found in the bindings it is assumed to be a binding of Uniform type with the glsl name
|
||||
// equals to the parameter name
|
||||
const QVector<int> uniformNamesIds = shader->uniformsNamesIds();
|
||||
const QVector<int> standardUniformNamesIds = shader->standardUniformNameIds();
|
||||
const QVector<int> uniformBlockNamesIds = shader->uniformBlockNamesIds();
|
||||
const QVector<int> shaderStorageBlockNamesIds = shader->storageBlockNamesIds();
|
||||
const QVector<int> attributeNamesIds = shader->attributeNamesIds();
|
||||
|
|
@ -1042,16 +1043,15 @@ void RenderView::setShaderAndUniforms(RenderCommand *command,
|
|||
shader->setFragOutputs(fragOutputs);
|
||||
}
|
||||
|
||||
if (!uniformNamesIds.isEmpty() || !attributeNamesIds.isEmpty() ||
|
||||
if (!uniformNamesIds.isEmpty() || !standardUniformNamesIds.isEmpty() ||
|
||||
!attributeNamesIds.isEmpty() ||
|
||||
!shaderStorageBlockNamesIds.isEmpty() || !attributeNamesIds.isEmpty()) {
|
||||
|
||||
// Set default standard uniforms without bindings
|
||||
const Matrix4x4 worldTransform = *(entity->worldTransform());
|
||||
|
||||
for (const int uniformNameId : uniformNamesIds) {
|
||||
if (ms_standardUniformSetters.contains(uniformNameId))
|
||||
for (const int uniformNameId : standardUniformNamesIds)
|
||||
setStandardUniformValue(command->m_parameterPack, uniformNameId, uniformNameId, entity, worldTransform);
|
||||
}
|
||||
|
||||
// Set default attributes
|
||||
command->m_activeAttributes = attributeNamesIds;
|
||||
|
|
|
|||
|
|
@ -168,7 +168,7 @@ private Q_SLOTS:
|
|||
engine.setRootEntity(entity);
|
||||
|
||||
QEventLoop eventLoop;
|
||||
QTimer::singleShot(100, &eventLoop, SLOT(quit()));
|
||||
QTimer::singleShot(1000, &eventLoop, SLOT(quit()));
|
||||
eventLoop.exec();
|
||||
|
||||
// THEN
|
||||
|
|
|
|||
Loading…
Reference in New Issue