Add a varying variable `multiview_data` for both surface and
post-processing shaders. Currently this only works as intended in
surface shader, and additional implementation to facilitate it for
post-processing will be following.
The `multiview_data` contains multiview information like whether
multiview is enabled for the current material and what the eye index is
in that case. This variable is globally available including fragment
shaders so that it can be referenced in user shaders in .material files.
Also this allows us to indirectly reference the constant variables such
as `gl_ViewID_OVR` and `gl_ViewIndex` in a platform-agnostic way.
Make the preprocessor `MATERIAL_FEATURE_LEVEL` available for both
surface and post-processing shaders, it used to be only available for
surface shader, and this will be referenced in post-processing shaders
later to support multiview for post-processing.
The commit 1747ae8f5a enfoces a correct
order for releasing resource. Fix the order to avoid crashes.
Make some samples to use the DEPTH32F format for better compatibility.
Some manufacturers don't fully support DEPTH24 on Vulkan. E.g., AMD
Radeon PRO W6400
- clarify precondition for VirtualMachineEnv, in particular,
JNI_OnLoad() must be called from a thread attached to the VM, and
should be called once. This is now enforced internally, subsequent
calls are ignored.
- sVirtualMachine was written and read from potentially different
threads without synchronization. It is now mutex protected.
- added fatal asserts in all locations that we cannot recover from;
previously we would stay in an undefined state.
BUGS=[390724273]
When targeting Vulkan with multiview, the shader
code generator was using the OpenGL extension
and built-in variables, which are not supported on
Vulkan.
Changed it to use GL_EXT_multiview instead of
GL_OVR_multiview2 when the target API is Vulkan.
* Introduce FrameGraphInfo class
* Move the assignment into pimpl
* Make ctors explicit
* Add ctors to fg info structs
* Revert the macro change to align with existing
* Address the comments
* Remove pimpl and move func def to .cc
* Fix
* Convert the FrameGraph to FrameGraphInfo
* Initialize and update debug server on engine side
* Fix compile error
* Address the comments
* Update
* Use camelCase
* Use camelCase
* Update
This commit renames all shader snippet files to conform to the newly
introduced naming convention outlined in README.md.
The new naming convention uses a `prefix_name.suffix` format to clearly
indicate the purpose and target shader stage of each snippet. This
improves the overall organization and readability of the shader code,
making it easier to understand how each snippet contributes to the
shader generation process.
No functional changes were made to the shader code itself or source
code. This is purely a refactoring for clarity and maintainability.
The old version that doesn't take a timeout now always waits forever;
before it waited for a few seconds on Android debug builds.
The new version has an explicit timeout that works on all platforms and
returns success status.
FIXES=[384043020]
SGSR stands for Snapdragon Game Super Resolution. It is an efficient
upscaler for mobile.
Split the upscaling passes into multiple methods in PostProcessManager.
Also, add a way to preserve the alpha channel in the FXAA pass.
- uninlined getHandleTag so that the code is not duplicated when
multiple backends are supported (e.g. GLES and Vulkan)
- added a lock for mDebugTags because, even if rare, it technically
can be accessed from multiple threads. This would happen only
on a failure. There should never be any contention on this lock.
Because of a recent ref-counting refactor, the swapchains are not
being immediately destroyed when destorySwapChain is called. This
might cause issue with following calls to createSwapChain.
We make sure the ref-counted resources are cleaned-up before new
swapchains are created.
Fixes#8288
* Introduce FrameGraphInfo class
* Move the assignment into pimpl
* Make ctors explicit
* Add ctors to fg info structs
* Revert the macro change to align with existing
* Address the comments
* Remove pimpl and move func def to .cc
* Fix
* Address the comment
* Remove redundant qualifiers in filament public headers
* remove redundant qualifiers in filament implementation
* remove redundant qualifiers in libutils public headers
* remove redundant qualifier for libutils implementation
* remove redundant qualifiers for libmath
* use is_same_v<> instead of is_same<>
* bring back Builder::name()
we keep Builder::name() on all object, and forward to the MixIn class
that does the implementation, so that we have correct documentation, and
better IDE completion.
* add missing const parameters in filament's implementation
* various source cleanup
- missing includes
- missing const
- C cast style
- superfluous inline keyword
* validate MaterialInstance references when destroyed
With this change we now enforce two things:
- All MaterialInstance of a Material must be destroyed when
destroying said Material. This has always been a documented
requirement of the public API, but wasn't enforced (only
a warning was printed).
This new assertion is unconditional.
- A MaterialInstance, when destroyed is no longer in use by any
Renderable.
So before destroying a MaterialInstance, the user of API needs to
ensure that either all Renderable using that MaterialInstance in one
of their Render Primitives are destroyed, or, that these Renderable
using that MaterialInstance are reset to another one or to null.
There is a new RenderableManager::clearMaterialInstanceAt() that can
be used to clear a MaterialInstance on a Render Primitive.
Additionally, a Render Primitive with a null MaterialInstance is now
silently skipped during rendering, instead of a null-dereference.
Finally, that second assert is protected by a new feature flag:
"features.engine.debug.assert_material_instance_in_use". This flag is
enabled on DEBUG builds and disabled on RELEASE builds by default.
The flag can be changed at any time using `Engine::setFeatureFlag()`.
BUGS=[333907416]
* Update filament/src/components/RenderableManager.cpp
Co-authored-by: Powei Feng <powei@google.com>
---------
Co-authored-by: Powei Feng <powei@google.com>
We add a bash script to download and install mdbook. For
linux or mac x86_64, we download prebuilts from github.
Otherwise, we use `cargo install` to build it with rust.
- Use mdbook to generate a book from collection of documents
- documents are
- copied and processed from READMEs
- original content stored in the docs_src folder
- markdeep docs transformed into embedded html
- Main logic is in script docs_src/build/run.py
The public dep for mesa has moved on to beyond llvm-18, but the
version we're compiling against is not supported by this change.
We workaround by ensuring that the llvm dep is less than 18 but
consistent with the clang version.
This feature is controled by a feature flag and is turned off at this point.
This CL shouldn't change the existing behavior of shadowmap allocation as
long as the atlas feature is not enanled.
When enabled, shadowmap allocations are not limited to layers of the
shadowmap texture, instead, an atlas is used meaning a layer can
be shared by multiple shadowmaps. At the very least this can save
a lot of memory as smaller shadowmaps can be packed together.
Currently this feature breaks some VSM features:
- mipmapping
- blurring
- when inserting an entry at a root other than zero, we need to update
the children count of the root's parent.
- the QuadTree array nodes need to be able to encode enough indices for
the largest "layer" in the tree. With 7 layers the largest one has
4096 entries, so we need 12 bits, not 8.
We use clang-format to format the shader files. Since we assume
clang is necessary for compilation, installing clang-format should
not be too much of an overhead in terms of adding dependency.
Currently, we only support posix systems (macOS, linux).
* Skeleton of fgviewer debug server
* Update the map for fg info
* Add ApiHandler skeleton class
* Format the files
Format the file
* Prevent fgviewer being built before ready
Add comment to fgviewer related lines
Fix cmake commands
* Update the copyright
* Address the comments
Address the comments
* Address the comments
* Specify the debug server
* Fix build options
Fix 3 bugs wrt matdbg:
1. The numbering scheme for materials with same name was buggy
2. The shared depth variants of the default material should also
show up as active material variants.
3. When two instantiation of FMaterial point to the exact same
bits, we still need to treat them as two materials. (Otherwise
we wouldn't be able to modify one of them in matdbg).
- use a lanczos filter for sampling the color buffer, instead of a
blackman-Harris window. This improves sharpness quite a bit.
- some cleanups of the shader code
- never use YCoCg when rectification is not enabled.
- fix the calculation of the confidence paramter when upscaling is used.
Upscaling works a lot better now, but it is still work in progress.
If the shared osmesa lib is not found, then we assume that the
library has been compile-time linked via the linker. This is to
accommodate build frameworks where compile-time linking is
preferred.
To allow for use-after-free discovery with ref-counting, we keep
a bit to indicate whether the handle is considered destroyed by
Filament. We assert against "cast"-ing a destroyed handle.
The `ShadowCascade` functions for computing splits all attempted to clamp `cascades` to [0,4] (evidently to avoid out-of-bounds access), but used `max`, instead giving a range of [4, x].
For applications using less than 4 cascades, this results in incorrect split locations and lower quality (much more obvious seam between cascades).
This change just switches to use `min` to ensure `cascades` is in the range [0,4].
When tangents are not supplied in a material, all "normals" related
public methods become undefined; remove access to them so we get
compile time errors instead of garbage values in the shader.
A ResourceList<> object was leaked when destroying a material until the
Engine was shut down. This could however grow unbounded if churning
through Materials.
What was actually leaked was entries in the hashmap linking a material
to its material instance list.
BUGS=[383158161]
When using async shader compilation, the compiler thread pool is a
standard pthread and not an NSThread. Therefore, it needs a manual
@autorelease pool, otherwise ARC objects never get truly released.
BUGS=[383167935]
Because ColorPassDescriptorSet is used for both the color pass and the
picking/ssr/structure passes, the texture it holds can be stale.
In this CL we fix this by reseting the offending textures when preparing
the picking/ssr/structure passes. This has a side effect of recreating
the descriptor-set internally. A better fix would be to use separate
descriptor-sets for these two cases and rely on the texture cache
to avoid recreation from a frame to the next.
BUGS=[376705346]
This restores the old behavior with depth variant caching. We pay the
price at engine init time, instead of when the variant is needed the
first time. We can revisit this later.
Note that the default material doesn't have all possible depth variants
(e.g. VSM), but that pre-caches the most popular ones.
BUGS=[381946222]
When a viewport with a negative left/bottom was used, an assert would
trigger on debug builds and release builds would get a wrong scissor.
This bug was introduced recently, we now do the offset/clipping math
in 64 bits, which is way simpler and convert back to Viewport at
the end.
BUGS=[381902791]
The workaround which were intended to be used with the native driver
only, were picked-up by the webgl backend when running on firefox,
probably because of the different GL string.
BUGS=[380425595]
When releasing array elements, we need to pass 0 as the
last argument if we want to copy local chnages back to
the Java array. JNI_ABORT should only be used when we
don't want the copy, i.e. when the array is read-only.
Fixes issue #8278.
* fix a HwProgram leak related to depth variant pre-caching
Materials that don't use a custom depth can share the same program for
all depth variants. We take advantage of that by pre-caching the
depths variants when a program is loaded. The depth variants themselves
are owned by the default material which is created first. When a
material is destroyed it skips deletion of those variants which will
be truly destroyed when the default material is destroyed.
Unfortunately, the default material doesn't contain all depth variants,
in particular, it doesn't have the VSM ones (because it's an unlit
material). On top of that, the way it pre-cached depth variant had
a bug that made it miss some picking variants.
Because of that, these variants were skipped during material destruction
but never actually destroyed, since the default material didn't know
anything about them.
This PR fixes this by making the pre-caching completely lazy. When
any material needs such a "precacheable" variant, it first checks if
the default material has it. If not, it creates the variant, caches it
locally and forwards it to the default material, which implicitly
becomes the owner. Just like before newly created material precache
everything the default material already has.
With this mechanism, it's impossible to have a depth variant without it
also existing in the default material.
This also simplify the non-public invalidate() method, which doesn't
need to populate the pre-cached programs, since this will happen
naturally when needed.
There was also another issue where post-process materials were
handled like regular materials. This didn't cause an problem but was
inefficient since these only have a handful of variants.
* Update filament/src/details/Material.cpp
Co-authored-by: Powei Feng <powei@google.com>
---------
Co-authored-by: Powei Feng <powei@google.com>
The previous fix attempt didn't work on some test. There are no known
bugs with AtomicFreeList other than tripping TSAN, and it's unclear
that TSAN isn't at fault.
However, switching to using a mutex works fine and doesn't appear to
be slower (it's actually faster with synthetic benchmarks on macOS)
BUGS=[377369108]
I do not think there was an actual error with AtomicFreeList, however
TSAN detected a data race when concurrent pop() happened. In that case,
there is indeed a race, where we can end-up reading data that is
already corrupted by the concurrent pop. However, that situation is
corrected by the following CAS. Somehow TSAN didn't see that.
The fix is strange and consists in replacing:
```
auto pNext = storage[offset].next;
```
with
```
auto s = storage[offset];
auto pNext = s.next;
```
In this PR we also adjust the memory ordering to be less strong. i.e.
we do not need `memory_order_seq_cst`, only the appropriate acquire or
release semantic.
In addition we also make `Node* next` a non-atomic variable again. It
should have been, but was change to placate an older version of TSAN.
BUGS=[377369108]
Continuing from PR #8220.
Here we change all of the references from the old ref-counting ways
to the new ref-counting structs and mechanisms. There should be no
functional change.
- Cache the render buffer in the render pass strucutre
- Enable the proteded path in the Render Target
- Make sure we build the protected version of the depth/color in the swap chaing
- Minor cleanup/restrucuring of the code
On ES2 devices (or in forceES2 mode), we emulate the sRGB swapchain
in the shader if the h/w doesn't support it. In that case, the emulation
is controlled by a uniform that technically lives in the frameUniforms
block. However, the frameUniforms buffer is not updated, instead,
the uniform is manually set. Unfortunately, the UBO emulation
overrides it with the uninitialized variable.
BUGS=[377913730]
Previously, we linked against libOSMesa through the linker and
then used dlopen to link against libGL. This is not how libOSMesa
is intended to be used. Instead, we use dlopen on libOSMesa
(via bluegl), which then will map the correct GL methods for us,
and for the OSMesa functions, we also map those functions
from libOSMesa (instead of relying on compile-time linker).
By providing a queue and the family index, we can now create
protected comand buffers that will be submitted to a protected
queue. The main abstraction is in VulkanCommands.h where we
introduced a CommandBufferPool.
Also did refactor on the "mStorage", fences, and semaphores of
the original VulkanCommands so that each buffer is associated
with one fence and one semaphore.
Feature flags are intended to be used when a new feature is added to
filament and have generally two purposes:
1) during feature development, the feature can be implemented but
disabled which can help developing large features. This way the
feature can be tested by stakeholders while it's being developed
without impacting other clients.
2) once a feature is ready, its flag can be enabled by default, but
in case the feature breaks something or has unintended consequence,
clients have the option to turn it off.
Feature flags are intended to have a relatively short life span, i.e.
once a feature is stable, the flag fill be removed.
There two types of feature flags. Constant feature flags can only be
set during Engine initialization via Engine::Builder. Non-constant
feature flags can be set at any time.
Feature flags SHOULD NOT be used as configuration or settings.
Feature flags are designed with a few ideas in mind:
- they are very cheap to check inside the engine
- non-constant flags can easily be toggled using ImGUI
We add a set of classes to the vk backend that will enable
cleaner ref-counting.
In particular, all allocation from the HandleAllocator will be
wrapped within a resource_ptr<> smart pointer. This struct will
maintain a count that will increment/decrement with respect to
references (similar to std::shared_ptr).
This commit only introduces the new classes/structs and does not
actually make any functional difference. A follow-up commit will
make the switch to use the smart pointer.
We also put VulkanFence and VulkanTimerQuery in a different header
because we will need to depend on them separately in the follow-up
(reason: they are accessed on the backend thread but allocated on
"sync"/filament thread).
Adding the basic mechanisms for creating and managing the protected
state. We also create the queue and get it. Finally we allocate
protected memory. Also removed some of the shared context logic
The goal of this PR is to get closer to being able to run all
FrameGraph passes in parallel. To achieve this we need all data
consumed by the "execute" closure of the FrameGraph passes to be
immutable or thread-safe. We also need the passes to never use the
Engine's global `DriverAPi&` object.
Specifically in this PR, we turn as many objects to `const` as possible
without major changes, and we pass the `DriverApi&` object as parameter
to render passes.
This work is far from being complete. So we also annotate with FIXMEs
all the places we can identify will be problematic (there are probably
others).
The main remaining issues are:
- main allocator is not thread-safe
- some places take a non-const View, Scene or Engine
- lazy allocation of materials and material instance usages are not
thread-safe.
This PR shouldn't change any behavior.
Move a lot of the code from beginRenderPass() to the initialization
of the RenderTarget. This will save us a bit of CPU when
RenderTarget is re-used.
We also reduce the size of the VulkanRenderTarget handle and put
must of the caching bits into a heap struct.
When multiview is enabled with the combining debug option toggled on, we
use an intermediate buffer that requires us to use the entire area of
the buffer as the viewport. Use xvp in this case.
* Capture the last win32 error immediately after failing win32 API functions are called in order to log it correctly. Prior to this change, intervening win32 API calls could clear the error code and it would not be logged.
* Oops fix bad whitespace in previous commit
In some cases, users set materials first without providing render primitives, which has incurred the attribute mismatching warning. This isn't helpful because users don't know what action they should take to remove the warning.
Emit the warning only when the primitive handle is initialized so the AttributeBitset is properly populated.
BUGS=[372755205]
RenderPass is now tracking the scissor state locally so it can avoid
re-setting the scissor when it doesn't change.
We also consolidate the scissor override and the scissor-viewport in
RenderPass::Execute.
RenderPass is now tracking the scissor state locally so it can avoid
re-setting the scissor when it doesn't change.
We also consolidate the scissor override and the scissor-viewport in
RenderPass::Execute.
- the main goal of this change was to move some state changes outside
of loops, usually with mip generation.
- for instance bindPostProcessDesciptorSet() must now be issued
manually (and can be done outside the loop)
- we also don't set the scissor for each pass
- we also move prepareMaterial() outside of getPipelineState(), it's
now done in PostProcessMaterial::getMaterial().
- We use PostProcessVariant instead of uint8_t everywhere
In the end we have three drawing helpers:
- commitAndRenderFullScreenQuad() which updates a material instance,
binds the corresponding material and draws a full screen quad.
- renderFullScreenQuad() which just renders a full screen quad.
- renderFullScreenQuadWithScissor() which does the same but scisorred
Additionally, we have the following helpers for getting materials and
instances:
- PostProcessMaterial::getMaterial(): which returns the FMaterial
- PostProcessMaterial::getMaterialInstance(): which is now a helper
returning a material instance from a PostProcessMaterial or FMaterial
Most of the change is pluming through these API changes.
It always references static data. Additionally, we don't need
to use a vector to store the specialization constants, because
it's also all static data.
And finally, we don't need a boolean to know the state of the
PostProcessMaterial, the mSize field can encode the same
information.
"history" is a map from a DescriptorSet pointer to a set of
bookkeeping values (we delay "binding" until "commit" so need to
keep values until then). Instead of using a map, we can store
these values in the DescriptorSet itself so that we save on a
map look-up.
ANGLE features should be set by apps, the system or developers but it's
not a good idea to set them in a library as it might conflict with other
libs etc.
we did it because it improved performance, but that should be fixed at
the angle level instead.
We are seeing a cluster of crashes that could be due to using an
EGLSurface whose ANativeWindow has become invalid. This could happen if
we continued to use (i.e. draw with) an EGLSurface after
SurfaceHolder::onSurfaceDestroyed() has returned.
This new flag enables an assertion that the native window is valid at
the time of makeCurrent(), which happens early in the frame.
BUG=[330392256]
Previously, default layout is based on usage, but this actually
has two paths (Filament's TextureUsage and the computed
VkTextureUsage) that do not always agree. We simplify so that
default layout is stored in the texture itself.
Also remove some unnecessary code that is no longer necessary.
In particular, we shouldn't be doing a flush and wait for the
transition to complete before updating a sampler descriptor.
We just need to make sure the layout before it is accessed is
correctly given in the update struct.
In certain compilers, the assignment operators defined as default
doesn't automatically make a call to the parent's method if it's
user-defined.
Make this behavior explicit to avoid this edge case.
BUGS=[371980551]
To ensure the source of readPixels() is properly copy-able, we
want the backing textures to be created with the right BLIT_SRC usage.
However, this was not documented in the API. We workaround the issue
to tag all color attachment textures as BLIT_SRC.
This workaround will be removed in the future. For now, violations of
this condition will elicit a warning being printed out.
the problem stems from a mismatch between the shader code
and the cpu code. if the shader is configured to read the shadow
map, then the cpu must generate it, otherwise we can get stale data.
Wether the shader reads the shadow map depends on the shadow type.
For directional shadows, the shader needs the SRE variant + a
"shadow enabled" bit per cascade in the main UBO.
For punctual shadows, the shader only needs the SRE variant.
Because of all that, if the conditions are met on the CPU side for
the shader to access the shadow map, we must make sure to generate it,
but in the case the shadow map would be empty (e.g. no shadow receivers),
we need to initialize it (and we can skip some work in the case of VSM).
BUGS=[369908659]
this caused the HAS_SHADOWS flag to not be disabled, this didn't
actually cause a problem because shadowing and SSR share the same
SRE variant bit. But both should never be active together.
Mesa always clears the generic binding if the buffer deleted
is bound to an indexed binding, even if it's not bound to the
generic binding.
BUGS=[371324321]
- We change GLDescriptorSet::Buffer default constructor to
workaround a client's compiler set up issue.
- We removed the assert_invariant that checks that ubo/samplers
are not changed after committed in DescriptorSet. This caused
an existing client's build to crash.
We use Mesa's gallium swrast to render as the driver with
Filament's backend set to GL. We provide a few scripts to parse
the tests (as jsons) and run gltf_viewer to produce the rendering.
For GL+Linux, PlatformGLX will try to open an X11 window
regardless of whether we are doing headless/offscreen rendering
or not.
Here we add an OSMesa platform, which will allow us to avoid
opening any window on Linux. This is particularly useful for
situation where a display is not available, like for CI.
One important detail is that even though we are displaying through
a window, we keep the SDL2 dependency in tact for gltf_viewer.
This is due to the fact that gltf_viewer is built upon
FilamentApp, which is heavily integrated with SDL2. This is mostly
ok since we won't be hitting any path for opening a window due to
gltf_viewer's existing support for headless mode.
Currently mLayerCount for RenderTarget is always updated to the number
of depth for attachments, which incurs unintended behaviors for some
types of textures. i.e., 2d array, cubemap array, and 3d textures.
Fix this by updating mLayerCount only for multiview use case.
BUGS=[369165616]
scissor() works like on metal now, that is, it is disabled when a
render pass starts.
The GL backend already assumed this in debug mode. We cannot really run
into issues at the moment because every time we get a new
MaterialInstance we set the scissor -- we do this both for the
color pass and the post-process passes. With this change we will be
able to skip setting the scissor altogether in a lot of cases.
- Also used a smaller runner as the gains from the 32-core was
not efficient when comparing output times.
- Clean-up:
- Rename the android continuous to a proper name
- set 'echo on' for the Windows release build so we'll know
why the output asset does not get "moved" correclty.
Found through testing that renderStandaloneView+vk+swiftshader
seems to cause synchronization issues, which results in incorrect
rendering. Here we workaround the issue by forcibly flush and
wait per renderStandaloneView call.
BUG=361822355
- Both Scene and IBL are holding on to a skybox reference. We
need to make sure the order they are destroyed in right order.
- Reloading IBL should trigger resetting the indrect light in
gltf_viewer.
FrameSkipper was recently broken because of a typo resulting in
the frame latency being always 3 instead of the default of 2.
This change also makes the maximum latency 2 instead of 3, because on
ANDROID, 3 can cause CPU throttling at seemingly random places on the
GL thread.
Clients can create a multi-layered render target that consists of array
textures, and use it as a custom render target.
A new sample app "hellostereo" demonstrates how to use this feature.
when debug markers are implemented with systrace, begin/end can is not
guaranteed to happen in the same C++ scope, so we can't really use
other scoped systraces.
- Pulled the android continuous workflow into an action
- Split the android continuous build into 3 ABIs armv7, armv8a,
and x86_64 (note that x86 is not present).
- Remove the upload artifacts step from previous workflow.
This was meant for letting client try a tip-of-tree Android
build. We can revisit this later. (Also removed mention
in README.md)
- Split the android continous into debug build and a release
build commands, enabling deletion of intermediate output
directory.
make sure to unset all textures in the per-view sampler group after
they are used, because the resource could be destroyed after the
pass is finished
- unset the fog and ibl_specular after the color pass
- move that cleanup a bit earlier
- in the case of screen-space reflection the structure pass is
set, but might not be used in the color pass, so we also need to
unset it after the SSR pass and before any other passes.
Also tag user texture "FTexture" if user doesn't provide a tag, this
is so that we can distinguish them from internal textures that might
not be tagged.
with a previous change we were too aggressive in falling back to
"no buffer padding", we need to do this only in the case where
"as subpass" would have been used if supported by the h/w.
This is because we had this assumption on vk and mtl backends already
and also because SYSTRACE works this way and we didn't have non-null
terminated strings. This makes things more consistant and less bug
prone.
this is because the "disposer" is now separate from the
ResourceAllocator, so even if we don't use the resource allocator we
need to register the handle with the disposer.
vk, metal and desktop gl all support depth clamp, GLES/android also does
with ANGLE. Add support for it in the backends.
use depth clamp to improve directional shadow quality; this allows
to render everything that's behind the camera at the same "zero" depth,
so we can reduce the depth range we need.
Fixes#6293
`DebugRegistry::setProperty` is no longer just applicable to debug
builds.
This change was previously added in 6c0bd36 but then reverted
in a7317e7. We re-enable it and separate it from the shadow
changes in this commit.
the framegraph blackboard tends to create a lot of problems hard to
debug, so we are now more explicit. here we remove usages of the
blackboard in RenderUtils.cpp.
default parameters were not initialized which could cause them to
be incorrectly evaluated in the shader. this is actually a pretty
crazy bug that has been around since forever and which we were
"lucky" to not run into sooner.
this was exposed with the specular extension that was added recently.
Verify the compatibility between a compiled material and the engine's
setting only when the engine is set up for stereo.
Default materials are always compiled with either 'instanced' or
'multiview. Therefore Filament will emit warnings unintentionally if the
engine is set up for stereo. This commit fixes it.
It is legal for the app to draw a frame even when FrameSkipper
detects that a frame should be skipped. In that case we used to
overwrite the most recent fence, but this wasn't ideal. We now
proceed as if the fence had signaled, i.e. we destroy it and
move all the fences up, creating a new one at the end of the
delayed array.
This is because the shadowmap doesn't store depth values so it doesn't
work to "flatten" all casters behind de camera to the near plane.
The bulk of shadowing works but the filtering/edges don't always.
Disable depth-clamping when VSM is enabled.
vk, metal and desktop gl all support depth clamp, GLES/android also does
with ANGLE. Add support for it in the backends.
use depth clamp to improve directional shadow quality; this allows
to render everything that's behind the camera at the same "zero" depth,
so we can reduce the depth range we need.
Fixes#6293
shadow cascades where not calculated properly because part of the
calculation took the cascade near/far into account, while another
part didn't. This resulted in cascades being too large. It didn't
create wrong shadows, but reduced (and in some case canceled) the
usefulness of the cascade.
We fix the problem by always using the projection matrix only for
describing the cascade's frustum, as opposed to just passing the
near/far plane distances.
Now the calculation of each cascade is completely self contained and
identical.
We also improve the orientation of the light frustum:
We can rotate the light frustum around the light direction axis, so
it aligns with the view direction, this generally result in smaller
light frustums. This cannot be used in stable mode.
A recent change broken the optional "depth clamp" as well as the
computation of the far plane of the light frustum. There was also
a case where DEBUG builds could assert.
- The far plane was no longer being "optimized" (i.e. moved as close
as possible), which resulted in less optimal use of the shadow texture.
the far plane can be moved as close as the farthest visible shadow
caster.
- After the camera/light frustums intersection we now see of the 2D
bounds seen from the light are empty and if so we bail, which prevents
an assertion later.
- finally, the "DEPTH_CLAMP" option is also updated for the new code
structure.
- the last View created was always overriding previous View's datasource
- because of lazy registering of the data source it was possible that
the registering lambda was called after the view was destroyed, leading
to crashes
- all view would share the same PID parameters and these would be
initialized to default value instead of the user provided value. so
debug build would behave differently.
With this change we improve things:
- now only the first view gets to publish its data source. it's still
not ideal, but works for our use case with gltf_Viewer
- the view can now unregister itself when it's destroyed
- only the view that successfully registered uses the debug PID values
and publishes its data source.
- the normal parameters are used until we query the datasource (from
imgui), so by default the behavior is now identical to release builds
This fixes a crash in gltf_viewer when opening the Debug panel.
Print a warning in case the sterescopic type in a compiled package is
different than what's in the engine's setting. The application may
proceed, but it could end up visual glitches when enabling stereoscopic
rendering.
This requires the stereoscopic type to be written into the package,
which needs a material version bump.
This reduces the latency of the timer query result; with the previous
code the latency could only increase, but there is no reason to wait
a whole frame for reading the next available result.
We just loop over them until we find one that has not signaled; instead
of doing one per frame.
we now have two levels of debug markers. Those that come from the "user"
(i.e. filament itself) are now always enabled and generate both
systrace and gl markers. the 2nd level is internal and always
disabled by default. Of enabled at compile time it'll emit markers for
each driver API method.
- use the same code on both ends of updating the free space. i.e.
both side compute the "used" space in exactly the same way.
the math was the same before, but the code was different which
could be confusing.
- assert for overflow before queuing the buffer. It wouldn't matter
anyways, because it's done with the condition lock held, so the
consumer would never have a chance to deuque it. still, less
confusing.
This commit 730bc99025 introduced a new
dependency on ResourceAllocator because of the new field
`std::unique_ptr<ResourceAllocator> mResourceAllocator{};` in
details/Renderer.h
This requires cpp files including details/Renderer.h to include
ResourceAllocator.h as well.
This compile issue only happens on the Windows compiler, Visual Studio.
This function attempts to set texture parameters in these two cases, but the
texture is not guaranteed to be bound. Perhaps it once was, but the assumption
broke at some point.
this change shouldn't have any impact on ARM, however, according
to cppreference it's not safe to mix seq_cst with other memory
orders:
"as soon as atomic operations that are not tagged memory_order_seq_cst
enter the picture, the sequential consistency guarantee for the program
is lost"
Value of mCgltfBuffersLoaded is sometimes retained across creation of FAssetLoader which skips loading the buffer in AssetLoaderExtended#createPrimitive leading to null pointer crash
This fixes a crash introduced by a8ace2891d
The refactored FrameInfoManager can cause a crash when IBL resource loading
happens because now the getLastFrameInfo() references an invalid value via the
`front` method. Return the default FrameInfo to resolve this.
Also fix a null pointer reference bug for OpenGLTimer::State, which
happenes when the renderer for IBLPrefilterContext is destroyed.
Adds multiview support for vulkan. This is done by adding a layerCount to the renderTarget, which is used to determine if multiview is available and being used in the current renderpass.
FIXES=[332425392]
Co-authored-by: Powei Feng <powei@google.com>
if it can't find a name for a node, it will revert to the config's
defaultNodeName, however, if that is nullptr also, a crash will occur.
so we provide a last-resort hardcoded name in that case.
Add Renderer::skipFrame() which should be called when intentionally
skipping frames, for instance because the screen content hasn't changed,
allowing Filament to performance needed periodic tasks, such as
cache garbage collection and callback dispatches.
We also improve the ResourceAllocator cache eviction policy:
- the cache is aggressively purged when skipping a frame
- we aggressively evict entries older than 3 frames
The default Config is now set to a more agressive setting.
The ResourceAllocator used to be global and owned by the Engine, this
was causing some issues when using several Renderers because each
one could cause the eviction of cache data for another.
We now have a ResourceAllocator per Renderer, which makes more sense
because most resources are allocated by the FrameGraph.
We also introduce a ResourceAllocatorDisposer class, which is used
for checking in and out a texture from the cache, and destroy the
texture when it's checked-out. That objet is still global.
* improve parallel_for a bit
We get about 40% performance increase. The gain comes from not having
to copy the JobData structure each time we create a job, by using a
new emplaceJob() method, we can create the structure directly into
its destination.
* avoid calling wakeAll() when possible
wakeAll() is very expensive and not always needed when a job finishes
because there may not be anyone waiting on that job.
We now maintain a waiter count per job, and use that to determine if
we need to notify or not.
And now that the JobSystem overhead is lower, we can decrease the size
of the jobs, which improves the load balancing.
* mActiveJobs fixes
some comments claimed mActiveJobs needed to be modified before or after
accessing the WorkQueue; this couldn't be correct because there were no
guaranteed global ordering with the workQueue.
- reduce the number of calls to notify_one() and notify_all().
notify_one() is not only called when running a new job, and
notify_all() only when a job finishes.
- don't hold the condition lock while calling notify_*(), as it is not
strictly needed, and because notify_*() can be very slow, there can
be a lot of contention on this lock as a result; blocking the whole
jobsystem thread pool.
- add a new version of run() that takes an opaque thread id that can
be retrieved from a job's execute function; this is especially
intended to be used by parallel_for(); it's just a more efficient
version of run() that avoids a hashmap lookup.
Overall these change yield a significant performance boost:
- running + waiting a job: +200%
- running many jobs: +150%
- running many jobs in parallel: +50%
- we use a circular buffer for the frame history so that
we don't have to copy the data when insert a new entry.
This also allows us to keep a reference to an entry, which
doesn't get invalidated when an entry is added/removed.
- we now store the gpu frame time in the correct slot (instead of
always the latest). It didn't matter before because the API wasn't
public and we only needed some recent frame time.
- a new public API now returns the frame history, which now contains
more data; in particular the main and backend thread's begin/end
frame time.
BUGS=[321110544]
- in case of failure we were munmap'ing the wrong size for the
guard page (in practice this never happened)
- the post-condition check was incorrect; it checked for nullptr instead
of MAP_FAILED. this also never happened in practice.
Also made a couple of small improvements:
- in case the special circular buffer mapping fails, log a message
as warning instead of debug.
- immediately memset (i.e. populate) the pages for the circular buffer
since they will all be accessed rather quickly.
- remove deprecated morphing APIs
- repair gltfio, samples and tests
The new API doesn't allow a MorphTargetBuffer per RenderPrimitive,
instead the MorphTargetBuffer is specified per Renderable.
gltfio separates RenderPrimitives from Renderables, in particular all
RenderPrimitives are created before their Renderable; this was
problematic for this change because all primitives must share
a single MorphTargetBuffer living in the Renderable.
To fix this, we're no longer initializing the morphing paramters
at RenderPrimitive creation, instead we store a reference to the
BufferSlot in the Primtive structure, so that later, when the Renderable
is created we can finally retrieve the BufferSlot and initialize its
morphing paramters, which are not available. The "morphing parameters"
are now expanded to contain the MorphTargetBuffer as before (except now
it's always the same for all the primitives of a Rendrable), as well
as the offset within the buffer and the vertex count.
Texture handles were resolved to pointers when updating a SamplerGroup,
as that point the handle was checked for use-after-free. However, the
texture could be destroyed later while still active in the SamplerGroup,
this would result in using the pointer which now contains garbage.
We now keep the handle and resolve the texture when binding samplers
to the program; which will also perform the use-after-free check.
If a user is using `setFrameScheduledCallback()`, managing the provided PresentCallable during engine shutdown is tricky -- we'll likely get a final frame scheduled when we flush the engine's work queue, but the PresentCallable will schedule the final CAMetalDrawable to be released on main thread afterwards, even if we call `present(false)` to skip it. If the swap chain is destroyed before that main queue block gets executed, the mutex presenting that drawable will no longer exist, causing a crash.
To make things easier, store the std::mutex in a shared_ptr, so that a PresentCallable can safely outlive the FSwapChain instance that created it and clean itself up afterwards.
Alternatives considered, all of which seem unfortunate:
* Require users to clear out the callback before shutting down the engine, so that any final drawables are immediately discarded instead of using PresentCallable
* Require users to split up the engine teardown across two main queue blocks, ensuring that the PresentCallable cleanup executes before swapchains are destroyed
* Drop the PresentCallable on the ground and leak the memory
When a user drags and drops a gltf file to the gltf_viewer window, it
loads the new asset.
While this happens, the function `checkAsset` tries parsing the gltf
file, but it doesn't free it. Fix this.
The number of SH bands used for the indirect light irradiance
computations can be set to 1, 2 or 3 (default) in Material::Builder.
For e.g. in lower-end devices w/ non HDR content, it might be
beneficial to set this value to 2.
BUGS=[341971013]
Abstracts the synchronization of the vulkan swapchain so that it is easier to override during the acquisition and presentation of images. A new structure (ImageSyncData) is created to hold swapchain synchronization data.
FIXES=[338303279]
PresentDrawable was moved to main thread by default in google#7535 and stopped
most crashes when a drawable is released. But there still appears to be crashes
if a drawable is released on main thread at the same time that -nextDrawable is
called from the Filament render thread. (It's likely that the drawable pool in
CAMetalLayer is completely non-thread-safe.)
So, add a mutex to the swapchain and always acquire it before creating or
releasing a CAMetalDrawable.
Users can opt out of this behavior by passing
-DFILAMENT_LOCK_METAL_DRAWABLE_POOL=0.
Currently, if this fails we log the error message to stderr (which
doesn't get captured by most crash reporting systems) and then crash in
a postcondition assert. By including the error message in an exception
reason and throwing an ObjC exception, we get better discoverability of
error causes.
(Building a render pipeline state from shaders is usually when a shader
actually gets JITted from LLVM IR to GPU-specific code, so if we
accidentally used a feature that's not available on the local GPU, we'll
find out about it here.)
going forward, instead of using the printf style syntax for panics
we use the c++ stream syntax
The new macros that replace ASSERT_*CONDITON are
FILAMENT_CHECK_PRECONDITON
FILAMENT_CHECK_POSTCONDITION
FILAMENT_CHECK_ARITIHMETIC
Example usage:
FILAMENT_CHECK_PRECONDITON(condition) << "Message";
It's also now possible to define FILAMENT_PANIC_USES_ABSL=1 to redirect
all these calls to Abseil's CHECK() macro.
Set combine_multiview_images to false by default as it's the desirable
setting for most Android devices.
Set the flag to true for GUI by default.
Put the `Combine Multiview Images` checkbox under the `Stereo mode` box
for an easier access.
The current API allowed to have a buffer for each primitive in a
renderable. We instead restrict the API so that there is a single
MorphTargetBuffer for the whole renderable, shared by all primitives.
The buffer can be shared thanks to the "offset" parameter on
setMorphTargetBufferAt().
Also
- fix FMorphTargetBuffer::updateDataAt()
- add support for the "offset" parameter of setMorphTargetBufferAt()
- Add option to build.sh to build for paritcular stereo
techniques (default to NONE). Only applies to samples.
- Consoldiate viewer checkbox for debugging stereo rendering
- Add DriverConfig flag for stereoscopic type so that it can
be used to determine availability of the feature and
(to be completed) enable corresponding GPU features.
Co-authored-by: Mathias Agopian <mathias@google.com>
we use a different hook for the draw() call when on an ES2 context,
this eliminates completely the overhead of supporting ES2 for the draw
call. draw calls are expected to be the most common calls.
- Use custom ICD path to enable Swiftshader instead of
specifying direct path to the lib.
- Remove unused `swiftshader` directory in `build`
- Remove swiftshader options in `build.sh` and cmakefiles
- Change BUILD.md
- Correctly handle XCB-only swapchain surface in VulkanPlatform
for swiftshader.
- Refactor `VulkanPlatform::ExtensionSet` so that `utils::CString`
is used instead of string_view, so that we don't get into
tricky lifetime issues with `const char*`
- a field was added, which broke the layout of the structure. We fix it
by adding constructors which will handle the old and new way of
initializing this structure.
- one of the test needed a hash update
- OpenGLContext wrongly asserted when trying to unbind texture 0
If a .metallib was compiled with a target iOS version that's newer than
the current device, loading the .metallib may succeed, but finding main0
(or any other function in it) will fail. Currently, this causes a crash
due to an assert. Logging the error and returning
MetalFunctionBundle::error() makes the crash slightly easier to
diagnose.
(Note that in practice, this will probably be a useless "Compiler
encountered an internal error" message -- the GPU backend is crashing,
and the Metal stub library sees XPC_ERROR_CONNECTION_INTERRUPTED. It
retries up to 3 times (crashing each time) and then gives up.)
* Add an Engine debug setting to force GLES 2.0
This setting is only meaningful on GLES backends, it's otherwise
ignored. When set to true, the backend will try to force a ES2 context
if supported. If not supported by the platform,
the backend will pretend it's a ES2 context.
This setting is currently only taken into account by the EGL platform.
* Update filament/backend/include/backend/Platform.h
Co-authored-by: Powei Feng <powei@google.com>
---------
Co-authored-by: Powei Feng <powei@google.com>
- make sure we can build with ES2 headers only
- make sure to not use ES3 features when in ES2 mode
(post processing was accidentally creating an R8 texture,
which is not supported)
I was unfortunately naive about the way that Filament handled external textures
on non-GLES platforms. This fix restricts the changes to Android (which is the
only place this change is required in the first place). Long story short, the
change broke WebGL. Desktop seems to be unaffected.
- At the end of a renderpass we use a more fine-grained barrier
for each of the attachments in the render target
- Make sure that buffer update are barrier'd from previous reads
- Remove previous Mali workaround barriers. Seems to be fine
without them on pixels + Mali.
This change will enable proper flat-shading and MikkTSpace.
Caveats:
- Only for disk-local glTF resources
- iOS, Web, Android do not work as of now
Fixes#6358, #7444
- use namespace for ImageUtility
- use FILAMENT_BACKEND_DEBUG_FLAG
- remove unused usage flag type
- add const list of VKFormat for iteration
- fix sampler name debug
The main goal of this change is to avoid having to select the
"per renderable" UBO at execution time. Instead we want the
PrimitiveInfo structure to already know which UBO will be used.
Concretely, this means that this determination must be done when
the RenderPass is created.
When automatic instancing is used, the RenderPass creates a temporary
UBO to store the instance info. This UBO's life-time is dictated by both
the life-time of the RenderPass and the Executors that where created
from it. For this reason we introduce SharedHandle<> to correctly
account for the owner's lifetime. This fixes a potential bugs where
that handle could have been destroyed and used later; in practice this
bug didn't happen however.
A couple other changes:
- RenderPass has a bunch of fields that were actually temporary, so we
removed those.
- The canonical "per-renderable" UBO was owned by View but accessed
through Scene. This was confusing, it's now accessed through View.
It's been a while that generateCommands() can only generate either
the depth or color pass but not both at once; we can simplify/de-dup
the code by leveraging that.
To allow easy enabling/disabling of debug options like vulkan
validation, android systrace, debug printing, and others, we
introduce an option to add a preprocessor flag so that a
backend can (optionally) use it to manage debug options.
* vk: Fix unsupported depth blitting
On certain hardware (pixel 4 for example), blitting of depth texture
is not supported as an "optimalTilingFeature". In these cases, we'd
would need to do a shader-based blit. We
- Add the shader blit in PostProcessingManager
- Add a driver API to check for support for blitting depthStencil
attachments.
- Fix some debugging ifdefs in vk backend.
The validation fixed is:
`[ VUID-vkCmdBlitImage-dstImage-02000 ] Object 0: handle = 0xb400007c300701d0, type = VK_OBJECT_TYPE_COMMAND_BUFFER; Object 1: handle = 0xf2039b0000000771, type = VK_OBJECT_TYPE_IMAGE; | MessageID = 0x86bc2a78 | In vkCmdBlitImage, VkFormatFeatureFlags (0x1c601) does not support required feature VK_FORMAT_FEATURE_2_BLIT_DST_BIT for format 126 used by VkImage 0xf2039b0000000771[] with tiling VK_IMAGE_TILING_OPTIMAL. The Vulkan spec states: The format features of dstImage must contain VK_FORMAT_FEATURE_BLIT_DST_BIT`
This largely undoes a change I did recently where PrimitiveInfo has
a FRenderPrimitive* to save some space and keep a command at 64 bytes.
This wasn't a good idea because the inner rendering loop shouldn't
to any dereference in the common case.
This change reorganises PrimitiveInfo such that it stores all the data
necessary to render a primitive in the common case. The less common
cases are when hybrid instancing, morphing or skinning are used; in
those cases, a dereference into the renderable SOA is needed.
PrimitiveInfo currently has 16 bytes free, which we keep for futur use.
In opengl it's possible to bind several textures to the same texture
unit as long as they're a different target. Until now we were tracking
that state. In practice it's not very useful to bind several textures
to the same unit (it is a little bit when updating texture data, but
not when rendering). With the coming change to a descriptor set API, it
is better to have a 1-to-1 mapping between bound textures and texture
units.
So with this change, only a single texture can be bound to a texture
unit. If another texture in bound to the same unit with a different
target, we first unbind the texture from the current target.
There is less state to track, and it allows us to
"unbind a texture unit" (whereas before we'd have to iterate through
all the possible targets for that unit and unbind all of them).
* don't rely on FMaterialInstance having a default ctor
FMaterialInstance needed a default ctor because it is a field of
FMaterial but cannot be initialized before FMaterial itself is
initialized. So we had a defautl ctor and we'd finish the initialization
later. Conceptually the default material instance should have been
new'ed and a pointer to it stored instead.
That's basically what we do now, but to avoid the extra allocation,
we in-place new and delete the default material instance into an
aligned_storage inside FMaterial.
* Update filament/src/details/Material.h
Co-authored-by: Ben Doherty <bendoherty@google.com>
---------
Co-authored-by: Ben Doherty <bendoherty@google.com>
the gl backend did some of its cleanup in the its destructor,
including calling into OpenGL, however, the destructor is called from
the main thread, not the GL thread, so these calls would be no-ops at
best, and crashes in the worst case.
* don't crash if we don't have a Camera set on View
- also add a method to query if a camera was set
* Update android/filament-android/src/main/java/com/google/android/filament/View.java
Co-authored-by: Powei Feng <powei@google.com>
---------
Co-authored-by: Powei Feng <powei@google.com>
using thread affinity naively on big.little architectures is very flaky,
for now it's better to simplify and not use it at all, let the kernel
figure things out.
BUGS=[333582569]
* gltfio: add Asset/Resource extended implementations
- Add gltfio/src/extended to implement an alternate loader for
primitives. This is largely based on the implementation in
AssetLoader/ResourceLoader
- Able to correctly produce flat shading from gltf that only have
vertex positions and indices.
- This is not hooked into current code and should have no
practical effect on gltfio.
Originally we did this because we wanted to run on a big core on
android. However setting the thread affinity in this way is fragile,
we are not guaranteed to be on a big core, and we don't even know
if some thread is pinned to that core already; which was the case
with some GL drivers. This can also cause scheduling problems with
other threads.
We just remove this logic entirely for now, and we'll figure out
something better later to run on a big core.
Fixes#7748
BUGS=[333949404]
This change introduces a new chunk type to material files for precompiled Metal libraries. Previously, SPIR-V was the only binary type, so there's also a couple of refactor commits present here. Nothing is changed in Filament or matc yet.
BUGS=[333547148]
- Use new descriptor set and layout caching
- Remove descriptor set related code in VulkanPipelineCache
- fix leaks for descriptor sets/layouts
FIXES=248594812,325157400
A MaterialParser could be leaked if several edits happened before they
were latched -- this was because the MaterialParser was stored as
a raw pointer instead of a unique_ptr<>, this was done as an attempt
to avoid to use a lock around accessing mPendingEdits.
Added
- Cache for layouts
- Pools for descriptor sets
- Cache for descriptor set updates
- Cache for pipeline layouts
Does not have effect on implementation.
- Move VulkanDescriptorSet to VulkanHandles.h
- Add VulkanDescriptorSetLayout to VulkanHandles.h
- Add "input" descriptor set types to VulkanUtility.h. These are
structs that will be defined in the backend API (shared across
all backends) and eventually passed from the front-end to the
vk backend.
- Logic to parse descriptor set layout from the spirv-v shaders.
- Move UsageFlags type to VulkanUtility.h
- Just prep work. No effect to current implementations.
We were calculating the shadow visibility of spot/point lights. The
visibility was calculated during the "execute" phase of the FrameGraph
but it was used/needed during the setup phase. The result was that
the visibility was always delayed by one frame (really it was stale
data from the previous calculation).
We are now computing the shadow visibility earlier, during the
setup phase. This is also better because we can now skip culling
of these shadow maps entirely if we know they're not visible.
Fixes#7715
going forward we want to be able to throw exceptions from the backend
at the very least, we need to be consistant, currently we are
potentially throwing exceptions from `noexcept` places.
this changes makes it possible to throw exceptions from the backend,
during handle construction and conversion to pointers, which wasn't
allowed before.
We still can't throw from dtors because it's generally a bad idea,
better abort in that case.
Replace the num_views for OpenGL multiviwe only when
- The engine is initialized with multiview stereo
- The variant for the material contains STE flag
- The program is for surface
- It's vertex shader (this is already in)
For OpenGL multiview, it honors the qualifier `layout(num_views = X)`
specified in shader files to determine the number of views for
multiview.
We cannot recompile materials everytime the value changes. So replace
the value of num_views with the engine's eye count when shaders compile.
This PR adds a new `pause()` option to the `Engine` `Builder` and a new function
`setPaused()` to the `Engine`. While paused, the rendering thread will pause
indefinitely for commands as if none are available. As soon as the rendering
thread is unpaused, the commands are immediately executed.
in case the swapchain creation fails, it will now return a swapchain
with an EGL_NO_SURFACE handle. this will avoid having to nullptr check
the pointer in various places and will revert to the previous behavior
on failure.
FIXES=[329659681]
We verify that the buffer given to setImage() is at least as large
as needed for the given region to transfer; at least based on the
size given.
This might help catch b/330407429.
BUGS=330407429
This is due to color attachments being set to store=discard when
they are multi-sampled. It's unclear why that condition exists. For
now, removing it will fix the rendering issues with transparent
object + MSAA. We'll keep it as such until an issue surfaces.
Fixes#7674
- dynamic (default) no restriction apply
- static bounds: bounds and world transform can't be changed
- static: additionaly morphing/skinning and vertex/index buffers are
immutable.
This will allow some optimizations in the future. Currently, we just
store the type but don't do anything with it.
Plumb through multiview configurations to the pipeline so that the
engine draws scenes using multiview extension. Users need to prepare
shaders compiled with the `multiview` param and set the
`stereoscopicType` flag to MULTIVIEW in the Engine::Config to enable
multiview feature.
In this change, postprocessings for multiview are not yet supported. So
we all disable them until they're supported.
The debug option `combineMultiviewImages` combines layers as one image,
which allows us to check the final result.
- TangentsJobExtended extracts data from cgltf accessor and
runs geometry::TangentSpaceMesh on the attributes and computes
the tangent space.
- The /extended folder is meant for running this process. Note that
this API might remesh the input and will require corresponding
changes that might break previous assumptions.
- The general flow of the code is modeled after src/TangentsJob.h
- This is not hooked into current code and should have no
practical effect on gltfio.
This new parameter indicates whether the render target will be created
for multiview.
If the value is greater than 1, it tells the render target should be
created for multiview. Otherwise, 1 or 0, it creates a single layer
render target.
Instead of holding pointers to class instances in VulkanDriver,
we standardize by making the relevant classes have proper
constructors and initialize in VulkanDriver's constructor
initializer list.
- `isSwapChainProtected()` is now virtual
- `createDefaultRenderTarget()` is renamed to `getDefaultFramebufferObject()`
- new `getCurrentContextType()` returns the current context type
- `makeCurrent` now takes an additional `ContextType`
- `PlatformEGL::getContextForType()` to retrieve the `EGLContext` for
a given type.
- `PlatformEGL::makeCurrent` non-virtual utilities to set only the
context or swapchains.
For reasons unknown, after upgrading to XCode 15.3, dlopen can
no longer find libvulkan.1.dylib. We fix it by explicitly adding
/usr/local/lib to rpath for macos.
PipelineState now holds a handle to a HwVertexBufferInfo.
DriverAPI::draw() is now technically deprecated and replaced by the
more efficient draw2(), which only takes an index offset, index count
and instance count. The Pipeline to use is now specified with a new
API bindPipeline() and the primitive to use with bindRenderPrimitive().
This allows clients to reuse RenderPrimitives and ultimately Pipelines.
This change reduces CPU usage significantly on Metal and Vulkan, by
reducing the need to lookup for a pipeline at every draw call.
The application, however, must be a "good citizen" by reusing
MaterialInstance and RenderPrimitive as much as possible. We do have
RenderPrimitive cache however, so reusing the same VertexBuffer and
associated parameters also works.
Some default materials such as defaultMaterial and skybox have discrete
material file for feature level 0.
Combine these materials as one utilizing the `-P` option of matc.
This adds a new material property (float postLightingMixFactor) which
is used to mix the original color with the post-lighting blended color.
The default value is 1.0, which keeps the current behavior.
FIXES=[328498606]
cmgen mirrors environment maps by default so that the reflection map
appears un-mirrored. IBLPrefilter didn't do that.
EquirectangularToCubemap now takes a Config parameter that allows to
specify the mirroring, which is enabled by default.
FIXES=[320856413]
Protected contexts are now supported by the OpenGLPlatform interface
and implemented in EGLPlatform.
Protected contexts can read from regular and protected resources but
can only write to protected resources (e.g. protected swap chains or
textures backed by protected memory. These can be created on Android
via AHardwareBuffer and EGLImage for instance).
The underlaying EGL implementation must support protected contexts.
Switching to a protected context is achieved by using a
protected-content SwapChain in Renderer::beginFrame().
A protected-content SwapChain can be created using the new
CONFIG_PROTECTED_CONTENT flag at creation time.
The OpenGL backend implementation will then use a protected context for
rendering until an unprotected SwapChain is used again.
The crux of this implementation is to use different VAOs in
the different contexts, because those can't be shared between contexts.
We also need to synchronize the state with our state cache and ensure
VAOs objects are destructed properly in the right context.
* Add new parameter -P for matc
This new matc parameter `-P` or `--material-parameter` allows users to
set material properties to the specified value.
Values passed through this matc parameters have the highest priorities.
I.e., they overwrite material properties specified in the material file.
Previously the cache would try to keep its size below a user-settable
value. This was not effective because when that value was too small,
it would cause a lot of churn every frame without actually keeping
the memory usage below the specified value.
We now evict buffer aggressively after they've not been used
(for two frames by default), but we don't cap the size of the cache.
The cache will naturally settle at the size it needs. When dynamic
resolution is used, it might be needed to increase resources
maximum age, which is a user-settable value still.
This improves performance on mobile on many scenes because the 64MB
default value was too low, causing the crash to thrash.
The validation error triggers on hellotriangle using AMD (desktop), QCOM (mobile) and Mali (mobile) GPU.
Before this MR, only a single semaphore object was used to synchronize all the calls to vkAcquireNextImage (signal) and vkQueueSubmit (wait).
The issue is that by the time vkQueueSubmit returns, the semaphore is not necessarily reset.
When multiple frames are in flight, the next call to vkAcquireNextImage might try to reuse the semaphore while it is still in the wait status.
The semaphore is reset at a driver/hardware-dependent timing that's likely to be linked to the GPU queue execution.
The solution proposed by this MR is to use a pool of semaphores big enough to cover all possible queue submissions.
Previous commit [1] changed the semantic of the index to
mBufferObjects. Here we just make sure that if a buffer has been
allocated, we don't allocate another (otherwise, we'd leak).
Also cleaned up `updateBoneIndicesAndWeights` indexing
[1]: a3131a64b6
- Add cache for ds layouts and ds
- Abstract descriptors API into VulkanDescriptorSetManager
- Note that this is just a draft and not hooked into the current
implementation.
- better naming
- TimerQueryFactory doesn't depend on OpenGLDriver anymore,
only a OpenGLContext.
- timer query factory is now owned by and accessed through OpenGLDriver
- we can't temporarily store a negative number
in the query shared state, because it now indicates an error.
This is supported only by the PlatformEGL currently. There is not much
that can be done with it either at this point. A protected swapchain is
one that can only be written by a protected context, however, there
is currently no way to create such context.
This is currently only implemented in the GLES backend and simply
exposes GL_EXT_protected_textures. There is not much that can be done
with this yet. Protected textures can't be read nor written at the
moment.
* Add a new material param, stereoscopicType
This new parameter allows us to specify which implementation of
stereoscopic rendering Filament uses for the material.
This change just includes material parameter addition and shader code
changes, so it doesn't affect the current rendering behavior.
These changes will follow as separate commits.
- render pipeline changes
- material parameter override via matc parameter
- material document update
We're going to add a new implementation of stereoscopic rendering using
multiview. Thus we want to remove the word `Instanced` from all methods
and properties.
This shader takes an array texture and a layer index to draw to the
current render target.
This will be used for debugging purpose to combine an array texture
rendered from the multiview feature that is going to be implemented
later, so that we can verify the feature properly performed.
When shader compilation happens in threadpool mode, shader source code
isn't stored correctly in the token. This leads to empty error messages
if a shader has problems later on.
- added many precondition checks and asserts to VertexBuffer creation
- simplified code in VertexBuffer as well
- enforce BONE_INDICES to integer when specified by user since that's
what shaders expect.
- better comments about *always* setting BONE_INDICES to integer
- some code simplification in RenderPass + some comments about skinning
- in the GL backend we no longer set the vertex buffer objects at
renderprimitive creation time, because they might not be available
yet. Instead, we let the natural age mechanism update them next
time it's needed. This allows us to add some asserts about the
declared buffer being present
We do this to better match Gl, Vulkan and Metal, which don't need
to specify the scissor in the pipeline. In practice, this will also
allow us to set the scissor less often, saving a bit of CPU.
These are missing parts from the commit
111ad96134.
NDK 26.1.10909125 is used by default
Minimum API level on Android is now API 21 instead of API 19. This allows the use of OpenGL ES 3.1
Throw an NSException when a program fails to compile and then is used for drawing; this helps aid debugging compiler errors in production, where stdout logs are not available.
The OOB would happen is the scene never had any renderables, in that
case the scene's SoA would stay unallocated, but the summedAreaTable
code relies on it have at least a capacity of 1.
It was incorrect to skip the RenderPass entirely because it might have
had some custom commands that needed to be executed (e.g. for applying
post-processing in subpass mode).
This new backend object holds the information needed to create the
pipeline on vulkan/metal relative to draw calls.
It is used to create HwVertexBuffer.
* Add OpenGL extension for multiview
This extension is going to be used for multiview implementation in
OpenGL.
Now the API isStereoSupported takes a stereo type as a parameter.
HwRenderPrimitive doesn't need to know about the index offset and
index count, these parameters are only needed when drawing. draw()
is updated consequently.
This is a first step towards being able to lower the overhead of
draw similar draw calls.
A side effect of this is that the HwRenderPrimitiveFactory now will
cache buffers regardless of their index count & offset.
This reduces resource utilisation for Views that never need shadows.
It saves a UBO, two Entities and about 10KB memory. We also lazily
allocate the debugging DataSource, which saves about 10K per View
in debug builds.
Overall this change makes "simple" Views less than 4KB heavy down from
about 24KB (debug, 14KB release).
The main changes:
- ShadowMapManager is now allocated lazily
- the ShadowMap cache object is also allocated lazily
- debug DataSource is allocated lazily
- ShadowMaps are prepared/initialized with a Builder, which makes it
clearer that some APIs are only for preparing the ShadowMap cache.
- each handle now has a 4-bits "age", meaning that handles are recycled
only after 16 alloc/free cycles.
This is used to detect double-free and use-after free.
This should also allow us to compare handles, because freeing and
reallocating an object, won't produce the same Handle (at least
for 16 rounds).
- removed "type safety" checks because it's almost impossible to
get it wrong thanks to our compile time type safety checks. This
didn't provide a useful value added.
- This feature is built on top of being able to set/get a 8 bits tag
associated with the memory block returned by the pool allocator. We
use the "extra" parameter of the allocator to allocate a "hidden"
structure containing the age of that memory block.
- Also we don't allow to compare Handle<> of different types
- update the pools sizes for metal and vulkan, which were very outdated.
- add debug code on all backends to print the size of each handle
(with a compile time switch)
The most important change is that now the 3 pools of HandleAllocator
are sized so that each can accommodate about the same amount of handles.
This makes it easier to reason about. The total amount of handles is
three times that, since there are 3 pools.
We also try to allocate the buckets so that handles are evenly
distributed, however, that's very hand wavy.
With the current setup the number of handles per pool is as follows:
- GL : 3240 / pool / MiB
- VK : 1820 / pool / MiB
- MTL: 1310 / pool / MiB
* Automatically flush CommandStream
When generating commands, we now automatically flush the CommandStream,
so that we're guaranteed to not overrun the circular buffer.
* clenaup CircularBuffer implementation and API
Also fix a bug in DEBUG mode that could corrupt the CircularBuffer, it
was due to a wrong debugging code attempting to clear the unused
area of the buffer (this was wrong because in "ashmem" mode, there are
no guaranteed unused areas).
* Fix a couple threading vs. allocations
- prepareVisibleLights was run on a dedicated thread (via JobSystem),
but was using its own local ArenaScope. This is wrong because it
could reset the root arena at any later point. This is fixed by
just not using a local ArenaScope.
- related to the above, the root Arena (LinearAllocatorArena) didn't
use a locked policy, which cause also cause problems since some
allocations are done off the main thread. We now pre-allocate the one
buffer we need.
This PR also renames some variable and types to improve readability.
* Rework RenderPass to improve allocations and API
RenderPass now is a fully immutable object that gets constructed with a
RenderPassBuilder. RenderPassBuilder can be passed around and doesn't
do any (major) allocations.
All RenderPass allocations and heavy lifting is done in
RenderPassBuilder::Build().
Additionally, RenderPass cannot be copied anymore.
Where allocations happen is now much clearer.
* new LinearAllocatorWithFallback
LinearAllocatorWithFallback is a linear allocator that can fall back
to the heap allocator. We use it for the high level command buffer to
avoid crashing when running out of memory.
FIXES=[277115740]
* Update filament/src/RenderPass.h
Co-authored-by: Powei Feng <powei@google.com>
* Update libs/utils/include/utils/Allocator.h
Co-authored-by: Powei Feng <powei@google.com>
---------
Co-authored-by: Powei Feng <powei@google.com>
- Add methods for adding attributes to the input mesh
- Add method in TangentSpaceMesh for when user provides the
tangents
- Separate client-side Algorithm enum from implementation algorithm
(AlgorithmImpl)
- Fix CMake config for combining static libs
32 sample may be more suited to 2x upsampling, it gives 8 samples per
high-res pixel (instead of 4). This is also what FSR 2.0 is using,
which is useful for comparing.
This has caused issues and over time we have reduced the use of
spinlocks, it was only used in few places and we still have evidence
that it's causing ANRs.
We use utils::Mutex instead which is a low overhead mutex implementation
on Linux systems.
FIXES=[321101014]
it was incorrectly mapping the equirect image to a cubemap due to a
typo in our overload of atan2 which was swapping its parameters.
atan2 is now removed, and we use atan(y,x) instead. Also modified the
code slightly so it matches almost exactly cmgen's.
FIXES=[320856413]
Some files were not shown because too many files have changed in this diff
Show More
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.