The VulkanProgram constructor was bailing out early and emitting a
warning because it saw that one of the stages wasn't fulfilled.
However it's okay for a pipeline to be missing a compute program.
Fixes regression that started with fabba73b1.
to emulate the bindless API in the gl backend we always used the highest
texture unit available. However at feature level 3, we support up to 62
textures, so the that max was bumped to 62 -- however, where we're not
on a feature level 2 device, that texture unit doesn't exist.
Instead we now always use binding 31, which is guaranteed to exist by
EGL's minspec.
to emulate the bindless API in the gl backend we always used the highest
texture unit available. However at feature level 3, we support up to 62
textures, so the that max was bumped to 62 -- however, where we're not
on a feature level 2 device, that texture unit doesn't exist.
Instead we now always use binding 31, which is guaranteed to exist by
EGL's minspec.
* minimal backend support for compute
- added api to dispatch a compute shader
- added api to create and bind a ssbo
- added api to read back a buffer
Only implemented in the gl backend
* Add a backend compute test suite
* basic support for compute shaders in matc
this is still very much work-in-progress.
We're not supporting images nor ssbo for now.
* rename UniformInterfaceBlock to BufferInterfaceBlock
* augment BufferInterfaceBlock to support ssbo features
- add support for std430
- add support for ssbo
- add support for variable-size array
- add support for memory qualifiers
* reformat MaterialBuilder
* material format: move subpasses outside of parameters
subpasses now are their own json property instead of being a
"parameter".
* refactor parameter() methods to match Buffer/SamplerInterfaceBlock
We're just shuffling the arguments.
* add support for buffers in .mat files
* filamat now generates buffer blocks (ssbo)
* take feature level into consideration when optimizing shaders
* don't store the 'uniform binding' chunk for level 2 materials
this includes some refactoring/cleanups of MaterialParser
* matinfo: fixes for compute
- separate subpasses from parameters
- don't attempt to print material properties
it is not true that the whole box is inside the frustum if we have
8 vertices and some frustum vertices are in the box -- that's even
non-sensical.
We now test for this case by checking that we have all (8) vertices of
the box inside the frustum.
This caused some shadows to be missing.
This is because most android devices only support 16 texture in the
shaders (94.4%), so we can't realistically have feature level 2 demand
that.
Instead feature level 2 enables compute/ES3.1 features.
This is a feature request from Google. It allows users to "preload" an
asset, ie you can now create all VertexBuffer objects, Texture objects,
etc, without actually creating any entities or renderable components.
In the past we used TransformManager to help out with computing the big
asset-level bounding box, but now we use `gltf_node_transform_world()`
because entities might not yet exist.
One minor side effect is that `FilamentAsset::getBoundingBox()` now
returns the AABB that was determined at load time, and does not account
for instances. As a result, our `gltf_instances` sample app looks
slightly different but this is expected.
In VulkanPipelineCache, `getShaderStageFlags()` and `getUsageFlags()`
are used to track which samplers are used in the VERTEX stage and which
are used in the FRAGMENT stage. The recent change I made was incorrect
because it did not account for samplers that are used in BOTH stages.
This fixes the recent regression where we see validation errors when
running `gltf_viewer` in ubershader mode.
Some (poorly authored) glTF assets have several `image` elements
that all refer to the same URL or buffer view. When this occurs,
we create only 1 Filament Texture.
These assets regressed after PR 6051, which consolidated the texture
related fields in `FilamentAsset`, but did not include an ownership flag
in the new `TextureInfo` struct.
- fix View::setVisibleLayers to match code. By default only layer 0
is active, despite the documentation stating otherwise.
- add a helper to enable/disable layers more easily
- don't use layer 0,1,2 for the overdraw function as they were used by
FilamentApp in "multi view" mode.
- improve scissor documentation, specify coordinate system and
clipping behavior
- scissor now takes the guard bands into account
- on the backend side the scissor is no longer clipped to the viewport
- clipping to the viewport is now done on the filament side
- don't set scissor when material instance doesn't specify one
(common case)
AssetLoader now loads assets in two passes:
- Pass 1 creates VertexBuffer objects, MorphTargetBuffer objects, etc.
- Pass 2 creates entities, renderables, etc (only if numInstances > 0)
This feature will help us integrate gltfio with an internal library at
Google.
The asset previously had three confusing fields related to textures:
mTextures, mTextureSlots, and mTextureBindings.
These are now consolidated into a single field, which simply has one top
level array item per `cgltf_texture`.
The memory footprint is smaller because we no longer bother to store
`TextureSampler` objects, instead we simply defer their construction
until calling setParameter.
Last but not least, we now assert in debug builds if the usages of a
particular texture have inconsistent sRGB flags. In the past,
inconsistent sRGB would be silently ignored.
In other words, we will now assert if you try to use the same texture
for `baseColor` and `normalMap`, whereas in the past we would simply
exhibit non-deterministic behavior in this situation (with respect to
sRGB semantics).
gltfio can now ask the material provider plugin which `Material` would
be used for a given set of requirements. Prior to this change, gltfio
could only create a new `MaterialInstance`.
This method is necessary to support an upcoming gltfio feature.
This broke asyncGetLoadProgress() and caused WebGL to crash reliably
because ResourceLoader got destroyed too soon.
Bug was introduced with de7dfc2ea6.
I intend to cherry pick this to rc/1.27.0, which is where it was
introduced, so there's no need to update the release notes.
This broke asyncGetLoadProgress() and caused WebGL to crash reliably
because ResourceLoader got destroyed too soon.
Bug was introduced with de7dfc2ea6.
I intend to cherry pick this to rc/1.27.0, which is where it was
introduced, so there's no need to update the release notes.
* check that user materials don't exceed their allowed features
* backend sampler limits now take feature level into account
- in the backend, the constants are now in an array indexed by the
feature level
- samplerBindingMap now asserts only what it can.
- matc (filamat) now logs the user samplers when an error is detected.
* Add JNI for TransformManager.getChildCount(), TransformManager.getChildren() and scene.hasEntity()
* Update RELEASE_NOTES.md
* Fixes
* Change getChildren to take a nullable array
* Remove no params TransformManager.getChildren()
* Update RELEASE_NOTES.md
Co-authored-by: Ben Doherty <benjdoherty15@gmail.com>
Co-authored-by: Ben Doherty <bendoherty@google.com>
One of the bloom texture ended-up dangling in the material's
SamplerGroup. That sampler group was never used to draw with, but was
made active which caused problem with the backends.
Also make sure the public API can unset a texture in a MaterialInstance
by passing nullptr for the texture.
For each "cgltf_material", we now create one "MaterialInstance", even
if a given asset has multiple instances. In the future, we might make
this behavior configurable to make better use of Filament's
auto-instancing feature.
This change is a feature request from Google, but also this behavior is
more consistent with the code comments.
Also some related cleanup:
(1) Use FixedCapacityVector instead of robin_map.
(2) Move the cache to move out of the asset and into the loader,
because it is only used at load time.
in a few places filamat loses the value of targetApi and targetLanguage
and attempt to guess it from other values, this lead to inconsistencies.
we now keep both targetApi and targetLanguage and use them appropriately.
in particular we don't use the optimization level to "guess" what
targetLangage we're on.
In the end this resolve a prior unit test failure and allows us to not
have to use "spirv" rules when generating only GLSL.
We use TargetLanguage::SPIRV instead of GLSL which affects how the
source GLSL is generated, in particular which version is used.
This change is not a problem for these unit tests, but is probably
exposing another problem -- we will address that separately.
We were keeping the list if uniform names in Material and passing
pointers to the backend. Unfortunately, HwProgram can outlive
Material because it is legal to destroy a Material once it's not
needed on the client side. e.g. just after rendering something.
This was happening with the IBLPrefilter code, but probably elsewhere
too.
We now just store CStrings in HwProgram.
The immutable inverse bind matrices can be shared among instances, so
they are now stored in Asset, not in Instance.
Also, there are now two "load" phases for skinning data:
(1) storing the inverse bind matrices
(2) building the Entity mappings (for animation efficiency)
Phase 1 is done in `ResourceLoader` because inverse bind matrices can
live in an external bin file.
Phase 2 is done during Instance creation, because that's when entities
are created.
Prior to this change, `recomputeBoundingBoxes` was an opt-in config
parameter in ResourceLoader. It is now a method on FilamentInstance.
The old API did not work for dynamically created instances. Since this
is a relatively obscure feature, we considered removing it completely,
especially since the computation requires the presence of CPU-side
vertex data combined with the transform hierarchy.
Instead of removing the feature, we decided to move it to a better
place. This paves the way for some upcoming improvements, which include
reducing the memory footprint for assets. It also improves overall code
organization and separation of concerns.
* Fix warning C4146: unary minus operator applied to unsigned type, result still unsigned
* Fix warning C4068: unknown pragma 'nounroll'
* Fix warning C4068: unknown pragma 'unroll'
* Fix warning C4068: unknown pragma 'clang'
* Fix warning C4305: 'initializing': truncation from 'double' to 'float'
* Fix warning C4267: 'argument': conversion from 'size_t' to 'utils::FixedCapacityVector<filament::uberz::WritableArchive::Material,std::allocator<T>,true>::size_type', possible loss of data
* Fix warning C4267: 'argument': conversion from 'size_t' to 'uint32_t', possible loss of data
* Fix warning C4244: 'initializing': conversion from 'A' to 'T', possible loss of data
* Fix warning C4334: '<<': result of 32-bit shift implicitly converted to 64 bits (was 64-bit shift intended?)
* Fix warning C4293: '>>': shift count negative or too big, undefined behavior
* Fix diagnostic warning C4189: 'channels': local variable is initialized but not referenced
* Use [[maybe_unused]] where possible and revert aa79bd6fa8.
* Revert unary minus for non-MSVC compilers
* Add macro for enabling warnings temporarily
* Get rid of UTILS_HAS_CXX17
* Revisit warning related macros
Co-authored-by: Levente Koncz <levente.koncz@shapr3d.com>
this case could cause an assert in debug builds. There was a few bugs:
- when computing the intersection between a box and a frustum, a special
case test had a typo which would cause extra work in some case. Also,
we were not detecting correctly when there was no intersection at all.
This could result in some intersection point being found.
- Finally, we reject the intersection volume when it has only 3 vertices
because that's not a volume.
Fixes#5933
The main goal of this change is to have "ugly" code only in filamat.
In particular, the sampler binding information is now recorded
into the material file and used on the filament side to inform the
backend.
This means that on the filament side we only have generic code with
all the "uglyness" in filamat. In particular SamplerBindingMap and
SibGenerator now only exist in filamat.
Files of greater interest:
Material.cpp, MaterialBuilder.cpp
This is a workaround for the following Chrome issues:
https://crbug.com/1348017 Compiling GLSL is very slow with struct arrays
https://crbug.com/1348363 Lighting looks wrong with D3D11 but not OpenGL
This requires a rebuild of materials for WebGL users.
Fixes#5859.
partially revert a recent change where Program needs a DriverApi in its
ctor. This was a misguided change. Backend API never take a DriverApi
as parameter.
Checking the feature level, for instance, should happen as a
precondition, or in the backend as postcondition.
GLES3.0 (and GL4.1) need informations about the uniform block bindings
because they don't allow to do that setup in the shaders. So we store
that information in the material blob and retrieve it on the filament
side in Material. This information is passed to Program so it can
create the bindings.
Prior to this change, this information was set by Material itself, but
this ment we had two places where these bindings were hardcoded.
The bulk of the change is to add a new material chunk which stores an
array of {name, binding}, retrieve it on the Material side and pass it
to Program.
- remove unused SamplerBindingMap parameter
In fact, the SamplerBindingMap is used, but it is passed inside the
MaterialInfo structure, so it doesn't need to be passed as parameter.
- Don't create unneeded SamplerBindingMap temporaries
This change was motivated by some internal work at Google and has the
benefit of simplifying the gltfio API and implementation. There are 2
major API changes:
(1) Consolidate separate loader entry points for GLB and GLTF.
The distinction between GLB and GLTF can be made from the file content
alone, because GLB has a 4-byte magic string in its header. There is no
need for separate entry points. Clients do not (and should not) need
to check the file name extension.
(2) Remove the distinction between "instanced" and "non-instanced"
glTF assets.
In the new scheme, all assets have at least 1 instance.
Broadly speaking, in gltfio an "asset" is a collection of Filament
objects like textures and vertex buffers, while an "instance" is a
collection of entities and components (e.g. the transform hierarchy).
This API change makes life easier for clients because they no longer
need to decide a priori if they will ever need to add instances.
This change also moves some public-facing methods from FilamentAsset to
FilamentInstance:
- getSkinCount, getSkinNameAt
- getJointCountAt, getJointsAt
- attachSkin, detachSkin
* Begin Sorting SubProjects into Folders
* Add more subprojects to folders
* Add even more subprojects to folders
* Add further subprojects to folders
* Move the last two projects
* Move Resources to a Resources subfolder
* Remove spaces to be stylistically coherent
* Revert Improper CMake Modifications
* Revert erroneous line removals
* Only specify sdl2's folder on WIN32
* Add the shader subprojects to a Generated folder
* Move shaders to Filament/Shaders
* new feature level API for backends
backend can now return a "feature level", each level corresponds to a
"bundle" of features.
Level1: ES3.0 capabilities
Level2: ES3.1 capabilities + 31 textures + cubemap arrays
Currently metal always returns level 1, GL and Vulkan return level 2
if 31 textures or more are supported.
* Add public APIs for feature levels
* Add infrastructure to check feature levels in materials
* validate material feature level on use
The validation is done when creating a renderable. If the engine doesn't
support the material's feature level, an exception is thrown (or assert
if exceptions are not enabled).
* material documentation
* activate ESSL 3.10 for feature level 2
also generate #defines to identify available feature levels
* support for cubemap arrays in the public API
if feature level 2 is supported, cubemap arrays can be used from the
public API.
* add release notes
With VERTEX_DOMAIN_DEVICE the vertex shader doesn't apply the
projection (since the vertices are already in clip space), however,
both TAA and guard bands need to jitter/offset the clip space, and
it is done at the projection level.
We now store the clip space offset separately so that it can be applied
to VERTEX_DOMAIN_DEVICE vertices.
We also introduce a new material parameter, vertexDomainDeviceJittered,
a boolean that controls whether clip space offset (above) is applied.
This is because a VERTEX_DOMAIN_DEVICE material that uses the built-in
projection matrices generally ends-up with the jitter already applied,
this is the case with the Skybox for instance.
Fixes#5917
Fixed a comment that said "We store 64 bytes per bone.". The actual
number is 32.
Developers who know their users have powerful devices may wish to exceed
ES3.0 minspec constraints to allow more bones and / or morph targets.
Fixes#5785.
The custom release callback that I provided was in the wrong place; it
was only being used for a path string, not the actual buffer content.
The cgltf API is a bit awkward in this area.
No need to update RELEASE_NOTES because this will be cherry picked to
the RC branch, which is where the bug introduced.
Fixes#5918.
Filament does not yet fully support threads with WASM, but this is a
baby step in that direction.
To enable experimental pthreads support, enable the WEBGL_PTHREADS CMake
option. This will enable pthreads support in `gltfio` and `utils`, which
is known to work, but not when served with GitHub Pages.
The web server must emit COOP, COEP and CORP headers, so our build
instructions now recommend the use of `emrun` for local testing.
This also changes our demos so that they do not use unpkg, which
does not work when using `emrun`, due to cross-origin restrictions.
Filament does not yet fully support threads with WASM, but this is a
baby step in that direction.
To enable experimental pthreads support, enable the WEBGL_PTHREADS CMake
option. This will enable pthreads support in `gltfio` and `utils`, which
is known to work, but not when served with GitHub Pages.
The web server must emit COOP, COEP and CORP headers, so our build
instructions now recommend the use of `emrun` for local testing.
This also changes our demos so that they do not use unpkg, which
does not work when using `emrun`, due to cross-origin restrictions.
This feature can improve load time when textures are downloaded from the
web on non-filesystem platforms like Android.
More specifically, this allows downloaded texture assets to arrive after
the user calls asyncBeginLoad(), which means that decoding and
downloading can occur concurrently.
Prior to this PR, we already used JobSystem for decoding, but we did not
kick off any jobs until after all assets were downloaded.
Still TBD: add this feature for external vertex data.
Partial fix for #5909.
Earlier versions of cgltf did not support file reader customization.
This was fixed back in Dec 2019 but at the time I did not notice, so
we never bothered cleaning up our usage.
In the future we would like WebGL + Android builds to permit texture
downloads to occur concurrently with the texture decoder jobs. This PR
is basically a preparatory refactoring, but with the nice side effect of
removing a memcpy.
it was a duplicate state from the true gl state which could easily cause
problems. It only existed to optimize state updates when nothing changed
but we already have fine-grained tests for this.
It was culled by the frame-graph because it didn't have "read" from
any of its resource, only writes. However, it does set uniforms, so need
to be called.
fix#5874
StructureOfArray always aligned each array to the same alignment as
malloc (usually 8 bytes), but that was not enough if one of its type
has stricter alignment requirements.
StructureOfArray now always honors at least the alignment requirement
of each array.
Also removed dependency on EntityInstance.h
Fixes#5727
We used to have a mix of fatal and non-fatal assertions for precondtions
errors. From now on, we always throw if exceptions are enabled or
crash with a log otherwise.
In most places this is simply replaced by `std::string_view`.
We also change a few internal/private headers so they accept
`std::string_view` instead of `utils::CString`.
Internally we use std::string_view and the public API is augmented
with APIs that take a length for strings, which makes them useable
with string_view parameters.
Also fix exception specification for all setParameter methods, which
can throw if exceptions are enabled (or exit the program otherwise).
When FTransformManager computes accurate world transforms, it adds downcasted leftover to translation part to restore precision.
However, both transltation and leftover are given as float3 - simply adding them resut float3, so addling leftover become meaningless.
one or both should be upcasted first.
I have disabled building SDL with headless EGL, because
SDL_config_minimal.h doesn't work with EGL, and I don't know how to
implement a an SDL config that would work with EGL.
I have verified that this works in a separate project, and that it
compiles in this project.
```
$ ./build.sh -e release
$ find ./out/ -name "*EGL*"
./out/cmake-release/filament/backend/CMakeFiles/backend.dir/src/opengl/platforms/PlatformEGL.cpp.o
./out/cmake-release/filament/backend/CMakeFiles/backend.dir/src/opengl/platforms/PlatformEGLHeadless.cpp.o
./out/cmake-release/libs/bluegl/CMakeFiles/bluegl.dir/src/BlueGLLinuxEGL.cpp.o
```
I have disabled building SDL with headless EGL, because
SDL_config_minimal.h doesn't work with EGL, and I don't know how to
implement a an SDL config that would work with EGL.
I have verified that this works in a separate project, and that it
compiles in this project.
```
$ ./build.sh -e release
$ find ./out/ -name "*EGL*"
./out/cmake-release/filament/backend/CMakeFiles/backend.dir/src/opengl/platforms/PlatformEGL.cpp.o
./out/cmake-release/filament/backend/CMakeFiles/backend.dir/src/opengl/platforms/PlatformEGLHeadless.cpp.o
./out/cmake-release/libs/bluegl/CMakeFiles/bluegl.dir/src/BlueGLLinuxEGL.cpp.o
```
GL_ES_30 becomes MOBILE
GL_CORE_41 becomes DESKTOP
ShaderModel controls which flavor of GLSL (GL or ES) is used both when
reading and outputting materials.
It's also used to set default quality settings and the default precision
of all fragment shaders.
Technically, Vulkan and Metal don't need this distinction, but the GL
backend does.
this is more in line with other APIs of the backend. This change is
complete for the GL backend, but for the metal/vulkan backend we still
use a SamplerGroup as the internal data structure, which is just
temporary.
Eventually, SamplerGroup should becomes a "filament" only API (not
a backend API).
SamplerGroup itself is now a more "traditional" class where copy and
move ctor do what you'd expect. This actually removes a few copy of
the internal data in some cases and uses less memory, at the cost of
doing some heap allocations, but they should be rare and outside of
the main loop.
we mow do most of the work of validating the sampler parameters and
resolving to an actual GL sampler, when updating a SamplerGroup,
instead of doing this each time a program is made active.
A lot of cpu work is saved when the same samplergroup is reused with
multiple programs.
this is the start at making HwSamplerGroup more "real". It shouldn't
keep a reference to the filament::SamplerGroup, which is just an object
to pass the data.
for now, we move the SamplerGroup reference into the concrete classes to
keep the same implementation. But now it becomes an "implementation
detail" of the respective backends.
- remove the 2 argument version of setSampler
- use a bool instead of bitfield for the dirty state
- try to avoid setting dirty bit if setting same sampler
Starting with 3.1.14, embind started to support for `noexcept`
which caused multiple definition errors since we have a workaround
in place that alreadys supplies template instantiations for `noexcept`.
This change should not affect G3 since our JS bindings are not used
in G3.
The upstream fix is here:
https://github.com/emscripten-core/emscripten/pull/17140Fixes#5789.
This is not intended to be used yet because we're not currently
checking that cubemap array are actually supported, however, if they
are, they should work.
the depth of the texture wasn't taken into account. In practice this
would restrict the number of mip levels of a 3d texture that would have
a larger dimension in depth.
The main goal is to allow more flexibility, allow cubemap arrays in
the future and better match vk and metal apis.
Main changes:
- remove updateCubeImage
- remove update2DImage
- update3DImage is now the only texture upload backend API
cubemaps are now treated just like a 2D array of 6 layers.
For this reason, Texture::setImage(..., FaceOFfsets) is deprecated.
Additionally, the 2D versions of Texture::setImage() become inline
helpers.
A side effect of this change is that it is now possible to update only
a single face of a cubemap, but also a region of a face (or faces).
This PR changes how Metal handles buffer updates. Previously, Metal allocated a full new buffer each time an `updateBufferObject` command was issued; however, it did not copy the previous contents of the buffer over to the new buffer, so partial updates did not work correctly.
Now, Metal allocates a single, private GPU buffer and employs temporary staging buffers whose contents get blitted to the private buffer at each update.
There's still some room for optimizations, and I need to give more thought to how I want to implement `updateBufferObjectUnsynchronized`.
- move all froxel configuration constants out of Engine.h, unlike
the previous todo/comment, these shouldn't be part of Engine::Config.
- same for irradiance map
For some android gpu drivers, some uniform arrays should be initialized to be used in the shader, even if not used.
Co-authored-by: Mathias Agopian <mathias@google.com>
This code adds a config object, "ConfigParams," to Engine creation parameters for setting memory buffer sizes for command buffers and driver handle arena sizes. It will use #define values (FILAMENT_PER_FRAME_COMMANDS_SIZE_IN_MB, etc.) as defaults (and as minimum acceptable values) if the user does not provide values. It attempts to validate the values given to prevent the user from creating a unusable state.
BlobDictionary and LineDictionary were storing blobs as map keys to
achieve simple compression, but they also stored duplicates of
in a vector for index-based lookup.
Now, the vector is storage and the map has keys that are string_view.
- getNear() and getCullingFar() now return doubles
- updated documentation
- all setProjection() calls can now throw (when enabled) and will
do so if preconditions are not met (instead of setting a default
projection).
- Frustum can now be logged on debug builds
This patch enables user scissor in Metal backend; There was no implementation for it.
While the absence of the feature in Metal does not incur serious problem, many rendering glitches were found in apps using ImGui due to it.
Co-authored-by: Benjamin Doherty <bendoherty@google.com>
auto-instancing can have some overhead, so when it is known that the
scene doesn't have identical primitives, it is better to disable it.
(disabled by default).
Also add some missing bindings for `enableAccurateTranslations`.
Reflects a change from Betty and should be cherry picked to v1.23.3
Users could customize the ImGuiHelper camera, but they had no control
over the scissor coordinates. This allows them to use vertically flipped
coordinates, which, unfortunately, is required for MediaPipe
integration.
Reflects a change from Betty and should be cherry picked to v1.23.3
Users could customize the ImGuiHelper camera, but they had no control
over the scissor coordinates. This allows them to use vertically flipped
coordinates, which, unfortunately, is required for MediaPipe
integration.
This was too tricky, it highlights that we definitely need refactor this
to share code with the flattener / unflattener pipeline. I'll look at
that next.
a 64 bytes pool seems to work with both clang and msvc, unfortunately,
c++ doesn't let us know the allocator object size at compile time
for map containers, so we have to guess.
* BlueVKDarwin: Simplify the build and loading process.
Some of our CMake logic was not necessary because we do not staticly
link against anything for Vulkan. All entry points are dynamically
loaded.
Some of the load-time code was also needlessly complicated. In fact the
ICD environment variable that we were setting is now deprecated.
I tested this PR with:
- macOS + June LunarG SDK
- Android on a Pixel 6
* Fix up, further simplification.
This lets us avoid the following validation error.
Attempting to create a VkDevice from a VkPhysicalDevice which is
from a portability driver without the
VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR bit in the
VkInstanceCreateInfo flags being set...
This will allow us to fix the validation error related to
VK_KHR_portability_enumeration.
Also, macOS comes with Python 3 nowadays so we're upgrading the script
from Python 2.
Unsynchronized update just means that the buffer is updated regardless
if what the gpu is doing, the synchronization is the responsibility of
the caller.
Also added resetBufferObject(), which essentially destroys and reallocate
a buffer for the same handle.
- rename PerRenderableUibBones to PerRenderableBonesUib to be more
consistant with other interface block naming.
- make sure the C++ struct and the UBO definition match.
PerRenderableBonesUib is a UBO with one bones[256] field, but the
C++ struct has a single bone and treated the UBO as an array.
This makes things less confusing.
We can now use sizeof(PerRenderableBonesUib) in many places which
better expresse what we are doing.
- Fix an off-by-one assert when setting a skinning buffer to a renderable
- Asserts that no more than 256 bones are associated to a renderable
- improve documentation and fix some typos
We no longer use the hardcoded objectUniform UBO name, instead, we
access the object uniforms through the new getObjectUniforms().
Because it's not possible to return a "Uniform Block" from a function
in GLSL, a large part of this change, is to replace the interface block
by a structure.
Note: getObjectUniforms() is not public, but it is used by gltfio to
access the userData field, which is also not public at the moment.
DEPTH commands are now sorted just like COLOR commands, that is,
they use a 10 bits z-bucket and the material id in the sorting key.
This allows instance-able primitives to be sorted next to each other.
We still use resgen for convience, but the archive is now passed in
from the client application.
This will allow us to shrink the gltfio Android library (stay tuned).
This boolean parameter is used with materials that need to access
`getInstanceIndex()` (filament's equivalent to `gl_InstanceIndex`).
It is false by default, and getInstanceIndex() is not accessible.
This is intended to be used in concert with
`RenderableManager::Builder::instances()`.
a 64 bytes pool seems to work with both clang and msvc, unfortunately,
c++ doesn't let us know the allocator object size at compile time
for map containers, so we have to guess.
An ubershader archive is a bundle of filamat packages with some metadata
that conveys which glTF features each material supports.
This PR does three things:
1. Adds a new command line tool called `uberz` that consumes a list
of filamat files and metadata text files and produces a single
ubershader archive.
2. Adds a new library (also called `uberz`) that is used by `gltfio`
to read ubershader archives, and used by the above command line
tool to write ubershader archives.
3. Enhances `UbershaderLoader` so that it no longers uses a hardcoded
set of materials, and instead takes an ubershader archive.
Ubershader archives have a simple binary layout that can be memcpy'd
directly into a C struct. The metadata is specified using a text file
with key-value pairs. These two file formats have formal desriptions in
the README in `libs/uberz`.
In a subsequent PR, we will remove the `gltfio_resources` target and
change the signature of `createUbershaderLoader` so that it takes
an archive.
We were re-building various C++ files in three different targets
(basis_encoder, basis_transcoder, basisu executable), it's probably
better just to set up proper dependencies between the libraries. Note
that I'm not sure if this actually improves build times.
More importantly, this creates a CMake target for the zstd library
because we want to use zstd in other places.
blendOrder was used to control the draw order of blended render
primitive within a Renderable. We now have an option to make the
blend order global, in this case those primitives with a global blend
order are always sorted solely using the blend order value (i.e. the
distance from the camera is not take into account).
This change includes a fix for an issue we filed against spirv-tools:
https://github.com/KhronosGroup/SPIRV-Tools/issues/4371
So, it should reduce the number of extraneous matrix copies in finalized
GLSL code.
I did quick size total of all filamat files (*) before and after this
update, it went from 11.3 MB to 11.1 MB.
(*) All backends are enabled, includes built-in Filament shaders and
gltfio ubershaders.
* Add JS bindings for Texture class methods
This change introduces bindings for the following methods:
- getWidth
- getHeight
- getDepth
- getLevels
Closes 4492
* Mark level arguments as optional
* Revert docs defs
* Revert docs/webgl/filament.js
if we have more than 16K of UBO data, we now use a "out of band" buffer
on the heap instead of the command stream, which has limited space.
to minimize the heap allocation we use a simple pool allocator that
recycles a few heap buffers (per Scene).
This optimizes and cleans up some code from a 3P contributor.
When computing a bounding box, there was no need for an inner loop
through the entire skins array.
Tested using the torus model in #4973 and the `-r` flag in gltf_viewer.
I think the most important thing here is that we now let users know that
"offset" is not a byte count. This also fixes some small typos, e.g.
"weights" was used in the docstring instead of "positions".
To avoid making API changes, this does not fix a few weird things I
noticed in the Java API. For example, there is a redundant "count"
argument in methods that take an array. Also some methods do not
provide an "offset" argument, which is not consistent with C++.
Our `morphNormal` GLSL function treats each normal target as a
displacement from the base normal (similar to the glTF spec) but the
normal that is extracted from the tangent frame is actually an absolute
normal.
In other words, if b is the base normal, we were doing:
b = b + w0 * n0 + w1 * n1 + ...
This is obviously wrong, since the base normal has an overpowering
influence.
The fixed math looks like this:
b = b + w0 * (n0 - b) + w1 * (n1 - b) + ...
Fixes#5584.
By design we shouldn't access the scene SOA when executing the
high level commands.
This change increases the size of a command to 64 bytes and
PrimitiveInfo to 48 bytes (both with some small padding left).
This removes usage of regexps from the parsing phase and splits the
program into three sub-packages: parser, database, and emitters.
The parser now generates an AST according to the formal grammar
described in the README:
https://github.com/google/filament/blob/pr/beamsplitter_rewrite2/tools/beamsplitter/README.md#grammar
This allows for nice readable error messages. More importantly, it
permits the C++ syntax to be less restrictive and paves the way for
possible expansion of the tool beyond `Options.h`.
I looked at the C++ AST generated by clang but it is huge and unwieldy.
For our purposes this simplified AST is much easier to work with.
The new lexer is inspired by the following Rob Pike talk.
- https://www.youtube.com/watch?v=HxaD_trXwRE
Beamsplitter does not use the state machine described in the above
prezo, but it does use a Go channel for separating the parser from the
lexer. In our case, the lexer is actually a recursive descent parser
with simple lookahead functionality. This made it easy for the "real"
parser to create an ergonomic coarse-grained AST.
This is a big change but it is a no-op in terms of the generated code.
* gltfio: Clear texture caches before loading resources
* iOS gltf-viewer: add double-tap to reload model for debugging
* iOS samples: add instructions on ASan / UBSan debugging
- Ensure C++17 is used to compile sample projects
- Upgrade to the latest Xcodegen and re-generate projects
- Add a bundle ID disambiguator so users don't need create unique bundle Ids when opening sample projects
- Add a simple generate-samples.sh script
The API is the same but there are some minor differences, which include:
- Ordering of fields in AmbientOcclusionOptions
- More @NonNull annotations that we forgot
- Javadoc formatting is different
This is a temporary workaround for a memory corruption issue observed on
some devices from a specific vendor. We will try to make this workaround
more targeted in a subequent change.
Partial revert for b2cdf9f2b4.
There were two places where we were doing unaligned reads: one when
computing the hash for the material identifier, and one when parsing
the chunk in ShaderReplacer.
We also had a potential overflow since civetweb does not add a trailing
null to incoming WebSockets messages.
This moves parser into a subpackage to shield it from the various
emitters (this folder structure is similar to what Rob Pike used for his
text templating library). This also adds a WIP Java code generator,
currently disabled.
We now have 3 public APIS:
- opaqueBlit() which is used for basic blitting and scaling and
supports sub-resources.
- blit() which is used for blitting + composition
- can optionally perform basic scaling
- doesn't support sub-resources
- upscale() which is used for high quality upscaling
- can do composition (blending)
- doesn't support sub-resources
This is a temporary workaround for a memory corruption issue observed on
some devices from a specific vendor. We will try to make this workaround
more targeted in a subequent change.
Partial revert for b2cdf9f2b4.
The most important change here is that we no longer apply the
backend (e.g. Metal/Vulkan) UV transformation before calling the
user's vertex shader. This is an API change for post-process materials
(but they're not public).
Now the user is responsible for using uvToRenderTargetUV() in their
shaders (either in the fragment or vertex as appropriate).
This makes it easier to handle offsets/transforms with all APIs.
Conceptually, the only thing that is needed is to call
uvToRenderTargetUV() just before making a texture call.
This fixes a couple of issues:
- some image shifting in metal/vk
- flare in metal/vk was upside down
We also simplify the DoF code quite a bit now that we can rely on the
rendertargets begin multiple of 16.
We also "fix" SSAO that was working by accident on metal/vk. The UV
correction was applied 3 times 2 of which were canceling each other.
This adds a code generator, implemented in Go.
This PR also prepares `Options.h` (the ground truth) by simplifying its
syntax just a bit. The ground truth file must have very simple C++
syntax, which is described in the README:
https://github.com/google/filament/blob/pr/codegen2/tools/codegen-options/README.md
This process revealed a small bug: `Filter.MEDIAN` was bound to the
incorrect value in Java.
The generated code is not yet used, stay tuned.
* Add multi-scene support to gltf_viewer.
To test this, I generated a multi-scene asset as follows.
```
gltf-transform merge Avocado/glTF/Avocado.gltf \
BarramundiFish/glTF/BarramundiFish.gltf \
~/Desktop/Merged.gltf
```
* Specify c++17 in pbxproj files.
When the guard band is enabled, the effective rendering area is
increased by a certain amount (currently 16 pixels on each side) so
that screen-space effects (e.g. SSAO, SSR, DoF) behave better around
the edges of the screen. Of course, this comes at a performance and
memory cost.
Currently the guard band is not configurable other than being optional.
Added c++, java and js bindings.
This also removes clipping of the blit rectangle that occurred in the VK
backend that is no longer necessary. There's also no need to assert
since validation will catch out-of-bounds blitting.
Reverts the clipping in acdb8addfd.
Also deprecate some fields of DisplayInfo this shouldn't be a problem
because they were not actually used.
This change should allow an external-to-filament code to manage
frame pacing (e.g. something like swappy).
- For completion, FilamentAsset now has getRenderableEntities(). This is
similar to sister methods getLightEntities() and getCameraEntities()
except there is no need to store a separate array.
- The web helmet demo does not need to enable shadows, they are already
enabled.
- The ViewerGui populateAsset() method was doing two things that are
now decoupled for clarity: setAsset() and populateAsset().
- The updateRootTransform() method is now called only when the autoscale
checkbox is toggled, instead of every frame.
- The getFooEntities() methods in Java now skip doing work for empty
lists. Actually these should not return arrays at all, but let's fix
that later, since it will break backwards compatibility.
This fixes the emscripten binding errors that we've been seeing
with the <filament-viewer> test page, which prevented us from
including web in the last few Filament releases.
The binding errors were caused by double-initializing the emscripten
module.
I fixed this by allowing clients (e.g. FilamentViewer) to call
Filament.init() more than once. We now accumulate a list of "on ready"
callbacks that get triggered after the emscripten module becomes ready.
As far as I can tell, multiple canvases were actually always broken, and
the viewer test page worked in the past only because we got lucky.
The previous code would convert each element of the source data
into 8 bit-per-element, but we wnat to preserve the original format
that the user provides.
The new solution is to use `slice()` which is a robust way to clone
all the data in a typed array.
This fixes the new regression with Triangle that Ben caught.
If emscripten grows the heap inside one of our BufferDescriptor binding
functions, then the old heap becomes "detached" and an error can
occur.
This fixes the issue seen with the Parquet demo that Ben caught.
All three types of caches (descriptor sets, pipelines, and pipeline
layouts) are now managed in exactly the same way. They all use an LRU
eviction scheme that is based on a count of command buffer flush
events.
Vulkan objects can only be destroyed if there are no in-flight command
buffers that reference them, so an easy way to know when it is safe to
evict a given entry is to wait for "N" flushes after its last use, where
"N" is the number of command buffers in the command buffer ring.
Another big simplification is that there are no more dirty flags,
instead we store two sets of state vectors for each type of cache: the
"currently bound" state, and the "current requirements" state.
Fixes#5142 by replacing unsafe pointers with map keys.
One of the differences between robin_map and unordered_map is the
following:
pointers to keys or values in the map are invalidated in the same
way as iterators to these keys-values
Therefore it is unsafe to track the pointer to a value that is stored
in a robin_map.
This is mostly just code cleanup. One actual bug was the fact that the
dummy sampler was re-created every time a new pipeline layout was
created.
It also felt strange to use `auto&` to refer to a C-style array. I
changed this into a `std::array` which is more consistent with other
fixed size arrays in this class.
Support legacy morphing (morphing with targets supplied via VertexAttributes) for older clients. This gives clients more time to transition over to the new MorphTargetBuffer API.
This allows `MorphStressTest` to work on Vulkan.
However, `Horse` is still broken because it provides positions but not
tangents. Separate fix for that is coming.
Partial fix for #5109.
This fixes validation errors and makes a first pass at simplification.
VulkanTexture now tracks image layout using RangeMap, which paves the
way for further simplification.
This will allow the Vulkan backend to efficiently track the subresource
image layouts for each texture.
This is a sparse container for a series of ordered non-overlapping
integer intervals, where each interval maps to a concrete value.
This is because we're using the same program variant for skinning
and morphing, in the skinning-only case, the buffer won't be accessed
in the shader, but it must be present.
fixes#5085
A recent refactor was causing the following error when the vertex domain
was set to `device`:
```
ERROR: main.vs:23: 'material' : undeclared identifier
ERROR: main.vs:23: 'materialVertex' : no matching overloaded function found
```
Bring color grading back into the Rec.709 color space to match
previous behaviors. This change also implements an exact inverse
tone map function for the "Filmic" operator.
SamplerGroup was comparing texture handles to decide if a texture needed
to be updated, however, texture handles are (quickly) recycled and
therefore can't be used for that purpose. e.g. if a texture is destroyed,
its handle could be reused quickly by another texture, if that texture
is now set on the SamplerGroup, it will ignore it, thinking it's not
different.
We were inserting the colorgrading subpass command between the
refracted and blended objects, instead of after all of them.
Another bad side effect of this was to trigger the refraction pass for
no reason.
The operator!= in std::array compares SPLIT_COUNT elements, which
is potentially greater than cascadeCount, which was the number of
initialized elements in splitPercentages.
std::allocator::deallocate() expects the same value that was given
during allocate().
Interestingly, this bug did not manifest any issues (even with ASAN) on
some platforms.
We should take care not to call glVertexAttribPointer when there is
no bound ARRAY_BUFFER (i.e. when its binding is zero).
This fixes the black screen seen with some WebGL samples after
the recent memory leak fix related to the new BufferObject API.
This leak was introduced in the following PR on April 7.
https://github.com/google/filament/pull/3775
The guilty party has been contacted and properly admonished for his
transgression.
This was tested by adding the following code after applyAnimation in
gltf_viewer.cpp
static int nframes = 0;
if (!gpath.empty() && nframes++ > 100) {
static int count = 0;
printf("reloading %d\n", count++);
nframes = 0;
app.resourceLoader->asyncCancelLoad();
app.resourceLoader->evictResourceData();
app.viewer->removeAsset();
app.assetLoader->destroyAsset(app.asset);
loadAsset(gpath, app);
loadResources(gpath, app);
}
The hang was caused by a subtle race. When a job is completed, its
thread must signal all the threads that might be waiting on this job.
The signaling code was attempting to signal only the minimum number
of threads -- this was important especially in the case where no threads
were waiting, then the call to notify() could be avoided.
Unfortunately, for performance reasons we're not calling notify() with
the condition lock held, this meant that between the time the number of
waiting threads was latched and the time of the notify() call, more
threads could enter their condition variable wait(), and it would
then be possible for these threads to wake up, instead of the thread
we were trying to wake up (the one waiting on the job).
It would then get stuck forever.
This bug was introduced in 2df639133b
Also add some debugging code for this kind of failure (disabled)
This wasn't very useful in the first place because we're recycling
handles very quickly. Additionally there was a race condition
which cause false positives.
This reverts commit bc6acd5c5a.
This reverts commit 3a15756c78.
When running semantic analysis on a material, we were arbitrarily choosing the first code gen permutation to analyze. So, running matc with arguments --api metal versus --api all would run analysis on slightly different shader code. This causes bugs when flags passed to glslang differ during semantic analysis. This change updates all semantic analysis to always use the same shader code.
When passing only 1 fence to vkWaitForFences, the `waitAll` argument
should not have any effect, but SwiftShader seems to skip the wait
when this argument is set to VK_FALSE.
More specifically, the failure to wait in `acquireWorkCommandBuffer`
causes the subsequent destruction of an in-use fence, which causes
a TSAN failure with Google's internal tests.
I am consulting with the SwiftShader team on a real fix, meanwhile
we can commit this easy workaround.
We have 5 usages of vkWaitForFences, one of which uses multiple fences
and should have used VK_TRUE anyway.
This prevents a SwiftShader crash and/or a slew of "no texture bound"
warnings that would appear when the client provides an IBL without
providing reflections texture, which should be a valid thing to do.
Note that it is okay to declare a sampler in GLSL that never gets bound,
as long as it is never sampled from. Since we always sample from the
IBL specular texture, we should always bind something to it.
With Vulkan, this warning would sometimes be a false positive. It could
trigger for internal samplers like `ssao` and `structure`, even though
they were not declared in SPIR-V.
With OpenGL, this warning would never be a false positive because it has
the luxury of calling `glGetUniformLocation`.
This adds a private attribute to our samplers called `strict` that
indicates whether or not a sampler should always have a bound texture.
For now the only strict samplers are the custom ones declared in the
user's material.
At some point I think we should consider adding `spirv-reflect` to our
tree to help with problems like this.
This fixes a bug seen with client applications that use ClearOptions
instead of Skybox, and one or more offscreen RenderTarget objects.
These apps would see junk pixels because Filament would only clear the
first render target in the frame.
The fix is to factor some the flag-setting logic in `beginFrame()` into
a private method, and call this method from `render()` each time
the user-level RenderTarget has been changed.
I wrote a simple C++ demo to reproduce the issue and to verify that
this fix works.
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.