Fix some ES2 issues

Fix specification of mipmaps when generating textures.

Fix oversight where emulated UBOs would not replace uniforms when swapped out
for another.
This commit is contained in:
Eliza Velasquez
2023-11-07 15:02:22 -08:00
committed by Powei Feng
parent 422dfcc1e6
commit 5b2d3ac225
8 changed files with 28 additions and 18 deletions

View File

@@ -8,3 +8,4 @@ appropriate header in [RELEASE_NOTES.md](./RELEASE_NOTES.md).
## Release notes for next branch cut

View File

@@ -17,6 +17,7 @@ Instead, if you are authoring a PR for the main branch, add your release note to
- engine: Add `Material::getFeatureLevel()`
- engine: Add missing `Material::getReflectionMode()` method in Java
- engine: Support basic usage of post-processing materials on feature level 0
- engine: Fix critical GLES 2.0 bugs
## v1.45.1

View File

@@ -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<HwBufferObject> boh,
GLBufferObject* bo = construct<GLBufferObject>(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<uint8_t const*>(ub->gl.buffer) + offset, ub->age };
mUniformBindings[index] = {
ub->gl.id,
static_cast<uint8_t const*>(ub->gl.buffer) + offset,
ub->age,
};
} else {
GLenum const target = GLUtils::getBufferBindingType(bindingType);

View File

@@ -83,11 +83,9 @@ public:
}
struct {
GLuint id;
union {
struct {
GLuint id;
GLenum binding;
};
GLenum binding;
void* buffer;
};
} gl;
@@ -363,7 +361,8 @@ private:
void setScissor(Viewport const& scissor) noexcept;
// ES2 only. Uniform buffer emulation binding points
std::array<std::pair<void const*, uint16_t>, Program::UNIFORM_BINDING_COUNT> mUniformBindings = {};
GLuint mLastAssignedEmulatedUboId = 0;
std::array<std::tuple<GLuint, void const*, uint16_t>, Program::UNIFORM_BINDING_COUNT> mUniformBindings = {};
// sampler buffer binding points (nullptr if not used)
std::array<GLSamplerGroup*, Program::SAMPLER_BINDING_COUNT> mSamplerBindings = {}; // 4 pointers

View File

@@ -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());

View File

@@ -72,7 +72,7 @@ public:
} 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 @@ private:
struct UniformsRecord {
Program::UniformInfo uniforms;
LocationInfo locations;
mutable GLuint id = 0;
mutable uint16_t age = std::numeric_limits<uint16_t>::max();
};
UniformsRecord const* mUniformsRecords = nullptr;

View File

@@ -2714,7 +2714,8 @@ FrameGraphId<FrameGraphTexture> 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);
}

View File

@@ -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);