diff --git a/NEW_RELEASE_NOTES.md b/NEW_RELEASE_NOTES.md index ec967554ed3..feef80e08ba 100644 --- a/NEW_RELEASE_NOTES.md +++ b/NEW_RELEASE_NOTES.md @@ -10,3 +10,4 @@ appropriate header in [RELEASE_NOTES.md](./RELEASE_NOTES.md). - engine: Support up to 4 side-by-side stereoscopic eyes, configurable at Engine creation time. See `Engine::Config::stereoscopicEyeCount`. [⚠️ **Recompile Materials**] +- engine: Fix critical GLES 2.0 bugs diff --git a/filament/backend/src/opengl/OpenGLDriver.cpp b/filament/backend/src/opengl/OpenGLDriver.cpp index 9e9f1c8ace9..cfe4cacde61 100644 --- a/filament/backend/src/opengl/OpenGLDriver.cpp +++ b/filament/backend/src/opengl/OpenGLDriver.cpp @@ -172,7 +172,7 @@ OpenGLDriver::OpenGLDriver(OpenGLPlatform* platform, const Platform::DriverConfi mShaderCompilerService(*this), mHandleAllocator("Handles", driverConfig.handleArenaSize), mSamplerMap(32) { - + std::fill(mSamplerBindings.begin(), mSamplerBindings.end(), nullptr); // set a reasonable default value for our stream array @@ -268,9 +268,9 @@ void OpenGLDriver::useProgram(OpenGLProgram* p) noexcept { if (UTILS_UNLIKELY(mContext.isES2())) { for (uint32_t i = 0; i < Program::UNIFORM_BINDING_COUNT; i++) { - auto [buffer, age] = mUniformBindings[i]; + auto [id, buffer, age] = mUniformBindings[i]; if (buffer) { - p->updateUniforms(i, buffer, age); + p->updateUniforms(i, id, buffer, age); } } // Set the output colorspace for this program (linear or rec709). This in only relevant @@ -479,6 +479,7 @@ void OpenGLDriver::createBufferObjectR(Handle boh, GLBufferObject* bo = construct(boh, byteCount, bindingType, usage); if (UTILS_UNLIKELY(bindingType == BufferObjectBinding::UNIFORM && gl.isES2())) { + bo->gl.id = ++mLastAssignedEmulatedUboId; bo->gl.buffer = malloc(byteCount); memset(bo->gl.buffer, 0, byteCount); } else { @@ -595,8 +596,9 @@ void OpenGLDriver::textureStorage(OpenGLDriver::GLTexture* t, } } else { glTexImage2D(t->gl.target, level, GLint(t->gl.internalFormat), - GLsizei(width), GLsizei(height), 0, - format, type, nullptr); + std::max(GLsizei(1), GLsizei(width >> level)), + std::max(GLsizei(1), GLsizei(height >> level)), + 0, format, type, nullptr); } } } @@ -2901,7 +2903,11 @@ void OpenGLDriver::bindBufferRange(BufferObjectBinding bindingType, uint32_t ind assert_invariant(offset + size <= ub->byteCount); if (UTILS_UNLIKELY(ub->bindingType == BufferObjectBinding::UNIFORM && gl.isES2())) { - mUniformBindings[index] = { static_cast(ub->gl.buffer) + offset, ub->age }; + mUniformBindings[index] = { + ub->gl.id, + static_cast(ub->gl.buffer) + offset, + ub->age, + }; } else { GLenum const target = GLUtils::getBufferBindingType(bindingType); diff --git a/filament/backend/src/opengl/OpenGLDriver.h b/filament/backend/src/opengl/OpenGLDriver.h index 1cf1be4d36f..f3c87c61768 100644 --- a/filament/backend/src/opengl/OpenGLDriver.h +++ b/filament/backend/src/opengl/OpenGLDriver.h @@ -83,11 +83,9 @@ class OpenGLDriver final : public DriverBase { } struct { + GLuint id; union { - struct { - GLuint id; - GLenum binding; - }; + GLenum binding; void* buffer; }; } gl; @@ -363,7 +361,8 @@ class OpenGLDriver final : public DriverBase { void setScissor(Viewport const& scissor) noexcept; // ES2 only. Uniform buffer emulation binding points - std::array, Program::UNIFORM_BINDING_COUNT> mUniformBindings = {}; + GLuint mLastAssignedEmulatedUboId = 0; + std::array, Program::UNIFORM_BINDING_COUNT> mUniformBindings = {}; // sampler buffer binding points (nullptr if not used) std::array mSamplerBindings = {}; // 4 pointers diff --git a/filament/backend/src/opengl/OpenGLProgram.cpp b/filament/backend/src/opengl/OpenGLProgram.cpp index 1c2593751f7..69412e1aea1 100644 --- a/filament/backend/src/opengl/OpenGLProgram.cpp +++ b/filament/backend/src/opengl/OpenGLProgram.cpp @@ -229,15 +229,16 @@ void OpenGLProgram::updateSamplers(OpenGLDriver* const gld) const noexcept { CHECK_GL_ERROR(utils::slog.e) } -void OpenGLProgram::updateUniforms(uint32_t index, void const* buffer, uint16_t age) noexcept { +void OpenGLProgram::updateUniforms(uint32_t index, GLuint id, void const* buffer, uint16_t age) noexcept { assert_invariant(mUniformsRecords); assert_invariant(buffer); // only update the uniforms if the UBO has changed since last time we updated UniformsRecord const& records = mUniformsRecords[index]; - if (records.age == age) { + if (records.id == id && records.age == age) { return; } + records.id = id; records.age = age; assert_invariant(records.uniforms.size() == records.locations.size()); diff --git a/filament/backend/src/opengl/OpenGLProgram.h b/filament/backend/src/opengl/OpenGLProgram.h index 5d183f6da1c..ddee9496690 100644 --- a/filament/backend/src/opengl/OpenGLProgram.h +++ b/filament/backend/src/opengl/OpenGLProgram.h @@ -72,7 +72,7 @@ class OpenGLProgram : public HwProgram { } gl; // 12 bytes // For ES2 only - void updateUniforms(uint32_t index, void const* buffer, uint16_t age) noexcept; + void updateUniforms(uint32_t index, GLuint id, void const* buffer, uint16_t age) noexcept; void setRec709ColorSpace(bool rec709) const noexcept; private: @@ -98,6 +98,7 @@ class OpenGLProgram : public HwProgram { struct UniformsRecord { Program::UniformInfo uniforms; LocationInfo locations; + mutable GLuint id = 0; mutable uint16_t age = std::numeric_limits::max(); }; UniformsRecord const* mUniformsRecords = nullptr; diff --git a/filament/src/PostProcessManager.cpp b/filament/src/PostProcessManager.cpp index 0930b630ae4..db252e29700 100644 --- a/filament/src/PostProcessManager.cpp +++ b/filament/src/PostProcessManager.cpp @@ -2714,7 +2714,8 @@ FrameGraphId PostProcessManager::upscale(FrameGraph& fg, bool filament::Viewport const& vp, FrameGraphTexture::Descriptor const& outDesc, backend::SamplerMagFilter filter) noexcept { - if (UTILS_LIKELY(!translucent && dsrOptions.quality == QualityLevel::LOW)) { + if (UTILS_LIKELY(!translucent && dsrOptions.quality == QualityLevel::LOW && + mEngine.getDriverApi().getFeatureLevel() >= FeatureLevel::FEATURE_LEVEL_1)) { return opaqueBlit(fg, input, vp, outDesc, filter); } diff --git a/shaders/src/depth_main.fs b/shaders/src/depth_main.fs index fa28309a88c..77608f3e15c 100644 --- a/shaders/src/depth_main.fs +++ b/shaders/src/depth_main.fs @@ -58,9 +58,9 @@ void main() { fragColor.zw = computeDepthMomentsVSM(-1.0 / depth); // requires at least RGBA16F #elif defined(VARIANT_HAS_PICKING) #if MATERIAL_FEATURE_LEVEL == 0 - outPicking.a = float((object_uniforms_objectId / 65536) % 256) / 255.0; - outPicking.b = float((object_uniforms_objectId / 256) % 256) / 255.0; - outPicking.g = float( object_uniforms_objectId % 256) / 255.0; + outPicking.a = mod(float(object_uniforms_objectId / 65536), 256.0) / 255.0; + outPicking.b = mod(float(object_uniforms_objectId / 256), 256.0) / 255.0; + outPicking.g = mod(float(object_uniforms_objectId) , 256.0) / 255.0; outPicking.r = vertex_position.z / vertex_position.w; #else outPicking.x = intBitsToFloat(object_uniforms_objectId);