Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix adreno driver crash related to morph target change. #5754

Merged
merged 15 commits into from
Jul 12, 2022
Merged
Show file tree
Hide file tree
Changes from 13 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion RELEASE_NOTES.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@ This file contains one line summaries of commits that are worthy of mentioning i
A new header is inserted each time a *tag* is created.

## main branch

- engine: Fix Adreno gpu crash introduced by gpu morph target change
- engine: Add optional memory configuration parameters to Engine initialization


## v1.25.2

- engine: `Camera::getNear()` and `Camera::getCullingFar()` now return `doubles`
Expand Down
4 changes: 3 additions & 1 deletion filament/backend/include/backend/DriverEnums.h
Original file line number Diff line number Diff line change
Expand Up @@ -1026,7 +1026,9 @@ enum class Workaround : uint16_t {
SPLIT_EASU,
// Backend allows feedback loop with ancillary buffers (depth/stencil) as long as they're read-only for
// the whole render pass.
ALLOW_READ_ONLY_ANCILLARY_FEEDBACK_LOOP
ALLOW_READ_ONLY_ANCILLARY_FEEDBACK_LOOP,
// for some uniform arrays, it's needed to do an initialization to avoid crash on adreno gpu
ADRENO_UNIFORM_ARRAY_CRASH
};

} // namespace filament::backend
Expand Down
2 changes: 2 additions & 0 deletions filament/backend/src/metal/MetalDriver.mm
Original file line number Diff line number Diff line change
Expand Up @@ -677,6 +677,8 @@
return false;
case Workaround::ALLOW_READ_ONLY_ANCILLARY_FEEDBACK_LOOP:
return true;
case Workaround::ADRENO_UNIFORM_ARRAY_CRASH:
return false;
}
return false;
}
Expand Down
3 changes: 3 additions & 0 deletions filament/backend/src/opengl/OpenGLContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,9 @@ OpenGLContext::OpenGLContext() noexcept {
// early exit condition is flattened in EASU code
bugs.split_easu = true;

// initialize the non used uniform array for adreno drivers.
bugs.enable_initialize_non_used_uniform_array = true;

int maj, min, driverMajor, driverMinor;
int c = sscanf(state.version, "OpenGL ES %d.%d V@%d.%d", // NOLINT(cert-err34-c)
&maj, &min, &driverMajor, &driverMinor);
Expand Down
7 changes: 7 additions & 0 deletions filament/backend/src/opengl/OpenGLContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,9 @@ class OpenGLContext {
// view that this is generally forbidden. However, this restriction is lifted on desktop
// GL and Vulkan and probably Metal.
bool allow_read_only_ancillary_feedback_loop = false;

// Some Adreno drivers would crash gl draw when there's uninitialized uniform array exists, even when the code using that uniform array is not called. it's needed to do an initialization to avoid it.
bool enable_initialize_non_used_uniform_array = false;
} bugs;

// state getters -- as needed.
Expand Down Expand Up @@ -257,6 +260,9 @@ class OpenGLContext {
{ bugs.allow_read_only_ancillary_feedback_loop,
"allow_read_only_ancillary_feedback_loop",
""},
{ bugs.enable_initialize_non_used_uniform_array,
"enable_initialize_non_used_uniform_array",
""},
}};

// Try to keep the State structure sorted by data-access patterns
Expand Down Expand Up @@ -720,6 +726,7 @@ GLuint OpenGLContext::getQuery(GLenum target) const noexcept {
return 0;
}
}

} // namespace filament

#endif //TNT_FILAMENT_BACKEND_OPENGLCONTEXT_H
2 changes: 2 additions & 0 deletions filament/backend/src/opengl/OpenGLDriver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1583,6 +1583,8 @@ bool OpenGLDriver::isWorkaroundNeeded(Workaround workaround) {
return mContext.bugs.split_easu;
case Workaround::ALLOW_READ_ONLY_ANCILLARY_FEEDBACK_LOOP:
return mContext.bugs.allow_read_only_ancillary_feedback_loop;
case Workaround::ADRENO_UNIFORM_ARRAY_CRASH:
return mContext.bugs.enable_initialize_non_used_uniform_array;
}
return false;
}
Expand Down
2 changes: 2 additions & 0 deletions filament/backend/src/vulkan/VulkanDriver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -878,6 +878,8 @@ bool VulkanDriver::isWorkaroundNeeded(Workaround workaround) {
return deviceProperties.vendorID == 0x5143; // Qualcomm
case Workaround::ALLOW_READ_ONLY_ANCILLARY_FEEDBACK_LOOP:
return true;
case Workaround::ADRENO_UNIFORM_ARRAY_CRASH:
return false;
hzzengxiaoqi marked this conversation as resolved.
Show resolved Hide resolved
}
return false;
}
Expand Down
15 changes: 15 additions & 0 deletions filament/src/components/RenderableManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -404,6 +404,15 @@ void FRenderableManager::create(
out, boneCount * sizeof(PerRenderableBoneUib::BoneData) }, 0);
}
}
else {
// When boneCount is 0, do an initialization for the bones uniform array to avoid crash on adreno gpu.
if (UTILS_UNLIKELY(driver.isWorkaroundNeeded(Workaround::ADRENO_UNIFORM_ARRAY_CRASH))) {
auto *initBones = driver.allocatePod<PerRenderableBoneUib::BoneData>(1);
std::uninitialized_fill_n(initBones, 1, FSkinningBuffer::makeBone({}));
driver.updateBufferObject(bones.handle, {
initBones, sizeof(PerRenderableBoneUib::BoneData) }, 0);
}
}
}
}

Expand Down Expand Up @@ -436,6 +445,12 @@ void FRenderableManager::create(
morphTargets[i] = { upcast(morphing.buffer), (uint32_t)morphing.offset,
(uint32_t)morphing.count };
}

// When targetCount equal 0, boneCount>0 in this case, do an initialization for the morphWeights uniform array to avoid crash on adreno gpu.
if (UTILS_UNLIKELY(targetCount == 0 && driver.isWorkaroundNeeded(Workaround::ADRENO_UNIFORM_ARRAY_CRASH))) {
float initWeights[1] = {0};
setMorphWeights(ci, initWeights, 1, 0);
}
}
}
engine.flushIfNeeded();
Expand Down