diff --git a/libraries/gpu-gl-common/src/gpu/gl/GLBackend.h b/libraries/gpu-gl-common/src/gpu/gl/GLBackend.h index ffd0466b79..2532de31b0 100644 --- a/libraries/gpu-gl-common/src/gpu/gl/GLBackend.h +++ b/libraries/gpu-gl-common/src/gpu/gl/GLBackend.h @@ -584,6 +584,7 @@ protected: friend class GLState; friend class GLTexture; friend class GLShader; + friend class GLPipeline; }; }} // namespace gpu::gl diff --git a/libraries/gpu-gl-common/src/gpu/gl/GLBackendShader.cpp b/libraries/gpu-gl-common/src/gpu/gl/GLBackendShader.cpp index f737842ec0..10b573276e 100644 --- a/libraries/gpu-gl-common/src/gpu/gl/GLBackendShader.cpp +++ b/libraries/gpu-gl-common/src/gpu/gl/GLBackendShader.cpp @@ -202,7 +202,7 @@ GLint GLBackend::getRealUniformLocation(GLint location) const { void GLBackend::postLinkProgram(ShaderObject& shaderObject, const Shader& program) const { const auto& glprogram = shaderObject.glprogram; - const auto& expectedUniforms = program.getReflection().uniforms; + auto expectedUniforms = program.getReflection(getShaderDialect(), getShaderVariant()).uniforms; auto& uniformRemap = shaderObject.uniformRemap; // initialize all the uniforms with an invalid location diff --git a/libraries/gpu-gl-common/src/gpu/gl/GLPipeline.cpp b/libraries/gpu-gl-common/src/gpu/gl/GLPipeline.cpp index e00dc9fc25..52e10eb417 100644 --- a/libraries/gpu-gl-common/src/gpu/gl/GLPipeline.cpp +++ b/libraries/gpu-gl-common/src/gpu/gl/GLPipeline.cpp @@ -52,7 +52,8 @@ GLPipeline* GLPipeline::sync(GLBackend& backend, const Pipeline& pipeline) { // Special case for view correction matrices, any pipeline that declares the correction buffer // uniform will automatically have it provided without any client code necessary. // Required for stable lighting in the HMD. - object->_cameraCorrection = shader->getReflection().validUniformBuffer(gpu::slot::buffer::CameraCorrection); + auto reflection = shader->getReflection(backend.getShaderDialect(), backend.getShaderVariant()); + object->_cameraCorrection = reflection.validUniformBuffer(gpu::slot::buffer::CameraCorrection); object->_program = programObject; object->_state = stateObject; diff --git a/libraries/gpu-gl/src/gpu/gl41/GL41BackendShader.cpp b/libraries/gpu-gl/src/gpu/gl41/GL41BackendShader.cpp index f33dd91d03..1b21be2e73 100644 --- a/libraries/gpu-gl/src/gpu/gl41/GL41BackendShader.cpp +++ b/libraries/gpu-gl/src/gpu/gl41/GL41BackendShader.cpp @@ -15,7 +15,7 @@ using namespace gpu::gl41; void GL41Backend::postLinkProgram(ShaderObject& programObject, const Shader& program) const { Parent::postLinkProgram(programObject, program); const auto& glprogram = programObject.glprogram; - const auto& reflection = program.getReflection(); + auto reflection = program.getReflection(getShaderDialect(), getShaderVariant()); // For the UBOs, use glUniformBlockBinding to fixup the locations based on the reflection { const auto& expectedUbos = reflection.uniformBuffers; @@ -43,25 +43,26 @@ void GL41Backend::postLinkProgram(ShaderObject& programObject, const Shader& pro } // For the resource buffers, do the same as for the textures, since in GL 4.1 that's how they're implemented + static const std::string TRANSFORM_OBJECT_BUFFER = "transformObjectBuffer"; { const auto& expectedResourceBuffers = reflection.resourceBuffers; const auto names = Shader::Reflection::getNames(expectedResourceBuffers); const auto resourceBufferUniforms = ::gl::Uniform::loadByName(glprogram, names); for (const auto& resourceBuffer : resourceBufferUniforms) { + + // Special case for the transformObjectBuffer, which is filtered out of the reflection data at shader load time + if (resourceBuffer.name == TRANSFORM_OBJECT_BUFFER) { + glProgramUniform1i(glprogram, resourceBuffer.binding, ::gpu::slot::texture::ObjectTransforms); + continue; + } const auto& targetBinding = expectedResourceBuffers.at(resourceBuffer.name); + if (resourceBuffer.name == std::string("polylineVerticesBuffer")) { + qDebug() << "Setting texture unit for " << resourceBuffer.name.c_str() << " to " << targetBinding; + } glProgramUniform1i(glprogram, resourceBuffer.binding, targetBinding); } } - // Special case for the transformObjectBuffer, which is filtered out of the reflection data at shader load time - // - { - static const std::string TRANSFORM_OBJECT_BUFFER = "transformObjectBuffer"; - const auto uniform = ::gl::Uniform::loadByName(glprogram, TRANSFORM_OBJECT_BUFFER); - if (-1 != uniform.binding) { - glProgramUniform1i(glprogram, uniform.binding, ::gpu::slot::texture::ObjectTransforms); - } - } } diff --git a/libraries/gpu/src/gpu/Shader.cpp b/libraries/gpu/src/gpu/Shader.cpp index d4236ac66c..6fef768a08 100755 --- a/libraries/gpu/src/gpu/Shader.cpp +++ b/libraries/gpu/src/gpu/Shader.cpp @@ -43,17 +43,25 @@ Shader::Shader(Type type, const Pointer& vertex, const Pointer& geometry, const shaders[VERTEX] = vertex; shaders[PIXEL] = pixel; } +} - auto& reflection = const_cast(getReflection()); - for (const auto& subShader : _shaders) { - reflection.merge(subShader->getReflection()); - } - if (_shaders[VERTEX]) { - reflection.inputs = _shaders[VERTEX]->getReflection().inputs; - } - if (_shaders[PIXEL]) { - reflection.outputs = _shaders[PIXEL]->getReflection().outputs; +Shader::Reflection Shader::getReflection(shader::Dialect dialect, shader::Variant variant) const { + if (_type == Shader::Type::PROGRAM) { + Reflection reflection; + for (const auto& subShader : _shaders) { + reflection.merge(subShader->getReflection(dialect, variant)); + } + if (_shaders[VERTEX]) { + reflection.inputs = _shaders[VERTEX]->getReflection(dialect, variant).inputs; + } + if (_shaders[PIXEL]) { + reflection.outputs = _shaders[PIXEL]->getReflection(dialect, variant).outputs; + } + + return reflection; } + + return _source.getReflection(dialect, variant); } Shader::~Shader() diff --git a/libraries/gpu/src/gpu/Shader.h b/libraries/gpu/src/gpu/Shader.h index 987e632025..6461437971 100755 --- a/libraries/gpu/src/gpu/Shader.h +++ b/libraries/gpu/src/gpu/Shader.h @@ -91,7 +91,7 @@ public: const Shaders& getShaders() const { return _shaders; } - const Reflection& getReflection() const { return _source.reflection; } + Reflection getReflection(shader::Dialect dialect, shader::Variant variant) const; // Compilation Handler can be passed while compiling a shader (in the makeProgram call) to be able to give the hand to // the caller thread if the compilation fails and to provide a different version of the source for it diff --git a/libraries/procedural/src/procedural/Procedural.cpp b/libraries/procedural/src/procedural/Procedural.cpp index dbdf9cc7d1..7d0b7c05ea 100644 --- a/libraries/procedural/src/procedural/Procedural.cpp +++ b/libraries/procedural/src/procedural/Procedural.cpp @@ -268,7 +268,7 @@ void Procedural::prepare(gpu::Batch& batch, int customSlot = procedural::slot::uniform::Custom; for (const auto& key : _data.uniforms.keys()) { std::string uniformName = key.toLocal8Bit().data(); - fragmentSource.reflection.uniforms[uniformName] = customSlot; + // fragmentSource.reflection.uniforms[uniformName] = customSlot; ++customSlot; } diff --git a/libraries/render/src/render/ShapePipeline.cpp b/libraries/render/src/render/ShapePipeline.cpp index 12947f5291..9942f1a46c 100644 --- a/libraries/render/src/render/ShapePipeline.cpp +++ b/libraries/render/src/render/ShapePipeline.cpp @@ -86,7 +86,7 @@ void ShapePlumber::addPipeline(const Key& key, const gpu::ShaderPointer& program void ShapePlumber::addPipeline(const Filter& filter, const gpu::ShaderPointer& program, const gpu::StatePointer& state, BatchSetter batchSetter, ItemSetter itemSetter) { ShapeKey key{ filter._flags }; - const auto& reflection = program->getReflection(); + auto reflection = program->getReflection(shader::Dialect::glsl450, shader::Variant::Mono); auto locations = std::make_shared(); locations->albedoTextureUnit = reflection.validTexture(graphics::slot::texture::MaterialAlbedo); locations->roughnessTextureUnit = reflection.validTexture(graphics::slot::texture::MaterialRoughness); diff --git a/libraries/shaders/src/shaders/Shaders.cpp b/libraries/shaders/src/shaders/Shaders.cpp index a074c2f0c9..02a3c9587e 100644 --- a/libraries/shaders/src/shaders/Shaders.cpp +++ b/libraries/shaders/src/shaders/Shaders.cpp @@ -131,7 +131,6 @@ Source::Pointer Source::loadSource(uint32_t shaderId) { for (const auto& dialect : dialects) { result->dialectSources[dialect] = loadDialectSource(dialect, shaderId); } - result->reflection = result->dialectSources[DEFAULT_DIALECT].variantSources[Variant::Mono].reflection; return result; } @@ -140,7 +139,6 @@ Source& Source::operator=(const Source& other) { name = other.name; dialectSources = other.dialectSources; replacements = other.replacements; - reflection = other.reflection; return *this; } diff --git a/libraries/shaders/src/shaders/Shaders.h b/libraries/shaders/src/shaders/Shaders.h index 134b2bdcf8..7eb4241de4 100644 --- a/libraries/shaders/src/shaders/Shaders.h +++ b/libraries/shaders/src/shaders/Shaders.h @@ -140,9 +140,6 @@ struct Source { // The name of the shader file, with extension, i.e. DrawColor.frag std::string name; - // Generic reflection, copied from the 450 dialect / mono variant - Reflection reflection; - // Map of platforms to their specific shaders std::unordered_map dialectSources;