* Add a Renderer API to force skipping frames
Renderer::skipNextFrames(size_t) can be used to force filament to
pretend the next N frames must be skipped. This is mostly useful for
debugging.
* Add DebugOptions to Settings
We still need to move the "Debug" features of gltf_viewer to this,
but this give us a framework to do it.
Currently there is one debug option that allows to set a number of
frames to skip.
ViewerGui propose a button to skip 10 frames using this framework
* Update libs/viewer/src/Settings.cpp
Co-authored-by: Powei Feng <powei@google.com>
* Update libs/viewer/src/Settings.cpp
Co-authored-by: Powei Feng <powei@google.com>
---------
Co-authored-by: Powei Feng <powei@google.com>
The Glslang SPIR-V remapper was removed, and replaced by the CanonicalizeIds
pass in spirv-opt. See https://github.com/KhronosGroup/SPIRV-Tools/pull/6174
Filament's GLSL post-optimization algorithm already runs CanonicalizeIds.
Bug: b:450891564
* fix a possible deadlock in AsyncJobQueue
drainAndExit() could get stuck because it waited for the job
queue to be empty, but that was not signaled.
in fact, drainAndExit() didn't need to do that.
* Improvements to FrameInfo
- return the GPU Complete timestamp
- return the app VSYNC timestamp
- works TimerQueries are not supported
The VSYNC time is just a convenience as it is the same value
provided by the application during Renderer::beginFrame() or via
Renderer::setVsyncTime().
it used to return false when setting the same value for the constant,
which other code used to invalidate the material or not. but it
was recently changed to always return true on success.
this reestablish the previous behavior.
Using struct as keys simplifies the parameter definitions of the
relevant pipeline, pipelinelayout, shader module methods. This
enables adding or removing fields without adding major changes
to method definitions.
Using utils::hash::MurmurHashFn also aligns with the style of
the rest of filament.
* Add a workaround for Filament's breaking change to add_subdirectory for Abseil, see: https://github.com/google/filament/issues/8611
* Fix #pragma warning syntax for MSVC
* Only search for an external Abseil dependency if a new option FILAMENT_USE_EXTERNAL_ABSL is set
* Make JsonishParser use utils::Status
- add unsupported error in utils::Status
- add invalid case in the test
* return a pair of Status and string in resolveEscapes;
use initializer list for JsonishString and move that to the header.
This is needed to instantiate `std::streampos`. It currently relies on transitive header inclusion to get that, which is going away for libc++ in ebcf1bf2ec.
- --no_rebuild will skip building the gltf_viewer again
- --num_threads will limit the number of threads used in running
the rendering test.
Both of these options are meant for debugging locally.
- Add WebGPUQeuueManager to manage queue submissions
- The manager will keep a "last status" field that will track
the status of the last submission.
- Any created HwFence will be associated with a status object.
- The object updates in a callback that indicates that the
submitted workfload has been completed.
This change addresses a platform-specific issue on Windows where shared
OpenGL contexts must be created on the same thread as the primary
context.
To resolve this, we now pre-create a pool of shared contexts when the
driver is initialized. These contexts are then distributed to other
threads as needed, ensuring shared context creation requirement on
Windows. This allows us to be able to use THREAD_POOL mode for shader
compiler service on Windows. So Windows build uses THREAD_POOL mode
instead of ASYNCHRONOUS mode as of this change.
This change also refactors the shader compiler service to catch and
report errors in the same thread where the program compilation and
linking actually performed as it's the correct way to use shared
contexts. Otherwise it may crashes.
* Use utils::Status in MaterialParser
* Use utils::sstream instead of std::stringstream
* Remove remaining std::cerr and dep; update MaterialParser::reflectParameters
* make error message in utils::Status more generic
---------
Co-authored-by: Powei Feng <powei@google.com>
- Fix the magnifier positioning for both compare and standalone
mode. Simplified a lot of the logic and streamlined passing
of states between components.
- Slight css adjustments
ImmutableCString is a string class similar to CString except it's
immutable. ImmutableCString occupies 16 bytes instead of 8 for CString.
However, ImmutableCString is able to avoid memory allocation when
constructed from a string literal, and in that way it us similar
to StaticString.
ImmutableCString can be auto converted from StaticString.
The backend tag tracking is updated to use ImmutableCString and
the FrameGraph resource manager us updated to use StaticString.
Together these changes significantly cut down heap allocations due to
internal tagging.
We also add optional tracking to {Immutable}CString.
* Minor changes in utils::Status
- << operator doesn't have to be friend
- simplify getErrorMessage to not use strlen internally
* Replace std::ostream to utils::io::ostream
* utils: RefCountedInternPool/RefCountedMap
First, introduce RefCountedInternPool, a reference counted intern pool of
Slice<const T>. Just acquire() a slice that you want and you're guaranteed to
get exactly one canonical value-equal Slice<const T> back.
Additionally, introduce the concept of NullValue to RefCountedMap. A NullValue
defines what should be considered an uninitialized value; by default, it's the
default value of that type (0 for ints, nullptr for pointers, etc). This allows
us to lazily-initialize values in the map. A client can acquire() a bunch of
different resources which will be initialized only when get(factory) is called.
If a client attempts to get() a value without specifying a factory, and the
value is not initialized (i.e. equal to NullValue{}()), RefCountedMap will
panic.
* utils: add unit tests for ref-counted collections
* utils: remove C++20 features, fix memory issue
* utils: remove RefCounted from InternPool
* engine: change spec constants to simple list
For a shader program cache to be keyed on the set of spec constants that a
program has set, we need to know full exact list of constants, including their
default values. If we're going to always hold a list of all constants all the
time, then we may as well store them as a simple list where each index is the ID
number of the spec constant.
As part of this change, we now write the default values of spec constants into
the material file metadata.
* fix indent
* engine: fix sRGB swapchain emulation
* slice: fix memory semantics
* slice: prefer passing slice by value
This lets us do nice things like coercing Slice<T> to Slice<const T>, etc.
* slice: fix unit tests
* slice: fix copy/assignment, hash function
Don't attempt to define a copy constructor/assignment operator which would
convert a constant type to a mutable type.
Additionally, fix the hash function such that we're hashing U instead of const
U.
* new utility AsyncJobQueue
this is a very simple job queue, it spawns a thread and runs the jobs
pushed to the queue in sequence.
* use AsyncJobQueue in OpenGLTimerQuery
The viewer supports pulling artifacts based on PR number, and now
we support providing Run ID as an alternative to identify the
renderdiff run on Github CI.
In the current implementation, the function std::cout is used inside a signal handler. This is problematic because std::cout is not
async-signal-safe. According to POSIX standards, only a small set of
functions are guaranteed to be safe when called from signal handlers,
and std::cout is not one of them. Using non-async-signal-safe functions
inside signal handlers leads to undefined behavior and can cause
crashes, deadlocks, or other unpredictable issues.
By making these changes, we avoid undefined behavior and ensure the
program can handle signals safely.
* new fenceWait() API in the backend
* correct implementation of fenceWait() for GL and WebGPU
- fenceWait() now works correctly if called before the fence is
created on the backend side
- the STL's condition wait_for() is actually a wait_until, which
means we have to make sure now() + timeout doesn't overflow.
- also we make sure to keep a reference to the fence internal state
while we wait so that we're safe if it's destroyed during that time.
* Implement fenceWait() properly on vulkan
On Vulkan, unfortunately, the implementation is complicated, as we
need three levels of "wait".
First we need to wait using a mutex/condition that the shared fence
is created (this is because on vulkan, all HwFence share the same
"state" associated to the same command buffer).
Once we have that, we need to wait for the VkFence to be submitted,
this is done using a read/write lock and condition variable. The
read/write lock is not needed at this stage, but in the next.
Once the fence is submitted, we can now wait using vkWaitForFences,
however, external host synchronization is needed. Multiple
vkWaitForFences can be issued together (and use the read lock), but
must be mutually exclusive with vkResetFences and vkQueueSubmit.
By construction, we know that this can't happen during vkQueueSubmit
due to the "2nd level" of wait, however we need to prevent
simultaneous calls to vkResetFences, this is done using a write lock.
By construction, we're guaranteed that when vkResetFences is called,
the fence has signaled, we just need to wait for all vkWaitForFences to
return.
A side effect of this change is that fenceGetStatus() has a better
implementation, since it's just a wait with timeout of 0.
* Update filament/backend/src/vulkan/VulkanDriver.cpp
Co-authored-by: Powei Feng <powei@google.com>
---------
Co-authored-by: Powei Feng <powei@google.com>