Compare commits

..
Author SHA1 Message Date
Powei Feng 65f2df7776 Merge branch 'rc/1.51.4' into release 2024-04-15 11:05:23 -07:00
Sungun Park b89a0173ef Merge branch 'rc/1.51.3' into release 2024-04-08 20:49:28 +00:00
Sungun Park 1fec588fb1 Bump version to 1.51.4 2024-04-08 20:49:28 +00:00
Sungun Park 4bed88289f Release Filament 1.51.3 2024-04-08 20:49:02 +00:00
Ben Doherty de1edbdf25 Metal re-apply: throw an NSException when attempting to draw with invalid program (#7741) 2024-04-05 17:51:01 -07:00
Ben Doherty d468303bc9 Export utils::panic function (#7740) 2024-04-05 17:50:56 -07:00
Ben Doherty 7a6138597e Metal re-apply: throw an NSException when attempting to draw with invalid program (#7741) 2024-04-05 17:50:07 -07:00
Ben Doherty 28da328815 Export utils::panic function (#7740) 2024-04-05 17:49:56 -07:00
Mathias Agopian de3c4b6d56 fix a possible leak when editing a material with matdbg
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.
2024-04-04 10:15:43 -07:00
Mathias Agopian 5d27240e0c clean-up lifetime of MaterialParser 2024-04-04 10:15:43 -07:00
Mathias Agopian 94fc37b8c2 fix missing headers 2024-04-04 10:15:43 -07:00
Powei Feng 532cb28ce9 vk: Introduce caches for descriptor sets/layouts (#7731)
Added
 - Cache for layouts
 - Pools for descriptor sets
 - Cache for descriptor set updates
 - Cache for pipeline layouts

Does not have effect on implementation.
2024-04-03 17:51:42 +00:00
Mathias Agopian b30d12aca5 split GLTexture and GLBufferObject to their own file 2024-04-02 23:34:30 -07:00
Mathias Agopian d891a6927f program is now 48 bytes instead of 56 2024-04-02 23:34:30 -07:00
Mathias Agopian 22b5715837 move mSamplerMap and ES2's mUniformBindings to OpenGLContext 2024-04-02 23:34:30 -07:00
Powei Feng 7eb08f11ea vk: add descriptor set/layout types to handles (#7728)
- 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.
2024-04-02 20:59:24 +00:00
Mathias Agopian 588a05f77c Fix point/spot shadow rendering bug
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
2024-04-01 17:09:34 -07:00
Benjamin Doherty 81658541a1 Bump version to 1.51.3 2024-04-01 16:44:40 -07:00
Benjamin Doherty d0eb56ff20 Merge branch 'rc/1.51.2' into release 2024-04-01 16:44:39 -07:00
Benjamin Doherty 3ec2b47df7 Release Filament 1.51.2 2024-04-01 16:44:33 -07:00
Mathias Agopian 1c55ad49ee add support for custom blend functions
BUGS=[331610785]
2024-04-01 13:40:34 -07:00
Mathias Agopian 348e61fd76 remove unused code 2024-04-01 13:40:34 -07:00
Mathias Agopian 8ce6d54930 remove wrong noexcept in the backend
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.
2024-03-29 14:59:43 -07:00
Mathias Agopian 8db5e700d7 GL backend should only allocate renderbuffers when possible
There was several cases where the the gl backend would wrongly  use a 
renderbuffer instead of a texture.


BUGS=[329491941]
2024-03-29 14:59:29 -07:00
Mathias Agopian 0ec3596440 the user can now set a panic handler callback
BUGS=[331457244]
2024-03-29 12:25:06 -07:00
Ben Doherty ee4c03d0f1 Fix WebGL build with newer Emscripten (#7721) 2024-03-28 14:15:32 -07:00
Powei Feng 85589a7d16 Merge branch 'rc/1.51.1' into release 2024-03-28 11:48:00 -07:00
Powei Feng d476c7fa1b Bump version to 1.51.2 2024-03-28 11:48:00 -07:00
Powei Feng f12e7f9fbf Release Filament 1.51.1 2024-03-28 11:47:52 -07:00
Nimrod Gileadi a068143953 Add semicolons to code snippet in AssetLoader.h (#7717) 2024-03-27 17:24:10 +00:00
Powei Feng 3ed008c0b6 Bump material version to 51 in MaterialEnums.h 2024-03-26 21:38:02 +00:00
Powei Feng 90d90094dc Bump material version to 51 in MaterialEnums.h 2024-03-26 14:37:13 -07:00
Sungun Park 54df4524eb Improve multiview shader replacement (#7706)
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)
2024-03-26 21:36:22 +00:00
Powei Feng 66ec81187d vk: delete instead of ref-count EmptyTexture (#7711) 2024-03-26 20:36:45 +00:00
Powei Feng d70f2e1b81 vk: delete instead of ref-count EmptyTexture (#7711) 2024-03-26 13:35:50 -07:00
Powei Feng 0efd94a769 Add missing include to Platform.h (#7709) 2024-03-26 20:09:47 +00:00
Powei Feng 2f359b73a4 Add missing include to Platform.h (#7709) 2024-03-26 19:51:57 +00:00
Eliza Velasquez 1801def1ee Allow rendering thread to pause
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.
2024-03-25 22:46:06 +00:00
Powei Feng 61155644d5 gl: v1.51.1 local fix for merge mistake 2024-03-25 22:13:40 +00:00
Sungun Park b3ec8b188e Add FILAMENT_ENABLE_MULTIVIEW option (#7707)
This allows the engine to include multiview shader code for default
materials.
2024-03-25 21:49:15 +00:00
Sungun Park abb0cbc98e Add FILAMENT_ENABLE_MULTIVIEW option (#7707)
This allows the engine to include multiview shader code for default
materials.
2024-03-25 21:43:04 +00:00
Jacob Su 2763931b47 fix install android samples apk error. (#7230) 2024-03-22 23:05:01 -07:00
Sungun Park 0ead96b606 Replace value of num_views with engine's eye count (#7696)
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.
2024-03-22 21:45:58 +00:00
Ben Doherty dbf0cde330 Metal: track buffer allocations (#7556) 2024-03-22 12:48:24 -07:00
Ben Doherty 317c1bb7ea Metal: track buffer allocations (#7556) 2024-03-22 12:47:56 -07:00
Ben Doherty 9aaaad9271 Improve Skybox eyeDirection precision (#7685) 2024-03-22 12:03:06 -07:00
Mathias Agopian 072562c571 Add an option to disable use-after-free checks in the backend
BUGS=330403836
2024-03-22 11:36:43 -07:00
Mathias Agopian 780799f30b PlatformEGL::createSwapChain never returns a nullptr anymore
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]
2024-03-22 11:36:37 -07:00
Mathias Agopian d2ce714e73 fix use-after-free disable option 2024-03-22 11:27:30 -07:00
Mathias Agopian 8398175d9c Add an option to disable use-after-free checks in the backend
BUGS=330403836
2024-03-22 10:24:29 -07:00
Sungun Park 26258a4718 Facilitate four views for multiview (#7694)
This change allows the combine function for multiview to be able to
combine more than two views side-by-side.
2024-03-22 17:09:08 +00:00
Mathias Agopian 3644e7f808 Fixes IBL prefilter has floor and ceiling flipped
FIXES=[330603077]
2024-03-21 13:28:24 -07:00
Powei Feng 4d774820d9 gl: Don't reference swapchain obj on Web
Fixes #7693
2024-03-21 13:27:45 -07:00
Eliza Velasquez aad45d9119 Fix typo 2024-03-21 19:59:47 +00:00
Eliza Velasquez 5389b37002 Incorporate feedback 2024-03-21 19:59:47 +00:00
Eliza Velasquez d5fe9e236f Allow rendering thread to pause
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.
2024-03-21 19:59:47 +00:00
Mathias Agopian 59890ac85a PlatformEGL::createSwapChain never returns a nullptr anymore
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]
2024-03-20 16:07:02 -07:00
Mathias Agopian 435969f565 attempt to detect buffer overflows in Texture::setImage()
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
2024-03-20 16:06:43 -07:00
Ben Doherty e3db39105f iOS: fix gltf-viewer crash while destruction ResourceLoader (#7684) 2024-03-19 16:14:45 -07:00
Powei Feng dfa821d351 vk: fix broken gltf renderings (#7680)
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
2024-03-19 22:38:52 +00:00
Powei Feng 1ab223c965 vk: minor fixes (#7682)
- Add description to a few debug options
- Set correct usage flag for blit-src/dest images
- Correctly initialize a debug-only field in VulkanProgram
2024-03-19 13:59:52 -07:00
Mathias Agopian 29bb60cd94 fix typo that caused a wrong assertion 2024-03-19 13:13:12 -07:00
Mathias Agopian 93b15dac87 The type of geometry of a renderable can now be specified
- 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.
2024-03-19 11:12:25 -07:00
Romain Guy a8fda9b4d0 Make PBR Neutral invertible (#7677)
Based on model-viewer's change at
https://github.com/google/model-viewer/pull/4716
2024-03-19 11:11:44 -07:00
Benjamin Doherty cf0c1f74dc Bump version to 1.51.1 2024-03-17 13:12:41 -07:00
Benjamin Doherty d3ca32efbe Merge branch 'rc/1.51.0' into release 2024-03-17 13:12:40 -07:00
Benjamin Doherty ba9cb2fe43 Release Filament 1.51.0 2024-03-17 13:12:32 -07:00
Sungun Park 0f7cffc407 Connect multiview components together (#7671)
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.
2024-03-15 22:01:38 +00:00
Mathias Agopian dace5fd695 minor fixes and cleanup to Primitive and BufferInfo factories
- both files use consistent names
- enforce that the keys are not moved around
- don't pass the value (which is 4 bytes) by reference
2024-03-15 11:26:47 -07:00
Powei Feng b23ee1bce4 gltfio: add extended tangents job (#7666)
- 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.
2024-03-15 17:46:08 +00:00
Mathias Agopian 25f017b883 fix missing headers 2024-03-14 16:41:21 -07:00
Benjamin Doherty de6df6dc0e Bump MATERIAL_VERSION to 51 2024-03-14 10:40:26 -07:00
Sungun Park 0def77eaa8 Add layerCount to createRenderTarget (#7660)
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.
2024-03-14 00:38:34 +00:00
Powei Feng 3c25dab22f vk: clean-up initialization of classes (#7667)
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.
2024-03-13 23:51:22 +00:00
Mathias Agopian 93a80fd084 More Platform improvements for protected contexts
- `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.
2024-03-13 16:13:34 -07:00
Mathias Agopian 963e097bdc handle non-0 default FBO with protected contextes 2024-03-13 16:13:34 -07:00
Mathias Agopian 86479781a5 assert when swapchain creation fails
This is better than risking a null-pointer dereference later.
2024-03-13 16:13:34 -07:00
Hanno J. Gödecke 4ea5872b26 fix: applyCrossFade use correct instance 2024-03-13 16:13:01 -07:00
Hanno J. Gödecke f27f0ef4fc fix: apply stashCrossFade to correct entity 2024-03-13 16:13:01 -07:00
Ben Doherty 6dd85c6530 Remove erroneous assertion (#7661) 2024-03-12 14:33:14 -07:00
Ben Doherty 348454781f Remove erroneous assertion (#7661) 2024-03-12 14:29:49 -07:00
Sungun Park bb6c8ef1c8 Add option FILAMENT_SAMPLES_STEREO_TYPE for samples/gltfio (#7658)
This option can be either "instanced" or "multiview", indicating what
stereoscopic rendering type shaders in samples/gltfio should be built
for.
2024-03-12 13:49:00 -07:00
Powei Feng fa6b4ebd04 gltfio: refactor for clarity (#7652)
- Pull certain utility functions in a separate header and cpp
- Refactor ResourceLoader::loadeResources into smaller methods
2024-03-12 20:31:19 +00:00
Ben Doherty 5ca7f41513 Metal: respect disableParallelShaderCompile config (#7659) 2024-03-12 13:08:43 -07:00
Ben Doherty 4ad07e25d4 Move SwapChain flags into separate file (#7654) 2024-03-12 13:08:35 -07:00
Ben Doherty 9aad4df441 Metal: respect disableParallelShaderCompile config (#7659) 2024-03-12 13:06:43 -07:00
Ben Doherty 2e581be8fd Move SwapChain flags into separate file (#7654) 2024-03-12 12:10:43 -07:00
Sungun Park 6d7eaf31d3 Add multiview filamat for default materials (#7644)
Add prebuilt materials for the engine default materials. They'll be
selected for multiview stereoscopic implementation.
2024-03-12 02:50:54 +00:00
Powei Feng dea345d28e geometry: fix mikktspace wrapper (#7651)
- Fix missing attributes in TangentSpaceMesh
- Fix missing reference in MikktspaceImpl.cpp
2024-03-11 22:27:46 +00:00
Sungun Park 89a191c2e9 Merge branch 'rc/1.50.6' into release 2024-03-11 21:38:38 +00:00
Sungun Park f63296fc18 Bump version to 1.51.0 2024-03-11 21:38:38 +00:00
Sungun Park c1dfd8553d Release Filament 1.50.6 2024-03-11 21:38:10 +00:00
Powei Feng 0c48f40836 vk: add /usr/local/lib to rpath on macos (#7643)
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.
2024-03-08 23:18:43 +00:00
Mathias Agopian cac4d2aa94 Modernize draw API.
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.
2024-03-08 13:42:10 -08:00
Sungun Park f8973d53d6 Consolidate materials for feature level (#7640)
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.
2024-03-08 12:26:53 -08:00
Ben Doherty ca27bb58bf Metal: change shader compilation pool size to 1 (#7639) 2024-03-08 10:33:37 -08:00
Ben Doherty d07168f49c Metal: change shader compilation pool size to 1 (#7639) 2024-03-08 10:32:38 -08:00
Mathias Agopian c3057e17bb add post-lighting mix factor support
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]
2024-03-08 10:32:21 -08:00
Powei Feng 23a8efd3dc vk: clean up debug tools (#7635)
- Fix broken resource leak print out.
 - Add sampler name to debugUtils when enabled
2024-03-08 01:15:24 +00:00
Mathias Agopian e1973978ae Set the protected attribute on EGLImage
We set the attribute based on the usage bits of the underlaying 
AHardwareBuffer.
2024-03-07 14:23:57 -08:00
Powei Feng 86d2e11801 Try fixing windows artifact output again (#7637)
The [previous] change assumed that the shell is powershell, but the shell is actually commands (cmd). 

The [previous] change assumed we're in the root directory.  This assumption is probably correct [ref]. So we keep that change.

[ref]:  https://github.com/google/filament/blob/main/build/windows/build-github.bat#L134
[previous]: 373c5710b1
2024-03-07 10:51:06 -08:00
Powei Feng b9a33b7d3e Try fixing windows artifact output again (#7637)
The [previous] change assumed that the shell is powershell, but the shell is actually commands (cmd). 

The [previous] change assumed we're in the root directory.  This assumption is probably correct [ref]. So we keep that change.

[ref]:  https://github.com/google/filament/blob/main/build/windows/build-github.bat#L134
[previous]: 373c5710b1
2024-03-07 01:09:04 +00:00
Mathias Agopian 434c226e8a IBLs were mirrored when using IBLPrefilter
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]
2024-03-06 15:04:30 -08:00
Sungun Park 0605e9fe82 Fix a warning (#7634)
This fixes a warning for 6601c7c2b5
2024-03-06 21:42:30 +00:00
Powei Feng cd528e57ab Merge branch 'rc/1.50.5' into release 2024-03-06 13:01:20 -08:00
Powei Feng 4a465450f1 Bump version to 1.50.6 2024-03-06 13:01:20 -08:00
Powei Feng 7eb3b2aaf5 Release Filament 1.50.5 2024-03-06 13:01:10 -08:00
Mathias Agopian 11d2ac1019 Add support for protected contexts
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.
2024-03-06 12:17:40 -08:00
Sungun Park 6601c7c2b5 Add new parameter -P for matc (#7632)
* 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.
2024-03-06 12:06:30 -08:00
Mathias Agopian 21d938a59f simplify the ResourceAllocator cache eviction strategy
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.
2024-03-06 11:00:17 -08:00
mdagois c84f80be7c Fixed validation error VUID-vkAcquireNextImageKHR-semaphore-01779 (#7626)
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.
2024-03-06 01:27:21 +00:00
Powei Feng 4e648b224f Revert "vk: remove subpasses to simplify descriptor set refactor (#7592)" (#7630)
This reverts commit a9793b3cf6.

Due to change in output for swiftshader
2024-03-05 17:02:20 -08:00
Powei Feng 9f33a2d062 Revert "vk: remove subpasses to simplify descriptor set refactor (#7592)" (#7630)
This reverts commit a9793b3cf6.

Due to change in output for swiftshader
2024-03-05 17:01:20 -08:00
Sungun Park 21d2847a6b Update code generator for multiview (#7616)
It generates shader code for multiview based on parameters.
2024-03-05 13:40:31 -08:00
Powei Feng 04c7f84c6f engine: avoid leaking vertex buffer (#7628)
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
2024-03-05 13:40:18 -08:00
Powei Feng 89d8f8ebbf engine: avoid leaking vertex buffer (#7628)
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
2024-03-05 20:09:16 +00:00
Powei Feng b9a069be05 vk: Initial draft for descriptor set refactoring (#7620)
- 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.
2024-03-05 19:05:57 +00:00
Mathias Agopian 7115bd2a34 more cleanup-up of timer queries
- 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.
2024-03-04 16:31:45 -08:00
Mathias Agopian 9ce7f32470 Small improvements and cleanup to SwapChain
For debugging we add a way to recreate the SwapChain with different
flags.
2024-03-04 11:28:20 -08:00
Ben Doherty d21613a5e6 Add SwapChain::getFrameScheduledCallback (#7599) 2024-03-04 09:20:10 -08:00
Mathias Agopian 167ec62667 Add protected mode to the FrameGraph.
In protected mode, the FrameGraph will automatically add the
PROTECTED usage bit to texture resources.
2024-02-29 15:35:46 -08:00
Mathias Agopian 2022be928e Timer queries can now return an error. 2024-02-29 10:58:34 -08:00
Mathias Agopian b921d78fe7 Add support for protected SwapChain.
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.
2024-02-29 10:58:06 -08:00
Mathias Agopian 9c0c56d6d0 add support for protected textures
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.
2024-02-29 10:57:42 -08:00
Sungun Park 43f6c4507e Make glFramebufferTextureMultiviewOVR available for Android (#7615)
This OpenGL function is going to be used for multiview on Android. Make
it available.
2024-02-29 10:32:22 -08:00
Sungun Park 57fff3a636 Add a new material param, stereoscopicType (#7613)
* 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
2024-02-28 22:14:44 +00:00
Sungun Park 8c31f46683 Keep supporting API level 19 (#7609)
This is a partial rollback from
d83b3858b3.

Keep supporting API level 19 for some of our clients.
2024-02-27 16:13:53 -08:00
Sungun Park af8f38d83c Keep supporting API level 19 (#7609)
This is a partial rollback from
d83b3858b3.

Keep supporting API level 19 for some of our clients.
2024-02-28 00:11:33 +00:00
Powei Feng 563c32b95b Merge branch 'rc/1.50.4' into release 2024-02-27 14:15:04 -08:00
Powei Feng ab0063bc6b Bump version to 1.50.5 2024-02-27 14:15:04 -08:00
Powei Feng b425d63b95 Release Filament 1.50.4 2024-02-27 14:14:49 -08:00
Sungun Park 02d2e2f644 Rename InstancedStereo as Stereo (#7608)
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.
2024-02-27 13:00:24 -08:00
Sungun Park ef488fdf57 Add blit array shader
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.
2024-02-26 22:51:40 +00:00
Yuri Schimke 4836f94635 Update NEW_RELEASE_NOTES.md 2024-02-26 14:24:16 -08:00
Yuri Schimke c2b5f08bc7 Fix Renderer FrameRateOptions interval default
From https://github.com/google/filament/issues/7539

And I got to the same conclusion based on https://github.com/google/filament/blob/f0f7e299d2ce1a5f3f62821b058353fe00c2015f/filament/src/details/View.cpp#L191
2024-02-26 14:24:16 -08:00
Mathias Agopian d05c61fe9a fix VulkanResourceBase size on Windows
VulkanResourceBase was intended to be 8 bytes, however, bitfields
are not packed by msvc if they don't use the same type.
2024-02-26 12:58:29 -08:00
Mathias Agopian af48bc3c74 add the disableParallelShaderCompile option to Engine::Config 2024-02-26 19:24:23 +00:00
Sungun Park 65dfac9637 Add stereoscopic type to Engine::Config (#7574)
* Add stereoscopic type to Engine::Config

This new type value will determine the algorithm used when stereoscopic
rendering is enabled.
2024-02-26 19:24:09 +00:00
Sungun Park 1ae82d325c Fix shader compilation in threadpool mode (#7602)
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.
2024-02-26 09:05:46 -08:00
Mathias Agopian f0f7e299d2 PlatformEGL cleanup 2024-02-23 16:15:22 -08:00
Mathias Agopian a3131a64b6 cleanup of attributes management
- 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
2024-02-23 15:48:06 -08:00
Romain Guy 36120106cd Add new PBR Neutral tone mapper (#7597)
This tone mapper was designed to preserve the color apperance
of materials. It provides good saturation and contrast while
controlling the highlights.
2024-02-23 14:33:26 -08:00
Powei Feng 7e96216b6c vk: fix window minimize on Win (#7596)
Fixes #7481
2024-02-23 19:52:05 +00:00
Powei Feng a9793b3cf6 vk: remove subpasses to simplify descriptor set refactor (#7592)
- Also did some clean up of debug code
2024-02-23 05:29:58 +00:00
Mathias Agopian 2260794a55 remove scissor from PipelineState
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.
2024-02-22 17:03:40 -08:00
Sungun Park d83b3858b3 Add missing changes for NDK version update (#7591)
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
2024-02-22 15:33:05 -08:00
Powei Feng 654a38c3bf Fix broken Android build (#7590)
The math for PrimitiveInfo's size is incorrect. We correct the
padding.

See commit 11a3c06418 to see where
the padding error originated.
2024-02-22 22:10:38 +00:00
Ben Doherty bf602516ec Metal: throw an NSException when attempting to draw with invalid program (#7581)
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.
2024-02-22 13:25:25 -08:00
Mathias Agopian 9e119937af Better fix for OOB when we have no renderable
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).
2024-02-21 23:55:18 -08:00
Mathias Agopian 859c5edb49 Better fix for OOB when we have no renderable
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).
2024-02-21 23:52:55 -08:00
Mathias Agopian 11a3c06418 PrimitiveInfo is running out of space
So we now access some of its members through a pointer, this is not
ideal, but we can re-optimize this later.
We will need more space in it soon.
2024-02-21 15:50:44 -08:00
Mathias Agopian 3fab93bf3d Add a HwVertexBufferInfo cache 2024-02-21 15:50:44 -08:00
Mathias Agopian 20caeb3889 Introduce HwVertexBufferInfo
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.
2024-02-21 15:50:44 -08:00
Mathias Agopian 6e5930c2a0 Bimap is a custom bi-directional map.
It is extracted from HwRenderPrimitiveFactory and cleaned-up a bit.
2024-02-21 15:50:44 -08:00
Powei Feng 486b9eef1e vk: add debug names to shader modules (#7577)
Also removed debugUtils workaround for Mesa since it's been addressed properly from the vk backend.
2024-02-21 23:29:31 +00:00
Ben Doherty 9b0718199f Fix an out-of-bounds memory access when no renderables are visible (#7587) 2024-02-21 21:55:47 +00:00
Benjamin Doherty 3e644b25f0 Fix an out-of-bounds memory access when no renderables are visible 2024-02-21 13:33:59 -08:00
Mathias Agopian dc6608350b fix a uninitialized memory access when no renderable are visible 2024-02-21 10:53:58 -08:00
Mathias Agopian fadd5eb953 fix a uninitialized memory access when no renderable are visible 2024-02-21 10:52:50 -08:00
Mathias Agopian 8b24950429 add the disableParallelShaderCompile option to Engine::Config 2024-02-21 08:47:47 -08:00
Powei Feng b48b6136ba geometry: properly reference memcpy usage (#7576) 2024-02-16 15:35:01 -08:00
Powei Feng 5d9337e6c2 geometry: properly reference memcpy usage (#7576) 2024-02-16 13:06:01 -08:00
Sungun Park 142b73d9d7 Add OpenGL extension for multiview (#7569)
* 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.
2024-02-15 08:21:00 -08:00
Mathias Agopian 5707043d96 Modernize HwRenderPrimitive and draw() APIs
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.
2024-02-13 22:34:54 -08:00
Sungun Park 4e6ae2b714 Add stereoscopic type to Engine::Config (#7574)
* Add stereoscopic type to Engine::Config

This new type value will determine the algorithm used when stereoscopic
rendering is enabled.
2024-02-13 20:40:30 -08:00
Sungun Park ca0f98c513 Merge branch 'rc/1.50.3' into release 2024-02-13 00:45:01 +00:00
Sungun Park 70b87510a2 Bump version to 1.50.4 2024-02-13 00:45:01 +00:00
Sungun Park a9e8f40287 Release Filament 1.50.3 2024-02-13 00:44:36 +00:00
Mathias Agopian 31b836282d fix a typo that broke the resourceallocator cache
the cache size is given in MiB not bytes, so we needed to convert it
to bytes.
2024-02-13 00:09:17 +00:00
Mathias Agopian 6ccfeddf26 fix a typo that broke the resourceallocator cache
the cache size is given in MiB not bytes, so we needed to convert it
to bytes.
2024-02-12 16:04:10 -08:00
Mathias Agopian 9c6020a77a Make VulkanResourceBase 8 bytes instead of 16. 2024-02-12 15:59:51 -08:00
Mathias Agopian e912dc2dc5 PipelineCache didn't need to store a copy of RasterState 2024-02-12 15:59:51 -08:00
Mathias Agopian a27260b87f lazy initialization of the ShadowMap cache in ShadowMapManager
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.
2024-02-12 14:32:50 -08:00
Mathias Agopian 653a015991 fix uninitialized memory access 2024-02-09 15:10:26 -08:00
Mathias Agopian ef703bb4be Better handle collisions and use-after-free detection
- 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
2024-02-09 12:07:42 -08:00
Mathias Agopian f9c8e65ef3 fix velocity update in FreeFlightManipulator
when the time step was getting to large, the velocity update could
become unstable and the camera would oscillate and eventually
fly off.
2024-02-09 12:07:13 -08:00
Mathias Agopian c43051728c fix a typo in handleallocator that could cause corruptions
Fixes #7563
2024-02-08 16:01:47 -08:00
Powei Feng cdd9c4aebe [release] update base64 command (#7559)
Seems like a `-i` is now necessary for the command. Note that we recently startede using mac-mx machines.
2024-02-07 12:58:16 -08:00
Powei Feng f3a61f100c [release] update base64 command (#7559)
Seems like a `-i` is now necessary for the command. Note that we recently startede using mac-mx machines.
2024-02-07 12:57:53 -08:00
Powei Feng 20acc01fcd [release] update base64 command (#7559)
Seems like a `-i` is now necessary for the command. Note that we recently startede using mac-mx machines.
2024-02-07 09:17:09 -08:00
Mathias Agopian d640ba853b rework how we size the HandleAllocator's pools
- 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
2024-02-06 21:28:04 -08:00
Mathias AgopianandPowei Feng 50d9d9f139 Improve memory allocations (#7540)
* 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>
2024-02-06 10:01:41 -08:00
Powei Feng 0774ce6b5e Bump version to 1.50.3 2024-02-06 17:40:08 +00:00
Powei Feng 60db518b75 Merge branch 'rc/1.50.2' into release 2024-02-06 17:40:08 +00:00
Powei Feng 7be9cdc7f8 Release Filament 1.50.2 2024-02-06 17:40:03 +00:00
Mathias Agopian af792e3d18 Resource allocator cache params can be set in Engine::Config
FIXES=[323386395]
2024-02-05 10:26:26 -08:00
Ben Doherty 3c5316f1e9 Metal: schedule PresentDrawable for destruction on the main thread (#7535) 2024-02-01 10:47:37 -08:00
Ben Doherty f93677548d Metal: schedule PresentDrawable for destruction on the main thread (#7535) 2024-02-01 10:45:58 -08:00
Mathias Agopian 1eff66e4ec wip: nullability attributes for backend 2024-02-01 10:36:42 -08:00
Mathias Agopian 34f8b9aa20 add nullability attributes to filament public APIs 2024-02-01 10:36:42 -08:00
Mathias Agopian 6d07443188 fixes builds fail when path to build directory contains spaces
fixes #7533
2024-02-01 10:35:06 -08:00
Powei Feng 1f33a6efd2 Merge branch 'rc/1.50.1' into release 2024-02-01 00:41:24 +00:00
Powei Feng 4127f619e1 Bump version to 1.50.2 2024-02-01 00:41:24 +00:00
Powei Feng 13a23703ad Release Filament 1.50.1 2024-02-01 00:41:19 +00:00
Powei Feng 57f6ca625c Update mac-continuous.yml (#7537)
ref: https://github.blog/changelog/2024-01-30-github-actions-introducing-the-new-m1-macos-runner-available-to-open-source/
2024-01-30 13:55:43 -08:00
Mathias Agopian 02f5903b67 fix external images
It turns out that many drivers require to rebind the external texture
after its content has changed, so we now always do that.

Bug #6188
2024-01-26 14:17:48 -08:00
Mathias Agopian c39a870abc fix mobile debug builds, missing incluldes 2024-01-26 11:14:16 -08:00
Mathias Agopian 09b8008e17 add missing public headers in backend 2024-01-26 10:58:28 -08:00
Mathias Agopian 59b59cf6be add missing includes in libutils public headers 2024-01-26 10:58:00 -08:00
Mathias Agopian 0df6013263 update remote ui 2024-01-26 10:57:37 -08:00
Mathias Agopian d5041fced7 support execinfo.h on Android 33 and above
Note: this currently requires to compile filament with API_LEVEL 33.
2024-01-25 14:50:29 -08:00
Mathias Agopian 9c54b8a777 fix typo that broke FSR upscaling 2024-01-25 10:34:47 -08:00
Mathias Agopian 8a534d0940 Fix missing/extra includes in all public headers 2024-01-24 23:13:14 -08:00
Mathias Agopian 130825422e Shadowmap texture vizualizer
The vizualizer is implemented inside filament itself and activated
using the debug registry. This intended for filament development use.
2024-01-24 11:28:11 -08:00
Powei Feng 984006ee25 geometry: allow additional attributes in TangentSpaceMesh (#7483)
- 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
2024-01-23 16:16:35 -08:00
Sungun Park b3cc4d11b8 Merge branch 'rc/1.50.0' into release 2024-01-23 21:10:19 +00:00
Sungun Park 8523f4e970 Bump version to 1.50.1 2024-01-23 21:10:19 +00:00
Sungun Park b676002521 Release Filament 1.50.0 2024-01-23 21:10:06 +00:00
Sungun Park 6b7450dc0b Update material version to 50 2024-01-22 23:25:59 +00:00
Sungun Park 8bdf7bd1e5 Update material version to 50 2024-01-22 15:25:06 -08:00
Mathias Agopian 7b384fb5e8 remove all uses of our custom spinlock
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]
2024-01-22 23:21:11 +00:00
Mathias Agopian 1262cb286c backend option to disable parallel shader compile 2024-01-22 12:43:27 -08:00
Powei Feng 20dc6d479b Merge branch 'rc/1.49.3' into release 2024-01-22 11:43:54 -08:00
Mathias Agopian ee6f3fb1dc Add sharpening option to TAA
We use the RCAS algorithm from FSR1. This is useful for when TAA
upscaling is enabled and similar to to what FSR2 is doing.
2024-01-19 14:40:04 -08:00
Mathias Agopian b9a9586abb taa: add a 32-sample mode and cleanup
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.
2024-01-19 14:40:04 -08:00
Mathias Agopian 6ee20a57aa remove all uses of our custom spinlock
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]
2024-01-19 12:05:07 -08:00
Mathias Agopian 368fa2bf39 fix IBLPrefilterContext::EquirectangularToCubemap
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]
2024-01-18 21:10:21 -08:00
Mathias Agopian 8f642892b4 taa: fixes input filtering option=OFF when upscaling is off
when upscaling is off, the confidence value is always 1.
2024-01-18 21:07:13 -08:00
Powei Feng 0736f3c3b3 Add missing includes (#7501)
BUG=320668410
2024-01-17 11:08:58 -08:00
Powei Feng 5435a8ed3b Add missing includes (#7501)
BUG=320668410
2024-01-17 11:04:42 -08:00
Powei Feng 6a7767f4e4 Bump version to 1.50.0 2024-01-10 13:57:25 -08:00
Powei Feng 628d387cbd Fix typo oin MaterialCompiler (#7477) 2024-01-08 15:07:07 -08:00
Eliza Velasquez 75a1c6d7a8 Generate dummy stereo variants for FL0 mats
See #7415 for a more detailed description of why this change is necessary.

The remaining variants which are filtered from FL0 materials are all related to
lighting, so further hacks like this won't be necessary.

Future work involves properly supporting differing sets of variants based on
shader language.
2024-01-08 13:04:55 -08:00
Ben Doherty 8c76370e2d Fix ostream linking error when compiling Linux DSO (#7470) 2024-01-04 10:43:50 -08:00
Benjamin Doherty bdc15a5c2d Bump version to 1.49.3 2024-01-02 14:53:07 -08:00
Benjamin Doherty acfe9298d9 Merge branch 'rc/1.49.2' into release 2024-01-02 14:53:06 -08:00
Benjamin Doherty 57f6e5371b Add string.h header 2024-01-02 13:23:54 -08:00
Mathias Agopian 9fa3cbfcde add a way to set a log consumer
this is a private API to capture filament's logs.
2023-12-19 12:09:28 -08:00
Mathias Agopian c81ece5c3c cleanup 2023-12-19 12:09:23 -08:00
Benjamin Doherty aae48c1121 Bump version to 1.49.2 2023-12-18 13:35:38 -08:00
Benjamin Doherty 918ce935b8 Merge branch 'rc/1.49.1' into release 2023-12-18 13:35:37 -08:00
Benjamin Doherty 6f37e07dba Bump MATERIAL_VERSION to 49 2023-12-18 09:57:31 -08:00
Benjamin Doherty 171b3279e0 Fix VulkanPlatformAndroidLinuxWindows for G3 2023-12-18 09:48:50 -08:00
Benjamin Doherty b3a1cfe7c9 Bump version to 1.49.1 2023-12-11 00:13:01 -08:00
Benjamin Doherty d273838e07 Merge branch 'rc/1.49.0' into release 2023-12-11 00:13:00 -08:00
Benjamin Doherty a1de8c924d Update RELEASE_NOTES 2023-12-11 00:09:20 -08:00
Benjamin Doherty 72765a5b0a Fix bump-version script on Darwin 2023-12-10 19:52:39 -08:00
Benjamin Doherty e1beabaa98 Bump MATERIAL_VERSION to 49 2023-12-10 19:43:28 -08:00
Eliza Velasquez ebaee14b8b Generate dummy skinning variants for FL0 mats
Even if skinning is not fully implemented on FL0, we have clients which depend
on materials with skinning variants that otherwise could easily be converted to
FL0 materials. There are two proper ways to deal with this:

1. Support skinning/morphing in Feature Level 0.

2. Allow ESSL 1.0 code and ESSL 3.0 code to support different sets of variants.

However, the simplest solution is to just include skinning/morphing variants,
but disable codegen for ESSL 1.0 code, making them identical to the base
variants. This shouldn't increase the file size much due to the dictionary
deflation. Of course, skinning will not work correctly on FL0, but this has
always been the case. Future work here would be to properly implement one of the
two solutions described above.
2023-12-10 19:19:17 -08:00
Powei Feng d4f08dafbb vk: workaround swiftshader spirv no-op issue (#7417)
Swiftshader runs spirv validation before compilation. However,
the validation does not like having Nop (no-op) in the input.
So we skip instructions instead of writing no-op for the
output of `workaroundSpecConstant`.

Also, fix issue to keep the value in the original shader if a
specialization wasn't provided.
2023-12-08 12:05:20 -08:00
Powei Feng 753fb102c4 spirv-headers: fix failed headers check (#7416)
Due to a cmake misconfiguration, we are installing spirv as part
of the release, public headers. It's now corrected.
2023-12-08 12:05:12 -08:00
Powei Feng b219113a55 vk: spec const workaround through runtime spirv modification (#7399)
To avoid driver edge cases with spec const, we manually change the
spec const into a regular constant in the spirv.

FIXES=310603393
2023-12-08 12:05:03 -08:00
Sungun Park 9140d44b29 Bump version to 1.49.0 2023-12-05 11:39:05 -08:00
Sungun Park 8b0d65768a Merge branch 'rc/1.48.0' into release 2023-12-05 11:34:11 -08:00
Powei Feng 349bf7be38 Update MATERIAL_VERSION to 48 2023-12-01 11:01:36 -08:00
Powei Feng a01d282f14 Add intermediate.h include to builtinResource.h (#7388) 2023-12-01 11:00:08 -08:00
Powei Feng 3c3296a114 Bump version to 1.48.0 2023-11-27 14:22:16 -08:00
Powei Feng 61501ba122 Merge branch 'rc/1.47.0' into release 2023-11-27 14:20:27 -08:00
Powei Feng 99ba40e965 Update MATERIAL_VERSION to 47 2023-11-27 19:40:34 +00:00
Eliza Velasquez 4116af7971 Enable optimizations for ESSL 1.0 code
The CL introducing the ESSL 1.0 chunk in materials inadvertently disabled
optimizations for said code. This commit reintroduces those optimizations and
fixes associated bugs which manifested. In particular, spirv-cross was
generating uints for bools; this has been fixed with a hack. Additionally,
spirv-cross is now compiled with exceptions enabled so that matc can gracefully
fail and show the code which failed to compile rather than abruptly aborting.
2023-11-27 19:32:59 +00:00
Eliza Velasquez 2fab93faff Fix typo in depth_main.fs 2023-11-27 19:32:47 +00:00
Eliza Velasquez b92c5cab07 Incorporate feedback 2023-11-27 19:32:34 +00:00
Eliza Velasquez 8ed9678cbe Update NEW_RELEASE_NOTES.md 2023-11-27 19:32:21 +00:00
Eliza Velasquez 731e52a3c1 Add option to matc to disable ESSL 1.0 codegen 2023-11-27 19:32:03 +00:00
Eliza Velasquez 687b6da800 Enable preprocessor optimization of ESSL 1.0
Since #7358 is blocked by an upstream spirv-cross issue, we can at least do a
bit of preprocessor optimization for ESSL 1.0 code in the meantime and introduce
the FILAMENT_EFFECTIVE_VERSION preprocessor definitions.
2023-11-27 19:31:52 +00:00
Ben Doherty 64f4c097ac Remove debug code in MetalShaderCompiler (#7368) 2023-11-15 13:55:34 -08:00
Powei Feng 0191e1fe46 Bump version to 1.47.0 2023-11-14 21:38:45 -08:00
Powei Feng 21093067db Merge branch 'rc/1.46.0' into release 2023-11-14 21:34:54 -08:00
Eliza Velasquez 1b10e7d4f3 Add FILAMENT_ENABLE_FEATURE_LEVEL_0 option
This allows clients to selectively exclude feature level 0 support.
2023-11-14 16:52:26 -08:00
Eliza Velasquez 5b2d3ac225 Fix some ES2 issues
Fix specification of mipmaps when generating textures.

Fix oversight where emulated UBOs would not replace uniforms when swapped out
for another.
2023-11-14 16:29:23 -08:00
Antonio MaioranoandPowei Feng 422dfcc1e6 Add missing include for latest glslang (#7365)
This change in glslang removes the include of "intermediate.h" from
GlslangToSpv.h:
https://github.com/KhronosGroup/glslang/commit/62de186c3383feef067feb6ea578f79977910722

As a result, the definition of "class TIntermediate" is removed, and
will fail compilation of MaterialCompiler.cpp when glslang is updated to
a version including the aforementioned change. We fix this by adding an
explicit include to this header in MaterialCompiler.cpp.

Co-authored-by: Powei Feng <powei@google.com>
2023-11-14 16:00:34 -08:00
Powei Feng 0d304393f4 Small compilation fixes (#7363)
- gltfio: Enable -Wall -Werror for gltfio_core
 - gltfio: Fix various errors that were missed warnings
 - matdbg: switch from std::atomic_uint64_t to
   std::atomic<uint64_t> for older clang
2023-11-14 14:21:52 -08:00
Mathias Agopian 57aa99e964 Fix (again) the shadow transform
- we were not using the correct field in ShadowMapManager
- we were not computing the transform correctly, it should applied
  after the local transform, not before.

FIXES=[299310624]
2023-11-13 22:29:52 -08:00
Mathias Agopian cfc133fcf1 repair visible shadow status
FIXES=[309519433]
2023-11-13 22:29:26 -08:00
Powei Feng 8eade6be1f Revert "engine: move setFrontFaceWindingInverted from View to MaterialInstance (#7331)" (#7360)
This reverts commit 038f07cb34.
2023-11-13 22:27:56 -08:00
Powei Feng 2250664e58 Update Material_VERSION to 46 2023-11-13 10:40:02 -08:00
Benjamin Doherty 8a27cc8b7f Bump version to 1.46.0 2023-11-09 10:11:39 -08:00
Benjamin Doherty d786d59ea1 Merge branch 'rc/1.45.1' into release 2023-11-09 10:09:56 -08:00
Ben Doherty 79116905aa Fix mix-precision quaternion conversions (#7339) 2023-11-08 12:38:23 -08:00
Benjamin Doherty 763950ec18 Revert "fix a couple shadow stability bugs"
This reverts commit 1b0db0fca2.
2023-11-08 12:33:24 -08:00
Mathias Agopian 13571868de don't use a spinlock for the HandleArena
We've seen hangs/ANR that are not well understood on that spinlock, so
for now we're going back to mutexes, which, on android, are very 
efficient under low contention (no syscall).

FIXES=[308029108]
2023-10-30 15:16:01 -07:00
Mathias Agopian 0f2c89b140 improvements to EntityManagers and Filament APIs (#7302)
* prevent public classes from being created on the stack

- we used to to this by deleting operator delete, but this prevented
  the internal "F" classes from being virtual; which can be useful
  when using EntityManger::Listener.
  now we just make the destructor protected in each class.

- EntityManger::Listener now has a virtual destructor so that
  objects could be correctly destroyed from Listener*

* improve EntityManger and Component managers

- all component managers now have the same "base" API
    - getComponentCount()
	- empty()
    - getEntity()
    - getEntities()

- Scene now has getEntityCount()

- EntityManager now has getEntityCount()

- all component manager implement gc() the same way, by calling destroy()

- SingleInstanceComponentManager::gc() that calls removeComponent() has
  been removed because it's dangerous. removeComponent() is often
  not enough, some additional cleanup might be needed.
2023-10-30 15:15:00 -07:00
Mathias Agopian f8b70e8ec5 fix a Transform component leak in CameraManager
CameraManager creates a Transform component for each Camera component
is not already present. However, it didn't destroy the transform
component when it's itself destroyed. the leaked transform component
would eventually be garbage collected, but caused significant
slow down and memory pressure. This is because camera components are
created every frame for the shadow maps.

FIXES=[303914944]
2023-10-30 15:14:52 -07:00
Mathias Agopian 7abdea5a2e improve BlobCache API and compatibility
- the insert and retrieve handlers can now be set/unset independently.
  this could be useful for debugging.

- program caching is disabled if the GL implementation doesn't support it.

- removed unused code

FIXES=[307549547]
2023-10-30 15:13:28 -07:00
Powei Feng cb3e808e8d Bump version to 1.45.1 2023-10-25 15:18:59 -07:00
Powei Feng b2e0b97bad Merge branch 'rc/1.45.0' into release 2023-10-25 15:16:19 -07:00
Mathias Agopian 9c0cbed214 OpenGLBlobCache: be more robust when shader fails to compile
- don't call BlobCache if link status false
- don't assume glGetProgramiv never fails
- don't assume malloc never fails

FIXES=[307549547]
2023-10-24 20:45:52 -07:00
Powei Feng c531a9c077 filamat: Fix MaterialInfo::userMaterialHasCustomDepth init (#7292)
Leaving it uninitialized leads to msan failure.
2023-10-24 20:45:34 -07:00
Powei Feng 2a1f762e23 Update MATERIAL_VERSION to 45 2023-10-22 22:19:41 -07:00
Ben Doherty 4dd98e63e4 Create use-after-free detector for Metal textures (#7250) 2023-10-20 17:16:55 -04:00
Ben Doherty 1b7187f427 Support stencil buffer when post-processing is disabled (#7227) 2023-10-20 17:08:30 -04:00
Benjamin Doherty 0dddd94eab Fix missing SkinningBuffer include 2023-10-18 13:45:08 -07:00
Benjamin Doherty 2ef0244266 Fix build failures due to filamat lite removal 2023-10-13 11:34:47 -07:00
Ben Doherty 0774bf9501 Remove problematic GlslangToSpv option: emitNonSemanticShaderDebugInfo (#7260) 2023-10-13 09:37:56 -07:00
Ben Doherty 8f5b2fd230 Update glslang to 277d09e679f0f4d9469c463c00cb11c6a040e65f (#7261) 2023-10-13 09:37:49 -07:00
Benjamin Doherty 274191036f Bump version to 1.45.0 2023-10-02 15:29:31 -07:00
Benjamin Doherty 13afbc2876 Merge branch 'rc/1.44.0' into release 2023-10-02 15:27:51 -07:00
Eliza Velasquez a7bb0a60fb Revert "Remove now-redundant feature level 0 materials"
This reverts most of commit 9a6b8bf24e. The hello
triangle sample remains unreverted.

The original commit inadvertently broke screen space reflections, and perhaps
other features when the default material was used. The source of the issue is
that MaterialBuilder.cpp (correctly) filters out variants that aren't supported
in feature level 0 materials, including screen space reflections.

Unfortunately, while the "feature level 0 compatibility" feature itself was
intended to make creating duplicate materials like this redundant in client
code, unfortunately, it seems the best solution for resolving this issue is to
simply keep these redundant materials in the core.

To elaborate: clients should expect that feature level 0 materials that they
create work on /all/ feature levels /exactly/ or /close to exactly/ identically.
This includes restricting more advanced features that theoretically could be
available on a higher feature level, like SSR. It's already true that if a user
would like to optionally opt-in to a more advanced material which takes
advantage of more advanced features, they would have to maintain two separate
versions of that material: one for feature level 3 and one for feature level 1.
It should be no different in this case.

However, the materials built into the engine core are an exception to this
expectation. Given that feature level 0 was tacked on after the fact with fewer
features, there must /by necessity/ have been a new material introduced for both
the default material and the default skybox specifically for feature level 0
with fewer features than extant client apps expected to be included by default.
I imagine if filament were to be rebuilt from the ground up, this exception
wouldn't exist. However, the end result is this somewhat messy redundancy.
2023-09-29 16:49:40 -07:00
Powei Feng 0650b13358 vk: remove uneeded log in readpixels 2023-09-28 15:27:17 -07:00
Powei Feng 6cd851e77e Update MATERIAL_VERSION to 44 2023-09-28 15:27:06 -07:00
Powei Feng 87a8cb3872 Bump version to 1.44.0 2023-09-27 11:30:16 -07:00
Powei Feng a4869eaf19 Merge branch 'rc/1.43.1' into release 2023-09-27 11:11:53 -07:00
Powei Feng 1740220f6a Update MATERIAL_VERSION to 43 2023-09-25 10:10:25 -07:00
Benjamin Doherty 5deccffdce Bump version to 1.43.1 2023-09-18 14:23:12 -07:00
Benjamin Doherty a76eacba67 Merge branch 'rc/1.43.0' into release 2023-09-18 14:22:06 -07:00
Benjamin Doherty ee31ca6fc0 Fix RELEASE_NOTES version 2023-09-18 14:20:30 -07:00
Benjamin Doherty 7dd6686087 Correct version to 1.43.0 2023-09-18 11:07:05 -07:00
Powei Feng fdffd93949 vulkan: fix fence deadlock (#7173)
Should only reset fences in VulkanCommands::gc
2023-09-14 17:11:49 -07:00
Powei Feng f0a0a9b2e1 Bump version to 1.42.3 2023-09-13 23:05:11 -07:00
Powei Feng e743e9243f Merge branch 'rc/1.42.2' into release 2023-09-13 22:59:52 -07:00
Powei Feng 8e13d53b1e vulkan: fix swapchain leak (#7161) 2023-09-11 23:23:04 -07:00
Ben Doherty ff274c8387 Fix incorrect SamplerParams operators (#7150) 2023-09-11 22:47:25 -07:00
Benjamin Doherty e08e1c209b Bump version to 1.42.2 2023-09-07 17:59:26 -07:00
Benjamin Doherty de310ed9ad Merge branch 'rc/1.42.1' into release 2023-09-07 17:55:24 -07:00
Powei Feng d01b29fa01 vulkan: properly set bool spec onst (#7125)
We wrote a bool directly into 4 bytes (as the first byte). This has two issues:
 - the other 3 bytes are not initialized
 - should be writing VK_TRUE/FALSE instead
2023-09-01 14:17:18 -07:00
Mathias Agopian 8cba3d4366 Revert "workaround another PowerVR compiler bug "
This reverts commit 58f96be2c4.

This caused material files to increase in size significantly. It turns
out that glslang has to generate a copy for each parameter that is
passed to a function as a non-const parameter.


This revert will break IMG devices again, but that should be the case
only on debug builds. Release builds lose the const qualifier by 
virtue of going through spirv. We'll try to address this some other 
way later.
2023-09-01 14:16:59 -07:00
Ben Doherty be1e51ad91 Update FrameCompletedCallback using directive (#7128) 2023-08-30 16:29:28 -07:00
Ben Doherty 29ce1cad84 Transition setFrameCompletedCallback to take a CallbackHandler (#7103) 2023-08-30 16:28:53 -07:00
Ben Doherty 6a967ad007 Make destroyFence asynchronous (#7127) 2023-08-30 16:28:36 -07:00
Powei Feng fe2bb3d9a4 Merge branch 'rc/1.42.0' into release 2023-08-28 13:26:35 -07:00
Mathias Agopian cd7973bdcf Revert "workaround another PowerVR compiler bug "
This reverts commit 58f96be2c4.

This caused material files to increase in size significantly. It turns
out that glslang has to generate a copy for each parameter that is
passed to a function as a non-const parameter.


This revert will break IMG devices again, but that should be the case
only on debug builds. Release builds lose the const qualifier by 
virtue of going through spirv. We'll try to address this some other 
way later.
2023-08-28 10:43:26 -07:00
Powei Feng e6384e0e92 Bump version to 1.42.1 2023-08-22 13:41:42 -07:00
Powei Feng e63dc17f54 Fix missing createFence (#7076)
Continuing from #7072
2023-08-21 10:59:42 -07:00
Powei Feng af338cf2ec Update MaterialEnums.h (#7098) 2023-08-21 10:52:25 -07:00
Benjamin Doherty f1d8a04337 Bump version to 1.42.0 2023-08-15 17:13:50 -07:00
Benjamin Doherty b13497e2a0 Merge branch 'rc/1.41.0' into release 2023-08-15 17:12:01 -07:00
Powei Feng 175c9f9966 Bump version to 1.41.0 2023-08-09 10:43:02 -07:00
Powei Feng 1a50420b46 Merge branch 'rc/1.40.5' into release 2023-08-09 10:32:50 -07:00
Powei Feng bbad75a012 vulkan: fix fence initialization (#7038)
Previously, we have a VulkanSync with a default constructor that
allows us to have sync objects that returns error when
actual fences are not yet present.  We need to replicate that
with VulkanFence since sync objects have been removed from the
API.

Fixes #7034
2023-08-07 10:17:15 -07:00
Powei Feng 25c08f19e3 vulkan: fix TSAN in readpixels (#7023) (#7028) 2023-08-02 11:00:48 -07:00
Benjamin Doherty 59063fb7b4 Bump version to 1.40.5 2023-08-01 15:39:35 -07:00
Benjamin Doherty 71f60de0ad Merge branch 'rc/1.40.4' into release 2023-08-01 15:38:37 -07:00
Powei Feng 743661109d vulkan: fix TSAN in readpixels 2023-08-01 15:35:06 -07:00
Benjamin Doherty 5014cbb023 Bump version to 1.40.4 2023-07-26 12:53:47 -07:00
Benjamin Doherty 4142e7a1cf Merge branch 'rc/1.40.3' into release 2023-07-26 12:52:12 -07:00
Benjamin Doherty a721e648b7 Bump version to 1.40.3 2023-07-17 15:50:20 -06:00
Benjamin Doherty 358e89ef08 Merge branch 'rc/1.40.2' into release 2023-07-17 15:49:29 -06:00
Benjamin Doherty e023e90e7a Bump version to 1.40.2 2023-07-12 13:44:52 -07:00
Benjamin Doherty a5b5b0c3a7 Merge branch 'rc/1.40.1' into release 2023-07-12 13:43:33 -07:00
Powei Feng b7b4d3c295 Update Material version to match 1.40.1 2023-07-10 14:27:51 -07:00
Benjamin Doherty a445c4e156 Merge branch 'rc/1.40.0' into release 2023-06-26 13:29:06 +08:00
Benjamin Doherty 1432c59499 Add missing atomic header 2023-06-26 13:23:38 +08:00
Benjamin Doherty 4c7c10fad0 Bump version to 1.40.1 2023-06-26 13:17:45 +08:00
Benjamin Doherty 7c8a0d1967 Bump MATERIAL_VERSION to 40 2023-06-26 10:33:02 +08:00
Powei Feng 11fbacea20 Update MaterialEnums.h to v39 2023-06-20 11:57:42 -07:00
Powei Feng 8cd70454c3 Update MaterialEnums.h to v39 2023-06-20 11:56:40 -07:00
Benjamin Doherty 1d988182fc Bump version to 1.40.0 2023-06-20 23:55:00 +08:00
Benjamin Doherty dba49f00df Merge branch 'rc/1.39.0' into release 2023-06-20 23:45:04 +08:00
Ben Doherty 89c0b44da9 Re-enable Metal half conversion, only register SimplificationPasses for Metal (#6883) 2023-06-20 14:27:44 +08:00
Ben Doherty 4f450fd5c4 Temporarily disable Metal relaxed to half pass due to spirv-cross bug (#6880) 2023-06-20 14:27:37 +08:00
Mathias Agopian f0943cfca2 align uniform buffer to 16 bytes
this is needed on armv7 because we use alignas to get strcture-alignment,
but that also implies (to the compiler) that the structure itself
is aligned properly.
2023-06-20 14:23:47 +08:00
Mathias Agopian 9aa52b79d4 helpers to fix jank when resizing a TextureView (#6889)
There was two related issues:
- we need to "latch" the new TextureView size when its resized. That
  can only be done by recreating the EGLSurface (i.e. recreating the
  SwapChain). UiHelper now calls onNativeWindowChanged in the case of
  the TextureView resize, so clients can recreate their SwapChain.
- we also needed to make sure that all current filament frames have
  finished to render (i.e. the last eglSwapBuffers has been called) so
  that they don't pick-up a new size (this happens after
  eglSwapBuffers) that doesn't match the viewport.

Fixes b/282220665
2023-06-12 23:13:48 -07:00
Powei Feng a82125dbbd vulkan: minor fixes (#6874)
- flush() and wait() before destroying a swapchain
 - Make sure the debug marker extension is enabled under correct
   circumstances.
 - Change shared_ptrs to unique_ptrs and raw pointers.
 - Rename most teardown methods to terminate()
2023-06-07 11:45:09 -07:00
Benjamin Doherty 24fcb299b5 Bump version to 1.39.0 2023-06-07 11:32:33 -05:00
Benjamin Doherty 753aa9ca61 Merge branch 'rc/1.38.0' into release 2023-06-07 11:31:21 -05:00
Benjamin Doherty a33eada7ec Bump version to 1.38.0 2023-06-07 11:29:02 -05:00
Benjamin Doherty 676a2be874 Correct MATERIAL_VERSION to 37 2023-06-05 17:20:18 -05:00
Powei Feng c95d466cdd Fix missing include (#6858) 2023-06-01 16:28:05 -07:00
Powei Feng 3d8ac384ad Update MATERIAL_VERSION to 38 (#6852) (#6854) 2023-05-31 15:00:34 -07:00
Powei Feng 57424cc7e9 Merge branch 'rc/1.37.0' into release 2023-05-30 16:22:31 -07:00
Powei Feng 78fe4ba547 vulkan: allow for headless linux builds (#6836) 2023-05-24 17:19:42 -07:00
Benjamin Doherty a3d25cd22b Bump version to 1.37.0 2023-05-15 16:57:27 -07:00
Benjamin Doherty 56bf841bac Merge branch 'rc/1.36.0' into release 2023-05-15 16:55:48 -07:00
Ben Doherty dfdf0db794 Fix incorrect target passed to glBindFramebuffer (#6807) 2023-05-15 15:28:44 -07:00
Benjamin Doherty bf6bd4eca8 Fix Android CI release build 2023-05-09 13:22:47 -04:00
Benjamin Doherty 36c69dda9c Fix Android CI release build 2023-05-09 13:22:20 -04:00
Benjamin Doherty f14fdc11f5 Bump MATERIAL_VERSION to 36 2023-05-08 18:07:13 -04:00
Benjamin Doherty 0157487b1f Bump version to 1.36.0 2023-05-08 18:06:59 -04:00
Benjamin Doherty 1716c856c3 Merge branch 'rc/1.35.0' into release 2023-05-08 18:05:07 -04:00
Benjamin Doherty 31521c70c2 Fix Android CI release build 2023-05-01 18:45:34 -04:00
Benjamin Doherty 8cac90d81e Bump MATERIAL_VERSION to 35 2023-05-01 13:37:24 -04:00
Benjamin Doherty 388b4f5efb Bump version to 1.35.0 2023-05-01 13:36:40 -04:00
Benjamin Doherty f9b5a7f301 Merge branch 'rc/1.34.0' into release 2023-05-01 13:35:16 -04:00
Benjamin Doherty 00c78cc225 Bump MATERIAL_VERSION to 34 2023-05-01 12:20:50 -04:00
Powei Feng 2bdb8b560c vulkan: fix RenderPass size (#6775) (#6776) 2023-04-27 14:09:46 -07:00
Benjamin Doherty a974fddd4c Bump version to 1.34.0 2023-04-25 13:10:24 -04:00
Benjamin Doherty 83a3e243da Merge branch 'rc/1.33.0' into release 2023-04-25 13:09:13 -04:00
Benjamin Doherty f286e308bf Bump version to 1.33.0 2023-04-19 14:11:43 -04:00
Benjamin Doherty 29af3be2e3 Merge branch 'rc/1.32.4' into release 2023-04-19 14:10:10 -04:00
Mathias Agopian 6623dcbebf fix specification constant injection in glsl
- boolean where handled as int
- always cast float to float()
2023-04-17 10:29:02 -04:00
Powei Feng 89dc43f361 vulkan: fix spec constant bool size 2023-04-17 10:28:44 -04:00
Ben Doherty b77aac43ea Fix float spec constant formatting (#6731) 2023-04-17 10:28:24 -04:00
Benjamin Doherty 0d63fa02ee Fix build when exceptions disabled 2023-04-17 10:28:00 -04:00
Benjamin Doherty e187bc442d Bump version to 1.32.4 2023-04-11 11:19:53 -07:00
Benjamin Doherty d62268fbfb Merge branch 'rc/1.32.3' into release 2023-04-11 11:17:47 -07:00
Benjamin Doherty 3b73e3de60 Bump version to 1.32.3 2023-04-05 12:56:23 -07:00
Benjamin Doherty 7685736d6c Merge branch 'rc/1.32.2' into release 2023-04-05 12:55:12 -07:00
Benjamin Doherty b8a3a7f221 Bump version to 1.32.2 2023-04-05 12:53:18 -07:00
Benjamin Doherty 732628acf5 Merge branch 'rc/1.32.1' into release 2023-03-21 15:48:49 -07:00
Powei Feng 7bd00d2b30 Revert "vulkan: async readPixels (#6605)" (#6644)
This reverts commit 6f25e8ae5a.

Reason for revert: breaks clients that were expecting synchronous readPixels for vulkan
2023-03-16 13:05:48 -07:00
Benjamin Doherty 0759797e61 Include atomic in VulkanCommands.h 2023-03-15 11:15:24 -07:00
Benjamin Doherty fddc5160c7 Bump version to 1.32.1 2023-03-14 10:48:50 -07:00
Benjamin Doherty 2a579c460f Merge branch 'rc/1.32.0' into release 2023-03-14 10:46:27 -07:00
Ben Doherty efdc801cff Vulkan: fix stack use-after-free (#6639) 2023-03-14 10:24:18 -07:00
Benjamin Doherty dd654c575a Bump MATERIAL_VERSION to 32 2023-03-13 14:04:13 -07:00
Benjamin Doherty 0c2599b6ca Bump version to 1.32.0 2023-03-09 10:40:39 -08:00
Benjamin Doherty 979d6742e0 Merge branch 'rc/1.31.7' into release 2023-03-09 10:39:41 -08:00
Mathias Agopian 4a7a033d04 Fix timer query breakage on webgl 2023-03-08 12:33:11 -08:00
Ben Doherty 5c2bbcb4a1 Remove compute shader assertion in GLProgram 2023-03-08 10:56:24 -08:00
Benjamin Doherty dec903a0ee Bump version to 1.31.7 2023-03-01 11:26:50 -08:00
Benjamin Doherty e9475b322b Merge branch 'rc/1.31.6' into release 2023-03-01 11:24:13 -08:00
Benjamin Doherty d9aead8aac Linux CI: use clang 14 2023-02-21 16:06:48 -08:00
Powei Feng ce148ebeb1 Update linux clang to version 10 (#6556) 2023-02-21 16:00:07 -08:00
Powei Feng e1315fbaa7 Update CI Ubuntu version 2023-02-21 15:57:00 -08:00
Benjamin Doherty 1690549392 Bump version to 1.31.6 2023-02-21 13:18:22 -08:00
Benjamin Doherty c73710e343 Merge branch 'rc/1.31.5' into release 2023-02-21 13:16:47 -08:00
Benjamin Doherty 092a0489da Bump version to 1.31.5 2023-02-13 11:53:24 -08:00
Benjamin Doherty 1c6279366f Merge branch 'rc/1.31.4' into release 2023-02-13 11:51:37 -08:00
Benjamin Doherty 2ac85049a9 Bump version to 1.31.4 2023-02-01 11:55:09 -08:00
Benjamin Doherty ea428a27d1 Merge branch 'rc/1.31.3' into release 2023-02-01 11:54:04 -08:00
Benjamin Doherty 3bef718238 Bump version to 1.31.3 2023-01-24 14:28:21 -08:00
Benjamin Doherty e9daaa0503 Merge branch 'rc/1.31.2' into release 2023-01-24 14:27:02 -08:00
Benjamin Doherty 6d3ea21993 Bump version to 1.31.2 2023-01-18 14:25:45 -08:00
Benjamin Doherty f39127605d Merge branch 'rc/1.31.1' into release 2023-01-18 14:23:59 -08:00
Ben Doherty db476f00f7 Vulkan: fix stack-use-after-scope ASAN error in VulkanContext.cpp (#6463) 2023-01-18 11:59:10 -08:00
Powei Feng e54d8ec0a4 [vulkan] enumerate: Returning size = 0 is ok (#6450) 2023-01-17 10:14:45 -08:00
Benjamin Doherty b95ac854b4 Bump version to 1.31.1 2023-01-10 12:52:49 -05:00
Benjamin Doherty 96443f6dac Merge branch 'rc/1.31.0' into release 2023-01-10 12:50:52 -05:00
Benjamin Doherty e5e3dff9fa Fix Windows CI build 2022-12-20 11:01:49 -07:00
Benjamin Doherty 31d9da38fd Fix CI build 2022-12-20 09:40:07 -07:00
Benjamin Doherty c5a59bb6b1 Bump version to 1.31.0 2022-12-19 11:14:41 -08:00
Benjamin Doherty e6854148d7 Merge branch 'rc/1.30.0' into release 2022-12-19 11:12:54 -08:00
Ben Doherty 001daf0350 Fix memory leak in Scene (#6387) 2022-12-16 14:38:38 -08:00
Mathias Agopian d26c48110d Fix Android continuous and presubmit builds
Since cmake 3.25 LINUX is automatically set based on CMAKE_SYSTEM_NAME, 
which the android cmake files are setting to "Linux". This created an
inconsistant state in our build system.
2022-12-15 11:54:33 -08:00
Mathias Agopian 15a070f0c9 Fix unused variables in release builds 2022-12-12 11:17:42 -08:00
Mathias Agopian 93230b06cf Fix Android continuous and presubmit builds
Since cmake 3.25 LINUX is automatically set based on CMAKE_SYSTEM_NAME, 
which the android cmake files are setting to "Linux". This created an
inconsistant state in our build system.
2022-12-12 10:44:49 -08:00
Mathias Agopian 4c55fc3c48 fix TransformManager high precision mode
The residual would be corrupted when using transactions.
2022-12-12 10:06:18 -08:00
Mathias Agopian a4797a631e Fix a WebGL program link failure
WebGL complained about:

Precisions of uniform block 'ShadowUniforms' member
'ShadowUniforms.shadows.texelSizeAtOneMeter' differ between VERTEX and
FRAGMENT shaders.


this field didn't have a precision qualifier, this might be specific to
WebGL or a Chrome bug, unsure. Either we fix it by specifying all
qualifiers.
2022-11-29 23:32:21 -08:00
Mathias Agopian 5868e857aa Fix a WebGL program link failure
WebGL complained about:

Precisions of uniform block 'ShadowUniforms' member 
'ShadowUniforms.shadows.texelSizeAtOneMeter' differ between VERTEX and 
FRAGMENT shaders.


this field didn't have a precision qualifier, this might be specific to
WebGL or a Chrome bug, unsure. Either we fix it by specifying all
qualifiers.
2022-11-29 23:31:03 -08:00
Benjamin Doherty 32ba063bd7 Fix CI build 2022-11-21 16:58:37 -08:00
Benjamin Doherty 02f0839f9b Bump version to 1.30.0 2022-11-21 15:45:27 -08:00
Benjamin Doherty e50f3c4c91 Merge branch 'rc/1.29.0' into release 2022-11-21 15:44:36 -08:00
Ben Doherty 7ca15bfc16 Use GitHub script for release asset upload (#6308) 2022-11-21 15:39:55 -08:00
Benjamin Doherty b7b7afb62a Bump version to 1.29.0 2022-11-09 16:43:08 -08:00
Benjamin Doherty b8ff6a9ad9 Merge branch 'rc/1.28.3' into release 2022-11-09 16:38:02 -08:00
Ben Doherty a1dcb4f259 Skip rendering renderables with missing geometry (#6281) 2022-11-09 16:35:31 -08:00
Benjamin Doherty c3501393fd Fix RELEASE_NOTES 2022-11-09 16:34:42 -08:00
Benjamin Doherty a03de75a4e Update Python requirements.txt to fix CI 2022-11-04 11:35:21 -07:00
Benjamin Doherty 0c3d59aba3 Update Python requirements.txt to fix CI 2022-11-03 16:15:29 -07:00
Benjamin Doherty ce1987f291 Fix iOS build 2022-11-01 15:10:57 -04:00
Benjamin Doherty 7eae926ed7 Bump version to 1.28.3 2022-11-01 13:03:19 -04:00
Benjamin Doherty 606af52eda Merge branch 'rc/1.28.2' into release 2022-11-01 13:02:05 -04:00
Benjamin Doherty 8ea30aea80 Update RELEASE_NOTES for 1.28.2 2022-11-01 13:00:04 -04:00
Ben Doherty 72dea695ba Fix G3 reported ubsan warning (#6257) 2022-11-01 12:52:10 -04:00
daemyung jang 1c0cf56ed0 Fix glTF breaking issue (#6239) 2022-10-28 13:08:50 -04:00
Benjamin Doherty bcb4eb35cd Bump version to 1.28.2 2022-10-25 13:09:21 -04:00
Benjamin Doherty bce2676335 Merge branch 'rc/1.28.1' into release 2022-10-25 13:08:12 -04:00
Benjamin Doherty 510097d722 Force spirv-cross to keep Metal argument buffer equal sized 2022-10-25 12:10:54 -04:00
Ben Doherty 5784118a12 Fix, don't use encoder.device (#6212) 2022-10-20 13:08:04 -04:00
Ben Doherty b5de0f2d23 Metal: fix simulator regression due to arg buffers (#6181) 2022-10-18 16:29:18 -04:00
Ben Doherty 04df3f4dad Metal: fix use-after-free ASAN error (#6203) 2022-10-18 16:29:12 -04:00
Benjamin Doherty 093ca4d623 Revert Android API_LEVEL change
glDispatchCompute requires Android API level 21, however bumping our
required minimum from 19 to 21 caused some clients' builds to fail.
Commenting-out that line for now to proceed with the 1.28.0 upgrade.
2022-10-18 16:28:58 -04:00
Mathias Agopian a3ed1558d3 fix a directional light shadowing issue
the shadow frustum could be be smaller than expected.
2022-10-14 15:42:03 -07:00
Benjamin Doherty fe379070ae Bump version to 1.28.1 2022-10-13 12:38:40 -04:00
Benjamin Doherty ead0a2f597 Merge branch 'rc/1.28.0' into release 2022-10-13 12:37:07 -04:00
Benjamin Doherty 5dbc593f90 Fix assertion in ShadowMap due to vertexCount 2022-10-12 18:16:53 -04:00
Ben Doherty d47dc12bf0 G3 fixes for 1.28.0 (#6174) 2022-10-12 14:48:37 -04:00
Philip Rideout 4392f63e57 Vulkan: fix black screen regression
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.
2022-10-12 14:48:25 -04:00
Ben Doherty f64b7aca79 Fix Metal argument buffer encoding (#6150) 2022-10-10 10:07:41 -07:00
Ben Doherty 3762ec5750 Fix Android release build (#6133) 2022-09-30 11:48:13 -07:00
Ben Doherty 4591fdd9c0 Fix Android release build (#6133) 2022-09-30 11:47:41 -07:00
Benjamin Doherty d3068d2a0e Bump version to 1.28.0 2022-09-29 13:13:18 -07:00
Benjamin Doherty ca0a4bc23a Merge branch 'rc/1.27.2' into release 2022-09-29 13:12:20 -07:00
Ben Doherty 433c163c61 Fixes for 1.27.2 release (#6125) 2022-09-29 13:08:39 -07:00
Mathias Agopian c867fda883 don't attempt to use more texture units than present
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.
2022-09-29 12:36:28 -07:00
Ben Doherty 566540ae6d Fix generic/Mutex.h not installed on Linux (#6117) 2022-09-28 16:49:03 -07:00
Benjamin Doherty 759f490dae Bump version to 1.27.2 2022-09-20 11:06:02 -07:00
Benjamin Doherty 867d4d44f5 Merge branch 'rc/1.27.1' into release 2022-09-20 11:04:58 -07:00
Ben Doherty 65747d5877 Update glslang to c0cf8ad87 (master) (#6076) 2022-09-19 12:38:05 -07:00
Benjamin Doherty bd357f6076 Bump version to 1.27.1 2022-09-13 10:15:12 -07:00
Benjamin Doherty 9e960b7d45 Merge branch 'rc/1.27.0' into release 2022-09-13 10:14:24 -07:00
Ben Doherty 0c54d4a6a1 Add return case to fix G3 compiler error (#6062) 2022-09-12 12:34:56 -07:00
Philip Rideout 526e846a81 gltfio: fix crash when material is unspecified 2022-09-06 22:13:19 -04:00
Philip Rideout 8bcfa373d4 gltfio: do not clear out the texture slots too early.
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.
2022-09-06 22:09:25 -04:00
Ben Doherty db9a0f2c1f Fix uberarchive not included in PodSpec (#6024) 2022-09-01 12:18:20 -04:00
Benjamin Doherty 646b1e2193 Bump version to 1.27.0 2022-08-31 12:04:55 -04:00
Benjamin Doherty 41bd30f81d Merge branch 'rc/1.26.0' into release 2022-08-31 12:04:08 -04:00
Mathias Agopian bd626aea27 material instanced property must be false by default.
this fix auto-instancing.
2022-08-26 18:28:56 -04:00
Benjamin Doherty 8a03f75485 Bump version to 1.26.0 2022-08-23 12:07:33 -04:00
Benjamin Doherty dc9594fbdf Merge branch 'rc/1.25.6' into release 2022-08-23 12:05:44 -04:00
Benjamin Doherty fad0b533c0 Update RELEASE_NOTES for 1.25.6 2022-08-23 12:03:28 -04:00
Benjamin Doherty 4d773e9453 Bump version to 1.25.6 2022-08-16 11:03:07 -07:00
Benjamin Doherty e0c610b013 Merge branch 'rc/1.25.5' into release 2022-08-16 11:01:04 -07:00
Benjamin Doherty 0da4f36c33 Bump version to 1.25.5 2022-08-16 10:54:00 -07:00
Ben Doherty 11d17e1db3 Fix SamplerGroup update issue (#5928) 2022-08-16 10:47:18 -07:00
Philip Rideout b8c318d923 WASM: Allow clients to enable pthreads.
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.
2022-08-12 15:43:28 -07:00
Philip Rideout e563cc6f5e gltfio: add 'detach' methods to allow ownership transfer
These new methods allow gltfio to be integrated into internal Google
libraries.
2022-08-09 14:37:44 -07:00
Benjamin Doherty cb8914ab96 Merge branch 'rc/1.25.4' into release 2022-08-02 11:47:52 -07:00
Alan Eneev 2fecda7bdc Headless EGL: Fallback to a 24-bit depth buffer 2022-07-29 10:10:46 -07:00
Alan Eneev 543d8efb25 Fix PlatformEGLHeadless build and add a build.sh option to build EGL
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
```
2022-07-29 10:10:40 -07:00
Benjamin Doherty 396b1079a7 Bump version to 1.25.4 2022-07-26 09:57:34 -07:00
Benjamin Doherty eedcd9f8cb Merge branch 'rc/1.25.3' into release 2022-07-26 09:56:22 -07:00
Ben Doherty ab252b210c Fix config object related build failures (#5814) 2022-07-26 09:51:55 -07:00
Benjamin Doherty 1071b8ea90 Bump version to 1.25.3 2022-07-18 15:15:03 -07:00
Benjamin Doherty a9c5bbf185 Merge branch 'rc/1.25.2' into release 2022-07-18 15:14:02 -07:00
Philip Rideout 8dd4bff7a7 gltfio: minor fixups to prep for g3 integration. 2022-07-18 15:11:36 -07:00
Philip Rideout 77c54446af gltfio: use openLocalTransformTransaction API. 2022-07-18 15:11:30 -07:00
Benjamin Doherty 4a0bc0af57 Bump version to 1.25.2 2022-07-11 15:51:55 -07:00
Benjamin Doherty a171e75e70 Merge branch 'rc/1.25.1' into release 2022-07-11 15:50:10 -07:00
Benjamin Doherty f5ffa092fe Bump version to 1.25.1 2022-07-06 19:09:34 -07:00
Benjamin Doherty 8de5fdd551 Merge branch 'rc/1.25.0' into release 2022-07-06 19:07:42 -07:00
Benjamin Doherty ecca3abe98 Bump version to 1.25.0 2022-07-01 12:09:29 -07:00
Benjamin Doherty 8570e35224 Merge branch 'rc/1.24.0' into release 2022-07-01 12:08:48 -07:00
Benjamin Doherty 84df9f9a03 Update version to 1.24.0 2022-07-01 12:03:38 -07:00
Benjamin Doherty 5f93fb9613 Update RELEASE_NOTES for 1.24.0 2022-06-30 16:37:03 -07:00
Benjamin Doherty 75f77fdbdd Metal: Allow Filament to disregard MTLTexture pixelFormat when importing 2022-06-30 16:04:28 -07:00
Ben Doherty 7825d582c2 CocoaPods: include uberz library (#5752) 2022-06-30 14:07:55 -07:00
Ben Doherty 5deb0ba933 CocoaPods: include uberz library (#5752) 2022-06-30 14:04:02 -07:00
Philip Rideout 18e917aaf2 ImGuiHelper: add support for Y flip. (#5748)
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.
2022-06-30 12:05:53 -07:00
Benjamin Doherty a165f3890a Vulkan: Support VMA_DYNAMIC_VULKAN_FUNCTIONS off 2022-06-21 15:09:26 -07:00
Philip Rideout f88b6d9c97 Do not trigger UB with string_view. 2022-06-20 21:11:52 -07:00
Mathias Agopian db8ecd9952 configure render primitive pool so it works with msvc
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.
2022-06-16 13:13:33 -07:00
Benjamin Doherty b5ec06c2d2 Fix build breakage 2022-06-15 17:05:53 -07:00
Benjamin Doherty dfbac8385e Merge branch 'rc/1.23.2' into release 2022-06-15 11:49:06 -07:00
Ben Doherty eaab737b2c NoopDriver: return unique handles (#5697) 2022-06-15 11:28:08 -07:00
Benjamin Doherty 45991cda0a Update RELEASE_NOTES for 1.23.2 2022-06-13 15:27:03 -07:00
Philip Rideout 09a016bb6f Remove an 'API Change' warning from one item. 2022-06-09 14:33:49 -07:00
Benjamin Doherty 31607d355d Bump version to 1.23.2 2022-06-06 15:18:57 -07:00
Benjamin Doherty a67d50b9e2 Merge branch 'rc/1.23.1' into release 2022-06-06 15:16:53 -07:00
Benjamin Doherty 8d42f53c80 Update RELEASE_NOTES for 1.23.1 2022-06-06 15:14:59 -07:00
Benjamin Doherty 5e21a55bce Revert "iOS: implement headleass swapchain (#5486)"
This reverts commit 0e5ba60cb6.

This causes issues in G3, still need to investigate the root cause.
2022-06-06 13:17:04 -07:00
Benjamin Doherty 85930ea2e8 Bump version to 1.23.1 2022-06-01 14:58:29 -07:00
Benjamin Doherty 4b3cde8b39 Merge branch 'rc/1.23.0' into release 2022-06-01 14:55:20 -07:00
Benjamin Doherty eedfa85355 Update RELEASE_NOTES for 1.23.0 2022-06-01 14:54:50 -07:00
Benjamin Doherty bb54c6c807 Release Filament 1.23.0 2022-06-01 14:53:48 -07:00
Benjamin Doherty c23f905858 Update RELEASE_NOTES for 1.23.0 2022-06-01 14:53:23 -07:00
Benjamin Doherty 8c7be0a1d0 Revert "iOS: implement headleass swapchain (#5486)"
This reverts commit 0e5ba60cb6.

This causes issues in G3, still need to investigate the root cause.
2022-05-31 11:29:38 -07:00
Benjamin Doherty 878497b3d5 Bump version to 1.23.0 2022-05-24 15:19:51 -07:00
Benjamin Doherty a155561769 Merge branch 'rc/1.22.2' into release 2022-05-24 15:17:55 -07:00
Benjamin Doherty 8b86a0ed2e Revert "iOS: implement headleass swapchain (#5486)"
This reverts commit 0e5ba60cb6.

This causes issues in G3, still need to investigate the root cause.
2022-05-24 20:13:10 +00:00
Benjamin Doherty 26f9a9b122 Update RELEASE_NOTES for 1.22.2 2022-05-23 12:40:47 -07:00
Ben Doherty 6e5f6978fb Add ktxreader and viewer libs to CocoaPods (#5573) 2022-05-18 16:24:51 -07:00
Ben Doherty 0d31d7b2de Add ktxreader and viewer libs to CocoaPods (#5573) 2022-05-18 16:13:26 -07:00
Benjamin Doherty dd862b7e0a Bump version to 1.22.2 2022-05-17 18:03:38 -07:00
Benjamin Doherty 52065f2cbd Merge branch 'rc/1.22.1' into release 2022-05-17 18:01:37 -07:00
Benjamin Doherty 77c02d5831 Update RELEASE_NOTES for 1.22.1 2022-05-17 17:51:37 -07:00
Ben Doherty f7e4c8d16d Add package name back to AndroidManifest.xml to fix G3 (#5569) 2022-05-17 17:51:21 -07:00
Philip Rideout b7410474ff Workaround: partially revert "don't issue a flush..."
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.
2022-05-16 10:39:55 -07:00
Benjamin Doherty 384cc4ebf6 Bump version to 1.22.1 2022-05-09 13:09:39 -07:00
Benjamin Doherty 7c0643f122 Merge branch 'rc/1.22.0' into release 2022-05-09 13:07:07 -07:00
Benjamin Doherty 58abae3067 Release Filament 1.22.0 2022-05-09 13:07:02 -07:00
Benjamin Doherty 4742693869 Update RELEASE_NOTES for 1.22.0 2022-05-09 13:04:55 -07:00
Benjamin Doherty 6c39e474ea Bump version to 1.22.0 2022-05-02 13:19:43 -04:00
Benjamin Doherty 5c8977c906 Merge branch 'rc/1.21.3' into release 2022-05-02 13:18:06 -04:00
Benjamin Doherty 6b3cc2e2f3 Update RELEASE_NOTES for 1.21.3 2022-05-02 13:12:51 -04:00
Ben Doherty 76b2edd6ea Move toCompressedFilamentEnum to Ktx1Reader header (#5493) 2022-04-29 14:50:24 -04:00
Benjamin Doherty 8ebb37d011 Bump version to 1.21.3 2022-04-25 16:58:19 -04:00
Benjamin Doherty 3366db83ef Merge branch 'rc/1.21.2' into release 2022-04-25 16:57:25 -04:00
Benjamin Doherty 5415254aac Update RELEASE_NOTES for 1.21.2 2022-04-25 16:50:53 -04:00
Benjamin Doherty caacc61602 Bump version to 1.21.2 2022-04-13 10:21:09 -06:00
Benjamin Doherty e902df19b2 Merge branch 'rc/1.21.1' into release 2022-04-13 10:15:50 -06:00
Benjamin Doherty 40b372dda7 Update RELEASE_NOTES for 1.21.1 2022-04-12 14:36:26 -06:00
Ben Doherty fd330a98aa Releases: specify Python dependencies in requirements.txt file (#5402) 2022-04-08 14:35:51 -07:00
Ben Doherty 90c23a7d5d Correctly prepare color grading as subpass programs (#5384) 2022-04-04 13:24:01 -07:00
Benjamin Doherty 5710304114 Bump version to 1.21.1 2022-04-04 13:03:39 -07:00
Benjamin Doherty 0f684820bc Merge branch 'rc/1.21.0' into release 2022-04-04 13:01:35 -07:00
Benjamin Doherty e1d2d6ade6 Update RELEASE_NOTES for 1.21.0 2022-04-04 12:58:54 -07:00
Mathias Agopian e0b6f2ca71 Change version number to 1.21.0 2022-04-04 12:41:38 -07:00
Benjamin Doherty 2a35ee279b Bump version to 1.20.6 2022-03-28 18:47:38 -07:00
Benjamin Doherty 5abf780360 Merge branch 'rc/1.20.5' into release 2022-03-28 18:45:34 -07:00
Benjamin Doherty 181f158ea9 Update RELEASE_NOTES for 1.20.5 2022-03-28 18:42:41 -07:00
Benjamin Doherty f4087fc81d Bump version to 1.20.5 2022-03-21 14:45:34 -07:00
Benjamin Doherty 82793f9b82 Merge branch 'rc/1.20.4' into release 2022-03-21 14:43:15 -07:00
Benjamin Doherty 537576e84a Update RELEASE_NOTES for 1.20.4 2022-03-21 14:42:35 -07:00
Benjamin Doherty 375d1f55e3 Release Filament 1.20.4 2022-03-21 14:38:14 -07:00
Benjamin Doherty 597218963f Update RELEASE_NOTES for 1.20.4 2022-03-21 14:37:17 -07:00
Philip Rideout 0d29b3ddc8 WebGL endFrame: restore additional default state. 2022-03-21 09:43:45 -07:00
Philip Rideout e0e3b42623 WebGL: reset VAO and texture bindings when frame ends. 2022-03-21 09:43:33 -07:00
Benjamin Doherty 0995ca6614 Bump version to 1.20.4 2022-03-14 14:19:36 -07:00
Benjamin Doherty 3d741fc8d4 Merge branch 'rc/1.20.3' into release 2022-03-14 14:17:54 -07:00
Benjamin Doherty c20772b458 Update RELEASE_NOTES for 1.20.3 2022-03-10 12:56:56 -08:00
Benjamin Doherty 4a6b659098 Bump version to 1.20.3 2022-03-07 14:12:28 -08:00
Benjamin Doherty 2b93f08ca5 Merge branch 'rc/1.20.2' into release 2022-03-07 14:10:07 -08:00
Benjamin Doherty fca62b8fff Update RELEASE_NOTES for 1.20.2 2022-03-07 14:08:41 -08:00
Benjamin Doherty dee6d9de2c Bump version to 1.20.2 2022-03-02 15:51:38 -08:00
Benjamin Doherty 574e3e7521 Merge branch 'rc/1.20.1' into release 2022-03-02 15:47:21 -08:00
Ben Doherty 29fdf82ac5 Make VulkanContext compatible with vk_mem_alloc dev 2022-03-02 12:10:20 -08:00
Benjamin Doherty c8cf2a54e8 Update RELEASE_NOTES for 1.20.1 2022-03-02 11:47:51 -08:00
Ben Doherty bfd32e67d4 Apply some clang-tidy fixes (#5281) 2022-03-02 11:43:51 -08:00
Benjamin Doherty 95915367fa Bump version to 1.20.1 2022-02-24 13:59:17 -08:00
Benjamin Doherty b769cfda62 Merge branch 'rc/1.20.0' into release 2022-02-24 13:57:10 -08:00
Benjamin Doherty 40ac88dfed Bump MATERIAL_VERSION to 20 2022-02-24 13:53:43 -08:00
Benjamin Doherty 6d96082f07 Bump version to 1.20.0 2022-02-24 13:53:43 -08:00
Benjamin Doherty 21f913db1c Update RELEASE_NOTES for 1.20.0 2022-02-24 13:53:42 -08:00
Ben Doherty 699a578966 Add SSR variant filter to matc (#5256) 2022-02-24 10:36:06 -08:00
Philip Rideout babbfa1394 Vulkan: remove layout checks from SwapChain.
These asserts will come back in the next Filament release, which has
much cleaner layout tracking.
2022-02-23 13:48:13 -08:00
Philip Rideout 73f0d58e10 Vulkan: fix backend tests (especially ReadPixels Y flip). 2022-02-23 11:18:29 -08:00
Philip Rideout 9cb4b74bbd Fix web apps that have multiple Filament viewers.
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.
2022-02-22 16:12:13 -08:00
Ben Doherty f2c8456971 Attempt to fix Windows CI builds (#5205) 2022-02-15 11:12:19 -08:00
Benjamin Doherty e571600c30 Bump version to 1.19.1 2022-02-14 13:48:59 -08:00
Benjamin Doherty e84c94d3eb Merge branch 'rc/1.19.0' into release 2022-02-14 13:46:45 -08:00
Benjamin Doherty e791d4818f Update RELEASE_NOTES for 1.19.0 2022-02-14 13:45:28 -08:00
Philip Rideout cdadb43e50 WebGL: another fix for BufferDescriptor bindings.
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.
2022-02-09 15:44:26 -08:00
Philip Rideout edaff60fbf WebGL: remove buffer sharing optimization.
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.
2022-02-09 12:51:06 -08:00
Benjamin Doherty 3f64e46557 Bump version to 1.19.0 2022-02-08 09:27:14 -08:00
Benjamin Doherty 32dab23bc6 Update RELEASE_NOTES for 1.18.0 2022-02-08 09:25:41 -08:00
Benjamin Doherty 362de7dd31 Merge branch 'rc/1.18.0' into release 2022-02-08 09:22:21 -08:00
Benjamin Doherty 6b01fbb903 Correct version to 1.18.0 2022-02-08 09:08:49 -08:00
Philip Rideout 4934d9f7bc Vulkan: fix leak when apps do not draw anything. 2022-02-07 14:27:06 -08:00
Ben Doherty ed73955b00 Initialize useLegacyMorphing to fix MSAN warning (#5164) 2022-02-07 11:28:03 -08:00
Ben Doherty 3f1f2726c4 Add a MAX_LEGACY_MORPH_TARGETS definition (#5163) 2022-02-07 11:27:45 -08:00
Philip Rideout 1a7bd7ea8d Rewrite VulkanPipelineCache (without changing its API).
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.
2022-02-03 17:37:40 -08:00
Ben Doherty 946ea43436 Fix sampler overflow check in SamplerBindingMap (#5143) 2022-02-02 11:04:48 -08:00
Philip Rideout 7f42385f5f VulkanPipelineCache: fix spurious SEGV.
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.
2022-02-01 16:34:34 -08:00
Philip Rideout 8845ac2b75 VulkanPipelineCache: code cleanup and minor fixes.
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.
2022-02-01 16:34:27 -08:00
Ben Doherty da85001d4d Support legacy morphing (#5129)
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.
2022-01-27 16:08:46 -08:00
Mathias Agopian 8d15079937 update material version to 18 2022-01-26 14:32:46 -08:00
adc542b5cd Bind samplers to specified shader stages (#5036)
Co-authored-by: Ben Doherty <bendoherty@google.com>
Co-authored-by: Mathias Agopian <mathias@google.com>
2022-01-26 14:31:30 -08:00
Philip Rideout 72feb044a3 Vulkan now supports offsets when uploading texture data.
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.
2022-01-26 14:31:00 -08:00
Philip Rideout c0ba260ddf Vulkan: clean up image layout management.
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.
2022-01-26 14:30:45 -08:00
Philip Rideout 2da215e8e7 RangeMap: improve naming convention, etc. 2022-01-26 14:30:23 -08:00
Philip Rideout 4d0368b5f1 RangeMap: improve the auto-merge functionality. 2022-01-26 14:30:09 -08:00
Philip Rideout d11c78857d utils: introduce RangeMap container and unit test.
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.
2022-01-26 14:29:45 -08:00
Mathias Agopian e829d90c4a A morphing buffer must be bound when skinning is active
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
2022-01-26 14:20:25 -08:00
Mathias Agopian a8006acd33 [GL backend] fix sampler binding bug
When a program had an unused SamplerInterfaceBlock, other samplers
could be bound to the wrong TMU

Fixes #5088
2022-01-26 14:20:12 -08:00
Benjamin Doherty 86ec502040 Bump version to 1.17.1 2022-01-24 12:52:22 -08:00
Benjamin Doherty b19a73cc50 Merge branch 'rc/1.17.0' into release 2022-01-24 12:50:22 -08:00
Benjamin Doherty a99c695932 Update RELEASE_NOTES for 1.17.0 2022-01-24 12:45:05 -08:00
Benjamin Doherty 8cd720b53a Bump version to 1.17.0 2022-01-18 13:54:40 -08:00
Benjamin Doherty 04df79e58f Merge branch 'rc/1.16.1' into release 2022-01-18 13:53:02 -08:00
Benjamin Doherty a4b3717762 Update RELEASE_NOTES for 1.16.1 2022-01-18 13:48:36 -08:00
Benjamin Doherty 1035e442ee Bump version to 1.16.1 2022-01-10 10:47:46 -08:00
Benjamin Doherty 60d3638f15 Merge branch 'rc/1.16.0' into release 2022-01-10 10:44:36 -08:00
Benjamin Doherty 3e7d3c9035 Update RELEASE_NOTES for 1.16.0 2022-01-10 10:41:14 -08:00
jeanlemotan eb360be2ad Fixed cubemap update 2022-01-10 10:34:49 -08:00
Benjamin Doherty 485ac8704d Bump version to 1.16.0 2022-01-04 11:55:19 -08:00
Benjamin Doherty dc74540423 Merge branch 'rc/1.15.2' into release 2022-01-04 11:53:02 -08:00
Benjamin Doherty 96219c22db Update RELEASE_NOTES for 1.15.2 2022-01-04 11:49:50 -08:00
Romain Guy f3b7048775 Add missing JNI impl (#4959) 2022-01-04 11:43:19 -08:00
Romain Guy aaed6fb376 Fix rounding math 2022-01-04 11:43:13 -08:00
Romain Guy 35a5d3310f Fix preprocessor test 2021-12-13 13:53:20 -07:00
Benjamin Doherty 9da79a1d2d Bump version to 1.15.2 2021-12-13 11:08:28 -07:00
Benjamin Doherty 595b355d1b Merge branch 'rc/1.15.1' into release 2021-12-13 11:06:45 -07:00
Benjamin Doherty 3a67d769f4 Update RELEASE_NOTES for 1.15.1 2021-12-06 16:54:28 -08:00
Benjamin Doherty 6fb536a937 Bump version to 1.15.1 2021-12-06 11:17:37 -08:00
Benjamin Doherty bb460d78d8 Merge branch 'rc/1.15.0' into release 2021-12-06 11:14:00 -08:00
Benjamin Doherty 838835a715 Update RELEASE_NOTES for 1.15.0 2021-12-02 11:52:04 -08:00
Romain Guy 63acd53e23 Use __ANDROID__ instead of ANDROID 2021-11-30 11:15:49 -08:00
Romain Guy fcd2d0457b Workaround for a build system issue 2021-11-30 11:15:42 -08:00
Benjamin Doherty 58fc26461b Bump version to 1.15.0 2021-11-29 14:08:28 -08:00
Benjamin Doherty fd82f6b04e Merge branch 'rc/1.14.2' into release 2021-11-29 14:07:03 -08:00
Benjamin Doherty cef3200533 Add additional RELEASE_NOTES for 1.14.2 2021-11-29 10:21:56 -08:00
Ben Doherty 634500c398 Fix, avoid divide-by-zero inside makeBone (#4889) 2021-11-24 16:29:33 -08:00
Ben Doherty b3e294ac54 Fix Metal depth comparison initialization (#4886) 2021-11-23 12:09:43 -08:00
Benjamin Doherty 2bf7535ad0 Update RELEASE_NOTES for 1.14.2 2021-11-22 10:16:00 -08:00
Benjamin Doherty 3315f75de9 Bump version to 1.14.2 2021-11-22 10:12:44 -08:00
Benjamin Doherty bbe7dbfa92 Merge branch 'rc/1.14.1' into release 2021-11-22 10:11:06 -08:00
Benjamin Doherty 5697922a65 Update RELEASE_NOTES for 1.14.1 2021-11-17 12:04:26 -08:00
Ben Doherty 4da83df2b9 Fix material compilation error with device vertex domain (#4865)
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
```
2021-11-17 12:03:55 -08:00
Ben Doherty 8f156d6588 Android: re-enable VSM cascade fix (#4863) 2021-11-17 10:19:09 -08:00
Benjamin Doherty cec0871c11 Bump version to 1.14.1 2021-11-15 10:09:45 -08:00
Benjamin Doherty 41a809368b Merge branch 'rc/1.14.0' into release 2021-11-15 10:07:56 -08:00
Romain Guy ea53eb9290 Skip task incompatible with configuration caching (#4831) 2021-11-09 15:56:00 -08:00
Benjamin Doherty 05875057c9 Update RELEASE_NOTES for 1.14.0 2021-11-09 15:51:13 -08:00
Benjamin Doherty 44125926d1 Disable configuration-cache 2021-11-08 17:05:34 -08:00
Benjamin Doherty 60734349de Bump version to 1.14.0 2021-11-08 11:52:50 -08:00
Benjamin Doherty fbfd5ec0ec Merge branch 'rc/1.13.0' into release 2021-11-08 11:50:19 -08:00
Ben Doherty a74a95cc65 Call VirtualMachineEnv::JNI_OnLoad for non-Android Java builds (better fix) (#4779) 2021-11-04 13:28:17 -07:00
Benjamin Doherty bc0ea16ff0 Update RELEASE_NOTES for 1.13.0 2021-11-02 13:15:53 -07:00
Mathias Agopian b2dc8aa84c Fix typo that broke the directional shadowmap 2021-11-02 13:11:44 -07:00
Benjamin Doherty 9987e8b6ab Bump version to 1.13.0 2021-11-01 14:59:11 -07:00
Benjamin Doherty 0d9bdcc008 Merge branch 'rc/1.12.11' into release 2021-11-01 14:55:58 -07:00
Benjamin Doherty b5c634045e Update RELEASE_NOTES for 1.12.11 2021-10-28 16:13:50 -07:00
Ben Doherty 1f05531d53 Call VirtualMachineEnv::JNI_OnLoad for non-Android Java builds (better fix) (#4779) 2021-10-28 16:02:23 -07:00
Benjamin Doherty 88f382f0e3 Revert "refactor colorgrading materials"
This reverts commit fb86a77cf8.
2021-10-28 15:56:50 -07:00
Benjamin Doherty 3e59925900 Remove problematic configuration-cache setting for release build 2021-10-28 15:56:26 -07:00
Benjamin Doherty ea404f8d4f Remove problematic configuration-cache setting for release build 2021-10-26 10:09:51 -07:00
Benjamin Doherty 602a550d93 Bump version to 1.12.11 2021-10-25 12:30:37 -07:00
Benjamin Doherty 12abbe2d23 Merge branch 'rc/1.12.10' into release 2021-10-25 11:06:18 -07:00
Benjamin Doherty fb0ee97588 Update RELEASE_NOTES for 1.12.10 2021-10-25 11:00:06 -07:00
Ben Doherty 56ef48c9c3 Fix, call VirtualMachineEnv::JNI_OnLoad for non-Android Java builds (#4749) 2021-10-25 10:39:24 -07:00
Benjamin Doherty 47c3dd3dd1 Revert "refactor colorgrading materials"
This reverts commit fb86a77cf8.
2021-10-25 10:37:52 -07:00
Benjamin Doherty c181648bfa Bump version to 1.12.10 2021-10-20 12:15:51 -07:00
Benjamin Doherty 0cf78b3abe Merge branch 'rc/1.12.9' into release 2021-10-20 12:12:33 -07:00
Ben Doherty 22889a7ad9 Fix VirtualMachineEnv.cpp with older JNI versions (#4752) 2021-10-20 11:16:55 -07:00
Ben Doherty a14451d0ac Fix, call VirtualMachineEnv::JNI_OnLoad for non-Android Java builds (#4749) 2021-10-20 10:41:34 -07:00
Benjamin Doherty 5dfdab10b7 Revert "refactor colorgrading materials"
This reverts commit fb86a77cf8.
2021-10-19 16:13:21 -07:00
Benjamin Doherty d6f2e3b8e9 Update RELEASE_NOTES for 1.12.9 2021-10-14 18:22:20 -07:00
Benjamin Doherty df30517743 Bump version to 1.12.9 2021-10-11 11:06:43 -07:00
Benjamin Doherty 8f80643c1a Merge branch 'rc/1.12.8' into release 2021-10-11 11:02:56 -07:00
Benjamin Doherty 5aea9be2fb Update RELEASE_NOTES for 1.12.8 2021-10-07 11:03:45 -07:00
Benjamin Doherty ad02e483d0 Bump version to 1.12.8 2021-10-04 10:26:57 -07:00
Benjamin Doherty f463d53036 Merge branch 'rc/1.12.7' into release 2021-10-04 10:21:42 -07:00
Benjamin Doherty b8d4408524 Update RELEASE_NOTES for 1.12.7 2021-10-04 10:18:56 -07:00
Benjamin Doherty fef70be848 Bump version to 1.12.7 2021-09-27 11:15:58 -07:00
Benjamin Doherty bdb12d9b24 Merge branch 'rc/1.12.6' into release 2021-09-27 11:12:42 -07:00
Ben Doherty 43ad283a83 Fix, missing call to setTransparencyMode (#4674) 2021-09-24 13:32:49 -07:00
Benjamin Doherty 2e4936afc4 Revert "fix a race in jobsystem"
This reverts commit 2feb0ad325.
2021-09-24 11:24:44 -07:00
Benjamin Doherty 891ffabd11 Update RELEASE_NOTES for 1.12.6 2021-09-23 17:25:25 -07:00
Ben Doherty e2c19498b4 Metal: don't call createTextureViewWithsSwizzle directly (#4662) 2021-09-23 11:28:04 -07:00
Ben Doherty c32630b265 Fix MetalBlitter crash when shader contains warnings (#4663) 2021-09-23 11:27:56 -07:00
Alexey Pelykh bf21e78d02 Podspec: include headers in nested directories (#4658) 2021-09-22 16:48:12 -07:00
Benjamin Doherty 525d4e08a3 Bump version to 1.12.6 2021-09-20 10:17:18 -07:00
Benjamin Doherty 2e9bf6d694 Merge branch 'rc/1.12.5' into release 2021-09-20 10:14:37 -07:00
Benjamin Doherty e845f01d85 Update RELEASE_NOTES for 1.12.5 2021-09-20 10:10:56 -07:00
Benjamin Doherty bef48be7b4 Bump version to 1.12.5 2021-09-13 10:47:09 -07:00
Benjamin Doherty b54fdc9e6e Merge branch 'rc/1.12.4' into release 2021-09-13 10:43:06 -07:00
Benjamin Doherty cedbf2e30b Update RELEASE_NOTES for 1.12.4 2021-09-13 10:40:55 -07:00
Benjamin Doherty 592f8d1b0d Bump version to 1.12.4 2021-09-08 11:05:44 -07:00
Benjamin Doherty 29612a684e Merge branch 'rc/1.12.3' into release 2021-09-08 11:03:53 -07:00
Benjamin Doherty e6d5807399 Bump version to 1.12.3 2021-08-30 11:46:51 -07:00
Benjamin Doherty fa2553251f Merge branch 'rc/1.12.2' into release 2021-08-30 11:44:00 -07:00
Benjamin Doherty 7387718852 Update RELEASE_NOTES for 1.12.2 2021-08-30 11:41:52 -07:00
Ben Doherty a503a6209a Fix regression with clipSpaceTransform (#4552) 2021-08-26 14:14:58 -07:00
Ben Doherty ce3e5f74e8 Fix Metal STREAM buffers (#4543) 2021-08-25 09:48:34 -07:00
Ben Doherty f37112358e Fix missing bookkeeping in bindUniformBufferRange (#4538) 2021-08-24 09:51:40 -07:00
Benjamin Doherty f368b14621 Bump version to 1.12.2 2021-08-23 12:41:33 -07:00
Benjamin Doherty 6960b1148a Merge branch 'rc/1.12.1' into release 2021-08-23 12:39:38 -07:00
Benjamin Doherty 3cc23aac25 Update RELEASE_NOTES for 1.12.1 2021-08-23 10:45:59 -07:00
Benjamin Doherty 11dc8740f2 Fix stack-use-after-scope error 2021-08-20 15:40:06 -07:00
Ben Doherty 4b797cff88 Windows: fix incorrect CRT flags with Visual Studio generators (#4516) 2021-08-20 10:56:41 -07:00
Ben Doherty fe1c1736cd Fix, potential null dereferences in MetalBlitter (#4481) 2021-08-10 16:30:11 -07:00
Benjamin Doherty 4058ef5f09 Bump version to 1.12.1 2021-08-09 12:06:47 -07:00
Benjamin Doherty d25ca01624 Merge branch 'rc/1.12.0' into release 2021-08-09 12:03:33 -07:00
Benjamin Doherty d96f87dbbf Update RELEASE_NOTES for 1.12.0 2021-08-09 12:01:46 -07:00
Ben Doherty 8a2e31023f Attempt to fix TSAN failure in ColorGrading.cpp (#4447) 2021-08-05 11:54:07 -07:00
Benjamin Doherty 1ea8e171d9 Bump version to 1.12.0 2021-08-03 11:18:56 -07:00
Benjamin Doherty e2be3dd0ac Merge branch 'rc/1.11.2' into release 2021-08-03 11:15:19 -07:00
Romain Guy 1c51164e7b Fix inverse tone mapping issues (#4437)
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.
2021-08-02 20:54:44 -07:00
Benjamin Doherty f190f03530 Update RELEASE_NOTES for 1.11.2 2021-08-02 11:17:42 -07:00
Ben Doherty 055fc7cbc1 Attempt to fix Windows CI by turning off concurrent builds (#4395) 2021-07-30 14:09:07 -07:00
Ben Doherty 9073fc3dc3 Attempt to fix Windows CI by turning off concurrent builds (#4395) 2021-07-28 10:49:37 -07:00
Ben Doherty 2409dc9bc4 Expose Engine::flush (#4385) 2021-07-26 15:09:14 -07:00
Benjamin Doherty 6586c8d70b Bump version to 1.11.2 2021-07-26 12:50:29 -07:00
Benjamin Doherty ac0c94da69 Merge branch 'rc/1.11.1' into release 2021-07-26 12:48:36 -07:00
Ben Doherty d19d6a72b0 Expose Engine::flush (#4385) 2021-07-26 12:10:19 -07:00
Benjamin Doherty c81b5d98ef Update RELEASE_NOTES for 1.11.1 2021-07-26 10:05:41 -07:00
Mathias Agopian 756866675f fix an issue where a sampler could fail to be updated
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.
2021-07-21 14:46:44 -07:00
Benjamin Doherty ebcd4925f7 Bump version to 1.11.1 2021-07-19 10:24:01 -07:00
Benjamin Doherty 13bed4fdf9 Merge branch 'rc/1.11.0' into release 2021-07-19 10:20:29 -07:00
Benjamin Doherty 1dae5c6b6c Update RELEASE_NOTES for 1.11.0 2021-07-19 10:18:07 -07:00
Benjamin Doherty 8e6663e4b0 Bump version to 1.11.0 2021-07-12 10:49:43 -07:00
Benjamin Doherty ba804444b8 Merge branch 'rc/1.10.7' into release 2021-07-12 10:47:12 -07:00
Benjamin Doherty 58cfb85004 Update RELEASE_NOTES for 1.10.7 2021-07-12 10:45:24 -07:00
Mathias Agopian ab46481b45 Fix colorgrading as subpass
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.
2021-07-12 10:35:01 -07:00
Mathias Agopian 4296782399 don't crash when refraction pass is empty 2021-07-12 09:53:37 -07:00
Benjamin Doherty ef375a7103 Bump version to 1.10.7 2021-07-07 11:02:30 -07:00
Benjamin Doherty fd258b7765 Merge branch 'rc/1.10.6' into release 2021-07-07 10:59:12 -07:00
Benjamin Doherty 147de8d372 Update RELEASE_NOTES for 1.10.6 2021-07-07 10:57:25 -07:00
Philip Rideout eb2a1928b6 ShadowMapManager: fix MSAN use-of-uninitialized-value.
The operator!= in std::array compares SPLIT_COUNT elements, which
is potentially greater than cascadeCount, which was the number of
initialized elements in splitPercentages.
2021-07-07 10:51:18 -07:00
Benjamin Doherty 35b033102f Bump version to 1.10.6 2021-06-28 12:07:58 -07:00
Benjamin Doherty 7bc65421a9 Merge branch 'rc/1.10.5' into release 2021-06-28 12:04:31 -07:00
Benjamin Doherty 736514cf37 Update RELEASE_NOTES for 1.10.5 2021-06-28 12:04:27 -07:00
Mathias Agopian db0158dae8 fix webgl build
we need to select opengl on webgl.
2021-06-28 08:27:46 -07:00
Benjamin Doherty e706695ed1 Bump version to 1.10.5 2021-06-21 11:18:26 -07:00
Benjamin Doherty e8877ffe2d Merge branch 'rc/1.10.4' into release 2021-06-21 11:16:10 -07:00
Benjamin Doherty 1fd5d9dae6 Update RELEASE_NOTES for 1.10.4 2021-06-21 11:14:35 -07:00
Ben Doherty cd48089318 filament-utils-android: fix string literal conversions (#4137) 2021-06-15 16:19:32 -06:00
Benjamin Doherty 6379ab22c9 Bump version to 1.10.4 2021-06-14 11:06:42 -06:00
Benjamin Doherty 0bf02b75d5 Merge branch 'rc/1.10.3' into release 2021-06-14 11:04:25 -06:00
Benjamin Doherty c4259b5598 Update RELEASE_NOTES for 1.10.3 2021-06-14 11:02:45 -06:00
Ben Doherty 6b3c1179bc Include sample-gltf-viewer with Android releases (#4099) 2021-06-08 10:41:48 -07:00
Philip Rideout c1a0e61e8e Fix FixedCapacityVector destructor.
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.
2021-06-07 15:56:33 -07:00
Benjamin Doherty fc06298ed4 Bump version to 1.10.3 2021-06-07 11:22:04 -07:00
Benjamin Doherty 4ca87b188c Merge branch 'rc/1.10.2' into release 2021-06-07 11:19:51 -07:00
Benjamin Doherty f1f60c3e0d Turn off warnings as errors for spirv-tools 2021-06-07 11:18:56 -07:00
Benjamin Doherty 76d21b56af Update RELEASE_NOTES for 1.10.2 2021-06-07 11:18:09 -07:00
Benjamin Doherty 0ab0e50a4f Turn off warnings as errors for spirv-tools 2021-06-02 11:16:42 -07:00
Benjamin Doherty 34f4c06a5c Bump version to 1.10.2 2021-06-01 11:17:32 -07:00
Benjamin Doherty 6de36f1e53 Merge branch 'rc/1.10.1' into release 2021-06-01 11:15:49 -07:00
Benjamin Doherty 2a9a3b1ac2 Update RELEASE_NOTES for 1.10.1 2021-06-01 11:13:04 -07:00
Benjamin Doherty 84b73a3770 Bump version to 1.10.1 2021-05-24 10:52:02 -07:00
Benjamin Doherty 662a10e273 Merge branch 'rc/1.10.0' into release 2021-05-24 10:49:10 -07:00
Benjamin Doherty ecce02502e Update RELEASE_NOTES for 1.10.0 2021-05-24 10:47:39 -07:00
Philip Rideout d17875aea1 ImGuiHelper: fix support for custom images.
The texture binding in the material instance needs to be restored to the
glyph atlas when a custom image is not in use.
2021-05-21 12:49:37 -07:00
Philip Rideout b8897a68f9 matc: detect missing end brace.
matc was failing to report certain kinds of syntax errors and would
read out-of-bounds memory.

This change casuses the flare material to fail.
2021-05-21 09:20:33 -07:00
Ben Doherty 84efd4871e API CHANGE: remove some Camera, Engine, and View deprecated APIs (#3965) 2021-05-19 12:02:13 -07:00
Benjamin Doherty 85ea5a6b70 Bump version to 1.10.0 2021-05-17 11:00:42 -07:00
Benjamin Doherty 77891acb92 Merge branch 'rc/1.9.25' into release 2021-05-17 10:57:30 -07:00
Benjamin Doherty 74fe102035 Update RELEASE_NOTES for 1.9.25 2021-05-17 10:54:38 -07:00
Philip Rideout 25cc554925 WASM: fix "Missing field" error for lensFlare. 2021-05-17 10:06:56 -07:00
Ben Doherty d787a521b5 Fix DIST_DIR setting for Windows builds (#3945) 2021-05-12 11:16:30 -07:00
Ben Doherty 46e52c71e1 Fix DIST_DIR setting for Windows builds (#3945) 2021-05-12 11:15:49 -07:00
Philip Rideout 1dad27a172 Repair WebGL and fix potential INVALID_OPERATION.
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.
2021-05-10 13:38:56 -07:00
Benjamin Doherty 60d230b380 Bump version to 1.9.25 2021-05-07 21:42:48 -07:00
Benjamin Doherty d7cb38e706 Merge branch 'rc/1.9.24' into release 2021-05-07 21:39:17 -07:00
Benjamin Doherty ce00cca6ee Update RELEASE_NOTES for 1.9.24 2021-05-07 21:36:49 -07:00
Philip Rideout d627d57bad Second memory leak fix. (#3906)
Fixes #3888.
2021-05-06 14:25:46 -07:00
Philip Rideout 8ffc776f1c Fix horrible memory leak in the GL driver. (#3894)
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);
        }
2021-05-04 18:22:08 -07:00
Benjamin Doherty be032b52c1 Bump version to 1.9.24 2021-05-03 10:42:19 -07:00
Benjamin Doherty 4388e81e5f Merge branch 'rc/1.9.23' into release 2021-05-03 10:40:49 -07:00
Benjamin Doherty 71a185d139 Update RELEASE_NOTES for 1.9.23 2021-05-03 10:38:59 -07:00
Benjamin Doherty d2cf5985ac Bump version to 1.9.23 2021-04-26 10:55:10 -07:00
Benjamin Doherty debcbb8e5c Merge branch 'rc/1.9.22' into release 2021-04-26 10:52:43 -07:00
Benjamin Doherty b9dd62c7d3 Update RELEASE_NOTES for 1.9.22 2021-04-26 10:47:11 -07:00
Benjamin Doherty dc2b430f34 Bump version to 1.9.22 2021-04-26 10:39:16 -07:00
Benjamin Doherty e5ef4e8868 Update RELEASE_NOTES for 1.9.21 2021-04-19 11:36:37 -07:00
Benjamin Doherty c0d6cd3ac3 Merge branch 'rc/1.9.21' into release 2021-04-19 11:34:23 -07:00
Benjamin Doherty b63ab2dc19 Update RELEASE_NOTES for 1.9.21 2021-04-19 11:32:31 -07:00
Benjamin Doherty 5d8dad561c Bump version to 1.9.21 2021-04-12 11:38:27 -07:00
Benjamin Doherty 8933be1ae2 Merge branch 'rc/1.9.20' into release 2021-04-12 11:36:17 -07:00
Benjamin Doherty 6b66b48b1d Update RELEASE_NOTES for 1.9.20 2021-04-12 11:35:45 -07:00
Benjamin Doherty 9c23eb6e33 Release Filament 1.9.20 2021-04-12 11:34:39 -07:00
Benjamin Doherty baea54a3fc Update RELEASE_NOTES for 1.9.20 2021-04-12 09:20:31 -07:00
Benjamin Doherty d9f800454c Bump version to 1.9.20 2021-04-05 11:14:17 -07:00
Benjamin Doherty f9ee0de07a Merge branch 'rc/1.9.19' into release 2021-04-05 11:11:13 -07:00
Benjamin Doherty 2786d0a9f7 Update RELEASE_NOTES for 1.9.19 2021-04-05 11:10:50 -07:00
Benjamin Doherty 491e8032e6 Release Filament 1.9.19 2021-04-05 11:10:20 -07:00
Benjamin Doherty ef3f13f5d3 Update RELEASE_NOTES for 1.9.19 2021-04-05 11:09:38 -07:00
Benjamin Doherty bcb5b2d790 Implement Metal BufferObjects 2021-04-05 11:01:36 -07:00
Ben Doherty 02de3f2e2a Fix, regression with Metal buffers (#3715) 2021-03-29 14:21:34 -07:00
Benjamin Doherty 0e7bb53c07 Bump version to 1.9.19 2021-03-29 11:09:32 -07:00
Benjamin Doherty 759109d478 Merge branch 'rc/1.9.18' into release 2021-03-29 11:06:55 -07:00
Benjamin Doherty 54d5af6edf Update RELEASE_NOTES for 1.9.18 2021-03-29 11:04:57 -07:00
Philip Rideout 38fbe47ced RenderTarget: fix NPE when depth is not present.
This fixes a recent regression that would occur when a RenderTarget
does not have a depth attachment.
2021-03-29 10:32:22 -07:00
Benjamin Doherty f066c925ba Bump version to 1.9.18 2021-03-22 10:16:34 -07:00
Benjamin Doherty 994fdf4e1d Merge branch 'rc/1.9.17' into release 2021-03-22 10:12:20 -07:00
Benjamin Doherty 50b50d65e3 Update RELEASE_NOTES for 1.9.17 2021-03-22 10:11:02 -07:00
Mathias Agopian 0aaa985649 Fix a hang in JobSystem
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)
2021-03-18 09:57:25 -07:00
Benjamin Doherty 29564f8eae Bump version to 1.9.17 2021-03-15 10:15:25 -07:00
Benjamin Doherty c15db68a5b Merge branch 'rc/1.9.16' into release 2021-03-15 10:12:56 -07:00
Benjamin Doherty 3452fb3e56 Update RELEASE_NOTES for 1.9.16 2021-03-15 10:10:40 -07:00
Mathias Agopian 35eb8e7be1 Revert GL backend handle tracking
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.
2021-03-12 13:02:55 -08:00
Mathias Agopian 834b774128 Fixes some issues with imported rendertargets
We were not declaring the attachments it was using.

Fixes #3628
2021-03-12 08:26:16 -08:00
Benjamin Doherty 5aa0eb9f9d Bump version to 1.9.16 2021-03-08 10:09:14 -08:00
Benjamin Doherty d9a6e2e649 Merge branch 'rc/1.9.15' into release 2021-03-08 10:07:00 -08:00
Benjamin Doherty cb823b16a1 Update RELEASE_NOTES for 1.9.15 2021-03-08 10:05:19 -08:00
Ben Doherty 0bd41e877e Downgrade Linux GitHub Actions environment to fix error (#3588) 2021-03-01 11:21:11 -08:00
Benjamin Doherty ecc3e73967 Bump version to 1.9.15 2021-03-01 11:13:44 -08:00
Benjamin Doherty 464b4c24f9 Merge branch 'rc/1.9.14' into release 2021-03-01 11:11:53 -08:00
Benjamin Doherty 32367516e8 Update RELEASE_NOTES for 1.9.14 2021-03-01 11:10:06 -08:00
Philip Rideout 1709a55606 filamat: Fix data race with SPIRV error registrations. 2021-02-26 10:34:36 -08:00
Benjamin Doherty 58b4455979 Bump version to 1.9.14 2021-02-22 10:32:56 -08:00
Benjamin Doherty ea1dede19c Merge branch 'rc/1.9.13' into release 2021-02-22 10:29:57 -08:00
Benjamin Doherty 20ea3381fa Update RELEASE_NOTES for 1.9.13 2021-02-22 10:28:21 -08:00
Philip Rideout 7aa6fccd7c Modernize Python print syntax to appease external codebase. 2021-02-19 11:38:18 -08:00
Philip Rideout adbd54f4f8 Change abs() to std::abs to appease external codebase. 2021-02-19 11:38:18 -08:00
Philip Rideout 9d54261f18 Move vk_mem_alloc to its own cpp.
This will improve parity between the GitHub repo and its sister codebase
within Google.
2021-02-19 11:38:18 -08:00
Philip Rideout a97757c9ae Avoid uninitialized reads in computeVisibilityMasks.
I verified that this code is not enabled in our GitHub builds, and I
verified that the MSAN error goes away.
2021-02-19 11:38:18 -08:00
Philip Rideout 7c79d9f89d Remove some Windows line endings.
These line endings cause annoying diffs when comparing Filament's GitHub
source with its twin sister within Google.
2021-02-19 11:38:18 -08:00
Benjamin Doherty bf0914f813 Bump version to 1.9.13 2021-02-16 10:48:24 -08:00
Benjamin Doherty b96bc30fbd Merge branch 'rc/1.9.12' into release 2021-02-16 10:44:13 -08:00
Benjamin Doherty 62b50eb8ba Update RELEASE_NOTES for 1.9.12 2021-02-16 10:42:41 -08:00
Ben Doherty b4932e384a matc: Use consistent params for semantic code analysis (#3524)
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.
2021-02-08 14:06:47 -08:00
Benjamin Doherty 5e68dc5f8d Bump version to 1.9.12 2021-02-08 09:58:15 -08:00
Benjamin Doherty f222f1b925 Merge branch 'rc/1.9.11' into release 2021-02-08 09:51:08 -08:00
Ben Doherty 22e4a54782 Update RELEASE_NOTES for 1.9.11 2021-02-08 09:50:23 -08:00
Benjamin Doherty 1289922c5f Release Filament 1.9.11 2021-02-08 09:48:50 -08:00
Ben Doherty 2839c352b8 Update RELEASE_NOTES for 1.9.11 2021-02-08 09:47:18 -08:00
Ben Doherty 6a01cbc312 Draft: fix TSAN issue by using lock in ColorGrading constructor (#3510)
This is a second attempt to fix Google3 TSAN failures seen inside of the ColorGrading constructor.

Related first attempt: #3462
2021-02-05 14:06:40 -08:00
Benjamin Doherty 6193156556 Bump version to 1.9.11 2021-02-01 11:49:12 -08:00
Benjamin Doherty fe23aa917d Merge branch 'rc/1.9.10' into release 2021-02-01 11:45:47 -08:00
Benjamin Doherty eb8a29a332 Update RELEASE_NOTES for 1.9.10 2021-02-01 11:45:17 -08:00
Ben Doherty 0626902530 Fix sporatic data race warning seen in Google3 (#3462) 2021-01-27 16:40:16 -08:00
Philip Rideout 042bfe2597 Partial fix for MSVC build. 2020-12-14 12:15:06 -08:00
Ben Doherty 97133f3591 Fix Windows iterator issue in Zip2Iterator and StructureOfArrays (#3322) 2020-12-14 12:14:53 -08:00
Philip Rideout d06cc4390e filamat: minify struct fields.
This shrinks the arm64 so file by 24 KiB.
2020-12-14 11:19:43 -08:00
Philip Rideout 6047d3235f Remove VSM variant from Skybox material. 2020-12-14 11:19:31 -08:00
Philip Rideout 2cda6e35bd math: reduce template bloat for matrices
This does not change our API, it merely reduces the number of
non-inlined function instantiations appearing in non-optimized binaries.
2020-12-14 11:19:22 -08:00
Philip Rideout 8f8d51e17b Code review fixups for libibl_lite. 2020-12-14 11:19:16 -08:00
Philip Rideout 6919e3b274 libibl: use C callback for progress 2020-12-14 11:19:09 -08:00
Philip Rideout 10bf944410 Add libibl_lite. 2020-12-14 11:19:03 -08:00
Philip Rideout 9a2f6fdb53 Vulkan: change vkWaitForFences usage for SwiftShader.
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.
2020-11-20 09:37:54 -08:00
Philip Rideout 761977d385 Filament should always bind an IBL texture.
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.
2020-11-19 13:28:19 -08:00
Ben Doherty 21248f15b5 Fix, matc crash when building mobile materials (#3296) 2020-11-16 14:37:55 -08:00
Benjamin Doherty 4f32817f6d Bump version to 1.9.10 2020-11-16 12:37:49 -08:00
Benjamin Doherty cc9e05e711 Merge branch 'rc/1.9.9' into release 2020-11-16 12:34:13 -08:00
Benjamin Doherty 419d68d4db Update RELEASE_NOTES for 1.9.9 2020-11-16 12:17:02 -08:00
Philip Rideout 8450232448 Improve the "unbound texture" warnings.
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.
2020-11-12 16:21:13 -08:00
Philip Rideout cc51726590 Vulkan: improve robustness by providing 1x1 fallback. 2020-11-12 10:36:13 -08:00
Philip Rideout 318e22af51 Fix clear behavior with RenderTarget API.
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.
2020-11-11 09:25:36 -08:00
Philip Rideout 68ac87dc24 NOOP backend should not care about GLSL vs SPIRV.
This fixes errors that would occur when using the NOOP backend with
materials that were built without OpenGL support.
2020-11-10 15:44:01 -08:00
Benjamin Doherty acb8f00075 Bump version to 1.9.9 2020-11-09 09:32:55 -08:00
Benjamin Doherty 06d9183aaa Merge branch 'rc/1.9.8' into release 2020-11-09 09:28:58 -08:00
Benjamin Doherty 75af25419d Update RELEASE_NOTES for 1.9.8 2020-11-09 09:26:27 -08:00
Benjamin Doherty f6b90d2a31 Bump version to 1.9.8 2020-11-09 09:21:36 -08:00
Philip Rideout a3822f4af0 Fix FENCE_WAIT_FOR_EVER in Linux.
The number of infinite nanoseconds was negative because we asked
chrono for a signed integer, so "wait forever" really meant "do not
wait at all".
2020-11-02 16:12:53 -08:00
Benjamin Doherty bcdad769ff Merge branch 'rc/1.9.7' into release 2020-11-02 11:03:57 -07:00
Benjamin Doherty be4fb4fdbb Update RELEASE_NOTES for 1.9.7 2020-11-02 10:59:19 -07:00
Benjamin Doherty 65394f6301 Bump version to 1.9.7 2020-10-26 11:34:20 -06:00
Benjamin Doherty b0beee03bc Merge branch 'rc/1.9.6' into release 2020-10-26 11:29:45 -06:00
Benjamin Doherty fe1de41b8e Update RELEASE_NOTES for 1.9.6 2020-10-26 11:25:31 -06:00
Benjamin Doherty a37b431e87 Bump version to 1.9.6 2020-10-19 11:55:13 -06:00
Benjamin Doherty 98107016b9 Merge branch 'rc/1.9.5' into release 2020-10-19 11:51:30 -06:00
Benjamin Doherty 8bccfc2863 Update RELEASE_NOTES for 1.9.5 2020-10-19 11:49:05 -06:00
Benjamin Doherty f54a0a3452 Fix CocoaPod version 2020-10-13 15:15:02 -06:00
Benjamin Doherty 6778ab0624 Fix CocoaPod version 2020-10-13 15:09:59 -06:00
Benjamin Doherty 269d636785 Bump version to 1.9.5 2020-10-12 12:03:29 -06:00
Benjamin Doherty 39862c91ce Merge branch 'rc/1.9.4' into release 2020-10-12 11:56:24 -06:00
Benjamin Doherty 523f4026b4 Update RELEASE_NOTES for 1.9.4 2020-10-12 11:52:01 -06:00
Benjamin Doherty a6bf162431 Bump version to 1.9.4 2020-10-07 16:06:23 -06:00
Benjamin Doherty 826e8d181c Merge branch 'rc/1.9.3' into release 2020-10-05 11:36:16 -06:00
Benjamin Doherty 16dfadbba0 Update RELEASE_NOTES for 1.9.3 2020-10-05 11:29:36 -06:00
Benjamin Doherty 5cbb97551f Bump version to 1.9.3 2020-09-28 11:40:31 -06:00
Benjamin Doherty defee767c3 Merge branch 'rc/1.9.2' into release 2020-09-28 11:27:47 -06:00
Benjamin Doherty 9560318521 Update RELEASE_NOTES for 1.9.2 2020-09-28 11:26:21 -06:00
Benjamin Doherty ef09feb048 Bump version to 1.9.2 2020-09-21 11:16:53 -06:00
Benjamin Doherty 39f323fe09 Merge branch 'rc/1.9.1' into release 2020-09-21 11:00:07 -06:00
Benjamin Doherty 11b95304ea Merge branch 'release' into rc/1.9.1 2020-09-21 10:59:52 -06:00
Benjamin Doherty b7c30a7916 Update RELEASE_NOTES for 1.9.1 2020-09-21 10:59:06 -06:00
Benjamin Doherty 4cae48fc77 Bump version to 1.9.1 2020-09-14 11:51:36 -07:00
Benjamin Doherty d1a93f0557 Update release notes for 1.9.0 2020-09-14 10:54:28 -07:00
Benjamin Doherty b93059fad7 Bump version to 1.9.0 2020-09-08 10:47:23 -07:00
391 changed files with 13262 additions and 4966 deletions
+1 -1
View File
@@ -10,7 +10,7 @@ on:
jobs:
build-android:
name: build-android
runs-on: macos-latest
runs-on: macos-14
steps:
- uses: actions/checkout@v3.3.0
+1 -1
View File
@@ -13,7 +13,7 @@ on:
jobs:
cocoapods-deploy:
name: cocoapods-deploy
runs-on: macos-latest
runs-on: macos-14
steps:
- name: Check out iOS/CocoaPods directory
uses: Bhacaz/checkout-files@49fc3050859046bf4f4873678d46099985640e89
+1 -1
View File
@@ -10,7 +10,7 @@ on:
jobs:
build-ios:
name: build-ios
runs-on: macos-latest
runs-on: macos-14
steps:
- uses: actions/checkout@v3.3.0
+1 -1
View File
@@ -10,7 +10,7 @@ on:
jobs:
build-mac:
name: build-mac
runs-on: macos-latest
runs-on: macos-14
steps:
- uses: actions/checkout@v3.3.0
+1 -1
View File
@@ -11,7 +11,7 @@ on:
jobs:
npm-deploy:
name: npm-deploy
runs-on: macos-latest
runs-on: macos-14
steps:
- uses: actions/checkout@v3.3.0
with:
+4 -4
View File
@@ -15,7 +15,7 @@ jobs:
strategy:
matrix:
os: [macos-latest, ubuntu-22.04]
os: [macos-14, ubuntu-22.04]
steps:
- uses: actions/checkout@v3.3.0
@@ -40,7 +40,7 @@ jobs:
build-android:
name: build-android
runs-on: macos-latest
runs-on: macos-14
steps:
- uses: actions/checkout@v3.3.0
@@ -54,7 +54,7 @@ jobs:
build-ios:
name: build-iOS
runs-on: macos-latest
runs-on: macos-14
steps:
- uses: actions/checkout@v3.3.0
@@ -67,7 +67,7 @@ jobs:
build-web:
name: build-web
runs-on: macos-latest
runs-on: macos-14
steps:
- uses: actions/checkout@v3.3.0
+6 -6
View File
@@ -31,7 +31,7 @@ jobs:
strategy:
matrix:
os: [macos-latest, ubuntu-22.04]
os: [macos-14, ubuntu-22.04]
steps:
- name: Decide Git ref
@@ -65,7 +65,7 @@ jobs:
build-web:
name: build-web
runs-on: macos-latest
runs-on: macos-14
if: github.event_name == 'release' || github.event.inputs.platform == 'web'
steps:
@@ -98,7 +98,7 @@ jobs:
build-android:
name: build-android
runs-on: macos-latest
runs-on: macos-14
if: github.event_name == 'release' || github.event.inputs.platform == 'android'
steps:
@@ -129,7 +129,7 @@ jobs:
- name: Sign sample-gltf-viewer
run: |
echo "${APK_KEYSTORE_BASE64}" > filament.jks.base64
base64 --decode filament.jks.base64 > filament.jks
base64 --decode -i filament.jks.base64 > filament.jks
BUILD_TOOLS_VERSION=$(ls ${ANDROID_HOME}/build-tools | sort -V | tail -n 1)
APKSIGNER=${ANDROID_HOME}/build-tools/${BUILD_TOOLS_VERSION}/apksigner
IN_FILE="out/sample-gltf-viewer-release.apk"
@@ -152,7 +152,7 @@ jobs:
build-ios:
name: build-ios
runs-on: macos-latest
runs-on: macos-14
if: github.event_name == 'release' || github.event.inputs.platform == 'ios'
steps:
@@ -205,7 +205,7 @@ jobs:
TAG: ${{ steps.git_ref.outputs.tag }}
run: |
build\windows\build-github.bat release
move out\filament-windows.tgz out\filament-$Env:TAG-windows.tgz
move out\filament-windows.tgz out\filament-%TAG%-windows.tgz
shell: cmd
- uses: actions/github-script@v6
env:
+1 -1
View File
@@ -10,7 +10,7 @@ on:
jobs:
build-web:
name: build-web
runs-on: macos-latest
runs-on: macos-14
steps:
- uses: actions/checkout@v3.3.0
+23 -4
View File
@@ -45,6 +45,8 @@ option(FILAMENT_ENABLE_TSAN "Enable Thread Sanitizer" OFF)
option(FILAMENT_ENABLE_FEATURE_LEVEL_0 "Enable Feature Level 0" ON)
option(FILAMENT_ENABLE_MULTIVIEW "Enable multiview for Filament" OFF)
set(FILAMENT_NDK_VERSION "" CACHE STRING
"Android NDK version or version prefix to be used when building for Android."
)
@@ -531,6 +533,21 @@ else()
option(FILAMENT_DISABLE_MATOPT "Disable material optimizations" ON)
endif()
# This only affects the prebuilt shader files in gltfio and samples, not filament library.
# The value can be either "instanced" or "multiview".
set(FILAMENT_SAMPLES_STEREO_TYPE "instanced" CACHE STRING
"Stereoscopic type that shader files in gltfio and samples are built for."
)
string(TOLOWER "${FILAMENT_SAMPLES_STEREO_TYPE}" FILAMENT_SAMPLES_STEREO_TYPE)
if (NOT FILAMENT_SAMPLES_STEREO_TYPE STREQUAL "instanced" AND NOT FILAMENT_SAMPLES_STEREO_TYPE STREQUAL "multiview")
message(FATAL_ERROR "Invalid stereo type: \"${FILAMENT_SAMPLES_STEREO_TYPE}\" choose either \"instanced\" or \"multiview\" ")
endif ()
# Compiling samples for multiview implies enabling multiview feature as well.
if (FILAMENT_SAMPLES_STEREO_TYPE STREQUAL "multiview")
set(FILAMENT_ENABLE_MULTIVIEW ON)
endif ()
# ==================================================================================================
# Material compilation flags
# ==================================================================================================
@@ -634,9 +651,9 @@ function(combine_static_libs TARGET OUTPUT DEPS)
# Loop through the dependent libraries and query their location on disk.
set(DEPS_FILES )
foreach(DEPENDENCY ${DEPS})
if(TARGET ${DEPENDENCY})
if (TARGET ${DEPENDENCY})
get_property(dep_type TARGET ${DEPENDENCY} PROPERTY TYPE)
if(dep_type STREQUAL "STATIC_LIBRARY")
if (dep_type STREQUAL "STATIC_LIBRARY")
list(APPEND DEPS_FILES "$<TARGET_FILE:${DEPENDENCY}>")
endif()
endif()
@@ -706,7 +723,7 @@ function(get_resgen_vars ARCHIVE_DIR ARCHIVE_NAME)
set(RESGEN_OUTPUTS "${OUTPUTS}" PARENT_SCOPE)
set(RESGEN_FLAGS -qx ${ARCHIVE_DIR} -p ${ARCHIVE_NAME} PARENT_SCOPE)
set(RESGEN_SOURCE "${ARCHIVE_DIR}/${ARCHIVE_NAME}${ASM_SUFFIX}.S" PARENT_SCOPE)
set(RESGEN_SOURCE_FLAGS "-I${ARCHIVE_DIR} ${ASM_ARCH_FLAG}" PARENT_SCOPE)
set(RESGEN_SOURCE_FLAGS "-I'${ARCHIVE_DIR}' ${ASM_ARCH_FLAG}" PARENT_SCOPE)
endif()
endfunction()
@@ -721,7 +738,6 @@ add_subdirectory(${LIBRARIES}/filabridge)
add_subdirectory(${LIBRARIES}/filaflat)
add_subdirectory(${LIBRARIES}/filagui)
add_subdirectory(${LIBRARIES}/filameshio)
add_subdirectory(${LIBRARIES}/geometry)
add_subdirectory(${LIBRARIES}/gltfio)
add_subdirectory(${LIBRARIES}/ibl)
add_subdirectory(${LIBRARIES}/iblprefilter)
@@ -749,6 +765,9 @@ add_subdirectory(${EXTERNAL}/jsmn/tnt)
add_subdirectory(${EXTERNAL}/stb/tnt)
add_subdirectory(${EXTERNAL}/getopt)
# Note that this has to be placed after mikktspace in order for combine_static_libs to work.
add_subdirectory(${LIBRARIES}/geometry)
if (FILAMENT_BUILD_FILAMAT OR IS_HOST_PLATFORM)
# spirv-tools must come before filamat, as filamat relies on the presence of the
# spirv-tools_SOURCE_DIR variable.
-2
View File
@@ -7,5 +7,3 @@ for next branch cut* header.
appropriate header in [RELEASE_NOTES.md](./RELEASE_NOTES.md).
## Release notes for next branch cut
- Metal: fix some shader artifacts by disabling fast math optimizations.
+2 -2
View File
@@ -31,7 +31,7 @@ repositories {
}
dependencies {
implementation 'com.google.android.filament:filament-android:1.49.3'
implementation 'com.google.android.filament:filament-android:1.51.4'
}
```
@@ -51,7 +51,7 @@ Here are all the libraries available in the group `com.google.android.filament`:
iOS projects can use CocoaPods to install the latest release:
```shell
pod 'Filament', '~> 1.49.3'
pod 'Filament', '~> 1.51.4'
```
### Snapshots
+45
View File
@@ -7,6 +7,51 @@ A new header is inserted each time a *tag* is created.
Instead, if you are authoring a PR for the main branch, add your release note to
[NEW_RELEASE_NOTES.md](./NEW_RELEASE_NOTES.md).
## v1.51.4
## v1.51.3
## v1.51.2
- engine: Add experimental APIs `Engine::builder::paused()` and `Engine::setPaused()`
## v1.51.1
## v1.51.0
- materials: add support for post-lighting mix factor (b/328498606) [⚠️ **New Material Version**]
## v1.50.6
- Add new API `SwapChain::getFrameScheduledCallback`
- vulkan: fixed validation error VUID-vkAcquireNextImageKHR-semaphore-01779
- opengl: Add support for protected content swapchains and contexts
## v1.50.5
- android: NDK 26.1.10909125 is used by default
- android: Minimum API level on Android is now API 21 instead of API 19. This allows the use of OpenGL ES 3.1
- rendering: New PBR Neutral tone mapper, designed to preserve materials color appearance
- android: Change default frameRateOptions.interval to 1.0
## v1.50.4
## v1.50.3
## v1.50.2
## v1.50.1
- Metal: fix some shader artifacts by disabling fast math optimizations.
- backend: remove `atan2` overload which had a typo and wasn't useful. Fixes b/320856413.
- utils: remove usages of `SpinLock`. Fixes b/321101014.
## v1.50.0
- engine: TAA now supports 4x upscaling [BETA] [⚠️ **New Material Version**]
+1 -1
View File
@@ -80,7 +80,7 @@ buildscript {
ext.versions = [
'jdk': 17,
'minSdk': 19,
'minSdk': 21,
'targetSdk': 34,
'compileSdk': 34,
'kotlin': '1.9.21',
@@ -391,6 +391,13 @@ Java_com_google_android_filament_Engine_nFlush(JNIEnv*, jclass,
engine->flush();
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_Engine_nSetPaused(JNIEnv*, jclass,
jlong nativeEngine, jboolean paused) {
Engine* engine = (Engine*) nativeEngine;
engine->setPaused(paused);
}
// Managers...
extern "C" JNIEXPORT jlong JNICALL
@@ -484,7 +491,11 @@ extern "C" JNIEXPORT void JNICALL Java_com_google_android_filament_Engine_nSetBu
extern "C" JNIEXPORT void JNICALL Java_com_google_android_filament_Engine_nSetBuilderConfig(JNIEnv*,
jclass, jlong nativeBuilder, jlong commandBufferSizeMB, jlong perRenderPassArenaSizeMB,
jlong driverHandleArenaSizeMB, jlong minCommandBufferSizeMB, jlong perFrameCommandsSizeMB,
jlong jobSystemThreadCount, jlong stereoscopicEyeCount) {
jlong jobSystemThreadCount,
jlong textureUseAfterFreePoolSize, jboolean disableParallelShaderCompile,
jint stereoscopicType, jlong stereoscopicEyeCount,
jlong resourceAllocatorCacheSizeMB, jlong resourceAllocatorCacheMaxAge,
jboolean disableHandleUseAfterFreeCheck) {
Engine::Builder* builder = (Engine::Builder*) nativeBuilder;
Engine::Config config = {
.commandBufferSizeMB = (uint32_t) commandBufferSizeMB,
@@ -493,7 +504,13 @@ extern "C" JNIEXPORT void JNICALL Java_com_google_android_filament_Engine_nSetBu
.minCommandBufferSizeMB = (uint32_t) minCommandBufferSizeMB,
.perFrameCommandsSizeMB = (uint32_t) perFrameCommandsSizeMB,
.jobSystemThreadCount = (uint32_t) jobSystemThreadCount,
.textureUseAfterFreePoolSize = (uint32_t) textureUseAfterFreePoolSize,
.disableParallelShaderCompile = (bool) disableParallelShaderCompile,
.stereoscopicType = (Engine::StereoscopicType) stereoscopicType,
.stereoscopicEyeCount = (uint8_t) stereoscopicEyeCount,
.resourceAllocatorCacheSizeMB = (uint32_t) resourceAllocatorCacheSizeMB,
.resourceAllocatorCacheMaxAge = (uint8_t) resourceAllocatorCacheMaxAge,
.disableHandleUseAfterFreeCheck = (bool) disableHandleUseAfterFreeCheck,
};
builder->config(&config);
}
@@ -510,6 +527,12 @@ extern "C" JNIEXPORT void JNICALL Java_com_google_android_filament_Engine_nSetBu
builder->sharedContext((void*) sharedContext);
}
extern "C" JNIEXPORT void JNICALL Java_com_google_android_filament_Engine_nSetBuilderPaused(
JNIEnv*, jclass, jlong nativeBuilder, jboolean paused) {
Engine::Builder* builder = (Engine::Builder*) nativeBuilder;
builder->paused((bool) paused);
}
extern "C" JNIEXPORT jlong JNICALL
Java_com_google_android_filament_Engine_nBuilderBuild(JNIEnv*, jclass, jlong nativeBuilder) {
Engine::Builder* builder = (Engine::Builder*) nativeBuilder;
@@ -104,6 +104,14 @@ Java_com_google_android_filament_RenderableManager_nBuilderGeometry__JIIJJIIII(J
(size_t) count);
}
extern "C"
JNIEXPORT void JNICALL
Java_com_google_android_filament_RenderableManager_nBuilderGeometryType(JNIEnv*, jclass,
jlong nativeBuilder, int type) {
RenderableManager::Builder *builder = (RenderableManager::Builder *) nativeBuilder;
builder->geometryType((RenderableManager::Builder::GeometryType)type);
}
extern "C"
JNIEXPORT void JNICALL
Java_com_google_android_filament_RenderableManager_nBuilderMaterial(JNIEnv*, jclass,
@@ -34,7 +34,15 @@ Java_com_google_android_filament_SwapChain_nSetFrameCompletedCallback(JNIEnv* en
}
extern "C" JNIEXPORT jboolean JNICALL
Java_com_google_android_filament_SwapChain_nIsSRGBSwapChainSupported(JNIEnv *, jclass, jlong nativeEngine) {
Java_com_google_android_filament_SwapChain_nIsSRGBSwapChainSupported(
JNIEnv *, jclass, jlong nativeEngine) {
Engine* engine = (Engine*) nativeEngine;
return (bool)SwapChain::isSRGBSwapChainSupported(*engine);
return (jboolean)SwapChain::isSRGBSwapChainSupported(*engine);
}
extern "C" JNIEXPORT jboolean JNICALL
Java_com_google_android_filament_SwapChain_nIsProtectedContentSupported(
JNIEnv *, jclass, jlong nativeEngine) {
Engine* engine = (Engine*) nativeEngine;
return (jboolean)SwapChain::isProtectedContentSupported(*engine);
}
@@ -47,6 +47,11 @@ Java_com_google_android_filament_ToneMapper_nCreateFilmicToneMapper(JNIEnv*, jcl
return (jlong) new FilmicToneMapper();
}
extern "C" JNIEXPORT jlong JNICALL
Java_com_google_android_filament_ToneMapper_nCreatePBRNeutralToneMapper(JNIEnv*, jclass) {
return (jlong) new PBRNeutralToneMapper();
}
extern "C" JNIEXPORT jlong JNICALL
Java_com_google_android_filament_ToneMapper_nCreateAgxToneMapper(JNIEnv*, jclass, jint look) {
return (jlong) new AgxToneMapper(AgxToneMapper::AgxLook(look));
@@ -158,6 +158,16 @@ public class Engine {
FEATURE_LEVEL_3,
};
/**
* The type of technique for stereoscopic rendering
*/
public enum StereoscopicType {
/** Stereoscopic rendering is performed using instanced rendering technique. */
INSTANCED,
/** Stereoscopic rendering is performed using the multiview feature from the graphics backend. */
MULTIVIEW,
};
/**
* Constructs <code>Engine</code> objects using a builder pattern.
*/
@@ -211,7 +221,11 @@ public class Engine {
nSetBuilderConfig(mNativeBuilder, config.commandBufferSizeMB,
config.perRenderPassArenaSizeMB, config.driverHandleArenaSizeMB,
config.minCommandBufferSizeMB, config.perFrameCommandsSizeMB,
config.jobSystemThreadCount, config.stereoscopicEyeCount);
config.jobSystemThreadCount,
config.textureUseAfterFreePoolSize, config.disableParallelShaderCompile,
config.stereoscopicType.ordinal(), config.stereoscopicEyeCount,
config.resourceAllocatorCacheSizeMB, config.resourceAllocatorCacheMaxAge,
config.disableHandleUseAfterFreeCheck);
return this;
}
@@ -226,6 +240,20 @@ public class Engine {
return this;
}
/**
* Sets the initial paused state of the rendering thread.
*
* <p>Warning: This is an experimental API. See {@link Engine#setPaused(boolean)} for
* caveats.
*
* @param paused Whether to start the rendering thread paused.
* @return A reference to this Builder for chaining calls.
*/
public Builder paused(boolean paused) {
nSetBuilderPaused(mNativeBuilder, paused);
return this;
}
/**
* Creates an instance of Engine
*
@@ -348,6 +376,35 @@ public class Engine {
*/
public long jobSystemThreadCount = 0;
/**
* Number of most-recently destroyed textures to track for use-after-free.
*
* This will cause the backend to throw an exception when a texture is freed but still bound
* to a SamplerGroup and used in a draw call. 0 disables completely.
*
* Currently only respected by the Metal backend.
*/
public long textureUseAfterFreePoolSize = 0;
/**
* Set to `true` to forcibly disable parallel shader compilation in the backend.
* Currently only honored by the GL backend.
*/
public boolean disableParallelShaderCompile = false;
/**
* The type of technique for stereoscopic rendering.
*
* This setting determines the algorithm used when stereoscopic rendering is enabled. This
* decision applies to the entire Engine for the lifetime of the Engine. E.g., multiple
* Views created from the Engine must use the same stereoscopic type.
*
* Each view can enable stereoscopic rendering via the StereoscopicOptions::enable flag.
*
* @see View#setStereoscopicOptions
*/
public StereoscopicType stereoscopicType = StereoscopicType.INSTANCED;
/**
* The number of eyes to render when stereoscopic rendering is enabled. Supported values are
* between 1 and Engine#getMaxStereoscopicEyes() (inclusive).
@@ -356,6 +413,21 @@ public class Engine {
* @see Engine#getMaxStereoscopicEyes
*/
public long stereoscopicEyeCount = 2;
/*
* @Deprecated This value is no longer used.
*/
public long resourceAllocatorCacheSizeMB = 64;
/*
* This value determines for how many frames are texture entries kept in the cache.
*/
public long resourceAllocatorCacheMaxAge = 2;
/*
* Disable backend handles use-after-free checks.
*/
public boolean disableHandleUseAfterFreeCheck = false;
}
private Engine(long nativeEngine, Config config) {
@@ -602,7 +674,7 @@ public class Engine {
*/
@NonNull
public SwapChain createSwapChain(@NonNull Object surface) {
return createSwapChain(surface, SwapChain.CONFIG_DEFAULT);
return createSwapChain(surface, SwapChainFlags.CONFIG_DEFAULT);
}
/**
@@ -610,15 +682,15 @@ public class Engine {
*
* @param surface on Android, <b>must be</b> an instance of {@link android.view.Surface}
*
* @param flags configuration flags, see {@link SwapChain}
* @param flags configuration flags, see {@link SwapChainFlags}
*
* @return a newly created {@link SwapChain} object
*
* @exception IllegalStateException can be thrown if the SwapChain couldn't be created
*
* @see SwapChain#CONFIG_DEFAULT
* @see SwapChain#CONFIG_TRANSPARENT
* @see SwapChain#CONFIG_READABLE
* @see SwapChainFlags#CONFIG_DEFAULT
* @see SwapChainFlags#CONFIG_TRANSPARENT
* @see SwapChainFlags#CONFIG_READABLE
*
*/
@NonNull
@@ -636,21 +708,22 @@ public class Engine {
*
* @param width width of the rendering buffer
* @param height height of the rendering buffer
* @param flags configuration flags, see {@link SwapChain}
* @param flags configuration flags, see {@link SwapChainFlags}
*
* @return a newly created {@link SwapChain} object
*
* @exception IllegalStateException can be thrown if the SwapChain couldn't be created
*
* @see SwapChain#CONFIG_DEFAULT
* @see SwapChain#CONFIG_TRANSPARENT
* @see SwapChain#CONFIG_READABLE
* @see SwapChainFlags#CONFIG_DEFAULT
* @see SwapChainFlags#CONFIG_TRANSPARENT
* @see SwapChainFlags#CONFIG_READABLE
*
*/
@NonNull
public SwapChain createSwapChain(int width, int height, long flags) {
if (width >= 0 && height >= 0) {
long nativeSwapChain = nCreateSwapChainHeadless(getNativeObject(), width, height, flags);
long nativeSwapChain =
nCreateSwapChainHeadless(getNativeObject(), width, height, flags);
if (nativeSwapChain == 0) throw new IllegalStateException("Couldn't create SwapChain");
return new SwapChain(nativeSwapChain, null);
}
@@ -662,11 +735,12 @@ public class Engine {
*
* @param surface a properly initialized {@link NativeSurface}
*
* @param flags configuration flags, see {@link SwapChain}
* @param flags configuration flags, see {@link SwapChainFlags}
*
* @return a newly created {@link SwapChain} object
*
* @exception IllegalStateException can be thrown if the {@link SwapChain} couldn't be created
* @exception IllegalStateException can be thrown if the {@link SwapChainFlags} couldn't be
* created
*/
@NonNull
public SwapChain createSwapChainFromNativeSurface(@NonNull NativeSurface surface, long flags) {
@@ -1135,6 +1209,22 @@ public class Engine {
nFlush(getNativeObject());
}
/**
* Pause or resume the rendering thread.
*
* <p>Warning: This is an experimental API. In particular, note the following caveats.
*
* <ul><li>
* Buffer callbacks will never be called as long as the rendering thread is paused.
* Do not rely on a buffer callback to unpause the thread.
* </li><li>
* While the rendering thread is paused, rendering commands will continue to be queued until the
* buffer limit is reached. When the limit is reached, the program will abort.
* </li></ul>
*/
public void setPaused(boolean paused) {
nSetPaused(getNativeObject(), paused);
}
@UsedByReflection("TextureHelper.java")
public long getNativeObject() {
@@ -1209,6 +1299,7 @@ public class Engine {
private static native void nDestroyEntity(long nativeEngine, int entity);
private static native void nFlushAndWait(long nativeEngine);
private static native void nFlush(long nativeEngine);
private static native void nSetPaused(long nativeEngine, boolean paused);
private static native long nGetTransformManager(long nativeEngine);
private static native long nGetLightManager(long nativeEngine);
private static native long nGetRenderableManager(long nativeEngine);
@@ -1227,8 +1318,12 @@ public class Engine {
private static native void nSetBuilderConfig(long nativeBuilder, long commandBufferSizeMB,
long perRenderPassArenaSizeMB, long driverHandleArenaSizeMB,
long minCommandBufferSizeMB, long perFrameCommandsSizeMB, long jobSystemThreadCount,
long stereoscopicEyeCount);
long textureUseAfterFreePoolSize, boolean disableParallelShaderCompile,
int stereoscopicType, long stereoscopicEyeCount,
long resourceAllocatorCacheSizeMB, long resourceAllocatorCacheMaxAge,
boolean disableHandleUseAfterFreeCheck);
private static native void nSetBuilderFeatureLevel(long nativeBuilder, int ordinal);
private static native void nSetBuilderSharedContext(long nativeBuilder, long sharedContext);
private static native void nSetBuilderPaused(long nativeBuilder, boolean paused);
private static native long nBuilderBuild(long nativeBuilder);
}
@@ -175,6 +175,32 @@ public class RenderableManager {
return this;
}
/**
* Type of geometry for a Renderable
*/
public enum GeometryType {
/** dynamic gemoetry has no restriction */
DYNAMIC,
/** bounds and world space transform are immutable */
STATIC_BOUNDS,
/** skinning/morphing not allowed and Vertex/IndexBuffer immutables */
STATIC
}
/**
* Specify whether this renderable has static bounds. In this context his means that
* the renderable's bounding box cannot change and that the renderable's transform is
* assumed immutable. Changing the renderable's transform via the TransformManager
* can lead to corrupted graphics. Note that skinning and morphing are not forbidden.
* Disabled by default.
* @param enable whether this renderable has static bounds. false by default.
*/
@NonNull
public Builder geometryType(GeometryType type) {
nBuilderGeometryType(mNativeBuilder, type.ordinal());
return this;
}
/**
* Binds a material instance to the specified primitive.
*
@@ -964,6 +990,7 @@ public class RenderableManager {
private static native void nBuilderGeometry(long nativeBuilder, int index, int value, long nativeVertexBuffer, long nativeIndexBuffer);
private static native void nBuilderGeometry(long nativeBuilder, int index, int value, long nativeVertexBuffer, long nativeIndexBuffer, int offset, int count);
private static native void nBuilderGeometry(long nativeBuilder, int index, int value, long nativeVertexBuffer, long nativeIndexBuffer, int offset, int minIndex, int maxIndex, int count);
private static native void nBuilderGeometryType(long nativeBuilder, int type);
private static native void nBuilderMaterial(long nativeBuilder, int index, long nativeMaterialInstance);
private static native void nBuilderBlendOrder(long nativeBuilder, int index, int blendOrder);
private static native void nBuilderGlobalBlendOrderEnabled(long nativeBuilder, int index, boolean enabled);
@@ -101,7 +101,7 @@ public class Renderer {
/**
* Desired frame interval in unit of 1 / DisplayInfo.refreshRate.
*/
public float interval = 1.0f / 60.0f;
public float interval = 1.0f;
/**
* Additional headroom for the GPU as a ratio of the targetFrameTime.
@@ -68,77 +68,30 @@ public class SwapChain {
private final Object mSurface;
private long mNativeObject;
public static final long CONFIG_DEFAULT = 0x0;
/**
* This flag indicates that the <code>SwapChain</code> must be allocated with an
* alpha-channel.
*/
public static final long CONFIG_TRANSPARENT = 0x1;
/**
* This flag indicates that the <code>SwapChain</code> may be used as a source surface
* for reading back render results. This config must be set when creating
* any <code>SwapChain</code> that will be used as the source for a blit operation.
*
* @see Renderer#copyFrame
*/
public static final long CONFIG_READABLE = 0x2;
/**
* Indicates that the native X11 window is an XCB window rather than an XLIB window.
* This is ignored on non-Linux platforms and in builds that support only one X11 API.
*/
public static final long CONFIG_ENABLE_XCB = 0x4;
/**
* Indicates that the SwapChain must automatically perform linear to sRGB encoding.
*
* This flag is ignored if isSRGBSwapChainSupported() is false.
*
* When using this flag, post-processing should be disabled.
*
* @see SwapChain#isSRGBSwapChainSupported
* @see View#setPostProcessingEnabled
*/
public static final long CONFIG_SRGB_COLORSPACE = 0x10;
/**
* Indicates that this SwapChain should allocate a stencil buffer in addition to a depth buffer.
*
* This flag is necessary when using View::setStencilBufferEnabled and rendering directly into
* the SwapChain (when post-processing is disabled).
*
* The specific format of the stencil buffer depends on platform support. The following pixel
* formats are tried, in order of preference:
*
* Depth only (without CONFIG_HAS_STENCIL_BUFFER):
* - DEPTH32F
* - DEPTH24
*
* Depth + stencil (with CONFIG_HAS_STENCIL_BUFFER):
* - DEPTH32F_STENCIL8
* - DEPTH24F_STENCIL8
*
* Note that enabling the stencil buffer may hinder depth precision and should only be used if
* necessary.
*
* @see View#setStencilBufferEnabled
* @see View#setPostProcessingEnabled
*/
public static final long CONFIG_HAS_STENCIL_BUFFER = 0x20;
SwapChain(long nativeSwapChain, Object surface) {
mNativeObject = nativeSwapChain;
mSurface = surface;
}
/**
* Return whether createSwapChain supports the SWAP_CHAIN_CONFIG_SRGB_COLORSPACE flag.
* Return whether createSwapChain supports the CONFIG_PROTECTED_CONTENT flag.
* The default implementation returns false.
*
* @param engine A reference to the filament Engine
* @return true if SWAP_CHAIN_CONFIG_SRGB_COLORSPACE is supported, false otherwise.
* @return true if CONFIG_PROTECTED_CONTENT is supported, false otherwise.
* @see SwapChainFlags#CONFIG_PROTECTED_CONTENT
*/
public static boolean isProtectedContentSupported(@NonNull Engine engine) {
return nIsProtectedContentSupported(engine.getNativeObject());
}
/**
* Return whether createSwapChain supports the CONFIG_SRGB_COLORSPACE flag.
* The default implementation returns false.
*
* @param engine A reference to the filament Engine
* @return true if CONFIG_SRGB_COLORSPACE is supported, false otherwise.
* @see SwapChainFlags#CONFIG_SRGB_COLORSPACE
*/
public static boolean isSRGBSwapChainSupported(@NonNull Engine engine) {
return nIsSRGBSwapChainSupported(engine.getNativeObject());
@@ -186,4 +139,5 @@ public class SwapChain {
private static native void nSetFrameCompletedCallback(long nativeSwapChain, Object handler, Runnable callback);
private static native boolean nIsSRGBSwapChainSupported(long nativeEngine);
private static native boolean nIsProtectedContentSupported(long nativeEngine);
}
@@ -0,0 +1,97 @@
/*
* Copyright (C) 2024 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.android.filament;
// Note: SwapChainFlags is kept separate from SwapChain so that UiHelper does not need to depend
// on SwapChain. This allows clients to use UiHelper without requiring all of Filament's Java
// classes.
/**
* Flags that a <code>SwapChain</code> can be created with to control behavior.
*
* @see Engine#createSwapChain
* @see Engine#createSwapChainFromNativeSurface
*/
public final class SwapChainFlags {
public static final long CONFIG_DEFAULT = 0x0;
/**
* This flag indicates that the <code>SwapChain</code> must be allocated with an
* alpha-channel.
*/
public static final long CONFIG_TRANSPARENT = 0x1;
/**
* This flag indicates that the <code>SwapChain</code> may be used as a source surface
* for reading back render results. This config must be set when creating
* any <code>SwapChain</code> that will be used as the source for a blit operation.
*
* @see Renderer#copyFrame
*/
public static final long CONFIG_READABLE = 0x2;
/**
* Indicates that the native X11 window is an XCB window rather than an XLIB window.
* This is ignored on non-Linux platforms and in builds that support only one X11 API.
*/
public static final long CONFIG_ENABLE_XCB = 0x4;
/**
* Indicates that the SwapChain must automatically perform linear to sRGB encoding.
*
* This flag is ignored if isSRGBSwapChainSupported() is false.
*
* When using this flag, post-processing should be disabled.
*
* @see SwapChain#isSRGBSwapChainSupported
* @see View#setPostProcessingEnabled
*/
public static final long CONFIG_SRGB_COLORSPACE = 0x10;
/**
* Indicates that this SwapChain should allocate a stencil buffer in addition to a depth buffer.
*
* This flag is necessary when using View::setStencilBufferEnabled and rendering directly into
* the SwapChain (when post-processing is disabled).
*
* The specific format of the stencil buffer depends on platform support. The following pixel
* formats are tried, in order of preference:
*
* Depth only (without CONFIG_HAS_STENCIL_BUFFER):
* - DEPTH32F
* - DEPTH24
*
* Depth + stencil (with CONFIG_HAS_STENCIL_BUFFER):
* - DEPTH32F_STENCIL8
* - DEPTH24F_STENCIL8
*
* Note that enabling the stencil buffer may hinder depth precision and should only be used if
* necessary.
*
* @see View#setStencilBufferEnabled
* @see View#setPostProcessingEnabled
*/
public static final long CONFIG_HAS_STENCIL_BUFFER = 0x20;
/**
* The SwapChain contains protected content. Only supported when isProtectedContentSupported()
* is true.
*/
public static final long CONFIG_PROTECTED_CONTENT = 0x40;
}
@@ -16,12 +16,14 @@ package com.google.android.filament;
* <li>Configurable tone mapping operators</li>
* <ul>
* <li>GenericToneMapper</li>
* <li>AgXToneMapper</li>
* </ul>
* <li>Fixed-aesthetic tone mapping operators</li>
* <ul>
* <li>ACESToneMapper</li>
* <li>ACESLegacyToneMapper</li>
* <li>FilmicToneMapper</li>
* <li>PBRNeutralToneMapper</li>
* </ul>
* <li>Debug/validation tone mapping operators</li>
* <ul>
@@ -100,11 +102,21 @@ public class ToneMapper {
}
}
/**
* Khronos PBR Neutral tone mapping operator. This tone mapper was designed
* to preserve the appearance of materials across lighting conditions while
* avoiding artifacts in the highlights in high dynamic range conditions.
*/
public static class PBRNeutralToneMapper extends ToneMapper {
public PBRNeutralToneMapper() {
super(nCreatePBRNeutralToneMapper());
}
}
/**
* AgX tone mapping operator.
*/
public static class Agx extends ToneMapper {
public enum AgxLook {
/**
* Base contrast with no look applied
@@ -233,6 +245,7 @@ public class ToneMapper {
private static native long nCreateACESToneMapper();
private static native long nCreateACESLegacyToneMapper();
private static native long nCreateFilmicToneMapper();
private static native long nCreatePBRNeutralToneMapper();
private static native long nCreateAgxToneMapper(int look);
private static native long nCreateGenericToneMapper(
float contrast, float midGrayIn, float midGrayOut, float hdrMax);
@@ -1882,7 +1882,7 @@ public class View {
* Options for Temporal Anti-aliasing (TAA)
* Most TAA parameters are extremely costly to change, as they will trigger the TAA post-process
* shaders to be recompiled. These options should be changed or set during initialization.
* `filterWidth`, `feedback` and `jitterPattern`, however, could be changed at any time.
* `filterWidth`, `feedback` and `jitterPattern`, however, can be changed at any time.
*
* `feedback` of 0.1 effectively accumulates a maximum of 19 samples in steady state.
* see "A Survey of Temporal Antialiasing Techniques" by Lei Yang and all for more information.
@@ -1925,6 +1925,7 @@ public class View {
UNIFORM_HELIX_X4,
HALTON_23_X8,
HALTON_23_X16,
HALTON_23_X32,
}
/**
@@ -1939,6 +1940,10 @@ public class View {
* texturing lod bias (typically -1 or -2)
*/
public float lodBias = -1.0f;
/**
* post-TAA sharpen, especially useful when upscaling is true.
*/
public float sharpness = 0.0f;
/**
* enables or disables temporal anti-aliasing
*/
@@ -27,7 +27,7 @@ import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.TextureView;
import com.google.android.filament.SwapChain;
import com.google.android.filament.SwapChainFlags;
/**
* UiHelper is a simple class that can manage either a SurfaceView, TextureView, or a SurfaceHolder
@@ -538,7 +538,7 @@ public class UiHelper {
* the options set on this UiHelper.
*/
public long getSwapChainFlags() {
return isOpaque() ? SwapChain.CONFIG_DEFAULT : SwapChain.CONFIG_TRANSPARENT;
return isOpaque() ? SwapChainFlags.CONFIG_DEFAULT : SwapChainFlags.CONFIG_TRANSPARENT;
}
/**
+8
View File
@@ -81,9 +81,17 @@ set(GLTFIO_SRCS
${GLTFIO_DIR}/src/TangentsJob.cpp
${GLTFIO_DIR}/src/TangentsJob.h
${GLTFIO_DIR}/src/UbershaderProvider.cpp
${GLTFIO_DIR}/src/Utility.cpp
${GLTFIO_DIR}/src/Utility.h
${GLTFIO_DIR}/src/Wireframe.cpp
${GLTFIO_DIR}/src/Wireframe.h
${GLTFIO_DIR}/src/downcast.h
${GLTFIO_DIR}/src/extended/AssetLoaderExtended.h
${GLTFIO_DIR}/src/extended/TangentsJobExtended.cpp
${GLTFIO_DIR}/src/extended/TangentsJobExtended.h
${GLTFIO_DIR}/src/extended/TangentSpaceMeshWrapper.cpp
${GLTFIO_DIR}/src/extended/TangentSpaceMeshWrapper.h
src/main/cpp/Animator.cpp
src/main/cpp/AssetLoader.cpp
+1 -1
View File
@@ -1,5 +1,5 @@
GROUP=com.google.android.filament
VERSION_NAME=1.49.3
VERSION_NAME=1.51.4
POM_DESCRIPTION=Real-time physically based rendering engine for Android.
@@ -30,7 +30,7 @@ android {
compileSdkVersion versions.compileSdk
defaultConfig {
applicationId "com.google.android.filament.gltf"
minSdkVersion 19
minSdkVersion versions.minSdk
targetSdkVersion versions.targetSdk
}
+1 -1
View File
@@ -516,7 +516,7 @@ function build_android {
if [[ "${BUILD_ANDROID_SAMPLES}" == "true" ]]; then
for sample in ${ANDROID_SAMPLES}; do
echo "Installing out/${sample}-debug.apk"
cp samples/${sample}/build/outputs/apk/debug/${sample}-debug-unsigned.apk \
cp samples/${sample}/build/outputs/apk/debug/${sample}-debug.apk \
../out/${sample}-debug.apk
done
fi
+1 -1
View File
@@ -1 +1 @@
25.1.8937393
26.1.10909125
+7 -1
View File
@@ -125,7 +125,13 @@ if [[ "${has_universal}" == "true" ]]; then
arch_output="${OUTPUT_PATH%.a}_${arch}.a"
arch_outputs+=("$arch_output")
combine_static_libs "$arch_output" $(find "$(pwd)/${archs_temp_dir}/${arch}" -iname '*.a')
archives=()
while IFS= read -r -d $'\0'; do
archives+=("$REPLY")
done < <(find "$(pwd)/${archs_temp_dir}/${arch}" -iname '*.a' -print0)
combine_static_libs "$arch_output" "$archives"
done
# Finally, combine the single-architecture archives into a universal binary.
+1 -1
View File
@@ -21,7 +21,7 @@ set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_VERSION 1)
# android
set(API_LEVEL 19)
set(API_LEVEL 21)
# architecture
set(ARCH armv7a-linux-androideabi)
+1 -1
View File
@@ -21,7 +21,7 @@ set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_VERSION 1)
# android
set(API_LEVEL 19)
set(API_LEVEL 21)
# architecture
set(ARCH i686-linux-android)
+32 -1
View File
@@ -1397,7 +1397,7 @@ Type
: `string`
Value
: Any of `opaque`, `transparent`, `fade`, `add`, `masked`, `multiply`, `screen`. Defaults to `opaque`.
: Any of `opaque`, `transparent`, `fade`, `add`, `masked`, `multiply`, `screen`, `custom`. Defaults to `opaque`.
Description
: Defines how/if the rendered object is blended with the content of the render target.
@@ -1420,6 +1420,7 @@ Description
of the material's output defines whether a fragment is discarded or not. Additionally,
ALPHA_TO_COVERAGE is enabled for non-translucent views. See the maskThreshold section for more
information.
- **Custom**: blending is enabled. But the blending function is user specified. See `blendFunction`.
!!! Note
When `blending` is set to `masked`, alpha to coverage is automatically enabled for the material.
@@ -1432,6 +1433,36 @@ material {
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
### Blending and transparency: blendFunction
Type
: `object`
Fields
: `srcRGB`, `srcA`, `dstRGB`, `dstA`
Description
: - *srcRGB*: source function applied to the RGB channels
- *srcA*: source function applied to the alpha channel
- *srcRGB*: destination function applied to the RGB channels
- *srcRGB*: destination function applied to the alpha channel
The values possible for each functions are one of `zero`, `one`, `srcColor`, `oneMinusSrcColor`,
`dstColor`, `oneMinusDstColor`, `srcAlpha`, `oneMinusSrcAlpha`, `dstAlpha`,
`oneMinusDstAlpha`, `srcAlphaSaturate`
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ JSON
material {
blending : custom,
blendFunction :
{
srcRGB: one,
srcA: one,
dstRGB: oneMinusSrcColor,
dstA: oneMinusSrcAlpha
}
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
### Blending and transparency: postLightingBlending
Type
File diff suppressed because one or more lines are too long
Binary file not shown.
+41 -17
View File
@@ -66,6 +66,7 @@ set(SRCS
src/Froxelizer.cpp
src/Frustum.cpp
src/HwRenderPrimitiveFactory.cpp
src/HwVertexBufferInfoFactory.cpp
src/IndexBuffer.cpp
src/IndirectLight.cpp
src/InstanceBuffer.cpp
@@ -137,6 +138,7 @@ set(SRCS
set(PRIVATE_HDRS
src/Allocators.h
src/Bimap.h
src/BufferPoolAllocator.h
src/ColorSpaceUtils.h
src/Culler.h
@@ -147,6 +149,7 @@ set(PRIVATE_HDRS
src/FrameSkipper.h
src/Froxelizer.h
src/HwRenderPrimitiveFactory.h
src/HwVertexBufferInfoFactory.h
src/Intersections.h
src/MaterialParser.h
src/PerViewUniforms.h
@@ -212,6 +215,7 @@ set(MATERIAL_SRCS
src/materials/antiAliasing/fxaa.mat
src/materials/antiAliasing/taa.mat
src/materials/blitLow.mat
src/materials/blitArray.mat
src/materials/bloom/bloomDownsample.mat
src/materials/bloom/bloomDownsample2x.mat
src/materials/bloom/bloomDownsample9.mat
@@ -238,6 +242,7 @@ set(MATERIAL_SRCS
src/materials/resolveDepth.mat
src/materials/separableGaussianBlur.mat
src/materials/skybox.mat
src/materials/shadowmap.mat
src/materials/ssao/bilateralBlur.mat
src/materials/ssao/bilateralBlurBentNormals.mat
src/materials/ssao/mipmapDepth.mat
@@ -247,8 +252,13 @@ set(MATERIAL_SRCS
)
set(MATERIAL_FL0_SRCS
src/materials/defaultMaterial0.mat
src/materials/skybox0.mat
src/materials/defaultMaterial.mat
src/materials/skybox.mat
)
set(MATERIAL_MULTIVIEW_SRCS
src/materials/defaultMaterial.mat
src/materials/skybox.mat
)
# Embed the binary resource blob for materials.
@@ -280,6 +290,11 @@ if (FILAMENT_ENABLE_FEATURE_LEVEL_0)
add_definitions(-DFILAMENT_ENABLE_FEATURE_LEVEL_0)
endif()
# Whether to include MULTIVIEW materials.
if (FILAMENT_ENABLE_MULTIVIEW)
add_definitions(-DFILAMENT_ENABLE_MULTIVIEW)
endif()
# ==================================================================================================
# Definitions
# ==================================================================================================
@@ -310,33 +325,42 @@ foreach (mat_src ${MATERIAL_SRCS})
get_filename_component(localname "${mat_src}" NAME_WE)
get_filename_component(fullname "${mat_src}" ABSOLUTE)
set(output_path "${MATERIAL_DIR}/${localname}.filamat")
add_custom_command(
OUTPUT ${output_path}
COMMAND matc ${MATC_BASE_FLAGS} -o ${output_path} ${fullname}
MAIN_DEPENDENCY ${fullname}
DEPENDS matc
COMMENT "Compiling material ${mat_src} to ${output_path}"
COMMENT "Compiling material ${fullname} to ${output_path}"
)
list(APPEND MATERIAL_BINS ${output_path})
endforeach()
if (FILAMENT_ENABLE_FEATURE_LEVEL_0)
foreach (mat_src ${MATERIAL_FL0_SRCS})
get_filename_component(localname "${mat_src}" NAME_WE)
get_filename_component(fullname "${mat_src}" ABSOLUTE)
set(output_path "${MATERIAL_DIR}/${localname}.filamat")
list(FIND MATERIAL_FL0_SRCS ${mat_src} index)
if (${index} GREATER -1 AND FILAMENT_ENABLE_FEATURE_LEVEL_0)
string(REGEX REPLACE "[.]filamat$" "_fl0.filamat" output_path_fl0 ${output_path})
add_custom_command(
OUTPUT ${output_path}
COMMAND matc ${MATC_BASE_FLAGS} -o ${output_path} ${fullname}
OUTPUT ${output_path_fl0}
COMMAND matc ${MATC_BASE_FLAGS} -PfeatureLevel=0 -o ${output_path_fl0} ${fullname}
MAIN_DEPENDENCY ${fullname}
DEPENDS matc
COMMENT "Compiling material ${mat_src} to ${output_path}"
COMMENT "Compiling material ${fullname} to ${output_path_fl0}"
)
list(APPEND MATERIAL_BINS ${output_path})
endforeach ()
endif ()
list(APPEND MATERIAL_BINS ${output_path_fl0})
endif ()
list(FIND MATERIAL_MULTIVIEW_SRCS ${mat_src} index)
if (${index} GREATER -1 AND FILAMENT_ENABLE_MULTIVIEW)
string(REGEX REPLACE "[.]filamat$" "_multiview.filamat" output_path_multiview ${output_path})
add_custom_command(
OUTPUT ${output_path_multiview}
COMMAND matc ${MATC_BASE_FLAGS} -PstereoscopicType=multiview -o ${output_path_multiview} ${fullname}
MAIN_DEPENDENCY ${fullname}
DEPENDS matc
COMMENT "Compiling material ${fullname} to ${output_path_multiview}"
)
list(APPEND MATERIAL_BINS ${output_path_multiview})
endif ()
endforeach()
# Additional dependencies on included files for materials
+6
View File
@@ -71,6 +71,8 @@ if (FILAMENT_SUPPORTS_OPENGL AND NOT FILAMENT_USE_EXTERNAL_GLES3 AND NOT FILAMEN
include/backend/platforms/OpenGLPlatform.h
src/opengl/gl_headers.cpp
src/opengl/gl_headers.h
src/opengl/GLBufferObject.h
src/opengl/GLTexture.h
src/opengl/GLUtils.cpp
src/opengl/GLUtils.h
src/opengl/OpenGLBlobCache.cpp
@@ -166,6 +168,10 @@ endif()
if (FILAMENT_SUPPORTS_VULKAN)
list(APPEND SRCS
include/backend/platforms/VulkanPlatform.h
src/vulkan/caching/VulkanDescriptorSetManager.cpp
src/vulkan/caching/VulkanDescriptorSetManager.h
src/vulkan/caching/VulkanPipelineLayoutCache.cpp
src/vulkan/caching/VulkanPipelineLayoutCache.h
src/vulkan/platform/VulkanPlatform.cpp
src/vulkan/platform/VulkanPlatformSwapChainImpl.cpp
src/vulkan/platform/VulkanPlatformSwapChainImpl.h
@@ -23,7 +23,6 @@
#include <utils/ostream.h>
#include <stddef.h>
#include <stdint.h>
namespace filament::backend {
@@ -17,8 +17,6 @@
#ifndef TNT_FILAMENT_BACKEND_CALLBACKHANDLER_H
#define TNT_FILAMENT_BACKEND_CALLBACKHANDLER_H
#include <utils/compiler.h>
namespace filament::backend {
/**
+53 -14
View File
@@ -28,7 +28,8 @@
#include <math/vec4.h>
#include <array> // FIXME: STL headers are not allowed in public headers
#include <array> // FIXME: STL headers are not allowed in public headers
#include <type_traits> // FIXME: STL headers are not allowed in public headers
#include <stddef.h>
#include <stdint.h>
@@ -80,7 +81,14 @@ static constexpr uint64_t SWAP_CHAIN_CONFIG_SRGB_COLORSPACE = 0x10;
/**
* Indicates that the SwapChain should also contain a stencil component.
*/
static constexpr uint64_t SWAP_CHAIN_HAS_STENCIL_BUFFER = 0x20;
static constexpr uint64_t SWAP_CHAIN_CONFIG_HAS_STENCIL_BUFFER = 0x20;
static constexpr uint64_t SWAP_CHAIN_HAS_STENCIL_BUFFER = SWAP_CHAIN_CONFIG_HAS_STENCIL_BUFFER;
/**
* The SwapChain contains protected content. Currently only supported by OpenGLPlatform and
* only when OpenGLPlatform::isProtectedContextSupported() is true.
*/
static constexpr uint64_t SWAP_CHAIN_CONFIG_PROTECTED_CONTENT = 0x40;
static constexpr size_t MAX_VERTEX_ATTRIBUTE_COUNT = 16; // This is guaranteed by OpenGL ES.
@@ -128,6 +136,12 @@ enum class Backend : uint8_t {
NOOP = 4, //!< Selects the no-op driver for testing purposes.
};
enum class TimerQueryResult : int8_t {
ERROR = -1, // an error occurred, result won't be available
NOT_READY = 0, // result to ready yet
AVAILABLE = 1, // result is available
};
static constexpr const char* backendToString(Backend backend) {
switch (backend) {
case Backend::NOOP:
@@ -658,16 +672,17 @@ enum class TextureFormat : uint16_t {
};
//! Bitmask describing the intended Texture Usage
enum class TextureUsage : uint8_t {
NONE = 0x00,
COLOR_ATTACHMENT = 0x01, //!< Texture can be used as a color attachment
DEPTH_ATTACHMENT = 0x02, //!< Texture can be used as a depth attachment
STENCIL_ATTACHMENT = 0x04, //!< Texture can be used as a stencil attachment
UPLOADABLE = 0x08, //!< Data can be uploaded into this texture (default)
SAMPLEABLE = 0x10, //!< Texture can be sampled (default)
SUBPASS_INPUT = 0x20, //!< Texture can be used as a subpass input
BLIT_SRC = 0x40, //!< Texture can be used the source of a blit()
BLIT_DST = 0x80, //!< Texture can be used the destination of a blit()
enum class TextureUsage : uint16_t {
NONE = 0x0000,
COLOR_ATTACHMENT = 0x0001, //!< Texture can be used as a color attachment
DEPTH_ATTACHMENT = 0x0002, //!< Texture can be used as a depth attachment
STENCIL_ATTACHMENT = 0x0004, //!< Texture can be used as a stencil attachment
UPLOADABLE = 0x0008, //!< Data can be uploaded into this texture (default)
SAMPLEABLE = 0x0010, //!< Texture can be sampled (default)
SUBPASS_INPUT = 0x0020, //!< Texture can be used as a subpass input
BLIT_SRC = 0x0040, //!< Texture can be used the source of a blit()
BLIT_DST = 0x0080, //!< Texture can be used the destination of a blit()
PROTECTED = 0x0100, //!< Texture can be used the destination of a blit()
DEFAULT = UPLOADABLE | SAMPLEABLE //!< Default texture usage
};
@@ -1171,11 +1186,27 @@ struct StencilState {
//! Stencil operations for front-facing polygons
StencilOperations front = {
.stencilFunc = StencilFunction::A, .ref = 0, .readMask = 0xff, .writeMask = 0xff };
.stencilFunc = StencilFunction::A,
.stencilOpStencilFail = StencilOperation::KEEP,
.padding0 = 0,
.stencilOpDepthFail = StencilOperation::KEEP,
.stencilOpDepthStencilPass = StencilOperation::KEEP,
.padding1 = 0,
.ref = 0,
.readMask = 0xff,
.writeMask = 0xff };
//! Stencil operations for back-facing polygons
StencilOperations back = {
.stencilFunc = StencilFunction::A, .ref = 0, .readMask = 0xff, .writeMask = 0xff };
.stencilFunc = StencilFunction::A,
.stencilOpStencilFail = StencilOperation::KEEP,
.padding0 = 0,
.stencilOpDepthFail = StencilOperation::KEEP,
.stencilOpDepthStencilPass = StencilOperation::KEEP,
.padding1 = 0,
.ref = 0,
.readMask = 0xff,
.writeMask = 0xff };
//! Whether stencil-buffer writes are enabled
bool stencilWrite = false;
@@ -1211,6 +1242,14 @@ enum class Workaround : uint16_t {
DISABLE_THREAD_AFFINITY
};
//! The type of technique for stereoscopic rendering
enum class StereoscopicType : uint8_t {
// Stereoscopic rendering is performed using instanced rendering technique.
INSTANCED,
// Stereoscopic rendering is performed using the multiview feature from the graphics backend.
MULTIVIEW,
};
} // namespace filament::backend
template<> struct utils::EnableBitMaskOperators<filament::backend::ShaderStageFlags>
+26 -26
View File
@@ -17,16 +17,14 @@
#ifndef TNT_FILAMENT_BACKEND_HANDLE_H
#define TNT_FILAMENT_BACKEND_HANDLE_H
#include <utils/compiler.h>
#if !defined(NDEBUG)
#include <utils/Log.h>
#include <utils/ostream.h>
#endif
#include <utils/debug.h>
#include <stdint.h>
#include <type_traits> // FIXME: STL headers are not allowed in public headers
#include <limits>
#include <type_traits>
#include <stdint.h>
namespace filament::backend {
@@ -41,6 +39,7 @@ struct HwStream;
struct HwSwapChain;
struct HwTexture;
struct HwTimerQuery;
struct HwVertexBufferInfo;
struct HwVertexBuffer;
/*
@@ -54,7 +53,7 @@ struct HwVertexBuffer;
class HandleBase {
public:
using HandleId = uint32_t;
static constexpr const HandleId nullid = HandleId{ std::numeric_limits<HandleId>::max() };
static constexpr const HandleId nullid = HandleId{ UINT32_MAX };
constexpr HandleBase() noexcept: object(nullid) {}
@@ -64,14 +63,6 @@ public:
// clear the handle, this doesn't free associated resources
void clear() noexcept { object = nullid; }
// compare handles
bool operator==(const HandleBase& rhs) const noexcept { return object == rhs.object; }
bool operator!=(const HandleBase& rhs) const noexcept { return object != rhs.object; }
bool operator<(const HandleBase& rhs) const noexcept { return object < rhs.object; }
bool operator<=(const HandleBase& rhs) const noexcept { return object <= rhs.object; }
bool operator>(const HandleBase& rhs) const noexcept { return object > rhs.object; }
bool operator>=(const HandleBase& rhs) const noexcept { return object >= rhs.object; }
// get this handle's handleId
HandleId getId() const noexcept { return object; }
@@ -103,6 +94,14 @@ struct Handle : public HandleBase {
explicit Handle(HandleId id) noexcept : HandleBase(id) { }
// compare handles of the same type
bool operator==(const Handle& rhs) const noexcept { return getId() == rhs.getId(); }
bool operator!=(const Handle& rhs) const noexcept { return getId() != rhs.getId(); }
bool operator<(const Handle& rhs) const noexcept { return getId() < rhs.getId(); }
bool operator<=(const Handle& rhs) const noexcept { return getId() <= rhs.getId(); }
bool operator>(const Handle& rhs) const noexcept { return getId() > rhs.getId(); }
bool operator>=(const Handle& rhs) const noexcept { return getId() >= rhs.getId(); }
// type-safe Handle cast
template<typename B, typename = std::enable_if_t<std::is_base_of<T, B>::value> >
Handle(Handle<B> const& base) noexcept : HandleBase(base) { } // NOLINT(hicpp-explicit-conversions,google-explicit-constructor)
@@ -116,18 +115,19 @@ private:
// Types used by the command stream
// (we use this renaming because the macro-system doesn't deal well with "<" and ">")
using BufferObjectHandle = Handle<HwBufferObject>;
using FenceHandle = Handle<HwFence>;
using IndexBufferHandle = Handle<HwIndexBuffer>;
using ProgramHandle = Handle<HwProgram>;
using RenderPrimitiveHandle = Handle<HwRenderPrimitive>;
using RenderTargetHandle = Handle<HwRenderTarget>;
using SamplerGroupHandle = Handle<HwSamplerGroup>;
using StreamHandle = Handle<HwStream>;
using SwapChainHandle = Handle<HwSwapChain>;
using TextureHandle = Handle<HwTexture>;
using TimerQueryHandle = Handle<HwTimerQuery>;
using VertexBufferHandle = Handle<HwVertexBuffer>;
using BufferObjectHandle = Handle<HwBufferObject>;
using FenceHandle = Handle<HwFence>;
using IndexBufferHandle = Handle<HwIndexBuffer>;
using ProgramHandle = Handle<HwProgram>;
using RenderPrimitiveHandle = Handle<HwRenderPrimitive>;
using RenderTargetHandle = Handle<HwRenderTarget>;
using SamplerGroupHandle = Handle<HwSamplerGroup>;
using StreamHandle = Handle<HwStream>;
using SwapChainHandle = Handle<HwSwapChain>;
using TextureHandle = Handle<HwTexture>;
using TimerQueryHandle = Handle<HwTimerQuery>;
using VertexBufferHandle = Handle<HwVertexBuffer>;
using VertexBufferInfoHandle = Handle<HwVertexBufferInfo>;
} // namespace filament::backend
@@ -20,7 +20,7 @@
#include <backend/DriverEnums.h>
#include <backend/Handle.h>
#include <limits>
#include <utils/ostream.h>
#include <stdint.h>
@@ -29,14 +29,13 @@ namespace filament::backend {
//! \privatesection
struct PipelineState {
Handle<HwProgram> program;
RasterState rasterState;
StencilState stencilState;
PolygonOffset polygonOffset;
Viewport scissor{ 0, 0,
(uint32_t)std::numeric_limits<int32_t>::max(),
(uint32_t)std::numeric_limits<int32_t>::max()
};
Handle<HwProgram> program; // 4
Handle<HwVertexBufferInfo> vertexBufferInfo; // 4
RasterState rasterState; // 4
StencilState stencilState; // 12
PolygonOffset polygonOffset; // 8
PrimitiveType primitiveType = PrimitiveType::TRIANGLES; // 1
uint8_t padding[3] = {}; // 3
};
} // namespace filament::backend
@@ -24,6 +24,7 @@
#include <utils/compiler.h>
#include <utils/debug.h>
#include <utils/ostream.h>
#include <stddef.h>
#include <stdint.h>
+58 -11
View File
@@ -19,11 +19,12 @@
#ifndef TNT_FILAMENT_BACKEND_PLATFORM_H
#define TNT_FILAMENT_BACKEND_PLATFORM_H
#include <backend/DriverEnums.h>
#include <utils/compiler.h>
#include <utils/Invocable.h>
#include <stddef.h>
#include <stdint.h>
namespace filament::backend {
class Driver;
@@ -41,18 +42,29 @@ public:
struct Stream {};
struct DriverConfig {
/*
* size of handle arena in bytes. Setting to 0 indicates default value is to be used.
/**
* Size of handle arena in bytes. Setting to 0 indicates default value is to be used.
* Driver clamps to valid values.
*/
size_t handleArenaSize = 0;
/*
* this number of most-recently destroyed textures will be tracked for use-after-free.
/**
* This number of most-recently destroyed textures will be tracked for use-after-free.
* Throws an exception when a texture is freed but still bound to a SamplerGroup and used in
* a draw call. 0 disables completely. Currently only respected by the Metal backend.
*/
size_t textureUseAfterFreePoolSize = 0;
/**
* Set to `true` to forcibly disable parallel shader compilation in the backend.
* Currently only honored by the GL and Metal backends.
*/
bool disableParallelShaderCompile = false;
/**
* Disable backend handles use-after-free checks.
*/
bool disableHandleUseAfterFreeCheck = false;
};
Platform() noexcept;
@@ -78,7 +90,7 @@ public:
*
* @return nullptr on failure, or a pointer to the newly created driver.
*/
virtual backend::Driver* createDriver(void* sharedContext,
virtual backend::Driver* UTILS_NULLABLE createDriver(void* UTILS_NULLABLE sharedContext,
const DriverConfig& driverConfig) noexcept = 0;
/**
@@ -96,7 +108,8 @@ public:
* cache.
*/
using InsertBlobFunc = utils::Invocable<
void(const void* key, size_t keySize, const void* value, size_t valueSize)>;
void(const void* UTILS_NONNULL key, size_t keySize,
const void* UTILS_NONNULL value, size_t valueSize)>;
/*
* RetrieveBlobFunc is an Invocable to an application-provided function that a
@@ -104,7 +117,8 @@ public:
* cache.
*/
using RetrieveBlobFunc = utils::Invocable<
size_t(const void* key, size_t keySize, void* value, size_t valueSize)>;
size_t(const void* UTILS_NONNULL key, size_t keySize,
void* UTILS_NONNULL value, size_t valueSize)>;
/**
* Sets the callback functions that the backend can use to interact with caching functionality
@@ -157,7 +171,8 @@ public:
* @param value pointer to the beginning of the value data that is to be inserted
* @param valueSize specifies the size in byte of the data pointed to by <value>
*/
void insertBlob(const void* key, size_t keySize, const void* value, size_t valueSize);
void insertBlob(const void* UTILS_NONNULL key, size_t keySize,
const void* UTILS_NONNULL value, size_t valueSize);
/**
* To retrieve the binary value associated with a given key from the cache, a
@@ -176,11 +191,43 @@ public:
* @return If the cache contains a value associated with the given key then the
* size of that binary value in bytes is returned. Otherwise 0 is returned.
*/
size_t retrieveBlob(const void* key, size_t keySize, void* value, size_t valueSize);
size_t retrieveBlob(const void* UTILS_NONNULL key, size_t keySize,
void* UTILS_NONNULL value, size_t valueSize);
using DebugUpdateStatFunc = utils::Invocable<void(const char* UTILS_NONNULL key, uint64_t value)>;
/**
* Sets the callback function that the backend can use to update backend-specific statistics
* to aid with debugging. This callback is guaranteed to be called on the Filament driver
* thread.
*
* @param debugUpdateStat an Invocable that updates debug statistics
*/
void setDebugUpdateStatFunc(DebugUpdateStatFunc&& debugUpdateStat) noexcept;
/**
* @return true if debugUpdateStat is valid.
*/
bool hasDebugUpdateStatFunc() const noexcept;
/**
* To track backend-specific statistics, the backend implementation can call the
* application-provided callback function debugUpdateStatFunc to associate or update a value
* with a given key. It is possible for this function to be called multiple times with the
* same key, in which case newer values should overwrite older values.
*
* This function is guaranteed to be called only on a single thread, the Filament driver
* thread.
*
* @param key a null-terminated C-string with the key of the debug statistic
* @param value the updated value of key
*/
void debugUpdateStat(const char* UTILS_NONNULL key, uint64_t value);
private:
InsertBlobFunc mInsertBlob;
RetrieveBlobFunc mRetrieveBlob;
DebugUpdateStatFunc mDebugUpdateStat;
};
} // namespace filament
@@ -21,8 +21,7 @@
#include <utils/compiler.h>
namespace filament {
namespace backend {
namespace filament::backend {
/**
* A PresentCallable is a callable object that, when called, schedules a frame for presentation on
@@ -98,7 +97,6 @@ private:
*/
using FrameFinishedCallback UTILS_DEPRECATED = void(*)(PresentCallable callable, void* user);
} // namespace backend
} // namespace filament
} // namespace filament::backend
#endif // TNT_FILAMENT_BACKEND_PRESENTCALLABLE
+15 -4
View File
@@ -17,17 +17,19 @@
#ifndef TNT_FILAMENT_BACKEND_PRIVATE_PROGRAM_H
#define TNT_FILAMENT_BACKEND_PRIVATE_PROGRAM_H
#include <utils/compiler.h>
#include <utils/CString.h>
#include <utils/FixedCapacityVector.h>
#include <utils/Invocable.h>
#include <utils/Log.h>
#include <utils/ostream.h>
#include <backend/DriverEnums.h>
#include <array>
#include <variant>
#include <array> // FIXME: STL headers are not allowed in public headers
#include <utility> // FIXME: STL headers are not allowed in public headers
#include <variant> // FIXME: STL headers are not allowed in public headers
#include <stddef.h>
#include <stdint.h>
namespace filament::backend {
@@ -114,6 +116,8 @@ public:
Program& cacheId(uint64_t cacheId) noexcept;
Program& multiview(bool multiview) noexcept;
ShaderSource const& getShadersSource() const noexcept { return mShadersSource; }
ShaderSource& getShadersSource() noexcept { return mShadersSource; }
@@ -141,6 +145,8 @@ public:
uint64_t getCacheId() const noexcept { return mCacheId; }
bool isMultiview() const noexcept { return mMultiview; }
CompilerPriorityQueue getPriorityQueue() const noexcept { return mPriorityQueue; }
private:
@@ -156,6 +162,11 @@ private:
utils::FixedCapacityVector<std::pair<utils::CString, uint8_t>> mAttributes;
std::array<UniformInfo, Program::UNIFORM_BINDING_COUNT> mBindingUniformInfo;
CompilerPriorityQueue mPriorityQueue = CompilerPriorityQueue::HIGH;
// Indicates the current engine was initialized with multiview stereo, and the variant for this
// program contains STE flag. This will be referred later for the OpenGL shader compiler to
// determine whether shader code replacement for the num_views should be performed.
// This variable could be promoted as a more generic variable later if other similar needs occur.
bool mMultiview = false;
};
} // namespace filament::backend
@@ -24,9 +24,6 @@
#include <utils/compiler.h>
#include <stddef.h>
#include <stdint.h>
namespace filament::backend {
struct UTILS_PUBLIC SamplerDescriptor {
@@ -17,9 +17,11 @@
#ifndef TNT_FILAMENT_BACKEND_TARGETBUFFERINFO_H
#define TNT_FILAMENT_BACKEND_TARGETBUFFERINFO_H
#include <backend/DriverEnums.h>
#include <backend/Handle.h>
#include <utils/ostream.h>
#include <stddef.h>
#include <stdint.h>
namespace filament::backend {
@@ -30,6 +32,10 @@ struct TargetBufferInfo {
// texture to be used as render target
Handle<HwTexture> handle;
// starting layer index for multiview. This value is only used when the `layerCount` for the
// render target is greater than 1.
uint8_t baseViewIndex = 0;
// level to be used
uint8_t level = 0;
@@ -78,7 +84,7 @@ public:
// this is here for backward compatibility
MRT(Handle<HwTexture> handle, uint8_t level, uint16_t layer) noexcept
: mInfos{{ handle, level, layer }} {
: mInfos{{ handle, 0, level, layer }} {
}
};
@@ -18,8 +18,15 @@
#define TNT_FILAMENT_BACKEND_PRIVATE_OPENGLPLATFORM_H
#include <backend/AcquiredImage.h>
#include <backend/DriverEnums.h>
#include <backend/Platform.h>
#include <utils/compiler.h>
#include <utils/Invocable.h>
#include <stddef.h>
#include <stdint.h>
namespace filament::backend {
class Driver;
@@ -38,8 +45,8 @@ protected:
* Derived classes can use this to instantiate the default OpenGLDriver backend.
* This is typically called from your implementation of createDriver()
*/
static Driver* createDefaultDriver(OpenGLPlatform* platform,
void* sharedContext, const DriverConfig& driverConfig);
static Driver* UTILS_NULLABLE createDefaultDriver(OpenGLPlatform* UTILS_NONNULL platform,
void* UTILS_NULLABLE sharedContext, const DriverConfig& driverConfig);
~OpenGLPlatform() noexcept override;
@@ -57,6 +64,22 @@ public:
*/
virtual void terminate() noexcept = 0;
/**
* Return whether createSwapChain supports the SWAP_CHAIN_CONFIG_SRGB_COLORSPACE flag.
* The default implementation returns false.
*
* @return true if SWAP_CHAIN_CONFIG_SRGB_COLORSPACE is supported, false otherwise.
*/
virtual bool isSRGBSwapChainSupported() const noexcept;
/**
* Return whether protected contexts are supported by this backend.
* If protected context are supported, the SWAP_CHAIN_CONFIG_PROTECTED_CONTENT flag can be
* used when creating a SwapChain.
* The default implementation returns false.
*/
virtual bool isProtectedContextSupported() const noexcept;
/**
* Called by the driver to create a SwapChain for this driver.
*
@@ -66,15 +89,8 @@ public:
* @return The driver's SwapChain object.
*
*/
virtual SwapChain* createSwapChain(void* nativeWindow, uint64_t flags) noexcept = 0;
/**
* Return whether createSwapChain supports the SWAP_CHAIN_CONFIG_SRGB_COLORSPACE flag.
* The default implementation returns false.
*
* @return true if SWAP_CHAIN_CONFIG_SRGB_COLORSPACE is supported, false otherwise.
*/
virtual bool isSRGBSwapChainSupported() const noexcept;
virtual SwapChain* UTILS_NULLABLE createSwapChain(
void* UTILS_NULLABLE nativeWindow, uint64_t flags) noexcept = 0;
/**
* Called by the driver create a headless SwapChain.
@@ -87,13 +103,14 @@ public:
* TODO: we need a more generic way of passing construction parameters
* A void* might be enough.
*/
virtual SwapChain* createSwapChain(uint32_t width, uint32_t height, uint64_t flags) noexcept = 0;
virtual SwapChain* UTILS_NULLABLE createSwapChain(
uint32_t width, uint32_t height, uint64_t flags) noexcept = 0;
/**
* Called by the driver to destroys the SwapChain
* @param swapChain SwapChain to be destroyed.
*/
virtual void destroySwapChain(SwapChain* swapChain) noexcept = 0;
virtual void destroySwapChain(SwapChain* UTILS_NONNULL swapChain) noexcept = 0;
/**
* Returns the set of buffers that must be preserved up to the call to commit().
@@ -106,28 +123,80 @@ public:
* @return buffer that must be preserved
* @see commit()
*/
virtual TargetBufferFlags getPreservedFlags(SwapChain* swapChain) noexcept;
virtual TargetBufferFlags getPreservedFlags(SwapChain* UTILS_NONNULL swapChain) noexcept;
/**
* Returns true if the swapchain is protected
*/
virtual bool isSwapChainProtected(Platform::SwapChain* UTILS_NONNULL swapChain) noexcept;
/**
* Called by the driver to establish the default FBO. The default implementation returns 0.
* @return a GLuint casted to a uint32_t that is an OpenGL framebuffer object.
*
* This method can be called either on the regular or protected OpenGL contexts and can return
* a different or identical name, since these names exist in different namespaces.
*
* @return a GLuint casted to a uint32_t that is an OpenGL framebuffer object.
*/
virtual uint32_t createDefaultRenderTarget() noexcept;
virtual uint32_t getDefaultFramebufferObject() noexcept;
/**
* Type of contexts available
*/
enum class ContextType {
NONE, //!< No current context
UNPROTECTED, //!< current context is unprotected
PROTECTED //!< current context supports protected content
};
/**
* Returns the type of the context currently in use. This value is updated by makeCurrent()
* and therefore can be cached between calls. ContextType::PROTECTED can only be returned
* if isProtectedContextSupported() is true.
* @return ContextType
*/
virtual ContextType getCurrentContextType() const noexcept;
/**
* Binds the requested context to the current thread and drawSwapChain to the default FBO
* returned by getDefaultFramebufferObject().
*
* @param type type of context to bind to the current thread.
* @param drawSwapChain SwapChain to draw to. It must be bound to the default FBO.
* @param readSwapChain SwapChain to read from (for operation like `glBlitFramebuffer`)
* @return true on success, false on error.
*/
virtual bool makeCurrent(ContextType type,
SwapChain* UTILS_NONNULL drawSwapChain,
SwapChain* UTILS_NONNULL readSwapChain) noexcept = 0;
/**
* Called by the driver to make the OpenGL context active on the calling thread and bind
* the drawSwapChain to the default render target (FBO) created with createDefaultRenderTarget.
* the drawSwapChain to the default FBO returned by getDefaultFramebufferObject().
* The context used is either the default context or the protected context. When a context
* change is necessary, the preContextChange and postContextChange callbacks are called,
* before and after the context change respectively. postContextChange is given the index
* of the new context (0 for default and 1 for protected).
* The default implementation just calls makeCurrent(getCurrentContextType(), SwapChain*, SwapChain*).
*
* @param drawSwapChain SwapChain to draw to. It must be bound to the default FBO.
* @param readSwapChain SwapChain to read from (for operation like `glBlitFramebuffer`)
* @param preContextChange called before the context changes
* @param postContextChange called after the context changes
*/
virtual void makeCurrent(SwapChain* drawSwapChain, SwapChain* readSwapChain) noexcept = 0;
virtual void makeCurrent(
SwapChain* UTILS_NONNULL drawSwapChain,
SwapChain* UTILS_NONNULL readSwapChain,
utils::Invocable<void()> preContextChange,
utils::Invocable<void(size_t index)> postContextChange) noexcept;
/**
* Called by the driver once the current frame finishes drawing. Typically, this should present
* the drawSwapChain. This is for example where `eglMakeCurrent()` would be called.
* @param swapChain the SwapChain to present.
*/
virtual void commit(SwapChain* swapChain) noexcept = 0;
virtual void commit(SwapChain* UTILS_NONNULL swapChain) noexcept = 0;
/**
* Set the time the next committed buffer should be presented to the user at.
@@ -152,14 +221,14 @@ public:
*
* @return A Fence object. The default implementation returns nullptr.
*/
virtual Fence* createFence() noexcept;
virtual Fence* UTILS_NULLABLE createFence() noexcept;
/**
* Destroys a Fence object. The default implementation does nothing.
*
* @param fence Fence to destroy.
*/
virtual void destroyFence(Fence* fence) noexcept;
virtual void destroyFence(Fence* UTILS_NONNULL fence) noexcept;
/**
* Waits on a Fence.
@@ -169,7 +238,7 @@ public:
* @return Whether the fence signaled or timed out. See backend::FenceStatus.
* The default implementation always return backend::FenceStatus::ERROR.
*/
virtual backend::FenceStatus waitFence(Fence* fence, uint64_t timeout) noexcept;
virtual backend::FenceStatus waitFence(Fence* UTILS_NONNULL fence, uint64_t timeout) noexcept;
// --------------------------------------------------------------------------------------------
@@ -183,13 +252,13 @@ public:
* @param nativeStream The native stream, this parameter depends on the concrete implementation.
* @return A new Stream object.
*/
virtual Stream* createStream(void* nativeStream) noexcept;
virtual Stream* UTILS_NULLABLE createStream(void* UTILS_NULLABLE nativeStream) noexcept;
/**
* Destroys a Stream.
* @param stream Stream to destroy.
*/
virtual void destroyStream(Stream* stream) noexcept;
virtual void destroyStream(Stream* UTILS_NONNULL stream) noexcept;
/**
* The specified stream takes ownership of the texture (tname) object
@@ -199,20 +268,21 @@ public:
* @param stream Stream to take ownership of the texture
* @param tname GL texture id to "bind" to the Stream.
*/
virtual void attach(Stream* stream, intptr_t tname) noexcept;
virtual void attach(Stream* UTILS_NONNULL stream, intptr_t tname) noexcept;
/**
* Destroys the texture associated to the stream
* @param stream Stream to detach from its texture
*/
virtual void detach(Stream* stream) noexcept;
virtual void detach(Stream* UTILS_NONNULL stream) noexcept;
/**
* Updates the content of the texture attached to the stream.
* @param stream Stream to update
* @param timestamp Output parameter: Timestamp of the image bound to the texture.
*/
virtual void updateTexImage(Stream* stream, int64_t* timestamp) noexcept;
virtual void updateTexImage(Stream* UTILS_NONNULL stream,
int64_t* UTILS_NONNULL timestamp) noexcept;
// --------------------------------------------------------------------------------------------
@@ -225,13 +295,13 @@ public:
* implementation could just return { 0, GL_TEXTURE_2D } at this point. The actual
* values can be delayed until setExternalImage.
*/
virtual ExternalTexture *createExternalImageTexture() noexcept;
virtual ExternalTexture* UTILS_NULLABLE createExternalImageTexture() noexcept;
/**
* Destroys an external texture handle and associated data.
* @param texture a pointer to the handle to destroy.
*/
virtual void destroyExternalImage(ExternalTexture* texture) noexcept;
virtual void destroyExternalImage(ExternalTexture* UTILS_NONNULL texture) noexcept;
// called on the application thread to allow Filament to take ownership of the image
@@ -244,7 +314,7 @@ public:
* @param externalImage A token representing the platform's external image.
* @see destroyExternalImage
*/
virtual void retainExternalImage(void* externalImage) noexcept;
virtual void retainExternalImage(void* UTILS_NONNULL externalImage) noexcept;
/**
* Called to bind the platform-specific externalImage to an ExternalTexture.
@@ -258,7 +328,8 @@ public:
* @param texture an in/out pointer to ExternalTexture, id and target can be updated if necessary.
* @return true on success, false on error.
*/
virtual bool setExternalImage(void* externalImage, ExternalTexture* texture) noexcept;
virtual bool setExternalImage(void* UTILS_NONNULL externalImage,
ExternalTexture* UTILS_NONNULL texture) noexcept;
/**
* The method allows platforms to convert a user-supplied external image object into a new type
@@ -17,11 +17,10 @@
#ifndef TNT_FILAMENT_BACKEND_OPENGL_OPENGL_PLATFORM_COCOA_GL_H
#define TNT_FILAMENT_BACKEND_OPENGL_OPENGL_PLATFORM_COCOA_GL_H
#include <stdint.h>
#include <backend/DriverEnums.h>
#include <backend/platforms/OpenGLPlatform.h>
#include <backend/DriverEnums.h>
#include <stdint.h>
namespace filament::backend {
@@ -58,7 +57,7 @@ protected:
SwapChain* createSwapChain(void* nativewindow, uint64_t flags) noexcept override;
SwapChain* createSwapChain(uint32_t width, uint32_t height, uint64_t flags) noexcept override;
void destroySwapChain(SwapChain* swapChain) noexcept override;
void makeCurrent(SwapChain* drawSwapChain, SwapChain* readSwapChain) noexcept override;
bool makeCurrent(ContextType type, SwapChain* drawSwapChain, SwapChain* readSwapChain) noexcept override;
void commit(SwapChain* swapChain) noexcept override;
OpenGLPlatform::ExternalTexture* createExternalImageTexture() noexcept override;
void destroyExternalImage(ExternalTexture* texture) noexcept override;
@@ -30,7 +30,7 @@ struct PlatformCocoaTouchGLImpl;
class PlatformCocoaTouchGL : public OpenGLPlatform {
public:
PlatformCocoaTouchGL();
~PlatformCocoaTouchGL() noexcept;
~PlatformCocoaTouchGL() noexcept override;
// --------------------------------------------------------------------------------------------
// Platform Interface
@@ -45,7 +45,7 @@ public:
void terminate() noexcept override;
uint32_t createDefaultRenderTarget() noexcept override;
uint32_t getDefaultFramebufferObject() noexcept override;
bool isExtraContextSupported() const noexcept override;
void createContext(bool shared) override;
@@ -53,7 +53,7 @@ public:
SwapChain* createSwapChain(void* nativewindow, uint64_t flags) noexcept override;
SwapChain* createSwapChain(uint32_t width, uint32_t height, uint64_t flags) noexcept override;
void destroySwapChain(SwapChain* swapChain) noexcept override;
void makeCurrent(SwapChain* drawSwapChain, SwapChain* readSwapChain) noexcept override;
bool makeCurrent(ContextType type, SwapChain* drawSwapChain, SwapChain* readSwapChain) noexcept override;
void commit(SwapChain* swapChain) noexcept override;
OpenGLPlatform::ExternalTexture* createExternalImageTexture() noexcept override;
@@ -17,18 +17,23 @@
#ifndef TNT_FILAMENT_BACKEND_OPENGL_OPENGL_PLATFORM_EGL_H
#define TNT_FILAMENT_BACKEND_OPENGL_OPENGL_PLATFORM_EGL_H
#include <stdint.h>
#include <backend/DriverEnums.h>
#include <backend/Platform.h>
#include <backend/platforms/OpenGLPlatform.h>
#include <EGL/egl.h>
#include <EGL/eglext.h>
#include <EGL/eglplatform.h>
#include <backend/platforms/OpenGLPlatform.h>
#include <backend/DriverEnums.h>
#include <utils/Invocable.h>
#include <initializer_list>
#include <utility>
#include <vector>
#include <stddef.h>
#include <stdint.h>
namespace filament::backend {
/**
@@ -38,15 +43,11 @@ class PlatformEGL : public OpenGLPlatform {
public:
PlatformEGL() noexcept;
bool isExtraContextSupported() const noexcept override;
void createContext(bool shared) override;
void releaseContext() noexcept override;
// Return true if we're on an OpenGL platform (as opposed to OpenGL ES). false by default.
virtual bool isOpenGL() const noexcept;
protected:
// --------------------------------------------------------------------------------------------
// Helper for EGL configs and attributes parameters
@@ -86,13 +87,30 @@ protected:
// --------------------------------------------------------------------------------------------
// OpenGLPlatform Interface
bool isExtraContextSupported() const noexcept override;
void createContext(bool shared) override;
void releaseContext() noexcept override;
void terminate() noexcept override;
bool isProtectedContextSupported() const noexcept override;
bool isSRGBSwapChainSupported() const noexcept override;
SwapChain* createSwapChain(void* nativewindow, uint64_t flags) noexcept override;
SwapChain* createSwapChain(uint32_t width, uint32_t height, uint64_t flags) noexcept override;
void destroySwapChain(SwapChain* swapChain) noexcept override;
void makeCurrent(SwapChain* drawSwapChain, SwapChain* readSwapChain) noexcept override;
bool isSwapChainProtected(SwapChain* swapChain) noexcept override;
ContextType getCurrentContextType() const noexcept override;
bool makeCurrent(ContextType type,
SwapChain* drawSwapChain,
SwapChain* readSwapChain) noexcept override;
void makeCurrent(SwapChain* drawSwapChain, SwapChain* readSwapChain,
utils::Invocable<void()> preContextChange,
utils::Invocable<void(size_t index)> postContextChange) noexcept override;
void commit(SwapChain* swapChain) noexcept override;
bool canCreateFence() noexcept override;
@@ -119,16 +137,27 @@ protected:
static void clearGlError() noexcept;
/**
* Always use this instead of eglMakeCurrent().
* Always use this instead of eglMakeCurrent(), as it tracks some state.
*/
EGLBoolean makeCurrent(EGLSurface drawSurface, EGLSurface readSurface) noexcept;
EGLContext getContextForType(ContextType type) const noexcept;
// makes the draw and read surface current without changing the current context
EGLBoolean makeCurrent(EGLSurface drawSurface, EGLSurface readSurface) noexcept {
return egl.makeCurrent(drawSurface, readSurface);
}
// makes context current and set draw and read surfaces to EGL_NO_SURFACE
EGLBoolean makeCurrent(EGLContext context) noexcept {
return egl.makeCurrent(context, mEGLDummySurface, mEGLDummySurface);
}
// TODO: this should probably use getters instead.
EGLDisplay mEGLDisplay = EGL_NO_DISPLAY;
EGLContext mEGLContext = EGL_NO_CONTEXT;
EGLSurface mCurrentDrawSurface = EGL_NO_SURFACE;
EGLSurface mCurrentReadSurface = EGL_NO_SURFACE;
EGLContext mEGLContextProtected = EGL_NO_CONTEXT;
EGLSurface mEGLDummySurface = EGL_NO_SURFACE;
ContextType mCurrentContextType = ContextType::NONE;
// mEGLConfig is valid only if ext.egl.KHR_no_config_context is false
EGLConfig mEGLConfig = EGL_NO_CONFIG_KHR;
Config mContextAttribs;
@@ -145,13 +174,38 @@ protected:
bool KHR_gl_colorspace = false;
bool KHR_no_config_context = false;
bool KHR_surfaceless_context = false;
bool EXT_protected_content = false;
} egl;
} ext;
struct SwapChainEGL : public Platform::SwapChain {
EGLSurface sur = EGL_NO_SURFACE;
Config attribs{};
EGLNativeWindowType nativeWindow{};
EGLConfig config{};
uint64_t flags{};
};
void initializeGlExtensions() noexcept;
protected:
EGLConfig findSwapChainConfig(uint64_t flags, bool window, bool pbuffer) const;
private:
class EGL {
EGLDisplay& mEGLDisplay;
EGLSurface mCurrentDrawSurface = EGL_NO_SURFACE;
EGLSurface mCurrentReadSurface = EGL_NO_SURFACE;
EGLContext mCurrentContext = EGL_NO_CONTEXT;
public:
explicit EGL(EGLDisplay& dpy) : mEGLDisplay(dpy) {}
EGLBoolean makeCurrent(EGLContext context,
EGLSurface drawSurface, EGLSurface readSurface) noexcept;
EGLBoolean makeCurrent(EGLSurface drawSurface, EGLSurface readSurface) noexcept {
return makeCurrent(mCurrentContext, drawSurface, readSurface);
}
} egl{ mEGLDisplay };
};
} // namespace filament::backend
@@ -17,8 +17,14 @@
#ifndef TNT_FILAMENT_BACKEND_OPENGL_OPENGL_PLATFORM_EGL_ANDROID_H
#define TNT_FILAMENT_BACKEND_OPENGL_OPENGL_PLATFORM_EGL_ANDROID_H
#include <backend/AcquiredImage.h>
#include <backend/Platform.h>
#include <backend/platforms/OpenGLPlatform.h>
#include <backend/platforms/PlatformEGL.h>
#include <stddef.h>
#include <stdint.h>
namespace filament::backend {
class ExternalStreamManagerAndroid;
@@ -51,7 +51,7 @@ protected:
SwapChain* createSwapChain(void* nativewindow, uint64_t flags) noexcept override;
SwapChain* createSwapChain(uint32_t width, uint32_t height, uint64_t flags) noexcept override;
void destroySwapChain(SwapChain* swapChain) noexcept override;
void makeCurrent(SwapChain* drawSwapChain, SwapChain* readSwapChain) noexcept override;
bool makeCurrent(ContextType type, SwapChain* drawSwapChain, SwapChain* readSwapChain) noexcept override;
void commit(SwapChain* swapChain) noexcept override;
private:
@@ -53,7 +53,7 @@ protected:
SwapChain* createSwapChain(void* nativewindow, uint64_t flags) noexcept override;
SwapChain* createSwapChain(uint32_t width, uint32_t height, uint64_t flags) noexcept override;
void destroySwapChain(SwapChain* swapChain) noexcept override;
void makeCurrent(SwapChain* drawSwapChain, SwapChain* readSwapChain) noexcept override;
bool makeCurrent(ContextType type, SwapChain* drawSwapChain, SwapChain* readSwapChain) noexcept override;
void commit(SwapChain* swapChain) noexcept override;
protected:
@@ -46,7 +46,7 @@ protected:
SwapChain* createSwapChain(void* nativewindow, uint64_t flags) noexcept override;
SwapChain* createSwapChain(uint32_t width, uint32_t height, uint64_t flags) noexcept override;
void destroySwapChain(SwapChain* swapChain) noexcept override;
void makeCurrent(SwapChain* drawSwapChain, SwapChain* readSwapChain) noexcept override;
bool makeCurrent(ContextType type, SwapChain* drawSwapChain, SwapChain* readSwapChain) noexcept override;
void commit(SwapChain* swapChain) noexcept override;
};
@@ -20,13 +20,18 @@
#include <backend/Platform.h>
#include <bluevk/BlueVK.h>
#include <utils/CString.h>
#include <utils/FixedCapacityVector.h>
#include <utils/PrivateImplementation.h>
#include <string_view>
#include <tuple>
#include <unordered_set>
#include <stddef.h>
#include <stdint.h>
namespace filament::backend {
using SwapChain = Platform::SwapChain;
@@ -17,7 +17,7 @@
#ifndef TNT_FILAMENT_BACKEND_PRIVATE_CIRCULARBUFFER_H
#define TNT_FILAMENT_BACKEND_PRIVATE_CIRCULARBUFFER_H
#include <utils/compiler.h>
#include <utils/debug.h>
#include <stddef.h>
#include <stdint.h>
@@ -40,28 +40,36 @@ public:
~CircularBuffer() noexcept;
// allocates 'size' bytes in the circular buffer and returns a pointer to the memory
// return the current head and moves it forward by size bytes
inline void* allocate(size_t size) noexcept {
static size_t getBlockSize() noexcept { return sPageSize; }
// Total size of circular buffer. This is a constant.
size_t size() const noexcept { return mSize; }
// Allocates `s` bytes in the circular buffer and returns a pointer to the memory. All
// allocations must not exceed size() bytes.
inline void* allocate(size_t s) noexcept {
// We can never allocate more that size().
assert_invariant(getUsed() + s <= size());
char* const cur = static_cast<char*>(mHead);
mHead = cur + size;
mHead = cur + s;
return cur;
}
// Total size of circular buffer
size_t size() const noexcept { return mSize; }
// returns true if the buffer is empty (e.g. after calling flush)
// Returns true if the buffer is empty, i.e.: no allocations were made since
// calling getBuffer();
bool empty() const noexcept { return mTail == mHead; }
void* getHead() const noexcept { return mHead; }
// Returns the size used since the last call to getBuffer()
size_t getUsed() const noexcept { return intptr_t(mHead) - intptr_t(mTail); }
void* getTail() const noexcept { return mTail; }
// call at least once every getRequiredSize() bytes allocated from the buffer
void circularize() noexcept;
static size_t getBlockSize() noexcept { return sPageSize; }
// Retrieves the current allocated range and frees it. It is the responsibility of the caller
// to make sure the returned range is no longer in use by the time allocate() allocates
// (size() - getUsed()) bytes.
struct Range {
void* tail;
void* head;
};
Range getBuffer() noexcept;
private:
void* alloc(size_t size) noexcept;
@@ -69,10 +77,10 @@ private:
// pointer to the beginning of the circular buffer (constant)
void* mData = nullptr;
int mUsesAshmem = -1;
int mAshmemFd = -1;
// size of the circular buffer (constant)
size_t mSize = 0;
size_t const mSize;
// pointer to the beginning of recorded data
void* mTail = nullptr;
@@ -19,19 +19,21 @@
#include "private/backend/CircularBuffer.h"
#include <utils/compiler.h>
#include <utils/Condition.h>
#include <utils/Mutex.h>
#include <vector>
#include <stddef.h>
#include <stdint.h>
namespace filament::backend {
/*
* A producer-consumer command queue that uses a CircularBuffer as main storage
*/
class CommandBufferQueue {
struct Slice {
struct Range {
void* begin;
void* end;
};
@@ -44,29 +46,33 @@ class CommandBufferQueue {
mutable utils::Mutex mLock;
mutable utils::Condition mCondition;
mutable std::vector<Slice> mCommandBuffersToExecute;
mutable std::vector<Range> mCommandBuffersToExecute;
size_t mFreeSpace = 0;
size_t mHighWatermark = 0;
uint32_t mExitRequested = 0;
bool mPaused = false;
static constexpr uint32_t EXIT_REQUESTED = 0x31415926;
public:
// requiredSize: guaranteed available space after flush()
CommandBufferQueue(size_t requiredSize, size_t bufferSize);
CommandBufferQueue(size_t requiredSize, size_t bufferSize, bool paused);
~CommandBufferQueue();
CircularBuffer& getCircularBuffer() { return mCircularBuffer; }
CircularBuffer& getCircularBuffer() noexcept { return mCircularBuffer; }
CircularBuffer const& getCircularBuffer() const noexcept { return mCircularBuffer; }
size_t getCapacity() const noexcept { return mRequiredSize; }
size_t getHighWatermark() const noexcept { return mHighWatermark; }
// wait for commands to be available and returns an array containing these commands
std::vector<Slice> waitForCommands() const;
std::vector<Range> waitForCommands() const;
// return the memory used by this command buffer to the circular buffer
// WARNING: releaseBuffer() must be called in sequence of the Slices returned by
// waitForCommands()
void releaseBuffer(Slice const& buffer);
void releaseBuffer(Range const& buffer);
// all commands buffers (Slices) written to this point are returned by waitForCommand(). This
// call blocks until the CircularBuffer has at least mRequiredSize bytes available.
@@ -75,6 +81,9 @@ public:
// returns from waitForCommands() immediately.
void requestExit();
// suspend or unsuspend the queue.
void setPaused(bool paused);
bool isExitRequested() const;
};
@@ -32,11 +32,13 @@
#include <backend/TargetBufferInfo.h>
#include <utils/compiler.h>
#include <utils/debug.h>
#include <utils/ThreadUtils.h>
#include <cstddef>
#include <functional>
#include <tuple>
#include <type_traits>
#include <utility>
#ifndef NDEBUG
@@ -132,7 +134,7 @@ struct CommandType<void (Driver::*)(ARGS...)> {
public:
template<typename M, typename D>
static inline void execute(M&& method, D&& driver, CommandBase* base, intptr_t* next) noexcept {
static inline void execute(M&& method, D&& driver, CommandBase* base, intptr_t* next) {
Command* self = static_cast<Command*>(base);
*next = align(sizeof(Command));
#if DEBUG_COMMAND_STREAM
@@ -152,21 +154,21 @@ struct CommandType<void (Driver::*)(ARGS...)> {
}
// placement new declared as "throw" to avoid the compiler's null-check
inline void* operator new(std::size_t size, void* ptr) {
inline void* operator new(std::size_t, void* ptr) {
assert_invariant(ptr);
return ptr;
}
};
};
// convert an method of "class Driver" into a Command<> type
// convert a method of "class Driver" into a Command<> type
#define COMMAND_TYPE(method) CommandType<decltype(&Driver::method)>::Command<&Driver::method>
// ------------------------------------------------------------------------------------------------
class CustomCommand : public CommandBase {
std::function<void()> mCommand;
static void execute(Driver&, CommandBase* base, intptr_t* next) noexcept;
static void execute(Driver&, CommandBase* base, intptr_t* next);
public:
inline CustomCommand(CustomCommand&& rhs) = default;
inline explicit CustomCommand(std::function<void()> cmd)
@@ -211,6 +213,8 @@ public:
CommandStream(CommandStream const& rhs) noexcept = delete;
CommandStream& operator=(CommandStream const& rhs) noexcept = delete;
CircularBuffer const& getCircularBuffer() const noexcept { return mCurrentBuffer; }
public:
#define DECL_DRIVER_API(methodName, paramsDecl, params) \
inline void methodName(paramsDecl) { \
@@ -29,6 +29,7 @@
#include <functional>
#include <stddef.h>
#include <stdint.h>
// Command debugging off. debugging virtuals are not called.
@@ -75,7 +76,7 @@ public:
// the fn function will execute a batch of driver commands
// this gives the driver a chance to wrap their execution in a meaningful manner
// the default implementation simply calls fn
virtual void execute(std::function<void(void)> const& fn) noexcept;
virtual void execute(std::function<void(void)> const& fn);
// This is called on debug build, or when enabled manually on the backend thread side.
virtual void debugCommandBegin(CommandStream* cmds,
@@ -167,12 +167,15 @@ DECL_DRIVER_API_0(resetState)
* -----------------------
*/
DECL_DRIVER_API_R_N(backend::VertexBufferHandle, createVertexBuffer,
DECL_DRIVER_API_R_N(backend::VertexBufferInfoHandle, createVertexBufferInfo,
uint8_t, bufferCount,
uint8_t, attributeCount,
uint32_t, vertexCount,
backend::AttributeArray, attributes)
DECL_DRIVER_API_R_N(backend::VertexBufferHandle, createVertexBuffer,
uint32_t, vertexCount,
backend::VertexBufferInfoHandle, vbih)
DECL_DRIVER_API_R_N(backend::IndexBufferHandle, createIndexBuffer,
backend::ElementType, elementType,
uint32_t, indexCount,
@@ -224,11 +227,7 @@ DECL_DRIVER_API_R_N(backend::SamplerGroupHandle, createSamplerGroup,
DECL_DRIVER_API_R_N(backend::RenderPrimitiveHandle, createRenderPrimitive,
backend::VertexBufferHandle, vbh,
backend::IndexBufferHandle, ibh,
backend::PrimitiveType, pt,
uint32_t, offset,
uint32_t, minIndex,
uint32_t, maxIndex,
uint32_t, count)
backend::PrimitiveType, pt)
DECL_DRIVER_API_R_N(backend::ProgramHandle, createProgram,
backend::Program&&, program)
@@ -240,6 +239,7 @@ DECL_DRIVER_API_R_N(backend::RenderTargetHandle, createRenderTarget,
uint32_t, width,
uint32_t, height,
uint8_t, samples,
uint8_t, layerCount,
backend::MRT, color,
backend::TargetBufferInfo, depth,
backend::TargetBufferInfo, stencil)
@@ -264,6 +264,7 @@ DECL_DRIVER_API_R_0(backend::TimerQueryHandle, createTimerQuery)
*/
DECL_DRIVER_API_N(destroyVertexBuffer, backend::VertexBufferHandle, vbh)
DECL_DRIVER_API_N(destroyVertexBufferInfo,backend::VertexBufferInfoHandle, vbih)
DECL_DRIVER_API_N(destroyIndexBuffer, backend::IndexBufferHandle, ibh)
DECL_DRIVER_API_N(destroyBufferObject, backend::BufferObjectHandle, ibh)
DECL_DRIVER_API_N(destroyRenderPrimitive, backend::RenderPrimitiveHandle, rph)
@@ -298,14 +299,16 @@ DECL_DRIVER_API_SYNCHRONOUS_0(bool, isFrameBufferFetchMultiSampleSupported)
DECL_DRIVER_API_SYNCHRONOUS_0(bool, isFrameTimeSupported)
DECL_DRIVER_API_SYNCHRONOUS_0(bool, isAutoDepthResolveSupported)
DECL_DRIVER_API_SYNCHRONOUS_0(bool, isSRGBSwapChainSupported)
DECL_DRIVER_API_SYNCHRONOUS_0(bool, isStereoSupported)
DECL_DRIVER_API_SYNCHRONOUS_0(bool, isProtectedContentSupported)
DECL_DRIVER_API_SYNCHRONOUS_N(bool, isStereoSupported, backend::StereoscopicType, stereoscopicType)
DECL_DRIVER_API_SYNCHRONOUS_0(bool, isParallelShaderCompileSupported)
DECL_DRIVER_API_SYNCHRONOUS_0(bool, isDepthStencilResolveSupported)
DECL_DRIVER_API_SYNCHRONOUS_0(bool, isProtectedTexturesSupported)
DECL_DRIVER_API_SYNCHRONOUS_0(uint8_t, getMaxDrawBuffers)
DECL_DRIVER_API_SYNCHRONOUS_0(size_t, getMaxUniformBufferSize)
DECL_DRIVER_API_SYNCHRONOUS_0(math::float2, getClipSpaceParams)
DECL_DRIVER_API_SYNCHRONOUS_N(void, setupExternalImage, void*, image)
DECL_DRIVER_API_SYNCHRONOUS_N(bool, getTimerQueryValue, backend::TimerQueryHandle, query, uint64_t*, elapsedTime)
DECL_DRIVER_API_SYNCHRONOUS_N(backend::TimerQueryResult, getTimerQueryValue, backend::TimerQueryHandle, query, uint64_t*, elapsedTime)
DECL_DRIVER_API_SYNCHRONOUS_N(bool, isWorkaroundNeeded, backend::Workaround, workaround)
DECL_DRIVER_API_SYNCHRONOUS_0(backend::FeatureLevel, getFeatureLevel)
@@ -491,15 +494,32 @@ DECL_DRIVER_API_N(blit,
math::uint2, srcOrigin,
math::uint2, size)
DECL_DRIVER_API_N(bindPipeline,
backend::PipelineState, state)
DECL_DRIVER_API_N(bindRenderPrimitive,
backend::RenderPrimitiveHandle, rph)
DECL_DRIVER_API_N(draw2,
uint32_t, indexOffset,
uint32_t, indexCount,
uint32_t, instanceCount)
DECL_DRIVER_API_N(draw,
backend::PipelineState, state,
backend::RenderPrimitiveHandle, rph,
uint32_t, indexOffset,
uint32_t, indexCount,
uint32_t, instanceCount)
DECL_DRIVER_API_N(dispatchCompute,
backend::ProgramHandle, program,
math::uint3, workGroupCount)
DECL_DRIVER_API_N(scissor,
Viewport, scissor)
#pragma clang diagnostic pop
@@ -22,29 +22,34 @@
#include <utils/Allocator.h>
#include <utils/Log.h>
#include <utils/compiler.h>
#include <utils/debug.h>
#include <utils/ostream.h>
#include <utils/Panic.h>
#include <tsl/robin_map.h>
#include <cstddef>
#include <exception>
#include <type_traits>
#include <unordered_map>
#include <utility>
#if !defined(NDEBUG) && UTILS_HAS_RTTI
# define HANDLE_TYPE_SAFETY 1
#else
# define HANDLE_TYPE_SAFETY 0
#endif
#include <stddef.h>
#include <stdint.h>
#define HandleAllocatorGL HandleAllocator<16, 64, 208>
#define HandleAllocatorVK HandleAllocator<16, 64, 880>
#define HandleAllocatorMTL HandleAllocator<16, 64, 584>
#define HandleAllocatorGL HandleAllocator<32, 64, 136> // ~4520 / pool / MiB
#define HandleAllocatorVK HandleAllocator<64, 160, 312> // ~1820 / pool / MiB
#define HandleAllocatorMTL HandleAllocator<32, 48, 552> // ~1660 / pool / MiB
namespace filament::backend {
/*
* A utility class to efficiently allocate and manage Handle<>
*/
template <size_t P0, size_t P1, size_t P2>
template<size_t P0, size_t P1, size_t P2>
class HandleAllocator {
public:
HandleAllocator(const char* name, size_t size) noexcept;
HandleAllocator(const char* name, size_t size, bool disableUseAfterFreeCheck) noexcept;
HandleAllocator(HandleAllocator const& rhs) = delete;
HandleAllocator& operator=(HandleAllocator const& rhs) = delete;
~HandleAllocator();
@@ -60,15 +65,10 @@ public:
*
*/
template<typename D, typename ... ARGS>
Handle<D> allocateAndConstruct(ARGS&& ... args) noexcept {
Handle<D> h{ allocateHandle<sizeof(D)>() };
Handle<D> allocateAndConstruct(ARGS&& ... args) {
Handle<D> h{ allocateHandle<D>() };
D* addr = handle_cast<D*>(h);
new(addr) D(std::forward<ARGS>(args)...);
#if HANDLE_TYPE_SAFETY
mLock.lock();
mHandleTypeId[addr] = typeid(D).name();
mLock.unlock();
#endif
return h;
}
@@ -84,13 +84,7 @@ public:
*/
template<typename D>
Handle<D> allocate() noexcept {
Handle<D> h{ allocateHandle<sizeof(D)>() };
#if HANDLE_TYPE_SAFETY
D* addr = handle_cast<D*>(h);
mLock.lock();
mHandleTypeId[addr] = typeid(D).name();
mLock.unlock();
#endif
Handle<D> h{ allocateHandle<D>() };
return h;
}
@@ -103,21 +97,14 @@ public:
*/
template<typename D, typename B, typename ... ARGS>
typename std::enable_if_t<std::is_base_of_v<B, D>, D>*
destroyAndConstruct(Handle<B> const& handle, ARGS&& ... args) noexcept {
destroyAndConstruct(Handle<B> const& handle, ARGS&& ... args) {
assert_invariant(handle);
D* addr = handle_cast<D*>(const_cast<Handle<B>&>(handle));
assert_invariant(addr);
// currently we implement construct<> with dtor+ctor, we could use operator= also
// but all our dtors are trivial, ~D() is actually a noop.
addr->~D();
new(addr) D(std::forward<ARGS>(args)...);
#if HANDLE_TYPE_SAFETY
mLock.lock();
mHandleTypeId[addr] = typeid(D).name();
mLock.unlock();
#endif
return addr;
}
@@ -134,12 +121,6 @@ public:
D* addr = handle_cast<D*>(const_cast<Handle<B>&>(handle));
assert_invariant(addr);
new(addr) D(std::forward<ARGS>(args)...);
#if HANDLE_TYPE_SAFETY
mLock.lock();
mHandleTypeId[addr] = typeid(D).name();
mLock.unlock();
#endif
return addr;
}
@@ -155,19 +136,8 @@ public:
void deallocate(Handle<B>& handle, D const* p) noexcept {
// allow to destroy the nullptr, similarly to operator delete
if (p) {
#if HANDLE_TYPE_SAFETY
mLock.lock();
auto typeId = mHandleTypeId[p];
mHandleTypeId.erase(p);
mLock.unlock();
if (UTILS_UNLIKELY(typeId != typeid(D).name())) {
utils::slog.e << "Destroying handle " << handle.getId() << ", type " << typeid(D).name()
<< ", but handle's actual type is " << typeId << utils::io::endl;
std::terminate();
}
#endif
p->~D();
deallocateHandle<sizeof(D)>(handle.getId());
deallocateHandle<D>(handle.getId());
}
}
@@ -193,9 +163,21 @@ public:
inline typename std::enable_if_t<
std::is_pointer_v<Dp> &&
std::is_base_of_v<B, typename std::remove_pointer_t<Dp>>, Dp>
handle_cast(Handle<B>& handle) noexcept {
handle_cast(Handle<B>& handle) {
assert_invariant(handle);
void* const p = handleToPointer(handle.getId());
auto [p, tag] = handleToPointer(handle.getId());
if (isPoolHandle(handle.getId())) {
// check for use after free
if (UTILS_UNLIKELY(!mUseAfterFreeCheckDisabled)) {
uint8_t const age = (tag & HANDLE_AGE_MASK) >> HANDLE_AGE_SHIFT;
auto const pNode = static_cast<typename Allocator::Node*>(p);
uint8_t const expectedAge = pNode[-1].age;
ASSERT_POSTCONDITION(expectedAge == age,
"use-after-free of Handle with id=%d", handle.getId());
}
}
return static_cast<Dp>(p);
}
@@ -203,36 +185,66 @@ public:
inline typename std::enable_if_t<
std::is_pointer_v<Dp> &&
std::is_base_of_v<B, typename std::remove_pointer_t<Dp>>, Dp>
handle_cast(Handle<B> const& handle) noexcept {
handle_cast(Handle<B> const& handle) {
return handle_cast<Dp>(const_cast<Handle<B>&>(handle));
}
private:
// template <int P0, int P1, int P2>
template<typename D>
static constexpr size_t getBucketSize() noexcept {
if constexpr (sizeof(D) <= P0) { return P0; }
if constexpr (sizeof(D) <= P1) { return P1; }
static_assert(sizeof(D) <= P2);
return P2;
}
class Allocator {
friend class HandleAllocator;
utils::PoolAllocator<P0, 16> mPool0;
utils::PoolAllocator<P1, 16> mPool1;
utils::PoolAllocator<P2, 16> mPool2;
static constexpr size_t MIN_ALIGNMENT = alignof(std::max_align_t);
struct Node { uint8_t age; };
// Note: using the `extra` parameter of PoolAllocator<>, even with a 1-byte structure,
// generally increases all pool allocations by 8-bytes because of alignment restrictions.
template<size_t SIZE>
using Pool = utils::PoolAllocator<SIZE, MIN_ALIGNMENT, sizeof(Node)>;
Pool<P0> mPool0;
Pool<P1> mPool1;
Pool<P2> mPool2;
UTILS_UNUSED_IN_RELEASE const utils::AreaPolicy::HeapArea& mArea;
bool mUseAfterFreeCheckDisabled;
public:
static constexpr size_t MIN_ALIGNMENT_SHIFT = 4;
explicit Allocator(const utils::AreaPolicy::HeapArea& area);
explicit Allocator(const utils::AreaPolicy::HeapArea& area, bool disableUseAfterFreeCheck);
static constexpr size_t getAlignment() noexcept { return MIN_ALIGNMENT; }
// this is in fact always called with a constexpr size argument
[[nodiscard]] inline void* alloc(size_t size, size_t alignment, size_t extra) noexcept {
[[nodiscard]] inline void* alloc(size_t size, size_t, size_t, uint8_t* outAge) noexcept {
void* p = nullptr;
if (size <= mPool0.getSize()) p = mPool0.alloc(size, 16, extra);
else if (size <= mPool1.getSize()) p = mPool1.alloc(size, 16, extra);
else if (size <= mPool2.getSize()) p = mPool2.alloc(size, 16, extra);
if (size <= mPool0.getSize()) p = mPool0.alloc(size);
else if (size <= mPool1.getSize()) p = mPool1.alloc(size);
else if (size <= mPool2.getSize()) p = mPool2.alloc(size);
if (UTILS_LIKELY(p)) {
Node const* const pNode = static_cast<Node const*>(p);
// we are guaranteed to have at least sizeof<Node> bytes of extra storage before
// the allocation address.
*outAge = pNode[-1].age;
}
return p;
}
// this is in fact always called with a constexpr size argument
inline void free(void* p, size_t size) noexcept {
inline void free(void* p, size_t size, uint8_t age) noexcept {
assert_invariant(p >= mArea.begin() && (char*)p + size <= (char*)mArea.end());
// check for double-free
Node* const pNode = static_cast<Node*>(p);
uint8_t& expectedAge = pNode[-1].age;
if (UTILS_UNLIKELY(!mUseAfterFreeCheckDisabled)) {
ASSERT_POSTCONDITION(expectedAge == age,
"double-free of Handle of size %d at %p", size, p);
}
expectedAge = (expectedAge + 1) & 0xF; // fixme
if (size <= mPool0.getSize()) { mPool0.free(p); return; }
if (size <= mPool1.getSize()) { mPool1.free(p); return; }
if (size <= mPool2.getSize()) { mPool2.free(p); return; }
@@ -254,24 +266,16 @@ private:
// allocateHandle()/deallocateHandle() selects the pool to use at compile-time based on the
// allocation size this is always inlined, because all these do is to call
// allocateHandleInPool()/deallocateHandleFromPool() with the right pool size.
template<size_t SIZE>
template<typename D>
HandleBase::HandleId allocateHandle() noexcept {
if constexpr (SIZE <= P0) { return allocateHandleInPool<P0>(); }
if constexpr (SIZE <= P1) { return allocateHandleInPool<P1>(); }
static_assert(SIZE <= P2);
return allocateHandleInPool<P2>();
constexpr size_t BUCKET_SIZE = getBucketSize<D>();
return allocateHandleInPool<BUCKET_SIZE>();
}
template<size_t SIZE>
template<typename D>
void deallocateHandle(HandleBase::HandleId id) noexcept {
if constexpr (SIZE <= P0) {
deallocateHandleFromPool<P0>(id);
} else if constexpr (SIZE <= P1) {
deallocateHandleFromPool<P1>(id);
} else {
static_assert(SIZE <= P2);
deallocateHandleFromPool<P2>(id);
}
constexpr size_t BUCKET_SIZE = getBucketSize<D>();
deallocateHandleFromPool<BUCKET_SIZE>(id);
}
// allocateHandleInPool()/deallocateHandleFromPool() is NOT inlined, which will cause three
@@ -280,9 +284,11 @@ private:
template<size_t SIZE>
UTILS_NOINLINE
HandleBase::HandleId allocateHandleInPool() noexcept {
void* p = mHandleArena.alloc(SIZE);
uint8_t age;
void* p = mHandleArena.alloc(SIZE, alignof(std::max_align_t), 0, &age);
if (UTILS_LIKELY(p)) {
return pointerToHandle(p);
uint32_t const tag = (uint32_t(age) << HANDLE_AGE_SHIFT) & HANDLE_AGE_MASK;
return arenaPointerToHandle(p, tag);
} else {
return allocateHandleSlow(SIZE);
}
@@ -292,42 +298,51 @@ private:
UTILS_NOINLINE
void deallocateHandleFromPool(HandleBase::HandleId id) noexcept {
if (UTILS_LIKELY(isPoolHandle(id))) {
void* p = handleToPointer(id);
mHandleArena.free(p, SIZE);
auto [p, tag] = handleToPointer(id);
uint8_t const age = (tag & HANDLE_AGE_MASK) >> HANDLE_AGE_SHIFT;
mHandleArena.free(p, SIZE, age);
} else {
deallocateHandleSlow(id, SIZE);
}
}
static constexpr uint32_t HEAP_HANDLE_FLAG = 0x80000000u;
// we handle a 4 bits age per address
static constexpr uint32_t HANDLE_HEAP_FLAG = 0x80000000u; // pool vs heap handle
static constexpr uint32_t HANDLE_AGE_MASK = 0x78000000u; // handle's age
static constexpr uint32_t HANDLE_INDEX_MASK = 0x07FFFFFFu; // handle index
static constexpr uint32_t HANDLE_TAG_MASK = HANDLE_AGE_MASK;
static constexpr uint32_t HANDLE_AGE_SHIFT = 27;
static bool isPoolHandle(HandleBase::HandleId id) noexcept {
return (id & HEAP_HANDLE_FLAG) == 0u;
return (id & HANDLE_HEAP_FLAG) == 0u;
}
HandleBase::HandleId allocateHandleSlow(size_t size) noexcept;
HandleBase::HandleId allocateHandleSlow(size_t size);
void deallocateHandleSlow(HandleBase::HandleId id, size_t size) noexcept;
// We inline this because it's just 4 instructions in the fast case
inline void* handleToPointer(HandleBase::HandleId id) const noexcept {
inline std::pair<void*, uint32_t> handleToPointer(HandleBase::HandleId id) const noexcept {
// note: the null handle will end-up returning nullptr b/c it'll be handled as
// a non-pool handle.
if (UTILS_LIKELY(isPoolHandle(id))) {
char* const base = (char*)mHandleArena.getArea().begin();
size_t offset = id << Allocator::MIN_ALIGNMENT_SHIFT;
return static_cast<void*>(base + offset);
uint32_t const tag = id & HANDLE_TAG_MASK;
size_t const offset = (id & HANDLE_INDEX_MASK) * Allocator::getAlignment();
return { static_cast<void*>(base + offset), tag };
}
return handleToPointerSlow(id);
return { handleToPointerSlow(id), 0 };
}
void* handleToPointerSlow(HandleBase::HandleId id) const noexcept;
// We inline this because it's just 3 instructions
inline HandleBase::HandleId pointerToHandle(void* p) const noexcept {
inline HandleBase::HandleId arenaPointerToHandle(void* p, uint32_t tag) const noexcept {
char* const base = (char*)mHandleArena.getArea().begin();
size_t offset = (char*)p - base;
auto id = HandleBase::HandleId(offset >> Allocator::MIN_ALIGNMENT_SHIFT);
assert_invariant((id & HEAP_HANDLE_FLAG) == 0);
size_t const offset = (char*)p - base;
assert_invariant((offset % Allocator::getAlignment()) == 0);
auto id = HandleBase::HandleId(offset / Allocator::getAlignment());
id |= tag & HANDLE_TAG_MASK;
assert_invariant((id & HANDLE_HEAP_FLAG) == 0);
return id;
}
@@ -337,9 +352,7 @@ private:
mutable utils::Mutex mLock;
tsl::robin_map<HandleBase::HandleId, void*> mOverflowMap;
HandleBase::HandleId mId = 0;
#if HANDLE_TYPE_SAFETY
mutable std::unordered_map<const void*, const char*> mHandleTypeId;
#endif
bool mUseAfterFreeCheckDisabled = false;
};
} // namespace filament::backend
@@ -19,9 +19,9 @@
#ifndef TNT_FILAMENT_BACKEND_PLATFORM_FACTORY_H
#define TNT_FILAMENT_BACKEND_PLATFORM_FACTORY_H
#include "backend/DriverEnums.h"
#include <backend/DriverEnums.h>
#include "utils/compiler.h"
#include <utils/compiler.h>
namespace filament::backend {
@@ -17,15 +17,13 @@
#ifndef TNT_FILAMENT_BACKEND_PRIVATE_SAMPLERGROUP_H
#define TNT_FILAMENT_BACKEND_PRIVATE_SAMPLERGROUP_H
#include "backend/DriverApiForward.h"
#include <utils/compiler.h>
#include <utils/FixedCapacityVector.h>
#include <backend/DriverApiForward.h>
#include <backend/DriverEnums.h>
#include <backend/Handle.h>
#include <backend/SamplerDescriptor.h>
#include <utils/FixedCapacityVector.h>
#include <utils/ostream.h>
#include <stddef.h>
namespace filament::backend {
+45 -26
View File
@@ -16,6 +16,14 @@
#include "private/backend/CircularBuffer.h"
#include <utils/Log.h>
#include <utils/Panic.h>
#include <utils/architecture.h>
#include <utils/ashmem.h>
#include <utils/compiler.h>
#include <utils/debug.h>
#include <utils/ostream.h>
#if !defined(WIN32) && !defined(__EMSCRIPTEN__) && !defined(IOS)
# include <sys/mman.h>
# include <unistd.h>
@@ -24,23 +32,20 @@
# define HAS_MMAP 0
#endif
#include <stdint.h>
#include <stddef.h>
#include <stdlib.h>
#include <stdio.h>
#include <utils/architecture.h>
#include <utils/ashmem.h>
#include <utils/debug.h>
#include <utils/Log.h>
#include <utils/Panic.h>
using namespace utils;
namespace filament::backend {
size_t CircularBuffer::sPageSize = arch::getPageSize();
CircularBuffer::CircularBuffer(size_t size) {
CircularBuffer::CircularBuffer(size_t size)
: mSize(size) {
mData = alloc(size);
mSize = size;
mTail = mData;
mHead = mData;
}
@@ -85,7 +90,7 @@ void* CircularBuffer::alloc(size_t size) noexcept {
MAP_PRIVATE, fd, (off_t)size);
if (vaddr_guard != MAP_FAILED && (vaddr_guard == (char*)vaddr_shadow + size)) {
// woo-hoo success!
mUsesAshmem = fd;
mAshmemFd = fd;
data = vaddr;
}
}
@@ -93,7 +98,7 @@ void* CircularBuffer::alloc(size_t size) noexcept {
}
}
if (UTILS_UNLIKELY(mUsesAshmem < 0)) {
if (UTILS_UNLIKELY(mAshmemFd < 0)) {
// ashmem failed
if (vaddr_guard != MAP_FAILED) {
munmap(vaddr_guard, size);
@@ -137,9 +142,9 @@ void CircularBuffer::dealloc() noexcept {
if (mData) {
size_t const BLOCK_SIZE = getBlockSize();
munmap(mData, mSize * 2 + BLOCK_SIZE);
if (mUsesAshmem >= 0) {
close(mUsesAshmem);
mUsesAshmem = -1;
if (mAshmemFd >= 0) {
close(mAshmemFd);
mAshmemFd = -1;
}
}
#else
@@ -149,23 +154,37 @@ void CircularBuffer::dealloc() noexcept {
}
void CircularBuffer::circularize() noexcept {
if (mUsesAshmem > 0) {
intptr_t const overflow = intptr_t(mHead) - (intptr_t(mData) + ssize_t(mSize));
if (overflow >= 0) {
assert_invariant(size_t(overflow) <= mSize);
mHead = (void *) (intptr_t(mData) + overflow);
#ifndef NDEBUG
memset(mData, 0xA5, size_t(overflow));
#endif
}
} else {
// Only circularize if mHead if in the second buffer.
if (intptr_t(mHead) - intptr_t(mData) > ssize_t(mSize)) {
CircularBuffer::Range CircularBuffer::getBuffer() noexcept {
Range const range{ .tail = mTail, .head = mHead };
char* const pData = static_cast<char*>(mData);
char const* const pEnd = pData + mSize;
char const* const pHead = static_cast<char const*>(mHead);
if (UTILS_UNLIKELY(pHead >= pEnd)) {
size_t const overflow = pHead - pEnd;
if (UTILS_LIKELY(mAshmemFd > 0)) {
assert_invariant(overflow <= mSize);
mHead = static_cast<void*>(pData + overflow);
// Data Tail End Head [virtual]
// v v v v
// +-------------:----+-----:--------------+
// | : | : |
// +-----:------------+--------------------+
// Head |<------ copy ------>| [physical]
} else {
// Data Tail End Head
// v v v v
// +-------------:----+-----:--------------+
// | : | : |
// +-----|------------+-----|--------------+
// |<---------------->|
// sliding window
mHead = mData;
}
}
mTail = mHead;
return range;
}
} // namespace filament::backend
+55 -27
View File
@@ -15,23 +15,35 @@
*/
#include "private/backend/CommandBufferQueue.h"
#include "private/backend/CircularBuffer.h"
#include "private/backend/CommandStream.h"
#include <utils/compiler.h>
#include <utils/Log.h>
#include <utils/Systrace.h>
#include <utils/Mutex.h>
#include <utils/ostream.h>
#include <utils/Panic.h>
#include <utils/Systrace.h>
#include <utils/debug.h>
#include "private/backend/BackendUtils.h"
#include "private/backend/CommandStream.h"
#include <algorithm>
#include <mutex>
#include <iterator>
#include <utility>
#include <vector>
#include <stddef.h>
#include <stdint.h>
using namespace utils;
namespace filament::backend {
CommandBufferQueue::CommandBufferQueue(size_t requiredSize, size_t bufferSize)
CommandBufferQueue::CommandBufferQueue(size_t requiredSize, size_t bufferSize, bool paused)
: mRequiredSize((requiredSize + (CircularBuffer::getBlockSize() - 1u)) & ~(CircularBuffer::getBlockSize() -1u)),
mCircularBuffer(bufferSize),
mFreeSpace(mCircularBuffer.size()) {
mFreeSpace(mCircularBuffer.size()),
mPaused(paused) {
assert_invariant(mCircularBuffer.size() > requiredSize);
}
@@ -45,6 +57,16 @@ void CommandBufferQueue::requestExit() {
mCondition.notify_one();
}
void CommandBufferQueue::setPaused(bool paused) {
std::lock_guard<utils::Mutex> const lock(mLock);
if (paused) {
mPaused = true;
} else {
mPaused = false;
mCondition.notify_one();
}
}
bool CommandBufferQueue::isExitRequested() const {
std::lock_guard<utils::Mutex> const lock(mLock);
ASSERT_PRECONDITION( mExitRequested == 0 || mExitRequested == EXIT_REQUESTED,
@@ -65,55 +87,61 @@ void CommandBufferQueue::flush() noexcept {
// always guaranteed to have enough space for the NoopCommand
new(circularBuffer.allocate(sizeof(NoopCommand))) NoopCommand(nullptr);
// end of this slice
void* const head = circularBuffer.getHead();
const size_t requiredSize = mRequiredSize;
// beginning of this slice
void* const tail = circularBuffer.getTail();
// get the current buffer
auto const [begin, end] = circularBuffer.getBuffer();
// size of this slice
uint32_t const used = uint32_t(intptr_t(head) - intptr_t(tail));
assert_invariant(circularBuffer.empty());
circularBuffer.circularize();
// size of the current buffer
size_t const used = std::distance(
static_cast<char const*>(begin), static_cast<char const*>(end));
std::unique_lock<utils::Mutex> lock(mLock);
mCommandBuffersToExecute.push_back({ tail, head });
mCommandBuffersToExecute.push_back({ begin, end });
mCondition.notify_one();
// circular buffer is too small, we corrupted the stream
ASSERT_POSTCONDITION(used <= mFreeSpace,
"Backend CommandStream overflow. Commands are corrupted and unrecoverable.\n"
"Please increase minCommandBufferSizeMB inside the Config passed to Engine::create.\n"
"Space used at this time: %u bytes",
(unsigned)used);
"Space used at this time: %u bytes, overflow: %u bytes",
(unsigned)used, unsigned(used - mFreeSpace));
// wait until there is enough space in the buffer
mFreeSpace -= used;
const size_t requiredSize = mRequiredSize;
if (UTILS_UNLIKELY(mFreeSpace < requiredSize)) {
#ifndef NDEBUG
size_t totalUsed = circularBuffer.size() - mFreeSpace;
mHighWatermark = std::max(mHighWatermark, totalUsed);
if (UTILS_UNLIKELY(totalUsed > requiredSize)) {
slog.d << "CommandStream used too much space: " << totalUsed
<< ", out of " << requiredSize << " (will block)" << io::endl;
}
size_t const totalUsed = circularBuffer.size() - mFreeSpace;
slog.d << "CommandStream used too much space (will block): "
<< "needed space " << requiredSize << " out of " << mFreeSpace
<< ", totalUsed=" << totalUsed << ", current=" << used
<< ", queue size=" << mCommandBuffersToExecute.size() << " buffers"
<< io::endl;
mHighWatermark = std::max(mHighWatermark, totalUsed);
#endif
mCondition.notify_one();
if (UTILS_LIKELY(mFreeSpace < requiredSize)) {
SYSTRACE_NAME("waiting: CircularBuffer::flush()");
ASSERT_POSTCONDITION(!mPaused,
"CommandStream is full, but since the rendering thread is paused, "
"the buffer cannot flush and we will deadlock. Instead, abort.");
mCondition.wait(lock, [this, requiredSize]() -> bool {
// TODO: on macOS, we need to call pumpEvents from time to time
return mFreeSpace >= requiredSize;
});
}
}
std::vector<CommandBufferQueue::Slice> CommandBufferQueue::waitForCommands() const {
std::vector<CommandBufferQueue::Range> CommandBufferQueue::waitForCommands() const {
if (!UTILS_HAS_THREADING) {
return std::move(mCommandBuffersToExecute);
}
std::unique_lock<utils::Mutex> lock(mLock);
while (mCommandBuffersToExecute.empty() && !mExitRequested) {
while ((mCommandBuffersToExecute.empty() || mPaused) && !mExitRequested) {
mCondition.wait(lock);
}
@@ -123,7 +151,7 @@ std::vector<CommandBufferQueue::Slice> CommandBufferQueue::waitForCommands() con
return std::move(mCommandBuffersToExecute);
}
void CommandBufferQueue::releaseBuffer(CommandBufferQueue::Slice const& buffer) {
void CommandBufferQueue::releaseBuffer(CommandBufferQueue::Range const& buffer) {
std::lock_guard<utils::Mutex> const lock(mLock);
mFreeSpace += uintptr_t(buffer.end) - uintptr_t(buffer.begin);
mCondition.notify_one();
+1 -1
View File
@@ -149,7 +149,7 @@ void CommandType<void (Driver::*)(ARGS...)>::Command<METHOD>::log() noexcept {
// ------------------------------------------------------------------------------------------------
void CustomCommand::execute(Driver&, CommandBase* base, intptr_t* next) noexcept {
void CustomCommand::execute(Driver&, CommandBase* base, intptr_t* next) {
*next = CustomCommand::align(sizeof(CustomCommand));
static_cast<CustomCommand*>(base)->mCommand();
static_cast<CustomCommand*>(base)->~CustomCommand();
+1
View File
@@ -19,6 +19,7 @@
#include <backend/PixelBufferDescriptor.h>
#include <cstring>
#include <stddef.h>
#include <stdint.h>
+15 -2
View File
@@ -21,7 +21,12 @@
#include <backend/AcquiredImage.h>
#include <backend/BufferDescriptor.h>
#include <backend/DriverEnums.h>
#include <utils/compiler.h>
#include <utils/debug.h>
#include <utils/Log.h>
#include <utils/ostream.h>
#include <utils/Systrace.h>
#include <math/half.h>
@@ -29,6 +34,13 @@
#include <math/vec3.h>
#include <math/vec4.h>
#include <functional>
#include <mutex>
#include <utility>
#include <stddef.h>
#include <stdint.h>
using namespace utils;
using namespace filament::math;
@@ -119,7 +131,8 @@ void DriverBase::purge() noexcept {
// ------------------------------------------------------------------------------------------------
void DriverBase::scheduleDestroySlow(BufferDescriptor&& buffer) noexcept {
scheduleCallback(buffer.getHandler(), [buffer = std::move(buffer)]() {
auto const handler = buffer.getHandler();
scheduleCallback(handler, [buffer = std::move(buffer)]() {
// user callback is called when BufferDescriptor gets destroyed
});
}
@@ -201,7 +214,7 @@ size_t Driver::getElementTypeSize(ElementType type) noexcept {
Driver::~Driver() noexcept = default;
void Driver::execute(std::function<void(void)> const& fn) noexcept {
void Driver::execute(std::function<void(void)> const& fn) {
fn();
}
+18 -17
View File
@@ -49,24 +49,28 @@ struct AcquiredImage;
struct HwBase {
};
struct HwVertexBuffer : public HwBase {
AttributeArray attributes{}; // 8 * MAX_VERTEX_ATTRIBUTE_COUNT
uint32_t vertexCount{}; // 4
struct HwVertexBufferInfo : public HwBase {
uint8_t bufferCount{}; // 1
uint8_t attributeCount{}; // 1
bool padding{}; // 1
uint8_t bufferObjectsVersion{}; // 1 -> total struct is 136 bytes
HwVertexBuffer() noexcept = default;
HwVertexBuffer(uint8_t bufferCount, uint8_t attributeCount, uint32_t elementCount,
AttributeArray const& attributes) noexcept
: attributes(attributes),
vertexCount(elementCount),
bufferCount(bufferCount),
bool padding[2]{}; // 2
HwVertexBufferInfo() noexcept = default;
HwVertexBufferInfo(uint8_t bufferCount, uint8_t attributeCount) noexcept
: bufferCount(bufferCount),
attributeCount(attributeCount) {
}
};
struct HwVertexBuffer : public HwBase {
uint32_t vertexCount{}; // 4
uint8_t bufferObjectsVersion{0xff}; // 1
bool padding[3]{}; // 2
HwVertexBuffer() noexcept = default;
explicit HwVertexBuffer(uint32_t vertextCount) noexcept
: vertexCount(vertextCount) {
}
};
struct HwBufferObject : public HwBase {
uint32_t byteCount{};
@@ -88,11 +92,6 @@ struct HwIndexBuffer : public HwBase {
};
struct HwRenderPrimitive : public HwBase {
uint32_t offset{};
uint32_t minIndex{};
uint32_t maxIndex{};
uint32_t count{};
uint32_t maxVertexCount{};
PrimitiveType type = PrimitiveType::TRIANGLES;
};
@@ -114,7 +113,9 @@ struct HwTexture : public HwBase {
uint8_t levels : 4; // This allows up to 15 levels (max texture size of 32768 x 32768)
uint8_t samples : 4; // Sample count per pixel (should always be a power of 2)
TextureFormat format{};
uint8_t reserved0 = 0;
TextureUsage usage{};
uint16_t reserved1 = 0;
HwStream* hwStream = nullptr;
HwTexture() noexcept : levels{}, samples{} {}
+59 -16
View File
@@ -16,9 +16,22 @@
#include "private/backend/HandleAllocator.h"
#include <backend/Handle.h>
#include <utils/Allocator.h>
#include <utils/Log.h>
#include <utils/Panic.h>
#include <utils/compiler.h>
#include <utils/debug.h>
#include <utils/ostream.h>
#include <algorithm>
#include <exception>
#include <limits>
#include <mutex>
#include <stdlib.h>
#include <string.h>
namespace filament::backend {
@@ -26,23 +39,47 @@ using namespace utils;
template <size_t P0, size_t P1, size_t P2>
UTILS_NOINLINE
HandleAllocator<P0, P1, P2>::Allocator::Allocator(AreaPolicy::HeapArea const& area)
: mArea(area) {
// TODO: we probably need a better way to set the size of these pools
const size_t unit = area.size() / 32;
const size_t offsetPool1 = unit;
const size_t offsetPool2 = 16 * unit;
char* const p = (char*)area.begin();
mPool0 = PoolAllocator< P0, 16>(p, p + offsetPool1);
mPool1 = PoolAllocator< P1, 16>(p + offsetPool1, p + offsetPool2);
mPool2 = PoolAllocator< P2, 16>(p + offsetPool2, area.end());
HandleAllocator<P0, P1, P2>::Allocator::Allocator(AreaPolicy::HeapArea const& area,
bool disableUseAfterFreeCheck)
: mArea(area),
mUseAfterFreeCheckDisabled(disableUseAfterFreeCheck) {
// The largest handle this allocator can generate currently depends on the architecture's
// min alignment, typically 8 or 16 bytes.
// e.g. On Android armv8, the alignment is 16 bytes, so for a 1 MiB heap, the largest handle
// index will be 65536. Note that this is not the same as the number of handles (which
// will always be less).
// Because our maximum representable handle currently is 0x07FFFFFF, the maximum no-nonsensical
// heap size is 2 GiB, which amounts to 7.6 millions handles per pool (in the GL case).
size_t const maxHeapSize = std::min(area.size(), HANDLE_INDEX_MASK * getAlignment());
if (UTILS_UNLIKELY(maxHeapSize != area.size())) {
slog.w << "HandleAllocator heap size reduced to "
<< maxHeapSize << " from " << area.size() << io::endl;
}
// make sure we start with a clean arena. This is needed to ensure that all blocks start
// with an age of 0.
memset(area.data(), 0, maxHeapSize);
// size the different pools so that they can all contain the same number of handles
size_t const count = maxHeapSize / (P0 + P1 + P2);
char* const p0 = static_cast<char*>(area.begin());
char* const p1 = p0 + count * P0;
char* const p2 = p1 + count * P1;
mPool0 = Pool<P0>(p0, count * P0);
mPool1 = Pool<P1>(p1, count * P1);
mPool2 = Pool<P2>(p2, count * P2);
}
// ------------------------------------------------------------------------------------------------
template <size_t P0, size_t P1, size_t P2>
HandleAllocator<P0, P1, P2>::HandleAllocator(const char* name, size_t size) noexcept
: mHandleArena(name, size) {
HandleAllocator<P0, P1, P2>::HandleAllocator(const char* name, size_t size,
bool disableUseAfterFreeCheck) noexcept
: mHandleArena(name, size, disableUseAfterFreeCheck),
mUseAfterFreeCheckDisabled(disableUseAfterFreeCheck) {
}
template <size_t P0, size_t P1, size_t P2>
@@ -70,14 +107,20 @@ void* HandleAllocator<P0, P1, P2>::handleToPointerSlow(HandleBase::HandleId id)
}
template <size_t P0, size_t P1, size_t P2>
HandleBase::HandleId HandleAllocator<P0, P1, P2>::allocateHandleSlow(size_t size) noexcept {
HandleBase::HandleId HandleAllocator<P0, P1, P2>::allocateHandleSlow(size_t size) {
void* p = ::malloc(size);
std::unique_lock lock(mLock);
HandleBase::HandleId id = (++mId) | HEAP_HANDLE_FLAG;
HandleBase::HandleId id = (++mId) | HANDLE_HEAP_FLAG;
ASSERT_POSTCONDITION(mId < HANDLE_HEAP_FLAG,
"No more Handle ids available! This can happen if HandleAllocator arena has been full"
" for a while. Please increase FILAMENT_OPENGL_HANDLE_ARENA_SIZE_IN_MB");
mOverflowMap.emplace(id, p);
lock.unlock();
if (UTILS_UNLIKELY(id == (HEAP_HANDLE_FLAG|1u))) { // meaning id was zero
if (UTILS_UNLIKELY(id == (HANDLE_HEAP_FLAG | 1u))) { // meaning id was zero
PANIC_LOG("HandleAllocator arena is full, using slower system heap. Please increase "
"the appropriate constant (e.g. FILAMENT_OPENGL_HANDLE_ARENA_SIZE_IN_MB).");
}
@@ -86,7 +129,7 @@ HandleBase::HandleId HandleAllocator<P0, P1, P2>::allocateHandleSlow(size_t size
template <size_t P0, size_t P1, size_t P2>
void HandleAllocator<P0, P1, P2>::deallocateHandleSlow(HandleBase::HandleId id, size_t) noexcept {
assert_invariant(id & HEAP_HANDLE_FLAG);
assert_invariant(id & HANDLE_HEAP_FLAG);
void* p = nullptr;
auto& overflowMap = mOverflowMap;
+14
View File
@@ -53,4 +53,18 @@ size_t Platform::retrieveBlob(void const* key, size_t keySize, void* value, size
return 0;
}
void Platform::setDebugUpdateStatFunc(DebugUpdateStatFunc&& debugUpdateStat) noexcept {
mDebugUpdateStat = std::move(debugUpdateStat);
}
bool Platform::hasDebugUpdateStatFunc() const noexcept {
return bool(mDebugUpdateStat);
}
void Platform::debugUpdateStat(const char* key, uint64_t value) {
if (mDebugUpdateStat) {
mDebugUpdateStat(key, value);
}
}
} // namespace filament::backend
+5
View File
@@ -91,6 +91,11 @@ Program& Program::cacheId(uint64_t cacheId) noexcept {
return *this;
}
Program& Program::multiview(bool multiview) noexcept {
mMultiview = multiview;
return *this;
}
io::ostream& operator<<(io::ostream& out, const Program& builder) {
out << "Program{";
builder.mLogger(out);
@@ -20,6 +20,7 @@
#include "MetalUtils.h"
#include <utils/Panic.h>
#include <utils/Log.h>
namespace filament::backend {
+47 -7
View File
@@ -18,7 +18,6 @@
#define TNT_FILAMENT_DRIVER_METALBUFFER_H
#include "MetalContext.h"
#include "MetalBufferPool.h"
#include <backend/DriverEnums.h>
@@ -28,9 +27,50 @@
#include <utility>
#include <memory>
#include <atomic>
namespace filament::backend {
class TrackedMetalBuffer {
public:
TrackedMetalBuffer() noexcept : mBuffer(nil) {}
TrackedMetalBuffer(id<MTLBuffer> buffer) noexcept : mBuffer(buffer) {
if (buffer) {
aliveBuffers++;
}
}
~TrackedMetalBuffer() {
if (mBuffer) {
aliveBuffers--;
}
}
TrackedMetalBuffer(TrackedMetalBuffer&&) = delete;
TrackedMetalBuffer(TrackedMetalBuffer const&) = delete;
TrackedMetalBuffer& operator=(TrackedMetalBuffer const&) = delete;
TrackedMetalBuffer& operator=(TrackedMetalBuffer&& rhs) noexcept {
swap(rhs);
return *this;
}
id<MTLBuffer> get() const noexcept { return mBuffer; }
operator bool() const noexcept { return bool(mBuffer); }
static uint64_t getAliveBuffers() { return aliveBuffers; }
private:
void swap(TrackedMetalBuffer& other) noexcept {
id<MTLBuffer> temp = mBuffer;
mBuffer = other.mBuffer;
other.mBuffer = temp;
}
id<MTLBuffer> mBuffer;
static std::atomic<uint64_t> aliveBuffers;
};
class MetalBuffer {
public:
@@ -82,7 +122,7 @@ public:
private:
id<MTLBuffer> mBuffer = nil;
TrackedMetalBuffer mBuffer;
size_t mBufferSize = 0;
void* mCpuBuffer = nullptr;
MetalContext& mContext;
@@ -151,7 +191,7 @@ public:
// finishes executing.
mAuxBuffer = [mDevice newBufferWithLength:mSlotSizeBytes options:mBufferOptions];
assert_invariant(mAuxBuffer);
return {mAuxBuffer, 0};
return {mAuxBuffer.get(), 0};
}
mCurrentSlot = (mCurrentSlot + 1) % mSlotCount;
mOccupiedSlots->fetch_add(1, std::memory_order_relaxed);
@@ -180,9 +220,9 @@ public:
*/
std::pair<id<MTLBuffer>, NSUInteger> getCurrentAllocation() const {
if (UTILS_UNLIKELY(mAuxBuffer)) {
return { mAuxBuffer, 0 };
return { mAuxBuffer.get(), 0 };
}
return { mBuffer, mCurrentSlot * mSlotSizeBytes };
return { mBuffer.get(), mCurrentSlot * mSlotSizeBytes };
}
bool canAccomodateLayout(MTLSizeAndAlign layout) const {
@@ -191,8 +231,8 @@ public:
private:
id<MTLDevice> mDevice;
id<MTLBuffer> mBuffer;
id<MTLBuffer> mAuxBuffer;
TrackedMetalBuffer mBuffer;
TrackedMetalBuffer mAuxBuffer;
MTLResourceOptions mBufferOptions;
+7 -4
View File
@@ -15,12 +15,15 @@
*/
#include "MetalBuffer.h"
#include "MetalBufferPool.h"
#include "MetalContext.h"
namespace filament {
namespace backend {
std::atomic<uint64_t> TrackedMetalBuffer::aliveBuffers = 0;
MetalBuffer::MetalBuffer(MetalContext& context, BufferObjectBinding bindingType, BufferUsage usage,
size_t size, bool forceGpuBuffer) : mBufferSize(size), mContext(context) {
// If the buffer is less than 4K in size and is updated frequently, we don't use an explicit
@@ -61,7 +64,7 @@ void MetalBuffer::copyIntoBuffer(void* src, size_t size, size_t byteOffset) {
// Acquire a staging buffer to hold the contents of this update.
MetalBufferPool* bufferPool = mContext.bufferPool;
const MetalBufferPoolEntry* const staging = bufferPool->acquireBuffer(size);
memcpy(staging->buffer.contents, src, size);
memcpy(staging->buffer.get().contents, src, size);
// The blit below requires that byteOffset be a multiple of 4.
ASSERT_PRECONDITION(!(byteOffset & 0x3u), "byteOffset must be a multiple of 4");
@@ -70,9 +73,9 @@ void MetalBuffer::copyIntoBuffer(void* src, size_t size, size_t byteOffset) {
id<MTLCommandBuffer> cmdBuffer = getPendingCommandBuffer(&mContext);
id<MTLBlitCommandEncoder> blitEncoder = [cmdBuffer blitCommandEncoder];
blitEncoder.label = @"Buffer upload blit";
[blitEncoder copyFromBuffer:staging->buffer
[blitEncoder copyFromBuffer:staging->buffer.get()
sourceOffset:0
toBuffer:mBuffer
toBuffer:mBuffer.get()
destinationOffset:byteOffset
size:size];
[blitEncoder endEncoding];
@@ -93,7 +96,7 @@ id<MTLBuffer> MetalBuffer::getGpuBufferForDraw(id<MTLCommandBuffer> cmdBuffer) n
return nil;
}
assert_invariant(mBuffer);
return mBuffer;
return mBuffer.get();
}
void MetalBuffer::bindBuffers(id<MTLCommandBuffer> cmdBuffer, id<MTLCommandEncoder> encoder,
+3 -1
View File
@@ -19,6 +19,8 @@
#include <Metal/Metal.h>
#include "MetalBuffer.h"
#include <map>
#include <mutex>
#include <unordered_set>
@@ -30,7 +32,7 @@ struct MetalContext;
// Immutable POD representing a shared CPU-GPU buffer.
struct MetalBufferPoolEntry {
id<MTLBuffer> buffer;
TrackedMetalBuffer buffer;
size_t capacity;
mutable uint64_t lastAccessed;
mutable uint32_t referenceCount;
@@ -19,6 +19,7 @@
#include "MetalContext.h"
#include <utils/Panic.h>
#include <utils/Log.h>
#include <utils/trap.h>
#include <thread>
@@ -44,12 +45,12 @@ MetalBufferPoolEntry const* MetalBufferPool::acquireBuffer(size_t numBytes) {
id<MTLBuffer> buffer = [mContext.device newBufferWithLength:numBytes
options:MTLResourceStorageModeShared];
ASSERT_POSTCONDITION(buffer, "Could not allocate Metal staging buffer of size %zu.", numBytes);
MetalBufferPoolEntry* stage = new MetalBufferPoolEntry({
MetalBufferPoolEntry* stage = new MetalBufferPoolEntry {
.buffer = buffer,
.capacity = numBytes,
.lastAccessed = mCurrentFrame,
.referenceCount = 1
});
};
mUsedStages.insert(stage);
return stage;
@@ -99,6 +99,7 @@ struct MetalContext {
std::array<BufferState, MAX_SSBO_COUNT> ssboState;
CullModeStateTracker cullModeState;
WindingStateTracker windingState;
Handle<HwRenderPrimitive> currentRenderPrimitive;
// State caches.
DepthStencilStateCache depthStencilStateCache;
+1 -4
View File
@@ -133,12 +133,9 @@ private:
mHandleAllocator.deallocate(handle, p);
}
inline void setRenderPrimitiveBuffer(Handle<HwRenderPrimitive> rph,
inline void setRenderPrimitiveBuffer(Handle<HwRenderPrimitive> rph, PrimitiveType pt,
Handle<HwVertexBuffer> vbh, Handle<HwIndexBuffer> ibh);
inline void setRenderPrimitiveRange(Handle<HwRenderPrimitive> rph, PrimitiveType pt,
uint32_t offset, uint32_t minIndex, uint32_t maxIndex, uint32_t count);
void finalizeSamplerGroup(MetalSamplerGroup* sg);
void enumerateBoundBuffers(BufferObjectBinding bindingType,
const std::function<void(const BufferState&, MetalBuffer*, uint32_t)>& f);
+181 -82
View File
@@ -20,6 +20,7 @@
#include "metal/MetalDriver.h"
#include "MetalBlitter.h"
#include "MetalBufferPool.h"
#include "MetalContext.h"
#include "MetalDriverFactory.h"
#include "MetalEnums.h"
@@ -36,6 +37,7 @@
#include <utils/Log.h>
#include <utils/Panic.h>
#include <utils/sstream.h>
#include <algorithm>
@@ -43,6 +45,42 @@ namespace filament {
namespace backend {
Driver* MetalDriverFactory::create(MetalPlatform* const platform, const Platform::DriverConfig& driverConfig) {
#if 0
// this is useful for development, but too verbose even for debug builds
// For reference on a 64-bits machine in Release mode:
// MetalTimerQuery : 16 few
// HwStream : 24 few
// MetalRenderPrimitive : 24 many
// MetalVertexBuffer : 32 moderate
// -- less than or equal 32 bytes
// MetalIndexBuffer : 40 moderate
// MetalFence : 48 few
// MetalBufferObject : 48 many
// -- less than or equal 48 bytes
// MetalSamplerGroup : 112 few
// MetalProgram : 152 moderate
// MetalTexture : 152 moderate
// MetalSwapChain : 184 few
// MetalRenderTarget : 272 few
// MetalVertexBufferInfo : 552 moderate
// -- less than or equal to 552 bytes
utils::slog.d
<< "\nMetalSwapChain: " << sizeof(MetalSwapChain)
<< "\nMetalBufferObject: " << sizeof(MetalBufferObject)
<< "\nMetalVertexBuffer: " << sizeof(MetalVertexBuffer)
<< "\nMetalVertexBufferInfo: " << sizeof(MetalVertexBufferInfo)
<< "\nMetalIndexBuffer: " << sizeof(MetalIndexBuffer)
<< "\nMetalSamplerGroup: " << sizeof(MetalSamplerGroup)
<< "\nMetalRenderPrimitive: " << sizeof(MetalRenderPrimitive)
<< "\nMetalTexture: " << sizeof(MetalTexture)
<< "\nMetalTimerQuery: " << sizeof(MetalTimerQuery)
<< "\nHwStream: " << sizeof(HwStream)
<< "\nMetalRenderTarget: " << sizeof(MetalRenderTarget)
<< "\nMetalFence: " << sizeof(MetalFence)
<< "\nMetalProgram: " << sizeof(MetalProgram)
<< utils::io::endl;
#endif
return MetalDriver::create(platform, driverConfig);
}
@@ -62,7 +100,9 @@ Dispatcher MetalDriver::getDispatcher() const noexcept {
MetalDriver::MetalDriver(MetalPlatform* platform, const Platform::DriverConfig& driverConfig) noexcept
: mPlatform(*platform),
mContext(new MetalContext(driverConfig.textureUseAfterFreePoolSize)),
mHandleAllocator("Handles", driverConfig.handleArenaSize) {
mHandleAllocator("Handles",
driverConfig.handleArenaSize,
driverConfig.disableHandleUseAfterFreeCheck) {
mContext->driver = this;
mContext->device = mPlatform.createDevice();
@@ -144,7 +184,10 @@ MetalDriver::MetalDriver(MetalPlatform* platform, const Platform::DriverConfig&
mContext->eventListener = [[MTLSharedEventListener alloc] initWithDispatchQueue:queue];
}
mContext->shaderCompiler = new MetalShaderCompiler(mContext->device, *this);
const MetalShaderCompiler::Mode compilerMode = driverConfig.disableParallelShaderCompile
? MetalShaderCompiler::Mode::SYNCHRONOUS
: MetalShaderCompiler::Mode::ASYNCHRONOUS;
mContext->shaderCompiler = new MetalShaderCompiler(mContext->device, *this, compilerMode);
mContext->shaderCompiler->init();
#if defined(FILAMENT_METAL_PROFILING)
@@ -173,6 +216,9 @@ void MetalDriver::beginFrame(int64_t monotonic_clock_ns, uint32_t frameId) {
#if defined(FILAMENT_METAL_PROFILING)
os_signpost_interval_begin(mContext->log, mContext->signpostId, "Frame encoding", "%{public}d", frameId);
#endif
if (mPlatform.hasDebugUpdateStatFunc()) {
mPlatform.debugUpdateStat("filament.metal.alive_buffers", TrackedMetalBuffer::getAliveBuffers());
}
}
void MetalDriver::setFrameScheduledCallback(Handle<HwSwapChain> sch,
@@ -245,10 +291,16 @@ void MetalDriver::finish(int) {
[oneOffBuffer waitUntilCompleted];
}
void MetalDriver::createVertexBufferR(Handle<HwVertexBuffer> vbh, uint8_t bufferCount,
uint8_t attributeCount, uint32_t vertexCount, AttributeArray attributes) {
construct_handle<MetalVertexBuffer>(vbh, *mContext, bufferCount,
attributeCount, vertexCount, attributes);
void MetalDriver::createVertexBufferInfoR(Handle<HwVertexBufferInfo> vbih, uint8_t bufferCount,
uint8_t attributeCount, AttributeArray attributes) {
construct_handle<MetalVertexBufferInfo>(vbih, *mContext,
bufferCount, attributeCount, attributes);
}
void MetalDriver::createVertexBufferR(Handle<HwVertexBuffer> vbh,
uint32_t vertexCount, Handle<HwVertexBufferInfo> vbih) {
MetalVertexBufferInfo const* const vbi = handle_cast<const MetalVertexBufferInfo>(vbih);
construct_handle<MetalVertexBuffer>(vbh, *mContext, vertexCount, vbi->bufferCount, vbih);
}
void MetalDriver::createIndexBufferR(Handle<HwIndexBuffer> ibh, ElementType elementType,
@@ -316,11 +368,9 @@ void MetalDriver::createSamplerGroupR(
void MetalDriver::createRenderPrimitiveR(Handle<HwRenderPrimitive> rph,
Handle<HwVertexBuffer> vbh, Handle<HwIndexBuffer> ibh,
PrimitiveType pt, uint32_t offset,
uint32_t minIndex, uint32_t maxIndex, uint32_t count) {
PrimitiveType pt) {
construct_handle<MetalRenderPrimitive>(rph);
MetalDriver::setRenderPrimitiveBuffer(rph, vbh, ibh);
MetalDriver::setRenderPrimitiveRange(rph, pt, offset, minIndex, maxIndex, count);
MetalDriver::setRenderPrimitiveBuffer(rph, pt, vbh, ibh);
}
void MetalDriver::createProgramR(Handle<HwProgram> rph, Program&& program) {
@@ -333,7 +383,7 @@ void MetalDriver::createDefaultRenderTargetR(Handle<HwRenderTarget> rth, int dum
void MetalDriver::createRenderTargetR(Handle<HwRenderTarget> rth,
TargetBufferFlags targetBufferFlags, uint32_t width, uint32_t height,
uint8_t samples, MRT color,
uint8_t samples, uint8_t layerCount, MRT color,
TargetBufferInfo depth, TargetBufferInfo stencil) {
ASSERT_PRECONDITION(!isInRenderPass(mContext),
"createRenderTarget must be called outside of a render pass.");
@@ -406,6 +456,10 @@ void MetalDriver::createTimerQueryR(Handle<HwTimerQuery> tqh, int) {
// nothing to do, timer query was constructed in createTimerQueryS
}
Handle<HwVertexBufferInfo> MetalDriver::createVertexBufferInfoS() noexcept {
return alloc_handle<MetalVertexBufferInfo>();
}
Handle<HwVertexBuffer> MetalDriver::createVertexBufferS() noexcept {
return alloc_handle<MetalVertexBuffer>();
}
@@ -470,6 +524,12 @@ Handle<HwTimerQuery> MetalDriver::createTimerQueryS() noexcept {
return alloc_and_construct_handle<MetalTimerQuery, HwTimerQuery>();
}
void MetalDriver::destroyVertexBufferInfo(Handle<HwVertexBufferInfo> vbih) {
if (vbih) {
destruct_handle<MetalVertexBufferInfo>(vbih);
}
}
void MetalDriver::destroyVertexBuffer(Handle<HwVertexBuffer> vbh) {
if (vbh) {
destruct_handle<MetalVertexBuffer>(vbh);
@@ -722,18 +782,33 @@ bool MetalDriver::isSRGBSwapChainSupported() {
return false;
}
bool MetalDriver::isStereoSupported() {
return true;
bool MetalDriver::isProtectedContentSupported() {
// the SWAP_CHAIN_CONFIG_PROTECTED_CONTENT flag is not supported
return false;
}
bool MetalDriver::isStereoSupported(backend::StereoscopicType stereoscopicType) {
switch (stereoscopicType) {
case backend::StereoscopicType::INSTANCED:
return true;
case backend::StereoscopicType::MULTIVIEW:
// TODO: implement multiview feature in Metal.
return false;
}
}
bool MetalDriver::isParallelShaderCompileSupported() {
return true;
return mContext->shaderCompiler->isParallelShaderCompileSupported();
}
bool MetalDriver::isDepthStencilResolveSupported() {
return false;
}
bool MetalDriver::isProtectedTexturesSupported() {
return false;
}
bool MetalDriver::isWorkaroundNeeded(Workaround workaround) {
switch (workaround) {
case Workaround::SPLIT_EASU:
@@ -860,9 +935,10 @@ void MetalDriver::setExternalImagePlane(Handle<HwTexture> th, void* image, uint3
void MetalDriver::setExternalStream(Handle<HwTexture> th, Handle<HwStream> sh) {
}
bool MetalDriver::getTimerQueryValue(Handle<HwTimerQuery> tqh, uint64_t* elapsedTime) {
TimerQueryResult MetalDriver::getTimerQueryValue(Handle<HwTimerQuery> tqh, uint64_t* elapsedTime) {
auto* tq = handle_cast<MetalTimerQuery>(tqh);
return mContext->timerQueryImpl->getQueryResult(tq, elapsedTime);
return mContext->timerQueryImpl->getQueryResult(tq, elapsedTime) ?
TimerQueryResult::AVAILABLE : TimerQueryResult::NOT_READY;
}
void MetalDriver::generateMipmaps(Handle<HwTexture> th) {
@@ -1029,23 +1105,14 @@ void MetalDriver::endRenderPass(int dummy) {
mContext->currentRenderPassEncoder = nil;
}
void MetalDriver::setRenderPrimitiveBuffer(Handle<HwRenderPrimitive> rph,
void MetalDriver::setRenderPrimitiveBuffer(Handle<HwRenderPrimitive> rph, PrimitiveType pt,
Handle<HwVertexBuffer> vbh, Handle<HwIndexBuffer> ibh) {
auto primitive = handle_cast<MetalRenderPrimitive>(rph);
auto vertexBuffer = handle_cast<MetalVertexBuffer>(vbh);
auto indexBuffer = handle_cast<MetalIndexBuffer>(ibh);
primitive->setBuffers(vertexBuffer, indexBuffer);
}
void MetalDriver::setRenderPrimitiveRange(Handle<HwRenderPrimitive> rph,
PrimitiveType pt, uint32_t offset, uint32_t minIndex, uint32_t maxIndex,
uint32_t count) {
auto primitive = handle_cast<MetalRenderPrimitive>(rph);
MetalVertexBufferInfo const* const vbi = handle_cast<MetalVertexBufferInfo>(vertexBuffer->vbih);
primitive->setBuffers(vbi, vertexBuffer, indexBuffer);
primitive->type = pt;
primitive->offset = offset * primitive->indexBuffer->elementSize;
primitive->count = count;
primitive->minIndex = minIndex;
primitive->maxIndex = maxIndex > minIndex ? maxIndex : primitive->maxVertexCount - 1;
}
void MetalDriver::makeCurrent(Handle<HwSwapChain> schDraw, Handle<HwSwapChain> schRead) {
@@ -1547,10 +1614,13 @@ void MetalDriver::finalizeSamplerGroup(MetalSamplerGroup* samplerGroup) {
}
}
void MetalDriver::draw(PipelineState ps, Handle<HwRenderPrimitive> rph, uint32_t instanceCount) {
void MetalDriver::bindPipeline(PipelineState ps) {
ASSERT_PRECONDITION(mContext->currentRenderPassEncoder != nullptr,
"Attempted to draw without a valid command encoder.");
auto primitive = handle_cast<MetalRenderPrimitive>(rph);
"bindPipeline() without a valid command encoder.");
MetalVertexBufferInfo const* const vbi =
handle_cast<MetalVertexBufferInfo>(ps.vertexBufferInfo);
auto program = handle_cast<MetalProgram>(ps.program);
const auto& rs = ps.rasterState;
@@ -1564,7 +1634,7 @@ void MetalDriver::draw(PipelineState ps, Handle<HwRenderPrimitive> rph, uint32_t
return;
}
ASSERT_PRECONDITION(bool(functions), "Attempting to draw with an invalid Metal program.");
functions.validate();
auto [fragment, vertex] = functions.getRasterFunctions();
@@ -1591,7 +1661,7 @@ void MetalDriver::draw(PipelineState ps, Handle<HwRenderPrimitive> rph, uint32_t
MetalPipelineState const pipelineState {
.vertexFunction = vertex,
.fragmentFunction = fragment,
.vertexDescription = primitive->vertexDescription,
.vertexDescription = vbi->vertexDescription,
.colorAttachmentPixelFormat = {
colorPixelFormat[0],
colorPixelFormat[1],
@@ -1685,50 +1755,6 @@ void MetalDriver::draw(PipelineState ps, Handle<HwRenderPrimitive> rph, uint32_t
mContext->currentPolygonOffset = ps.polygonOffset;
}
// Set scissor-rectangle.
// In order to do this, we compute the intersection between:
// 1. the scissor rectangle
// 2. the render target attachment dimensions (important, as the scissor can't be set larger)
// fmax/min are used below to guard against NaN and because the MTLViewport/MTLRegion
// coordinates are doubles.
MTLRegion scissor = mContext->currentRenderTarget->getRegionFromClientRect(ps.scissor);
const float sleft = scissor.origin.x, sright = scissor.origin.x + scissor.size.width;
const float stop = scissor.origin.y, sbottom = scissor.origin.y + scissor.size.height;
// Attachment extent
const auto attachmentSize = mContext->currentRenderTarget->getAttachmentSize();
const float aleft = 0.0f, atop = 0.0f;
const float aright = static_cast<float>(attachmentSize.x);
const float abottom = static_cast<float>(attachmentSize.y);
const auto left = std::fmax(sleft, aleft);
const auto right = std::fmin(sright, aright);
const auto top = std::fmax(stop, atop);
const auto bottom = std::fmin(sbottom, abottom);
MTLScissorRect scissorRect = {
.x = static_cast<NSUInteger>(left),
.y = static_cast<NSUInteger>(top),
.width = static_cast<NSUInteger>(right - left),
.height = static_cast<NSUInteger>(bottom - top)
};
[mContext->currentRenderPassEncoder setScissorRect:scissorRect];
// Bind uniform buffers.
MetalBuffer* uniformsToBind[Program::UNIFORM_BINDING_COUNT] = { nil };
NSUInteger offsets[Program::UNIFORM_BINDING_COUNT] = { 0 };
enumerateBoundBuffers(BufferObjectBinding::UNIFORM,
[&uniformsToBind, &offsets](const BufferState& state, MetalBuffer* buffer,
uint32_t index) {
uniformsToBind[index] = buffer;
offsets[index] = state.offset;
});
MetalBuffer::bindBuffers(getPendingCommandBuffer(mContext), mContext->currentRenderPassEncoder,
UNIFORM_BUFFER_BINDING_START, MetalBuffer::Stage::VERTEX | MetalBuffer::Stage::FRAGMENT,
uniformsToBind, offsets, Program::UNIFORM_BINDING_COUNT);
// Bind sampler groups (argument buffers).
for (size_t s = 0; s < Program::SAMPLER_BINDING_COUNT; s++) {
MetalSamplerGroup* const samplerGroup = mContext->samplerBindings[s];
@@ -1759,19 +1785,29 @@ void MetalDriver::draw(PipelineState ps, Handle<HwRenderPrimitive> rph, uint32_t
atIndex:(SAMPLER_GROUP_BINDING_START + s)];
}
}
}
void MetalDriver::bindRenderPrimitive(Handle<HwRenderPrimitive> rph) {
ASSERT_PRECONDITION(mContext->currentRenderPassEncoder != nullptr,
"bindRenderPrimitive() without a valid command encoder.");
// Bind the user vertex buffers.
MetalBuffer* vertexBuffers[MAX_VERTEX_BUFFER_COUNT] = {};
size_t vertexBufferOffsets[MAX_VERTEX_BUFFER_COUNT] = {};
size_t maxBufferIndex = 0;
MetalRenderPrimitive const* const primitive = handle_cast<MetalRenderPrimitive>(rph);
MetalVertexBufferInfo const* const vbi =
handle_cast<MetalVertexBufferInfo>(primitive->vertexBuffer->vbih);
mContext->currentRenderPrimitive = rph;
auto vb = primitive->vertexBuffer;
for (auto m : primitive->bufferMapping) {
for (auto m : vbi->bufferMapping) {
assert_invariant(
m.bufferArgumentIndex >= USER_VERTEX_BUFFER_BINDING_START &&
m.bufferArgumentIndex < USER_VERTEX_BUFFER_BINDING_START + MAX_VERTEX_BUFFER_COUNT);
size_t vertexBufferIndex = m.bufferArgumentIndex - USER_VERTEX_BUFFER_BINDING_START;
size_t const vertexBufferIndex = m.bufferArgumentIndex - USER_VERTEX_BUFFER_BINDING_START;
vertexBuffers[vertexBufferIndex] = vb->buffers[m.sourceBufferIndex];
maxBufferIndex = std::max(maxBufferIndex, vertexBufferIndex);
}
@@ -1786,19 +1822,50 @@ void MetalDriver::draw(PipelineState ps, Handle<HwRenderPrimitive> rph, uint32_t
[mContext->currentRenderPassEncoder setVertexBytes:bytes
length:16
atIndex:ZERO_VERTEX_BUFFER_BINDING];
}
void MetalDriver::draw2(uint32_t indexOffset, uint32_t indexCount, uint32_t instanceCount) {
ASSERT_PRECONDITION(mContext->currentRenderPassEncoder != nullptr,
"draw() without a valid command encoder.");
// Bind uniform buffers.
MetalBuffer* uniformsToBind[Program::UNIFORM_BINDING_COUNT] = { nil };
NSUInteger offsets[Program::UNIFORM_BINDING_COUNT] = { 0 };
enumerateBoundBuffers(BufferObjectBinding::UNIFORM,
[&uniformsToBind, &offsets](const BufferState& state, MetalBuffer* buffer,
uint32_t index) {
uniformsToBind[index] = buffer;
offsets[index] = state.offset;
});
MetalBuffer::bindBuffers(getPendingCommandBuffer(mContext), mContext->currentRenderPassEncoder,
UNIFORM_BUFFER_BINDING_START, MetalBuffer::Stage::VERTEX | MetalBuffer::Stage::FRAGMENT,
uniformsToBind, offsets, Program::UNIFORM_BINDING_COUNT);
auto primitive = handle_cast<MetalRenderPrimitive>(mContext->currentRenderPrimitive);
MetalIndexBuffer* indexBuffer = primitive->indexBuffer;
id<MTLCommandBuffer> cmdBuffer = getPendingCommandBuffer(mContext);
id<MTLBuffer> metalIndexBuffer = indexBuffer->buffer.getGpuBufferForDraw(cmdBuffer);
[mContext->currentRenderPassEncoder drawIndexedPrimitives:getMetalPrimitiveType(primitive->type)
indexCount:primitive->count
indexCount:indexCount
indexType:getIndexType(indexBuffer->elementSize)
indexBuffer:metalIndexBuffer
indexBufferOffset:primitive->offset
indexBufferOffset:indexOffset * primitive->indexBuffer->elementSize
instanceCount:instanceCount];
}
void MetalDriver::draw(PipelineState ps, Handle<HwRenderPrimitive> rph,
uint32_t const indexOffset, uint32_t const indexCount, uint32_t const instanceCount) {
MetalRenderPrimitive const* const rp = handle_cast<MetalRenderPrimitive>(rph);
ps.primitiveType = rp->type;
ps.vertexBufferInfo = rp->vertexBuffer->vbih;
bindPipeline(ps);
bindRenderPrimitive(rph);
draw2(indexOffset, indexCount, instanceCount);
}
void MetalDriver::dispatchCompute(Handle<HwProgram> program, math::uint3 workGroupCount) {
ASSERT_PRECONDITION(!isInRenderPass(mContext),
"dispatchCompute must be called outside of a render pass.");
@@ -1868,6 +1935,38 @@ void MetalDriver::dispatchCompute(Handle<HwProgram> program, math::uint3 workGro
[computeEncoder endEncoding];
}
void MetalDriver::scissor(Viewport scissorBox) {
// Set scissor-rectangle.
// In order to do this, we compute the intersection between:
// 1. the scissor rectangle
// 2. the render target attachment dimensions (important, as the scissor can't be set larger)
// fmax/min are used below to guard against NaN and because the MTLViewport/MTLRegion
// coordinates are doubles.
MTLRegion scissor = mContext->currentRenderTarget->getRegionFromClientRect(scissorBox);
const float sleft = scissor.origin.x, sright = scissor.origin.x + scissor.size.width;
const float stop = scissor.origin.y, sbottom = scissor.origin.y + scissor.size.height;
// Attachment extent
const auto attachmentSize = mContext->currentRenderTarget->getAttachmentSize();
const float aleft = 0.0f, atop = 0.0f;
const float aright = static_cast<float>(attachmentSize.x);
const float abottom = static_cast<float>(attachmentSize.y);
const auto left = std::fmax(sleft, aleft);
const auto right = std::fmin(sright, aright);
const auto top = std::fmax(stop, atop);
const auto bottom = std::fmin(sbottom, abottom);
MTLScissorRect scissorRect = {
.x = static_cast<NSUInteger>(left),
.y = static_cast<NSUInteger>(top),
.width = static_cast<NSUInteger>(right - left),
.height = static_cast<NSUInteger>(bottom - top)
};
[mContext->currentRenderPassEncoder setScissorRect:scissorRect];
}
void MetalDriver::beginTimerQuery(Handle<HwTimerQuery> tqh) {
ASSERT_PRECONDITION(!isInRenderPass(mContext),
"beginTimerQuery must be called outside of a render pass.");
@@ -21,6 +21,7 @@
#include "MetalUtils.h"
#include <utils/Panic.h>
#include <utils/Log.h>
#include <utils/trap.h>
#define NSERROR_CHECK(message) \
+29 -22
View File
@@ -145,28 +145,9 @@ private:
MetalBuffer buffer;
};
struct MetalVertexBuffer : public HwVertexBuffer {
MetalVertexBuffer(MetalContext& context, uint8_t bufferCount, uint8_t attributeCount,
uint32_t vertexCount, AttributeArray const& attributes);
utils::FixedCapacityVector<MetalBuffer*> buffers;
};
struct MetalIndexBuffer : public HwIndexBuffer {
MetalIndexBuffer(MetalContext& context, BufferUsage usage, uint8_t elementSize,
uint32_t indexCount);
MetalBuffer buffer;
};
struct MetalRenderPrimitive : public HwRenderPrimitive {
MetalRenderPrimitive();
void setBuffers(MetalVertexBuffer* vertexBuffer, MetalIndexBuffer* indexBuffer);
// The pointers to MetalVertexBuffer and MetalIndexBuffer are "weak".
// The MetalVertexBuffer and MetalIndexBuffer must outlive the MetalRenderPrimitive.
MetalVertexBuffer* vertexBuffer = nullptr;
MetalIndexBuffer* indexBuffer = nullptr;
struct MetalVertexBufferInfo : public HwVertexBufferInfo {
MetalVertexBufferInfo(MetalContext& context,
uint8_t bufferCount, uint8_t attributeCount, AttributeArray const& attributes);
// This struct is used to create the pipeline description to describe vertex assembly.
VertexDescription vertexDescription = {};
@@ -185,6 +166,32 @@ struct MetalRenderPrimitive : public HwRenderPrimitive {
utils::FixedCapacityVector<Entry> bufferMapping;
};
struct MetalVertexBuffer : public HwVertexBuffer {
MetalVertexBuffer(MetalContext& context,
uint32_t vertexCount, uint32_t bufferCount, Handle<HwVertexBufferInfo> vbih);
Handle<HwVertexBufferInfo> vbih;
utils::FixedCapacityVector<MetalBuffer*> buffers;
};
struct MetalIndexBuffer : public HwIndexBuffer {
MetalIndexBuffer(MetalContext& context, BufferUsage usage, uint8_t elementSize,
uint32_t indexCount);
MetalBuffer buffer;
};
struct MetalRenderPrimitive : public HwRenderPrimitive {
MetalRenderPrimitive();
void setBuffers(MetalVertexBufferInfo const* const vbi,
MetalVertexBuffer* vertexBuffer, MetalIndexBuffer* indexBuffer);
// The pointers to MetalVertexBuffer and MetalIndexBuffer are "weak".
// The MetalVertexBuffer and MetalIndexBuffer must outlive the MetalRenderPrimitive.
MetalVertexBuffer* vertexBuffer = nullptr;
MetalIndexBuffer* indexBuffer = nullptr;
};
class MetalProgram : public HwProgram {
public:
MetalProgram(MetalContext& context, Program&& program) noexcept;
+79 -53
View File
@@ -19,6 +19,7 @@
#include "MetalBlitter.h"
#include "MetalEnums.h"
#include "MetalUtils.h"
#include "MetalBufferPool.h"
#include <filament/SwapChain.h>
@@ -245,30 +246,53 @@ void MetalSwapChain::present() {
}
}
struct PresentDrawableData {
void* drawable = nullptr;
MetalDriver* driver = nullptr;
#ifndef FILAMENT_RELEASE_PRESENT_DRAWABLE_MAIN_THREAD
#define FILAMENT_RELEASE_PRESENT_DRAWABLE_MAIN_THREAD 1
#endif
class PresentDrawableData {
public:
PresentDrawableData() = delete;
PresentDrawableData(const PresentDrawableData&) = delete;
PresentDrawableData& operator=(const PresentDrawableData&) = delete;
static PresentDrawableData* create(id<CAMetalDrawable> drawable, MetalDriver* driver) {
assert_invariant(driver);
return new PresentDrawableData(drawable, driver);
}
static void maybePresentAndDestroyAsync(PresentDrawableData* that, bool shouldPresent) {
if (shouldPresent) {
[that->mDrawable present];
}
#if FILAMENT_RELEASE_PRESENT_DRAWABLE_MAIN_THREAD == 1
// mDrawable is acquired on the driver thread. Typically, we would release this object on
// the same thread, but after receiving consistent crash reports from within
// [CAMetalDrawable dealloc], we suspect this object requires releasing on the main thread.
dispatch_async(dispatch_get_main_queue(), ^{ cleanupAndDestroy(that); });
#else
that->mDriver->runAtNextTick([that]() { cleanupAndDestroy(that); });
#endif
}
private:
PresentDrawableData(id<CAMetalDrawable> drawable, MetalDriver* driver)
: mDrawable(drawable), mDriver(driver) {}
static void cleanupAndDestroy(PresentDrawableData *that) {
that->mDrawable = nil;
that->mDriver = nullptr;
delete that;
}
id<CAMetalDrawable> mDrawable;
MetalDriver* mDriver = nullptr;
};
void presentDrawable(bool presentFrame, void* user) {
auto* presentDrawableData = static_cast<PresentDrawableData*>(user);
// CFBridgingRelease here is used to balance the CFBridgingRetain inside acquireDrawable.
id<CAMetalDrawable> drawable =
(id<CAMetalDrawable>)CFBridgingRelease(presentDrawableData->drawable);
if (presentFrame) {
[drawable present];
}
// Schedule the drawable destruction on the driver thread.
void* voidDrawable = (void*) CFBridgingRetain(drawable);
MetalDriver* driver = presentDrawableData->driver;
driver->runAtNextTick([voidDrawable]() {
// The drawable is released here.
CFBridgingRelease(voidDrawable);
});
delete presentDrawableData;
PresentDrawableData::maybePresentAndDestroyAsync(presentDrawableData, presentFrame);
}
void MetalSwapChain::scheduleFrameScheduledCallback() {
@@ -277,21 +301,16 @@ void MetalSwapChain::scheduleFrameScheduledCallback() {
}
assert_invariant(drawable);
FrameScheduledCallback callback = frameScheduledCallback;
// This block strongly captures drawable to keep it alive until the handler executes.
// We cannot simply reference this->drawable inside the block because the block would then only
// capture the _this_ pointer (MetalSwapChain*) instead of the drawable.
id<CAMetalDrawable> d = drawable;
// Destroy this by calling maybePresentAndDestroyAsync() later.
auto* presentData = PresentDrawableData::create(drawable, context.driver);
FrameScheduledCallback userCallback = frameScheduledCallback;
void* userData = frameScheduledUserData;
MetalDriver* driver = context.driver;
[getPendingCommandBuffer(&context) addScheduledHandler:^(id<MTLCommandBuffer> cb) {
// CFBridgingRetain is used here to give the drawable a +1 retain count before
// casting it to a void*.
auto* presentDrawableData = new PresentDrawableData;
presentDrawableData->drawable = (void*) CFBridgingRetain(d);
presentDrawableData->driver = driver;
PresentCallable callable(presentDrawable, (void*) presentDrawableData);
callback(callable, userData);
PresentCallable callable(presentDrawable, static_cast<void*>(presentData));
userCallback(callable, userData);
}];
}
@@ -322,23 +341,12 @@ void MetalBufferObject::updateBufferUnsynchronized(void* data, size_t size, uint
buffer.copyIntoBufferUnsynchronized(data, size, byteOffset);
}
MetalVertexBuffer::MetalVertexBuffer(MetalContext& context, uint8_t bufferCount,
uint8_t attributeCount, uint32_t vertexCount, AttributeArray const& attributes)
: HwVertexBuffer(bufferCount, attributeCount, vertexCount, attributes), buffers(bufferCount, nullptr) {}
MetalVertexBufferInfo::MetalVertexBufferInfo(MetalContext& context, uint8_t bufferCount,
uint8_t attributeCount, AttributeArray const& attributes)
: HwVertexBufferInfo(bufferCount, attributeCount),
bufferMapping(utils::FixedCapacityVector<Entry>::with_capacity(MAX_VERTEX_BUFFER_COUNT)) {
MetalIndexBuffer::MetalIndexBuffer(MetalContext& context, BufferUsage usage, uint8_t elementSize,
uint32_t indexCount) : HwIndexBuffer(elementSize, indexCount),
buffer(context, BufferObjectBinding::VERTEX, usage, elementSize * indexCount, true) { }
MetalRenderPrimitive::MetalRenderPrimitive()
: bufferMapping(utils::FixedCapacityVector<Entry>::with_capacity(MAX_VERTEX_BUFFER_COUNT)) {}
void MetalRenderPrimitive::setBuffers(MetalVertexBuffer* vertexBuffer, MetalIndexBuffer*
indexBuffer) {
this->vertexBuffer = vertexBuffer;
this->indexBuffer = indexBuffer;
const size_t attributeCount = vertexBuffer->attributes.size();
const size_t maxAttributeCount = attributes.size();
auto& mapping = bufferMapping;
mapping.clear();
@@ -378,8 +386,8 @@ void MetalRenderPrimitive::setBuffers(MetalVertexBuffer* vertexBuffer, MetalInde
}
};
for (uint32_t attributeIndex = 0; attributeIndex < attributeCount; attributeIndex++) {
const auto& attribute = vertexBuffer->attributes[attributeIndex];
for (uint32_t attributeIndex = 0; attributeIndex < maxAttributeCount; attributeIndex++) {
const auto& attribute = attributes[attributeIndex];
// If the attribute is unused, bind it to the zero buffer. It's a Metal error for a shader
// to read from missing vertex attributes.
@@ -406,6 +414,24 @@ void MetalRenderPrimitive::setBuffers(MetalVertexBuffer* vertexBuffer, MetalInde
}
}
MetalVertexBuffer::MetalVertexBuffer(MetalContext& context,
uint32_t vertexCount, uint32_t bufferCount, Handle<HwVertexBufferInfo> vbih)
: HwVertexBuffer(vertexCount), vbih(vbih), buffers(bufferCount, nullptr) {
}
MetalIndexBuffer::MetalIndexBuffer(MetalContext& context, BufferUsage usage, uint8_t elementSize,
uint32_t indexCount) : HwIndexBuffer(elementSize, indexCount),
buffer(context, BufferObjectBinding::VERTEX, usage, elementSize * indexCount, true) { }
MetalRenderPrimitive::MetalRenderPrimitive() {
}
void MetalRenderPrimitive::setBuffers(MetalVertexBufferInfo const* const vbi,
MetalVertexBuffer* vertexBuffer, MetalIndexBuffer* indexBuffer) {
this->vertexBuffer = vertexBuffer;
this->indexBuffer = indexBuffer;
}
MetalProgram::MetalProgram(MetalContext& context, Program&& program) noexcept
: HwProgram(program.getName()), mContext(context) {
@@ -745,13 +771,13 @@ void MetalTexture::loadWithCopyBuffer(uint32_t level, uint32_t slice, MTLRegion
PixelBufferDescriptor const& data, const PixelBufferShape& shape) {
const size_t stagingBufferSize = shape.totalBytes;
auto entry = context.bufferPool->acquireBuffer(stagingBufferSize);
memcpy(entry->buffer.contents,
memcpy(entry->buffer.get().contents,
static_cast<uint8_t*>(data.buffer) + shape.sourceOffset,
stagingBufferSize);
id<MTLCommandBuffer> blitCommandBuffer = getPendingCommandBuffer(&context);
id<MTLBlitCommandEncoder> blitCommandEncoder = [blitCommandBuffer blitCommandEncoder];
blitCommandEncoder.label = @"Texture upload buffer blit";
[blitCommandEncoder copyFromBuffer:entry->buffer
[blitCommandEncoder copyFromBuffer:entry->buffer.get()
sourceOffset:0
sourceBytesPerRow:shape.bytesPerRow
sourceBytesPerImage:shape.bytesPerSlice
@@ -30,6 +30,8 @@
#include <array>
#include <memory>
#include <tuple>
#include <variant>
namespace filament::backend {
@@ -39,43 +41,81 @@ class MetalShaderCompiler {
struct MetalProgramToken;
public:
enum class Mode {
SYNCHRONOUS, // synchronous shader compilation
ASYNCHRONOUS // asynchronous shader compilation
};
class MetalFunctionBundle {
public:
MetalFunctionBundle() = default;
MetalFunctionBundle(id<MTLFunction> fragment, id<MTLFunction> vertex)
: functions{fragment, vertex} {
using Raster = std::tuple<id<MTLFunction>, id<MTLFunction>>;
using Compute = id<MTLFunction>;
using Error = std::tuple<NSString*, NSString*>; // error message, Program name
struct None {};
MetalFunctionBundle() : mPrograms{None{}} {}
explicit operator bool() const { return isValid(); }
bool isValid() const noexcept {
return std::holds_alternative<Raster>(mPrograms) ||
std::holds_alternative<Compute>(mPrograms);
}
/**
* Throws an NSException if this MetalFunctionBundle either contains an error or is empty.
*
* If this MetalFunctionBundle contains an error, will throw a MetalCompilationFailure
* NSException with the error string and program name passed to
* MetalFunctionBundle::error(NSString*, NSString*).
*
* If this MetalFunctionBundle is empty, will throw a MetalEmptyFunctionBundle NSException.
*/
void validate() const;
Raster getRasterFunctions() const {
assert_invariant(std::holds_alternative<Raster>(mPrograms));
return std::get<Raster>(mPrograms);
}
Compute getComputeFunction() const {
assert_invariant(std::holds_alternative<Compute>(mPrograms));
return std::get<Compute>(mPrograms);
}
static MetalFunctionBundle none() {
return MetalFunctionBundle(None{});
}
static MetalFunctionBundle raster(id<MTLFunction> fragment, id<MTLFunction> vertex) {
assert_invariant(fragment && vertex);
assert_invariant(fragment.functionType == MTLFunctionTypeFragment);
assert_invariant(vertex.functionType == MTLFunctionTypeVertex);
return MetalFunctionBundle(Raster{fragment, vertex});
}
explicit MetalFunctionBundle(id<MTLFunction> compute) : functions{compute, nil} {
static MetalFunctionBundle compute(id<MTLFunction> compute) {
assert_invariant(compute);
assert_invariant(compute.functionType == MTLFunctionTypeKernel);
return MetalFunctionBundle(Compute{compute});
}
std::pair<id<MTLFunction>, id<MTLFunction>> getRasterFunctions() const noexcept {
assert_invariant(functions[0].functionType == MTLFunctionTypeFragment);
assert_invariant(functions[1].functionType == MTLFunctionTypeVertex);
return {functions[0], functions[1]};
static MetalFunctionBundle error(NSString* errorMessage, NSString* programName) {
return MetalFunctionBundle(Error{errorMessage, programName});
}
id<MTLFunction> getComputeFunction() const noexcept {
assert_invariant(functions[0].functionType == MTLFunctionTypeKernel);
return functions[0];
}
explicit operator bool() const { return functions[0] != nil; }
private:
// Can hold two functions, either:
// - fragment and vertex (for rasterization pipelines)
// - compute (for compute pipelines)
id<MTLFunction> functions[2] = {nil, nil};
MetalFunctionBundle(None&& t) : mPrograms(std::move(t)) {}
MetalFunctionBundle(Raster&& t) : mPrograms(std::move(t)) {}
MetalFunctionBundle(Compute&& t) : mPrograms(std::move(t)) {}
MetalFunctionBundle(Error&& t) : mPrograms(std::move(t)) {}
std::variant<Raster, Compute, None, Error> mPrograms;
};
using program_token_t = std::shared_ptr<MetalProgramToken>;
explicit MetalShaderCompiler(id<MTLDevice> device, MetalDriver& driver);
explicit MetalShaderCompiler(id<MTLDevice> device, MetalDriver& driver, Mode mode);
MetalShaderCompiler(MetalShaderCompiler const& rhs) = delete;
MetalShaderCompiler(MetalShaderCompiler&& rhs) = delete;
@@ -85,15 +125,15 @@ public:
void init() noexcept;
void terminate() noexcept;
// Creates a program asynchronously
bool isParallelShaderCompileSupported() const noexcept;
// Creates a program, either synchronously or asynchronously, depending on the Mode
// MetalShaderCompiler was constructed with.
program_token_t createProgram(utils::CString const& name, Program&& program);
// Returns the functions, blocking if necessary. The Token is destroyed and becomes invalid.
MetalFunctionBundle getProgram(program_token_t& token);
// Destroys a valid token and all associated resources. Used to "cancel" a program compilation.
static void terminate(program_token_t& token);
void notifyWhenAllProgramsAreReady(
CallbackHandler* handler, CallbackHandler::Callback callback, void* user);
@@ -103,6 +143,7 @@ private:
CompilerThreadPool mCompilerThreadPool;
id<MTLDevice> mDevice;
CallbackManager mCallbackManager;
Mode mMode;
};
} // namespace filament::backend
@@ -70,22 +70,31 @@ struct MetalShaderCompiler::MetalProgramToken : ProgramToken {
MetalShaderCompiler::MetalProgramToken::~MetalProgramToken() = default;
MetalShaderCompiler::MetalShaderCompiler(id<MTLDevice> device, MetalDriver& driver)
MetalShaderCompiler::MetalShaderCompiler(id<MTLDevice> device, MetalDriver& driver, Mode mode)
: mDevice(device),
mCallbackManager(driver) {
mCallbackManager(driver),
mMode(mode) {
}
void MetalShaderCompiler::init() noexcept {
const uint32_t poolSize = 2;
mCompilerThreadPool.init(poolSize, []() {}, []() {});
const uint32_t poolSize = 1;
if (mMode == Mode::ASYNCHRONOUS) {
mCompilerThreadPool.init(poolSize, []() {}, []() {});
}
}
void MetalShaderCompiler::terminate() noexcept {
mCompilerThreadPool.terminate();
if (mMode == Mode::ASYNCHRONOUS) {
mCompilerThreadPool.terminate();
}
mCallbackManager.terminate();
}
bool MetalShaderCompiler::isParallelShaderCompileSupported() const noexcept {
return mMode == Mode::ASYNCHRONOUS;
}
/* static */ MetalShaderCompiler::MetalFunctionBundle MetalShaderCompiler::compileProgram(
const Program& program, id<MTLDevice> device) {
std::array<id<MTLFunction>, Program::SHADER_TYPE_COUNT> functions = { nil };
@@ -118,13 +127,16 @@ void MetalShaderCompiler::terminate() noexcept {
options:options
error:&error];
if (library == nil) {
NSString* errorMessage = @"unknown error";
if (error) {
auto description =
[error.localizedDescription cStringUsingEncoding:NSUTF8StringEncoding];
utils::slog.w << description << utils::io::endl;
errorMessage = error.localizedDescription;
}
PANIC_LOG("Failed to compile Metal program.");
return {};
NSString* programName = [NSString stringWithFormat:@"%s", program.getName().c_str_safe()];
return MetalFunctionBundle::error(errorMessage, programName);
}
MTLFunctionConstantValues* constants = [MTLFunctionConstantValues new];
@@ -160,14 +172,15 @@ void MetalShaderCompiler::terminate() noexcept {
assert_invariant(isRasterizationProgram != isComputeProgram);
if (isRasterizationProgram) {
return {fragmentFunction, vertexFunction};
return MetalFunctionBundle::raster(fragmentFunction, vertexFunction);
}
if (isComputeProgram) {
return MetalFunctionBundle{computeFunction};
return MetalFunctionBundle::compute(computeFunction);
}
return {};
// Should never reach here.
return MetalFunctionBundle::none();
}
MetalShaderCompiler::program_token_t MetalShaderCompiler::createProgram(
@@ -176,14 +189,26 @@ MetalShaderCompiler::program_token_t MetalShaderCompiler::createProgram(
token->handle = mCallbackManager.get();
CompilerPriorityQueue const priorityQueue = program.getPriorityQueue();
mCompilerThreadPool.queue(priorityQueue, token,
[this, name, device = mDevice, program = std::move(program), token]() {
MetalFunctionBundle compiledProgram = compileProgram(program, device);
switch (mMode) {
case Mode::ASYNCHRONOUS: {
CompilerPriorityQueue const priorityQueue = program.getPriorityQueue();
mCompilerThreadPool.queue(priorityQueue, token,
[this, name, device = mDevice, program = std::move(program), token]() {
MetalFunctionBundle compiledProgram = compileProgram(program, device);
token->set(compiledProgram);
mCallbackManager.put(token->handle);
});
token->set(compiledProgram);
mCallbackManager.put(token->handle);
});
break;
}
case Mode::SYNCHRONOUS: {
MetalFunctionBundle compiledProgram = compileProgram(program, mDevice);
token->set(compiledProgram);
mCallbackManager.put(token->handle);
break;
}
}
return token;
}
@@ -191,38 +216,46 @@ MetalShaderCompiler::program_token_t MetalShaderCompiler::createProgram(
MetalShaderCompiler::MetalFunctionBundle MetalShaderCompiler::getProgram(program_token_t& token) {
assert_invariant(token);
if (!token->isReady()) {
auto job = mCompilerThreadPool.dequeue(token);
if (job) {
job();
if (mMode == Mode::ASYNCHRONOUS) {
if (!token->isReady()) {
auto job = mCompilerThreadPool.dequeue(token);
if (job) {
job();
}
}
}
// The job isn't guaranteed to have finished yet. We may have failed to dequeue it above,
// which means it's currently running. In that case get() will block until it finishes.
MetalShaderCompiler::MetalFunctionBundle program = token->get();
token = nullptr;
return program;
}
/* static */ void MetalShaderCompiler::terminate(program_token_t& token) {
assert_invariant(token);
auto job = token->compiler.mCompilerThreadPool.dequeue(token);
if (!job) {
// The job is being executed right now (or has already executed).
token->wait();
} else {
// The job has not executed yet.
token->compiler.mCallbackManager.put(token->handle);
}
token.reset();
}
void MetalShaderCompiler::notifyWhenAllProgramsAreReady(
CallbackHandler* handler, CallbackHandler::Callback callback, void* user) {
mCallbackManager.setCallback(handler, callback, user);
}
UTILS_NOINLINE
void MetalShaderCompiler::MetalFunctionBundle::validate() const {
if (UTILS_UNLIKELY(std::holds_alternative<Error>(mPrograms))) {
auto [errorMessage, programName] = std::get<Error>(mPrograms);
NSString* reason =
[NSString stringWithFormat:
@"Attempting to draw with an id<MTLFunction> that failed to compile.\n"
@"Program: %@\n"
@"%@", programName, errorMessage];
[[NSException exceptionWithName:@"MetalCompilationFailure"
reason:reason
userInfo:nil] raise];
} else if (UTILS_UNLIKELY(std::holds_alternative<None>(mPrograms))) {
NSString* reason = @"Attempting to draw with an empty id<MTLFunction>.";
[[NSException exceptionWithName:@"MetalEmptyFunctionBundle"
reason:reason
userInfo:nil] raise];
}
}
} // namespace filament::backend
+2
View File
@@ -18,6 +18,8 @@
#include "MetalEnums.h"
#include <utils/Log.h>
namespace filament {
namespace backend {
+28 -4
View File
@@ -77,6 +77,9 @@ void NoopDriver::finish(int) {
void NoopDriver::destroyRenderPrimitive(Handle<HwRenderPrimitive> rph) {
}
void NoopDriver::destroyVertexBufferInfo(Handle<HwVertexBufferInfo> vbih) {
}
void NoopDriver::destroyVertexBuffer(Handle<HwVertexBuffer> vbh) {
}
@@ -174,7 +177,11 @@ bool NoopDriver::isSRGBSwapChainSupported() {
return false;
}
bool NoopDriver::isStereoSupported() {
bool NoopDriver::isProtectedContentSupported() {
return false;
}
bool NoopDriver::isStereoSupported(backend::StereoscopicType) {
return false;
}
@@ -186,6 +193,10 @@ bool NoopDriver::isDepthStencilResolveSupported() {
return true;
}
bool NoopDriver::isProtectedTexturesSupported() {
return true;
}
bool NoopDriver::isWorkaroundNeeded(Workaround) {
return false;
}
@@ -241,8 +252,8 @@ void NoopDriver::update3DImage(Handle<HwTexture> th,
void NoopDriver::setupExternalImage(void* image) {
}
bool NoopDriver::getTimerQueryValue(Handle<HwTimerQuery> tqh, uint64_t* elapsedTime) {
return false;
TimerQueryResult NoopDriver::getTimerQueryValue(Handle<HwTimerQuery> tqh, uint64_t* elapsedTime) {
return TimerQueryResult::ERROR;
}
void NoopDriver::setExternalImage(Handle<HwTexture> th, void* image) {
@@ -339,13 +350,26 @@ void NoopDriver::blit(
math::uint2 size) {
}
void NoopDriver::bindPipeline(PipelineState pipelineState) {
}
void NoopDriver::bindRenderPrimitive(Handle<HwRenderPrimitive> rph) {
}
void NoopDriver::draw2(uint32_t indexOffset, uint32_t indexCount, uint32_t instanceCount) {
}
void NoopDriver::draw(PipelineState pipelineState, Handle<HwRenderPrimitive> rph,
uint32_t instanceCount) {
uint32_t indexOffset, uint32_t indexCount, uint32_t instanceCount) {
}
void NoopDriver::dispatchCompute(Handle<HwProgram> program, math::uint3 workGroupCount) {
}
void NoopDriver::scissor(
Viewport scissor) {
}
void NoopDriver::beginTimerQuery(Handle<HwTimerQuery> tqh) {
}
@@ -0,0 +1,51 @@
/*
* Copyright (C) 2024 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef TNT_FILAMENT_BACKEND_OPENGL_GLBUFFEROBJECT_H
#define TNT_FILAMENT_BACKEND_OPENGL_GLBUFFEROBJECT_H
#include "DriverBase.h"
#include "gl_headers.h"
#include <backend/DriverEnums.h>
#include <stdint.h>
namespace filament::backend {
struct GLBufferObject : public HwBufferObject {
using HwBufferObject::HwBufferObject;
GLBufferObject(uint32_t size,
BufferObjectBinding bindingType, BufferUsage usage) noexcept
: HwBufferObject(size), usage(usage), bindingType(bindingType) {
}
struct {
GLuint id;
union {
GLenum binding;
void* buffer;
};
} gl;
BufferUsage usage;
BufferObjectBinding bindingType;
uint16_t age = 0;
};
} // namespace filament::backend
#endif //TNT_FILAMENT_BACKEND_OPENGL_GLBUFFEROBJECT_H
+55
View File
@@ -0,0 +1,55 @@
/*
* Copyright (C) 2024 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef TNT_FILAMENT_BACKEND_OPENGL_GLTEXTURE_H
#define TNT_FILAMENT_BACKEND_OPENGL_GLTEXTURE_H
#include "DriverBase.h"
#include "gl_headers.h"
#include <backend/platforms/OpenGLPlatform.h>
#include <stdint.h>
namespace filament::backend {
struct GLTexture : public HwTexture {
using HwTexture::HwTexture;
struct GL {
GL() noexcept : imported(false), sidecarSamples(1), reserved(0) {}
GLuint id = 0; // texture or renderbuffer id
GLenum target = 0;
GLenum internalFormat = 0;
GLuint sidecarRenderBufferMS = 0; // multi-sample sidecar renderbuffer
// texture parameters go here too
GLfloat anisotropy = 1.0;
int8_t baseLevel = 127;
int8_t maxLevel = -1;
uint8_t targetIndex = 0; // optimization: index corresponding to target
bool imported : 1;
uint8_t sidecarSamples : 4;
uint8_t reserved : 3;
} gl;
OpenGLPlatform::ExternalTexture* externalTexture = nullptr;
};
} // namespace filament::backend
#endif //TNT_FILAMENT_BACKEND_OPENGL_GLTEXTURE_H
+177 -15
View File
@@ -16,10 +16,25 @@
#include "OpenGLContext.h"
#include <backend/platforms/OpenGLPlatform.h>
#include "GLUtils.h"
#include "OpenGLTimerQuery.h"
#include <backend/platforms/OpenGLPlatform.h>
#include <backend/DriverEnums.h>
#include <utils/compiler.h>
#include <utils/debug.h>
#include <utils/Log.h>
#include <utils/ostream.h>
#include <functional>
#include <string_view>
#include <utility>
#include <stddef.h>
#include <stdio.h>
#include <string.h>
// change to true to display all GL extensions in the console on start-up
#define DEBUG_PRINT_EXTENSIONS false
@@ -48,7 +63,9 @@ bool OpenGLContext::queryOpenGLVersion(GLint* major, GLint* minor) noexcept {
#endif
}
OpenGLContext::OpenGLContext() noexcept {
OpenGLContext::OpenGLContext(OpenGLPlatform& platform) noexcept
: mPlatform(platform),
mSamplerMap(32) {
state.vao.p = &mDefaultVAO;
@@ -231,6 +248,58 @@ OpenGLContext::OpenGLContext() noexcept {
glDebugMessageCallback(cb, nullptr);
}
#endif
mTimerQueryFactory = TimerQueryFactory::init(platform, *this);
}
OpenGLContext::~OpenGLContext() noexcept {
#ifndef FILAMENT_SILENCE_NOT_SUPPORTED_BY_ES2
if (!isES2()) {
for (auto& item: mSamplerMap) {
unbindSampler(item.second);
glDeleteSamplers(1, &item.second);
}
mSamplerMap.clear();
}
#endif
delete mTimerQueryFactory;
}
void OpenGLContext::destroyWithContext(
size_t index, std::function<void(OpenGLContext&)> const& closure) noexcept {
if (index == 0) {
// Note: we only need to delay the destruction of objects on the unprotected context
// (index 0) because the protected context is always immediately destroyed and all its
// active objects and bindings are then automatically destroyed.
// TODO: this is only guaranteed for EGLPlatform, but that's the only one we care about.
mDestroyWithNormalContext.push_back(closure);
}
}
void OpenGLContext::unbindEverything() noexcept {
// TODO: we're supposed to unbind everything here so that resources don't get
// stuck in this context (contextIndex) when destroyed in the other context.
// However, because EGLPlatform always immediately destroys the protected context (1),
// the bindings will automatically be severed when we switch back to the default context.
// Since bindings now only exist in one context, we don't have a ref-counting issue to
// worry about.
}
void OpenGLContext::synchronizeStateAndCache(size_t index) noexcept {
// if we're just switching back to context 0, run all the pending destructors
if (index == 0) {
auto list = std::move(mDestroyWithNormalContext);
for (auto&& fn: list) {
fn(*this);
}
}
// the default FBO could be invalid
mDefaultFbo[index].reset();
contextIndex = index;
resetState();
}
void OpenGLContext::setDefaultState() noexcept {
@@ -427,7 +496,6 @@ void OpenGLContext::initBugs(Bugs* bugs, Extensions const& exts,
if (strstr(renderer, "Mali-T")) {
bugs->disable_glFlush = true;
bugs->disable_shared_context_draws = true;
bugs->texture_external_needs_rebind = true;
// We have not verified that timer queries work on Mali-T, so we disable to be safe.
bugs->dont_use_timer_query = true;
}
@@ -600,6 +668,7 @@ void OpenGLContext::initExtensionsGLES(Extensions* ext, GLint major, GLint minor
ext->EXT_disjoint_timer_query = exts.has("GL_EXT_disjoint_timer_query"sv);
ext->EXT_multisampled_render_to_texture = exts.has("GL_EXT_multisampled_render_to_texture"sv);
ext->EXT_multisampled_render_to_texture2 = exts.has("GL_EXT_multisampled_render_to_texture2"sv);
ext->EXT_protected_textures = exts.has("GL_EXT_protected_textures"sv);
#endif
ext->EXT_shader_framebuffer_fetch = exts.has("GL_EXT_shader_framebuffer_fetch"sv);
#ifndef __EMSCRIPTEN__
@@ -623,6 +692,7 @@ void OpenGLContext::initExtensionsGLES(Extensions* ext, GLint major, GLint minor
ext->OES_standard_derivatives = exts.has("GL_OES_standard_derivatives"sv);
ext->OES_texture_npot = exts.has("GL_OES_texture_npot"sv);
ext->OES_vertex_array_object = exts.has("GL_OES_vertex_array_object"sv);
ext->OVR_multiview2 = exts.has("GL_OVR_multiview2"sv);
ext->WEBGL_compressed_texture_etc = exts.has("WEBGL_compressed_texture_etc"sv);
ext->WEBGL_compressed_texture_s3tc = exts.has("WEBGL_compressed_texture_s3tc"sv);
ext->WEBGL_compressed_texture_s3tc_srgb = exts.has("WEBGL_compressed_texture_s3tc_srgb"sv);
@@ -687,6 +757,7 @@ void OpenGLContext::initExtensionsGL(Extensions* ext, GLint major, GLint minor)
ext->OES_standard_derivatives = true;
ext->OES_texture_npot = true;
ext->OES_vertex_array_object = true;
ext->OVR_multiview2 = exts.has("GL_OVR_multiview2"sv);
ext->WEBGL_compressed_texture_etc = false;
ext->WEBGL_compressed_texture_s3tc = false;
ext->WEBGL_compressed_texture_s3tc_srgb = false;
@@ -708,6 +779,51 @@ void OpenGLContext::initExtensionsGL(Extensions* ext, GLint major, GLint minor)
#endif // BACKEND_OPENGL_VERSION_GL
GLuint OpenGLContext::bindFramebuffer(GLenum target, GLuint buffer) noexcept {
if (UTILS_UNLIKELY(buffer == 0)) {
// we're binding the default frame buffer, resolve its actual name
auto& defaultFboForThisContext = mDefaultFbo[contextIndex];
if (UTILS_UNLIKELY(!defaultFboForThisContext.has_value())) {
defaultFboForThisContext = GLuint(mPlatform.getDefaultFramebufferObject());
}
buffer = defaultFboForThisContext.value();
}
bindFramebufferResolved(target, buffer);
return buffer;
}
void OpenGLContext::unbindFramebuffer(GLenum target) noexcept {
bindFramebufferResolved(target, 0);
}
void OpenGLContext::bindFramebufferResolved(GLenum target, GLuint buffer) noexcept {
switch (target) {
case GL_FRAMEBUFFER:
if (state.draw_fbo != buffer || state.read_fbo != buffer) {
state.draw_fbo = state.read_fbo = buffer;
glBindFramebuffer(target, buffer);
}
break;
#ifndef FILAMENT_SILENCE_NOT_SUPPORTED_BY_ES2
case GL_DRAW_FRAMEBUFFER:
if (state.draw_fbo != buffer) {
state.draw_fbo = buffer;
glBindFramebuffer(target, buffer);
}
break;
case GL_READ_FRAMEBUFFER:
if (state.read_fbo != buffer) {
state.read_fbo = buffer;
glBindFramebuffer(target, buffer);
}
break;
#endif
default:
break;
}
}
void OpenGLContext::bindBuffer(GLenum target, GLuint buffer) noexcept {
if (target == GL_ELEMENT_ARRAY_BUFFER) {
constexpr size_t targetIndex = getIndexForBufferTarget(GL_ELEMENT_ARRAY_BUFFER);
@@ -818,19 +934,53 @@ void OpenGLContext::deleteBuffers(GLsizei n, const GLuint* buffers, GLenum targe
#endif
}
void OpenGLContext::deleteVertexArrays(GLsizei n, const GLuint* arrays) noexcept {
procs.deleteVertexArrays(n, arrays);
// if one of the destroyed VAO is bound, clear the binding.
for (GLsizei i = 0; i < n; ++i) {
if (state.vao.p->vao == arrays[i]) {
void OpenGLContext::deleteVertexArray(GLuint vao) noexcept {
if (UTILS_LIKELY(vao)) {
procs.deleteVertexArrays(1, &vao);
// if the destroyed VAO is bound, clear the binding.
if (state.vao.p->vao[contextIndex] == vao) {
bindVertexArray(nullptr);
break;
}
}
}
#ifndef FILAMENT_SILENCE_NOT_SUPPORTED_BY_ES2
GLuint OpenGLContext::getSamplerSlow(SamplerParams params) const noexcept {
assert_invariant(mSamplerMap.find(params) == mSamplerMap.end());
using namespace GLUtils;
GLuint s;
glGenSamplers(1, &s);
glSamplerParameteri(s, GL_TEXTURE_MIN_FILTER, (GLint)getTextureFilter(params.filterMin));
glSamplerParameteri(s, GL_TEXTURE_MAG_FILTER, (GLint)getTextureFilter(params.filterMag));
glSamplerParameteri(s, GL_TEXTURE_WRAP_S, (GLint)getWrapMode(params.wrapS));
glSamplerParameteri(s, GL_TEXTURE_WRAP_T, (GLint)getWrapMode(params.wrapT));
glSamplerParameteri(s, GL_TEXTURE_WRAP_R, (GLint)getWrapMode(params.wrapR));
glSamplerParameteri(s, GL_TEXTURE_COMPARE_MODE, (GLint)getTextureCompareMode(params.compareMode));
glSamplerParameteri(s, GL_TEXTURE_COMPARE_FUNC, (GLint)getTextureCompareFunc(params.compareFunc));
#if defined(GL_EXT_texture_filter_anisotropic)
if (ext.EXT_texture_filter_anisotropic &&
!bugs.texture_filter_anisotropic_broken_on_sampler) {
GLfloat const anisotropy = float(1u << params.anisotropyLog2);
glSamplerParameterf(s, GL_TEXTURE_MAX_ANISOTROPY_EXT,
std::min(gets.max_anisotropy, anisotropy));
}
#endif
CHECK_GL_ERROR(utils::slog.e)
mSamplerMap[params] = s;
return s;
}
#endif
void OpenGLContext::resetState() noexcept {
// Force GL state to match the Filament state
// increase the state version so other parts of the state know to reset
state.age++;
if (state.major > 2) {
#ifndef FILAMENT_SILENCE_NOT_SUPPORTED_BY_ES2
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, state.draw_fbo);
@@ -847,11 +997,8 @@ void OpenGLContext::resetState() noexcept {
glUseProgram(state.program.use);
// state.vao
if (state.vao.p) {
procs.bindVertexArray(state.vao.p->vao);
} else {
bindVertexArray(nullptr);
}
state.vao.p = nullptr;
bindVertexArray(nullptr);
// state.raster
glFrontFace(state.raster.frontFace);
@@ -1007,7 +1154,22 @@ void OpenGLContext::resetState() noexcept {
state.window.viewport.w
);
glDepthRangef(state.window.depthRange.x, state.window.depthRange.y);
}
void OpenGLContext::createTimerQuery(GLTimerQuery* query) {
mTimerQueryFactory->createTimerQuery(query);
}
void OpenGLContext::destroyTimerQuery(GLTimerQuery* query) {
mTimerQueryFactory->destroyTimerQuery(query);
}
void OpenGLContext::beginTimeElapsedQuery(GLTimerQuery* query) {
mTimerQueryFactory->beginTimeElapsedQuery(query);
}
void OpenGLContext::endTimeElapsedQuery(OpenGLDriver& driver, GLTimerQuery* query) {
mTimerQueryFactory->endTimeElapsedQuery(driver, query);
}
} // namesapce filament
+137 -66
View File
@@ -17,25 +17,39 @@
#ifndef TNT_FILAMENT_BACKEND_OPENGLCONTEXT_H
#define TNT_FILAMENT_BACKEND_OPENGLCONTEXT_H
#include <math/vec4.h>
#include <utils/CString.h>
#include <utils/debug.h>
#include "OpenGLTimerQuery.h"
#include <backend/platforms/OpenGLPlatform.h>
#include <backend/DriverEnums.h>
#include <backend/Handle.h>
#include "GLUtils.h"
#include "gl_headers.h"
#include <utils/compiler.h>
#include <utils/bitset.h>
#include <utils/debug.h>
#include <math/vec2.h>
#include <math/vec4.h>
#include <tsl/robin_map.h>
#include <array>
#include <set>
#include <functional>
#include <optional>
#include <tuple>
#include <utility>
#include <vector>
#include <stddef.h>
#include <stdint.h>
namespace filament::backend {
class OpenGLPlatform;
class OpenGLContext {
class OpenGLContext final : public TimerQueryFactoryInterface {
public:
static constexpr const size_t MAX_TEXTURE_UNIT_COUNT = MAX_SAMPLER_COUNT;
static constexpr const size_t DUMMY_TEXTURE_BINDING = 7; // highest binding guaranteed to work with ES2
@@ -46,19 +60,29 @@ public:
struct RenderPrimitive {
static_assert(MAX_VERTEX_ATTRIBUTE_COUNT <= 16);
GLuint vao = 0; // 4
GLuint vao[2] = {}; // 4
GLuint elementArray = 0; // 4
utils::bitset<uint16_t> vertexAttribArray; // 2
mutable utils::bitset<uint16_t> vertexAttribArray; // 2
// If this version number does not match vertexBufferWithObjects->bufferObjectsVersion,
// then the VAO needs to be updated.
// if this differs from vertexBufferWithObjects->bufferObjectsVersion, this VAO needs to
// be updated (see OpenGLDriver::updateVertexArrayObject())
uint8_t vertexBufferVersion = 0; // 1
// if this differs from OpenGLContext::state.age, this VAO needs to
// be updated (see OpenGLDriver::updateVertexArrayObject())
uint8_t stateVersion = 0; // 1
// If this differs from OpenGLContext::state.age, this VAO's name needs to be updated.
// See OpenGLContext::bindVertexArray()
uint8_t nameVersion = 0; // 1
// Size in bytes of indices in the index buffer
uint8_t indicesSize = 0; // 1
// The optional 32-bit handle to a GLVertexBuffer is necessary only if the referenced
// VertexBuffer supports buffer objects. If this is zero, then the VBO handles array is
// immutable.
Handle<HwVertexBuffer> vertexBufferWithObjects = {}; // 4
Handle<HwVertexBuffer> vertexBufferWithObjects; // 4
GLenum getIndicesType() const noexcept {
return indicesSize == 4 ? GL_UNSIGNED_INT : GL_UNSIGNED_SHORT;
@@ -67,7 +91,18 @@ public:
static bool queryOpenGLVersion(GLint* major, GLint* minor) noexcept;
OpenGLContext() noexcept;
explicit OpenGLContext(OpenGLPlatform& platform) noexcept;
~OpenGLContext() noexcept final;
// TimerQueryInterface ------------------------------------------------------------------------
// note: OpenGLContext being final ensures (clang) these are not called through the vtable
void createTimerQuery(GLTimerQuery* query) override;
void destroyTimerQuery(GLTimerQuery* query) override;
void beginTimeElapsedQuery(GLTimerQuery* query) override;
void endTimeElapsedQuery(OpenGLDriver& driver, GLTimerQuery* query) override;
// --------------------------------------------------------------------------------------------
template<int MAJOR, int MINOR>
inline bool isAtLeastGL() const noexcept {
@@ -123,10 +158,11 @@ public:
inline void bindBufferRange(GLenum target, GLuint index, GLuint buffer,
GLintptr offset, GLsizeiptr size) noexcept;
inline void bindFramebuffer(GLenum target, GLuint buffer) noexcept;
GLuint bindFramebuffer(GLenum target, GLuint buffer) noexcept;
void unbindFramebuffer(GLenum target) noexcept;
inline void enableVertexAttribArray(GLuint index) noexcept;
inline void disableVertexAttribArray(GLuint index) noexcept;
inline void enableVertexAttribArray(RenderPrimitive const* rp, GLuint index) noexcept;
inline void disableVertexAttribArray(RenderPrimitive const* rp, GLuint index) noexcept;
inline void enable(GLenum cap) noexcept;
inline void disable(GLenum cap) noexcept;
inline void frontFace(GLenum mode) noexcept;
@@ -148,7 +184,9 @@ public:
inline void depthRange(GLclampf near, GLclampf far) noexcept;
void deleteBuffers(GLsizei n, const GLuint* buffers, GLenum target) noexcept;
void deleteVertexArrays(GLsizei n, const GLuint* arrays) noexcept;
void deleteVertexArray(GLuint vao) noexcept;
void destroyWithContext(size_t index, std::function<void(OpenGLContext&)> const& closure) noexcept;
// glGet*() values
struct Gets {
@@ -183,6 +221,7 @@ public:
bool EXT_discard_framebuffer;
bool EXT_multisampled_render_to_texture2;
bool EXT_multisampled_render_to_texture;
bool EXT_protected_textures;
bool EXT_shader_framebuffer_fetch;
bool EXT_texture_compression_bptc;
bool EXT_texture_compression_etc2;
@@ -205,6 +244,7 @@ public:
bool OES_standard_derivatives;
bool OES_texture_npot;
bool OES_vertex_array_object;
bool OVR_multiview2;
bool WEBGL_compressed_texture_etc;
bool WEBGL_compressed_texture_s3tc;
bool WEBGL_compressed_texture_s3tc_srgb;
@@ -222,10 +262,6 @@ public:
// Some drivers have gl state issues when drawing from shared contexts
bool disable_shared_context_draws;
// Some drivers require the GL_TEXTURE_EXTERNAL_OES target to be bound when
// the texture image changes, even if it's already bound to that texture
bool texture_external_needs_rebind;
// Some web browsers seem to immediately clear the default framebuffer when calling
// glInvalidateFramebuffer with WebGL 2.0
bool disable_invalidate_framebuffer;
@@ -294,8 +330,19 @@ public:
FeatureLevel getFeatureLevel() const noexcept { return mFeatureLevel; }
// This is the index of the context in use. Must be 0 or 1. This is used to manange the
// OpenGL name of ContainerObjects within each context.
uint32_t contextIndex = 0;
// Try to keep the State structure sorted by data-access patterns
struct State {
State() noexcept = default;
// make sure we don't copy this state by accident
State(State const& rhs) = delete;
State(State&& rhs) noexcept = delete;
State& operator=(State const& rhs) = delete;
State& operator=(State&& rhs) noexcept = delete;
GLint major = 0;
GLint minor = 0;
@@ -400,6 +447,7 @@ public:
vec4gli viewport { 0 };
vec2glf depthRange { 0.0f, 1.0f };
} window;
uint8_t age = 0;
} state;
struct Procs {
@@ -419,9 +467,47 @@ public:
void (* maxShaderCompilerThreadsKHR)(GLuint count);
} procs{};
void unbindEverything() noexcept;
void synchronizeStateAndCache(size_t index) noexcept;
void setEs2UniformBinding(size_t index, GLuint id, void const* data, uint16_t age) noexcept {
mUniformBindings[index] = { id, data, age };
}
auto getEs2UniformBinding(size_t index) const noexcept {
return mUniformBindings[index];
}
#ifndef FILAMENT_SILENCE_NOT_SUPPORTED_BY_ES2
GLuint getSamplerSlow(SamplerParams sp) const noexcept;
inline GLuint getSampler(SamplerParams sp) const noexcept {
assert_invariant(!sp.padding0);
assert_invariant(!sp.padding1);
assert_invariant(!sp.padding2);
auto& samplerMap = mSamplerMap;
auto pos = samplerMap.find(sp);
if (UTILS_UNLIKELY(pos == samplerMap.end())) {
return getSamplerSlow(sp);
}
return pos->second;
}
#endif
private:
OpenGLPlatform& mPlatform;
ShaderModel mShaderModel = ShaderModel::MOBILE;
FeatureLevel mFeatureLevel = FeatureLevel::FEATURE_LEVEL_1;
TimerQueryFactoryInterface* mTimerQueryFactory = nullptr;
std::vector<std::function<void(OpenGLContext&)>> mDestroyWithNormalContext;
RenderPrimitive mDefaultVAO;
std::optional<GLuint> mDefaultFbo[2];
std::array<
std::tuple<GLuint, void const*, uint16_t>,
CONFIG_UNIFORM_BINDING_COUNT> mUniformBindings = {};
mutable tsl::robin_map<SamplerParams, GLuint,
SamplerParams::Hasher, SamplerParams::EqualTo> mSamplerMap;
void bindFramebufferResolved(GLenum target, GLuint buffer) noexcept;
const std::array<std::tuple<bool const&, char const*, char const*>, sizeof(bugs)> mBugDatabase{{
{ bugs.disable_glFlush,
@@ -433,9 +519,6 @@ private:
{ bugs.disable_shared_context_draws,
"disable_shared_context_draws",
""},
{ bugs.texture_external_needs_rebind,
"texture_external_needs_rebind",
""},
{ bugs.disable_invalidate_framebuffer,
"disable_invalidate_framebuffer",
""},
@@ -477,8 +560,6 @@ private:
""},
}};
RenderPrimitive mDefaultVAO;
// this is chosen to minimize code size
#if defined(BACKEND_OPENGL_VERSION_GLES)
static void initExtensionsGLES(Extensions* ext, GLint major, GLint minor) noexcept;
@@ -636,11 +717,26 @@ void OpenGLContext::depthRange(GLclampf near, GLclampf far) noexcept {
void OpenGLContext::bindVertexArray(RenderPrimitive const* p) noexcept {
RenderPrimitive* vao = p ? const_cast<RenderPrimitive *>(p) : &mDefaultVAO;
update_state(state.vao.p, vao, [&]() {
procs.bindVertexArray(vao->vao);
// See if we need to create a name for this VAO on the fly, this would happen if:
// - we're not the default VAO, because its name is always 0
// - our name is 0, this could happen if this VAO was created in the "other" context
// - the nameVersion is out of date *and* we're on the protected context, in this case:
// - the name must be stale from a previous use of this context because we always
// destroy the protected context when we're done with it.
bool const recreateVaoName = p != &mDefaultVAO &&
((vao->vao[contextIndex] == 0) ||
(vao->nameVersion != state.age && contextIndex == 1));
if (UTILS_UNLIKELY(recreateVaoName)) {
vao->nameVersion = state.age;
procs.genVertexArrays(1, &vao->vao[contextIndex]);
}
procs.bindVertexArray(vao->vao[contextIndex]);
// update GL_ELEMENT_ARRAY_BUFFER, which is updated by glBindVertexArray
size_t const targetIndex = getIndexForBufferTarget(GL_ELEMENT_ARRAY_BUFFER);
state.buffers.genericBinding[targetIndex] = vao->elementArray;
if (UTILS_UNLIKELY(bugs.vao_doesnt_store_element_array_buffer_binding)) {
if (UTILS_UNLIKELY(bugs.vao_doesnt_store_element_array_buffer_binding || recreateVaoName)) {
// This shouldn't be needed, but it looks like some drivers don't do the implicit
// glBindBuffer().
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vao->elementArray);
@@ -678,40 +774,13 @@ void OpenGLContext::bindBufferRange(GLenum target, GLuint index, GLuint buffer,
#endif
}
void OpenGLContext::bindFramebuffer(GLenum target, GLuint buffer) noexcept {
switch (target) {
case GL_FRAMEBUFFER:
if (state.draw_fbo != buffer || state.read_fbo != buffer) {
state.draw_fbo = state.read_fbo = buffer;
glBindFramebuffer(target, buffer);
}
break;
#ifndef FILAMENT_SILENCE_NOT_SUPPORTED_BY_ES2
case GL_DRAW_FRAMEBUFFER:
if (state.draw_fbo != buffer) {
state.draw_fbo = buffer;
glBindFramebuffer(target, buffer);
}
break;
case GL_READ_FRAMEBUFFER:
if (state.read_fbo != buffer) {
state.read_fbo = buffer;
glBindFramebuffer(target, buffer);
}
break;
#endif
default:
break;
}
}
void OpenGLContext::bindTexture(GLuint unit, GLuint target, GLuint texId, size_t targetIndex) noexcept {
assert_invariant(targetIndex == getIndexForTextureTarget(target));
assert_invariant(targetIndex < TEXTURE_TARGET_COUNT);
update_state(state.textures.units[unit].targets[targetIndex].texture_id, texId, [&]() {
activeTexture(unit);
glBindTexture(target, texId);
}, (target == GL_TEXTURE_EXTERNAL_OES) && bugs.texture_external_needs_rebind);
}, target == GL_TEXTURE_EXTERNAL_OES);
}
void OpenGLContext::bindTexture(GLuint unit, GLuint target, GLuint texId) noexcept {
@@ -724,20 +793,22 @@ void OpenGLContext::useProgram(GLuint program) noexcept {
});
}
void OpenGLContext::enableVertexAttribArray(GLuint index) noexcept {
assert_invariant(state.vao.p);
assert_invariant(index < state.vao.p->vertexAttribArray.size());
if (UTILS_UNLIKELY(!state.vao.p->vertexAttribArray[index])) {
state.vao.p->vertexAttribArray.set(index);
void OpenGLContext::enableVertexAttribArray(RenderPrimitive const* rp, GLuint index) noexcept {
assert_invariant(rp);
assert_invariant(index < rp->vertexAttribArray.size());
bool const force = rp->stateVersion != state.age;
if (UTILS_UNLIKELY(force || !rp->vertexAttribArray[index])) {
rp->vertexAttribArray.set(index);
glEnableVertexAttribArray(index);
}
}
void OpenGLContext::disableVertexAttribArray(GLuint index) noexcept {
assert_invariant(state.vao.p);
assert_invariant(index < state.vao.p->vertexAttribArray.size());
if (UTILS_UNLIKELY(state.vao.p->vertexAttribArray[index])) {
state.vao.p->vertexAttribArray.unset(index);
void OpenGLContext::disableVertexAttribArray(RenderPrimitive const* rp, GLuint index) noexcept {
assert_invariant(rp);
assert_invariant(index < rp->vertexAttribArray.size());
bool const force = rp->stateVersion != state.age;
if (UTILS_UNLIKELY(force || rp->vertexAttribArray[index])) {
rp->vertexAttribArray.unset(index);
glDisableVertexAttribArray(index);
}
}
File diff suppressed because it is too large Load Diff
+61 -89
View File
@@ -18,27 +18,44 @@
#define TNT_FILAMENT_BACKEND_OPENGL_OPENGLDRIVER_H
#include "DriverBase.h"
#include "GLUtils.h"
#include "OpenGLContext.h"
#include "OpenGLTimerQuery.h"
#include "GLBufferObject.h"
#include "GLTexture.h"
#include "ShaderCompilerService.h"
#include "private/backend/Driver.h"
#include "private/backend/HandleAllocator.h"
#include <backend/platforms/OpenGLPlatform.h>
#include <backend/AcquiredImage.h>
#include <backend/DriverEnums.h>
#include <backend/Handle.h>
#include <backend/Platform.h>
#include <backend/Program.h>
#include <backend/TargetBufferInfo.h>
#include "private/backend/Driver.h"
#include "private/backend/HandleAllocator.h"
#include <utils/FixedCapacityVector.h>
#include <utils/compiler.h>
#include <utils/Allocator.h>
#include <utils/debug.h>
#include <math/vec4.h>
#include <tsl/robin_map.h>
#include <set>
#include <array>
#include <condition_variable>
#include <functional>
#include <memory>
#include <mutex>
#include <tuple>
#include <type_traits>
#include <utility>
#include <vector>
#include <stddef.h>
#include <stdint.h>
#ifndef FILAMENT_OPENGL_HANDLE_ARENA_SIZE_IN_MB
# define FILAMENT_OPENGL_HANDLE_ARENA_SIZE_IN_MB 4
@@ -51,15 +68,17 @@ class PixelBufferDescriptor;
struct TargetBufferInfo;
class OpenGLProgram;
class OpenGLTimerQueryInterface;
class TimerQueryFactoryInterface;
class OpenGLDriver final : public DriverBase {
inline explicit OpenGLDriver(OpenGLPlatform* platform, const Platform::DriverConfig& driverConfig) noexcept;
inline explicit OpenGLDriver(OpenGLPlatform* platform,
const Platform::DriverConfig& driverConfig) noexcept;
~OpenGLDriver() noexcept final;
Dispatcher getDispatcher() const noexcept final;
public:
static Driver* create(OpenGLPlatform* platform, void* sharedGLContext, const Platform::DriverConfig& driverConfig) noexcept;
static Driver* create(OpenGLPlatform* platform, void* sharedGLContext,
const Platform::DriverConfig& driverConfig) noexcept;
class DebugMarker {
OpenGLDriver& driver;
@@ -75,27 +94,22 @@ public:
bool rec709 = false;
};
struct GLBufferObject : public HwBufferObject {
using HwBufferObject::HwBufferObject;
GLBufferObject(uint32_t size,
BufferObjectBinding bindingType, BufferUsage usage) noexcept
: HwBufferObject(size), usage(usage), bindingType(bindingType) {
struct GLVertexBufferInfo : public HwVertexBufferInfo {
GLVertexBufferInfo() noexcept = default;
GLVertexBufferInfo(uint8_t bufferCount, uint8_t attributeCount,
AttributeArray const& attributes)
: HwVertexBufferInfo(bufferCount, attributeCount),
attributes(attributes) {
}
struct {
GLuint id;
union {
GLenum binding;
void* buffer;
};
} gl;
BufferUsage usage;
BufferObjectBinding bindingType;
uint16_t age = 0;
AttributeArray attributes;
};
struct GLVertexBuffer : public HwVertexBuffer {
using HwVertexBuffer::HwVertexBuffer;
GLVertexBuffer() noexcept = default;
GLVertexBuffer(uint32_t vertexCount, Handle<HwVertexBufferInfo> vbih)
: HwVertexBuffer(vertexCount), vbih(vbih) {
}
Handle<HwVertexBufferInfo> vbih;
struct {
// 4 * MAX_VERTEX_ATTRIBUTE_COUNT bytes
std::array<GLuint, MAX_VERTEX_ATTRIBUTE_COUNT> buffers{};
@@ -109,7 +123,6 @@ public:
} gl;
};
struct GLTexture;
struct GLSamplerGroup : public HwSamplerGroup {
using HwSamplerGroup::HwSamplerGroup;
struct Entry {
@@ -123,39 +136,14 @@ public:
struct GLRenderPrimitive : public HwRenderPrimitive {
using HwRenderPrimitive::HwRenderPrimitive;
OpenGLContext::RenderPrimitive gl;
Handle<HwVertexBufferInfo> vbih;
};
struct GLTexture : public HwTexture {
using HwTexture::HwTexture;
struct GL {
GL() noexcept : imported(false), sidecarSamples(1), reserved(0) {}
GLuint id = 0; // texture or renderbuffer id
GLenum target = 0;
GLenum internalFormat = 0;
GLuint sidecarRenderBufferMS = 0; // multi-sample sidecar renderbuffer
using GLBufferObject = filament::backend::GLBufferObject;
// texture parameters go here too
GLfloat anisotropy = 1.0;
int8_t baseLevel = 127;
int8_t maxLevel = -1;
uint8_t targetIndex = 0; // optimization: index corresponding to target
bool imported : 1;
uint8_t sidecarSamples : 4;
uint8_t reserved : 3;
} gl;
using GLTexture = filament::backend::GLTexture;
OpenGLPlatform::ExternalTexture* externalTexture = nullptr;
};
struct GLTimerQuery : public HwTimerQuery {
struct State {
struct {
GLuint query;
} gl;
std::atomic<int64_t> elapsed{};
};
std::shared_ptr<State> state;
};
using GLTimerQuery = filament::backend::GLTimerQuery;
struct GLStream : public HwStream {
using HwStream::HwStream;
@@ -209,8 +197,8 @@ private:
OpenGLContext mContext;
ShaderCompilerService mShaderCompilerService;
friend class OpenGLTimerQueryFactory;
friend class TimerQueryNative;
friend class TimerQueryFactory;
friend class TimerQueryNativeFactory;
OpenGLContext& getContext() noexcept { return mContext; }
ShaderCompilerService& getShaderCompilerService() noexcept {
@@ -244,13 +232,13 @@ private:
HandleAllocatorGL mHandleAllocator;
template<typename D, typename ... ARGS>
Handle<D> initHandle(ARGS&& ... args) noexcept {
Handle<D> initHandle(ARGS&& ... args) {
return mHandleAllocator.allocateAndConstruct<D>(std::forward<ARGS>(args) ...);
}
template<typename D, typename B, typename ... ARGS>
typename std::enable_if<std::is_base_of<B, D>::value, D>::type*
construct(Handle<B> const& handle, ARGS&& ... args) noexcept {
construct(Handle<B> const& handle, ARGS&& ... args) {
return mHandleAllocator.destroyAndConstruct<D, B>(handle, std::forward<ARGS>(args) ...);
}
@@ -264,7 +252,7 @@ private:
typename std::enable_if_t<
std::is_pointer_v<Dp> &&
std::is_base_of_v<B, typename std::remove_pointer_t<Dp>>, Dp>
handle_cast(Handle<B>& handle) noexcept {
handle_cast(Handle<B>& handle) {
return mHandleAllocator.handle_cast<Dp, B>(handle);
}
@@ -272,7 +260,7 @@ private:
inline typename std::enable_if_t<
std::is_pointer_v<Dp> &&
std::is_base_of_v<B, typename std::remove_pointer_t<Dp>>, Dp>
handle_cast(Handle<B> const& handle) noexcept {
handle_cast(Handle<B> const& handle) {
return mHandleAllocator.handle_cast<Dp, B>(handle);
}
@@ -290,7 +278,7 @@ private:
void updateVertexArrayObject(GLRenderPrimitive* rp, GLVertexBuffer const* vb);
void framebufferTexture(TargetBufferInfo const& binfo,
GLRenderTarget const* rt, GLenum attachment) noexcept;
GLRenderTarget const* rt, GLenum attachment, uint8_t layerCount) noexcept;
void setRasterState(RasterState rs) noexcept;
@@ -311,8 +299,8 @@ private:
void renderBufferStorage(GLuint rbo, GLenum internalformat, uint32_t width,
uint32_t height, uint8_t samples) const noexcept;
void textureStorage(GLTexture* t,
uint32_t width, uint32_t height, uint32_t depth) noexcept;
void textureStorage(OpenGLDriver::GLTexture* t, uint32_t width, uint32_t height,
uint32_t depth, bool useProtectedMemory) noexcept;
/* State tracking GL wrappers... */
@@ -324,29 +312,13 @@ private:
void resolvePass(ResolveAction action, GLRenderTarget const* rt,
TargetBufferFlags discardFlags) noexcept;
#ifndef FILAMENT_SILENCE_NOT_SUPPORTED_BY_ES2
GLuint getSamplerSlow(SamplerParams sp) const noexcept;
inline GLuint getSampler(SamplerParams sp) const noexcept {
assert_invariant(!sp.padding0);
assert_invariant(!sp.padding1);
assert_invariant(!sp.padding2);
auto& samplerMap = mSamplerMap;
auto pos = samplerMap.find(sp);
if (UTILS_UNLIKELY(pos == samplerMap.end())) {
return getSamplerSlow(sp);
}
return pos->second;
}
#endif
const std::array<GLSamplerGroup*, Program::SAMPLER_BINDING_COUNT>& getSamplerBindings() const {
return mSamplerBindings;
}
using AttachmentArray = std::array<GLenum, MRT::MAX_SUPPORTED_RENDER_TARGET_COUNT + 2>;
static GLsizei getAttachments(AttachmentArray& attachments,
GLRenderTarget const* rt, TargetBufferFlags buffers) noexcept;
static GLsizei getAttachments(AttachmentArray& attachments, TargetBufferFlags buffers,
bool isDefaultFramebuffer) noexcept;
// state required to represent the current render pass
Handle<HwRenderTarget> mRenderPassTarget;
@@ -355,6 +327,10 @@ private:
GLboolean mRenderPassDepthWrite{};
GLboolean mRenderPassStencilWrite{};
GLRenderPrimitive const* mBoundRenderPrimitive = nullptr;
bool mValidProgram = false;
void clearWithRasterPipe(TargetBufferFlags clearFlags,
math::float4 const& linearColor, GLfloat depth, GLint stencil) noexcept;
@@ -362,14 +338,10 @@ private:
// ES2 only. Uniform buffer emulation binding points
GLuint mLastAssignedEmulatedUboId = 0;
std::array<std::tuple<GLuint, void const*, uint16_t>, Program::UNIFORM_BINDING_COUNT> mUniformBindings = {};
// sampler buffer binding points (nullptr if not used)
std::array<GLSamplerGroup*, Program::SAMPLER_BINDING_COUNT> mSamplerBindings = {}; // 4 pointers
mutable tsl::robin_map<SamplerParams, GLuint,
SamplerParams::Hasher, SamplerParams::EqualTo> mSamplerMap;
// this must be accessed from the driver thread only
std::vector<GLTexture*> mTexturesWithStreamsAttached;
@@ -397,8 +369,8 @@ private:
void executeEveryNowAndThenOps() noexcept;
std::vector<std::function<bool()>> mEveryNowAndThenOps;
// timer query implementation
OpenGLTimerQueryInterface* mTimerQueryImpl = nullptr;
const Platform::DriverConfig mDriverConfig;
Platform::DriverConfig const& getDriverConfig() const noexcept { return mDriverConfig; }
// for ES2 sRGB support
GLSwapChain* mCurrentDrawSwapChain = nullptr;
+30 -2
View File
@@ -18,6 +18,17 @@
#include "OpenGLDriverFactory.h"
#include <backend/AcquiredImage.h>
#include <backend/DriverEnums.h>
#include <backend/Platform.h>
#include <utils/compiler.h>
#include <utils/Invocable.h>
#include <stddef.h>
#include <stdint.h>
#include <stdlib.h>
namespace filament::backend {
Driver* OpenGLPlatform::createDefaultDriver(OpenGLPlatform* platform,
@@ -27,14 +38,27 @@ Driver* OpenGLPlatform::createDefaultDriver(OpenGLPlatform* platform,
OpenGLPlatform::~OpenGLPlatform() noexcept = default;
void OpenGLPlatform::makeCurrent(SwapChain* drawSwapChain, SwapChain* readSwapChain,
utils::Invocable<void()>, utils::Invocable<void(size_t)>) noexcept {
makeCurrent(getCurrentContextType(), drawSwapChain, readSwapChain);
}
bool OpenGLPlatform::isProtectedContextSupported() const noexcept {
return false;
}
bool OpenGLPlatform::isSRGBSwapChainSupported() const noexcept {
return false;
}
uint32_t OpenGLPlatform::createDefaultRenderTarget() noexcept {
uint32_t OpenGLPlatform::getDefaultFramebufferObject() noexcept {
return 0;
}
OpenGLPlatform::ContextType OpenGLPlatform::getCurrentContextType() const noexcept {
return ContextType::UNPROTECTED;
}
void OpenGLPlatform::setPresentationTime(
UTILS_UNUSED int64_t presentationTimeInNanosecond) noexcept {
}
@@ -105,10 +129,14 @@ AcquiredImage OpenGLPlatform::transformAcquiredImage(AcquiredImage source) noexc
return source;
}
TargetBufferFlags OpenGLPlatform::getPreservedFlags(UTILS_UNUSED SwapChain* swapChain) noexcept {
TargetBufferFlags OpenGLPlatform::getPreservedFlags(UTILS_UNUSED SwapChain*) noexcept {
return TargetBufferFlags::NONE;
}
bool OpenGLPlatform::isSwapChainProtected(UTILS_UNUSED SwapChain*) noexcept {
return false;
}
bool OpenGLPlatform::isExtraContextSupported() const noexcept {
return false;
}
+11 -2
View File
@@ -16,16 +16,25 @@
#include "OpenGLProgram.h"
#include "BlobCacheKey.h"
#include "GLUtils.h"
#include "OpenGLDriver.h"
#include "ShaderCompilerService.h"
#include <backend/Program.h>
#include <private/backend/BackendUtils.h>
#include <utils/debug.h>
#include <utils/compiler.h>
#include <utils/Log.h>
#include <utils/Systrace.h>
#include <private/backend/BackendUtils.h>
#include <array>
#include <string_view>
#include <utility>
#include <new>
#include <stddef.h>
namespace filament::backend {
+15 -10
View File
@@ -28,6 +28,9 @@
#include <utils/compiler.h>
#include <utils/FixedCapacityVector.h>
#include <array>
#include <limits>
#include <stddef.h>
#include <stdint.h>
@@ -67,14 +70,14 @@ public:
}
}
struct {
GLuint program = 0;
} gl; // 12 bytes
// For ES2 only
void updateUniforms(uint32_t index, GLuint id, void const* buffer, uint16_t age) noexcept;
void setRec709ColorSpace(bool rec709) const noexcept;
struct {
GLuint program = 0;
} gl; // 4 bytes
private:
// keep these away from of other class attributes
struct LazyInitializationData;
@@ -86,14 +89,17 @@ private:
void updateSamplers(OpenGLDriver* gld) const noexcept;
ShaderCompilerService::program_token_t mToken{};
// number of bindings actually used by this program
uint8_t mUsedBindingsCount = 0u;
UTILS_UNUSED uint8_t padding[3] = {};
std::array<uint8_t, Program::SAMPLER_BINDING_COUNT> mUsedSamplerBindingPoints; // 4 bytes
ShaderCompilerService::program_token_t mToken{}; // 16 bytes
uint8_t mUsedBindingsCount = 0u; // 1 byte
UTILS_UNUSED uint8_t padding[3] = {}; // 3 bytes
// only needed for ES2
GLint mRec709Location = -1; // 4 bytes
using LocationInfo = utils::FixedCapacityVector<GLint>;
struct UniformsRecord {
Program::UniformInfo uniforms;
@@ -102,11 +108,10 @@ private:
mutable uint16_t age = std::numeric_limits<uint16_t>::max();
};
UniformsRecord const* mUniformsRecords = nullptr;
GLint mRec709Location = -1;
};
// if OpenGLProgram is larger tha 64 bytes, it'll fall in a larger Handle bucket.
static_assert(sizeof(OpenGLProgram) <= 64);
static_assert(sizeof(OpenGLProgram) <= 64); // currently 48 bytes
} // namespace filament::backend
@@ -16,110 +16,132 @@
#include "OpenGLTimerQuery.h"
#include "GLUtils.h"
#include "OpenGLDriver.h"
#include <backend/Platform.h>
#include <backend/platforms/OpenGLPlatform.h>
#include <backend/DriverEnums.h>
#include <utils/compiler.h>
#include <utils/debug.h>
#include <utils/JobSystem.h>
#include <utils/Log.h>
#include <utils/Mutex.h>
#include <utils/Systrace.h>
#include <utils/debug.h>
#include <atomic>
#include <memory>
#include <mutex>
#include <new>
#include <utility>
#include <stdint.h>
namespace filament::backend {
using namespace backend;
using namespace GLUtils;
class OpenGLDriver;
// ------------------------------------------------------------------------------------------------
bool OpenGLTimerQueryFactory::mGpuTimeSupported = false;
bool TimerQueryFactory::mGpuTimeSupported = false;
OpenGLTimerQueryInterface* OpenGLTimerQueryFactory::init(
OpenGLPlatform& platform, OpenGLDriver& driver) noexcept {
(void)driver;
TimerQueryFactoryInterface* TimerQueryFactory::init(
OpenGLPlatform& platform, OpenGLContext& context) noexcept {
(void)context;
OpenGLTimerQueryInterface* impl;
TimerQueryFactoryInterface* impl = nullptr;
#if defined(BACKEND_OPENGL_VERSION_GL) || defined(GL_EXT_disjoint_timer_query)
auto& context = driver.getContext();
if (context.ext.EXT_disjoint_timer_query) {
// timer queries are available
if (context.bugs.dont_use_timer_query && platform.canCreateFence()) {
// however, they don't work well, revert to using fences if we can.
impl = new(std::nothrow) OpenGLTimerQueryFence(platform);
impl = new(std::nothrow) TimerQueryFenceFactory(platform);
} else {
impl = new(std::nothrow) TimerQueryNative(driver);
impl = new(std::nothrow) TimerQueryNativeFactory(context);
}
mGpuTimeSupported = true;
} else
#endif
if (platform.canCreateFence()) {
// no timer queries, but we can use fences
impl = new(std::nothrow) OpenGLTimerQueryFence(platform);
impl = new(std::nothrow) TimerQueryFenceFactory(platform);
mGpuTimeSupported = true;
} else {
// no queries, no fences -- that's a problem
impl = new(std::nothrow) TimerQueryFallback();
impl = new(std::nothrow) TimerQueryFallbackFactory();
mGpuTimeSupported = false;
}
assert_invariant(impl);
return impl;
}
// ------------------------------------------------------------------------------------------------
OpenGLTimerQueryInterface::~OpenGLTimerQueryInterface() = default;
TimerQueryFactoryInterface::~TimerQueryFactoryInterface() = default;
// This is a backend synchronous call
bool OpenGLTimerQueryInterface::getTimerQueryValue(GLTimerQuery* tq, uint64_t* elapsedTime) noexcept {
TimerQueryResult TimerQueryFactoryInterface::getTimerQueryValue(
GLTimerQuery* tq, uint64_t* elapsedTime) noexcept {
if (UTILS_LIKELY(tq->state)) {
int64_t const elapsed = tq->state->elapsed.load(std::memory_order_relaxed);
bool const available = elapsed > 0;
if (available) {
if (elapsed > 0) {
*elapsedTime = elapsed;
return TimerQueryResult::AVAILABLE;
}
return available;
return TimerQueryResult(elapsed);
}
return false;
return TimerQueryResult::ERROR;
}
// ------------------------------------------------------------------------------------------------
#if defined(BACKEND_OPENGL_VERSION_GL) || defined(GL_EXT_disjoint_timer_query)
TimerQueryNative::TimerQueryNative(OpenGLDriver& driver)
: mDriver(driver) {
TimerQueryNativeFactory::TimerQueryNativeFactory(OpenGLContext& context)
: mContext(context) {
}
TimerQueryNative::~TimerQueryNative() = default;
TimerQueryNativeFactory::~TimerQueryNativeFactory() = default;
void TimerQueryNative::createTimerQuery(GLTimerQuery* tq) {
if (UTILS_UNLIKELY(!tq->state)) {
tq->state = std::make_shared<GLTimerQuery::State>();
}
mDriver.getContext().procs.genQueries(1u, &tq->state->gl.query);
void TimerQueryNativeFactory::createTimerQuery(GLTimerQuery* tq) {
assert_invariant(!tq->state);
tq->state = std::make_shared<GLTimerQuery::State>();
mContext.procs.genQueries(1u, &tq->state->gl.query);
CHECK_GL_ERROR(utils::slog.e)
}
void TimerQueryNative::destroyTimerQuery(GLTimerQuery* tq) {
void TimerQueryNativeFactory::destroyTimerQuery(GLTimerQuery* tq) {
assert_invariant(tq->state);
mDriver.getContext().procs.deleteQueries(1u, &tq->state->gl.query);
mContext.procs.deleteQueries(1u, &tq->state->gl.query);
CHECK_GL_ERROR(utils::slog.e)
tq->state.reset();
}
void TimerQueryNativeFactory::beginTimeElapsedQuery(GLTimerQuery* tq) {
assert_invariant(tq->state);
tq->state->elapsed.store(int64_t(TimerQueryResult::NOT_READY), std::memory_order_relaxed);
mContext.procs.beginQuery(GL_TIME_ELAPSED, tq->state->gl.query);
CHECK_GL_ERROR(utils::slog.e)
}
void TimerQueryNative::beginTimeElapsedQuery(GLTimerQuery* tq) {
void TimerQueryNativeFactory::endTimeElapsedQuery(OpenGLDriver& driver, GLTimerQuery* tq) {
assert_invariant(tq->state);
tq->state->elapsed.store(0);
mDriver.getContext().procs.beginQuery(GL_TIME_ELAPSED, tq->state->gl.query);
CHECK_GL_ERROR(utils::slog.e)
}
void TimerQueryNative::endTimeElapsedQuery(GLTimerQuery* tq) {
assert_invariant(tq->state);
mDriver.getContext().procs.endQuery(GL_TIME_ELAPSED);
mContext.procs.endQuery(GL_TIME_ELAPSED);
CHECK_GL_ERROR(utils::slog.e)
std::weak_ptr<GLTimerQuery::State> const weak = tq->state;
mDriver.runEveryNowAndThen([context = mDriver.getContext(), weak]() -> bool {
driver.runEveryNowAndThen([&context = mContext, weak]() -> bool {
auto state = weak.lock();
if (state) {
GLuint available = 0;
@@ -133,6 +155,8 @@ void TimerQueryNative::endTimeElapsedQuery(GLTimerQuery* tq) {
// we won't end-up here if we're on ES and don't have GL_EXT_disjoint_timer_query
context.procs.getQueryObjectui64v(state->gl.query, GL_QUERY_RESULT, &elapsedTime);
state->elapsed.store((int64_t)elapsedTime, std::memory_order_relaxed);
} else {
state->elapsed.store(int64_t(TimerQueryResult::ERROR), std::memory_order_relaxed);
}
return true;
});
@@ -142,7 +166,7 @@ void TimerQueryNative::endTimeElapsedQuery(GLTimerQuery* tq) {
// ------------------------------------------------------------------------------------------------
OpenGLTimerQueryFence::OpenGLTimerQueryFence(OpenGLPlatform& platform)
TimerQueryFenceFactory::TimerQueryFenceFactory(OpenGLPlatform& platform)
: mPlatform(platform) {
mQueue.reserve(2);
mThread = std::thread([this]() {
@@ -166,7 +190,8 @@ OpenGLTimerQueryFence::OpenGLTimerQueryFence(OpenGLPlatform& platform)
});
}
OpenGLTimerQueryFence::~OpenGLTimerQueryFence() {
TimerQueryFenceFactory::~TimerQueryFenceFactory() {
assert_invariant(mQueue.empty());
if (mThread.joinable()) {
std::unique_lock<utils::Mutex> lock(mLock);
mExitRequested = true;
@@ -178,27 +203,26 @@ OpenGLTimerQueryFence::~OpenGLTimerQueryFence() {
}
}
void OpenGLTimerQueryFence::enqueue(OpenGLTimerQueryFence::Job&& job) {
void TimerQueryFenceFactory::push(TimerQueryFenceFactory::Job&& job) {
std::unique_lock<utils::Mutex> const lock(mLock);
mQueue.push_back(std::forward<Job>(job));
mQueue.push_back(std::move(job));
mCondition.notify_one();
}
void OpenGLTimerQueryFence::createTimerQuery(GLTimerQuery* tq) {
if (UTILS_UNLIKELY(!tq->state)) {
tq->state = std::make_shared<GLTimerQuery::State>();
}
void TimerQueryFenceFactory::createTimerQuery(GLTimerQuery* tq) {
assert_invariant(!tq->state);
tq->state = std::make_shared<GLTimerQuery::State>();
}
void OpenGLTimerQueryFence::destroyTimerQuery(GLTimerQuery* tq) {
void TimerQueryFenceFactory::destroyTimerQuery(GLTimerQuery* tq) {
assert_invariant(tq->state);
tq->state.reset();
}
void OpenGLTimerQueryFence::beginTimeElapsedQuery(GLTimerQuery* tq) {
void TimerQueryFenceFactory::beginTimeElapsedQuery(GLTimerQuery* tq) {
assert_invariant(tq->state);
tq->state->elapsed.store(0);
tq->state->elapsed.store(int64_t(TimerQueryResult::NOT_READY), std::memory_order_relaxed);
Platform::Fence* fence = mPlatform.createFence();
std::weak_ptr<GLTimerQuery::State> const weak = tq->state;
// FIXME: this implementation of beginTimeElapsedQuery is usually wrong; it ends up
@@ -207,12 +231,11 @@ void OpenGLTimerQueryFence::beginTimeElapsedQuery(GLTimerQuery* tq) {
// on a dummy target for instance, or somehow latch the begin time at the next renderpass
// start.
push([&platform = mPlatform, fence, weak]() {
push([&platform = mPlatform, fence = mPlatform.createFence(), weak]() {
auto state = weak.lock();
if (state) {
platform.waitFence(fence, FENCE_WAIT_FOR_EVER);
int64_t const then = clock::now().time_since_epoch().count();
state->elapsed.store(-then, std::memory_order_relaxed);
state->then = clock::now().time_since_epoch().count();
SYSTRACE_CONTEXT();
SYSTRACE_ASYNC_BEGIN("OpenGLTimerQueryFence", intptr_t(state.get()));
}
@@ -220,19 +243,16 @@ void OpenGLTimerQueryFence::beginTimeElapsedQuery(GLTimerQuery* tq) {
});
}
void OpenGLTimerQueryFence::endTimeElapsedQuery(GLTimerQuery* tq) {
void TimerQueryFenceFactory::endTimeElapsedQuery(OpenGLDriver&, GLTimerQuery* tq) {
assert_invariant(tq->state);
Platform::Fence* fence = mPlatform.createFence();
std::weak_ptr<GLTimerQuery::State> const weak = tq->state;
push([&platform = mPlatform, fence, weak]() {
push([&platform = mPlatform, fence = mPlatform.createFence(), weak]() {
auto state = weak.lock();
if (state) {
platform.waitFence(fence, FENCE_WAIT_FOR_EVER);
int64_t const now = clock::now().time_since_epoch().count();
int64_t const then = state->elapsed.load(std::memory_order_relaxed);
assert_invariant(then < 0);
state->elapsed.store(now + then, std::memory_order_relaxed);
state->elapsed.store(now - state->then, std::memory_order_relaxed);
SYSTRACE_CONTEXT();
SYSTRACE_ASYNC_END("OpenGLTimerQueryFence", intptr_t(state.get()));
}
@@ -242,34 +262,32 @@ void OpenGLTimerQueryFence::endTimeElapsedQuery(GLTimerQuery* tq) {
// ------------------------------------------------------------------------------------------------
TimerQueryFallback::TimerQueryFallback() = default;
TimerQueryFallbackFactory::TimerQueryFallbackFactory() = default;
TimerQueryFallback::~TimerQueryFallback() = default;
TimerQueryFallbackFactory::~TimerQueryFallbackFactory() = default;
void TimerQueryFallback::createTimerQuery(GLTimerQuery* tq) {
if (UTILS_UNLIKELY(!tq->state)) {
tq->state = std::make_shared<GLTimerQuery::State>();
}
void TimerQueryFallbackFactory::createTimerQuery(GLTimerQuery* tq) {
assert_invariant(!tq->state);
tq->state = std::make_shared<GLTimerQuery::State>();
}
void TimerQueryFallback::destroyTimerQuery(GLTimerQuery* tq) {
void TimerQueryFallbackFactory::destroyTimerQuery(GLTimerQuery* tq) {
assert_invariant(tq->state);
tq->state.reset();
}
void TimerQueryFallback::beginTimeElapsedQuery(OpenGLTimerQueryInterface::GLTimerQuery* tq) {
void TimerQueryFallbackFactory::beginTimeElapsedQuery(GLTimerQuery* tq) {
assert_invariant(tq->state);
// this implementation measures the CPU time, but we have no h/w support
int64_t const then = clock::now().time_since_epoch().count();
tq->state->elapsed.store(-then, std::memory_order_relaxed);
tq->state->then = clock::now().time_since_epoch().count();
tq->state->elapsed.store(int64_t(TimerQueryResult::NOT_READY), std::memory_order_relaxed);
}
void TimerQueryFallback::endTimeElapsedQuery(OpenGLTimerQueryInterface::GLTimerQuery* tq) {
void TimerQueryFallbackFactory::endTimeElapsedQuery(OpenGLDriver&, GLTimerQuery* tq) {
assert_invariant(tq->state);
// this implementation measures the CPU time, but we have no h/w support
int64_t const now = clock::now().time_since_epoch().count();
int64_t const then = tq->state->elapsed.load(std::memory_order_relaxed);
assert_invariant(then < 0);
tq->state->elapsed.store(now + then, std::memory_order_relaxed);
tq->state->elapsed.store(now - tq->state->then, std::memory_order_relaxed);
}
} // namespace filament::backend

Some files were not shown because too many files have changed in this diff Show More