fix a crash on adreno when vsm is enabled
fixes b/285928132
This commit is contained in:
committed by
Mathias Agopian
parent
07642fec83
commit
fdc3f302d9
@@ -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;
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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()) {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user