fix a crash on adreno when vsm is enabled

fixes b/285928132
This commit is contained in:
Mathias Agopian
2023-06-06 09:55:35 -07:00
committed by Mathias Agopian
parent 07642fec83
commit fdc3f302d9
8 changed files with 39 additions and 32 deletions
@@ -1130,7 +1130,9 @@ enum class Workaround : uint16_t {
ADRENO_UNIFORM_ARRAY_CRASH,
// Workaround a Metal pipeline compilation error with the message:
// "Could not statically determine the target of a texture". See light_indirect.fs
A8X_STATIC_TEXTURE_TARGET_ERROR
A8X_STATIC_TEXTURE_TARGET_ERROR,
// Adreno drivers sometimes aren't able to blit into a layer of a texture array.
DISABLE_BLIT_INTO_TEXTURE_ARRAY,
};
} // namespace filament::backend
@@ -724,6 +724,8 @@ bool MetalDriver::isWorkaroundNeeded(Workaround workaround) {
return false;
case Workaround::A8X_STATIC_TEXTURE_TARGET_ERROR:
return mContext->bugs.a8xStaticTextureTargetError;
case Workaround::DISABLE_BLIT_INTO_TEXTURE_ARRAY:
return false;
}
return false;
}
@@ -221,13 +221,13 @@ OpenGLContext::OpenGLContext() noexcept {
// Blits to texture arrays are failing
// This bug continues to reproduce, though at times we've seen it appear to "go away".
// The standalone sample app that was written to show this problem still reproduces.
// The working hypthesis is that some other state affects this behavior.
bugs.disable_sidecar_blit_into_texture_array = true;
// The working hypothesis is that some other state affects this behavior.
bugs.disable_blit_into_texture_array = true;
// early exit condition is flattened in EASU code
bugs.split_easu = true;
// initialize the non used uniform array for adreno drivers.
// initialize the non-used uniform array for Adreno drivers.
bugs.enable_initialize_non_used_uniform_array = true;
int maj, min, driverMajor, driverMinor;
+3 -3
View File
@@ -262,7 +262,7 @@ public:
// Some drivers can't blit from a sidecar renderbuffer into a layer of a texture array.
// This technique is used for VSM with MSAA turned on.
bool disable_sidecar_blit_into_texture_array;
bool disable_blit_into_texture_array;
// Some drivers incorrectly flatten the early exit condition in the EASU code, in which
// case we need an alternative algorithm
@@ -446,8 +446,8 @@ private:
{ bugs.dont_use_timer_query,
"dont_use_timer_query",
""},
{ bugs.disable_sidecar_blit_into_texture_array,
"disable_sidecar_blit_into_texture_array",
{ bugs.disable_blit_into_texture_array,
"disable_blit_into_texture_array",
""},
{ bugs.split_easu,
"split_easu",
+11 -18
View File
@@ -968,9 +968,14 @@ void OpenGLDriver::framebufferTexture(TargetBufferInfo const& binfo,
break;
}
// depth/stencil attachment must match the rendertarget sample count
// this is because EXT_multisampled_render_to_texture doesn't guarantee depth/stencil
// is resolved.
// depth/stencil attachments must match the rendertarget sample count
// because EXT_multisampled_render_to_texture[2] doesn't resolve the depth/stencil
// buffers:
// for EXT_multisampled_render_to_texture
// "the contents of the multisample buffer become undefined"
// for EXT_multisampled_render_to_texture2
// "the contents of the multisample buffer is discarded rather than resolved -
// equivalent to the application calling InvalidateFramebuffer for this attachment"
UTILS_UNUSED bool attachmentTypeNotSupportedByMSRTT = false;
switch (attachment) {
#ifndef FILAMENT_SILENCE_NOT_SUPPORTED_BY_ES2
@@ -1018,22 +1023,8 @@ void OpenGLDriver::framebufferTexture(TargetBufferInfo const& binfo,
attachmentTypeNotSupportedByMSRTT = true;
}
// There's a bug with certain drivers preventing us from emulating
// EXT_multisampled_render_to_texture when the texture is a TEXTURE_2D_ARRAY, so we'll simply
// fall back to non-MSAA rendering for now. Also, MSRTT is never available for TEXTURE_2D_ARRAY,
// and since we are a 2D array, we know we're sampleable and therefore that a resolve will
// be needed.
// Note that this affects VSM shadows in particular.
// TODO: a better workaround would be to do the resolve by hand in that case
const bool disableMultisampling =
gl.bugs.disable_sidecar_blit_into_texture_array &&
rt->gl.samples > 1 && t->samples <= 1 &&
(target == GL_TEXTURE_2D_ARRAY ||
target == GL_TEXTURE_CUBE_MAP_ARRAY); // implies MSRTT is not available
if (rt->gl.samples <= 1 ||
(rt->gl.samples > 1 && t->samples > 1 && gl.features.multisample_texture) ||
disableMultisampling) {
(rt->gl.samples > 1 && t->samples > 1 && gl.features.multisample_texture)) {
// on GL3.2 / GLES3.1 and above multisample is handled when creating the texture.
// If multisampled textures are not supported and we end-up here, things should
// still work, albeit without MSAA.
@@ -1876,6 +1867,8 @@ bool OpenGLDriver::isWorkaroundNeeded(Workaround workaround) {
return mContext.bugs.allow_read_only_ancillary_feedback_loop;
case Workaround::ADRENO_UNIFORM_ARRAY_CRASH:
return mContext.bugs.enable_initialize_non_used_uniform_array;
case Workaround::DISABLE_BLIT_INTO_TEXTURE_ARRAY:
return mContext.bugs.disable_blit_into_texture_array;
default:
return false;
}
@@ -780,6 +780,8 @@ bool VulkanDriver::isWorkaroundNeeded(Workaround workaround) {
return false;
case Workaround::ADRENO_UNIFORM_ARRAY_CRASH:
return false;
case Workaround::DISABLE_BLIT_INTO_TEXTURE_ARRAY:
return false;
default:
return false;
}
+5 -2
View File
@@ -824,7 +824,7 @@ ShadowMapManager::ShadowTechnique ShadowMapManager::updateSpotShadowMaps(FEngine
return shadowTechnique;
}
void ShadowMapManager::calculateTextureRequirements(FEngine&, FView& view,
void ShadowMapManager::calculateTextureRequirements(FEngine& engine, FView& view,
FScene::LightSoa const&) noexcept {
// Lay out the shadow maps. For now, we take the largest requested dimension and allocate a
@@ -854,7 +854,10 @@ void ShadowMapManager::calculateTextureRequirements(FEngine&, FView& view,
const bool useMipmapping = view.hasVSM() &&
((vsmShadowOptions.anisotropy > 0) || vsmShadowOptions.mipmapping);
const uint8_t msaaSamples = vsmShadowOptions.msaaSamples;
uint8_t msaaSamples = vsmShadowOptions.msaaSamples;
if (engine.getDriverApi().isWorkaroundNeeded(Workaround::DISABLE_BLIT_INTO_TEXTURE_ARRAY)) {
msaaSamples = 1;
}
TextureFormat format = TextureFormat::DEPTH16;
if (view.hasVSM()) {
+10 -5
View File
@@ -447,8 +447,10 @@ void FRenderableManager::create(
}
}
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))) {
// 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, {
@@ -458,7 +460,8 @@ void FRenderableManager::create(
}
}
// Create and initialize all needed MorphTargets. It's required to avoid branches in hot loops.
// Create and initialize all needed MorphTargets.
// It's required to avoid branches in hot loops.
MorphTargets* morphTargets = new MorphTargets[entryCount];
for (size_t i = 0; i < entryCount; ++i) {
morphTargets[i] = { mEngine.getDummyMorphTargetBuffer(), 0, 0 };
@@ -488,8 +491,10 @@ void FRenderableManager::create(
(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))) {
// 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);
}